我的测试学习站TEST LEARNING HUB
开始学习
首页/我的面试题/如何结合日志系统分析 bug,关系型数据库

如何结合日志系统分析 bug,关系型数据库

日志系统怎么建

一套好用的日志系统,至少要解决:

  • 结构化:JSON 格式,字段稳定,便于检索和聚合。
  • 关联:traceId、spanId、requestId、userId、orderId。
  • 分级:DEBUG、INFO、WARN、ERROR,生产环境控制级别。
  • 集中化:ELK/EFK、Loki、Splunk、云日志服务。
  • 保留和索引:按天/大小滚动,重要日志长期保留。
  • 安全:脱敏手机号、身份证、密码、token,不记录敏感信息。
  • 告警:错误率、关键字、超时、队列堆积。

推荐日志字段:

{
  "timestamp": "2026-10-18T12:00:00.123Z",
  "level": "ERROR",
  "service": "order-service",
  "traceId": "a1b2c3",
  "spanId": "d4e5f6",
  "userId": "u1001",
  "orderId": "NO10001",
  "method": "POST",
  "path": "/api/orders",
  "status": 500,
  "durationMs": 1200,
  "error": "duplicate key value violates unique constraint",
  "message": "create order failed"
}

排查 bug 的流程

1. 收集事实

  • 发生时间、用户、订单号、请求 ID。
  • 复现步骤、环境、版本。
  • 影响范围:单个用户还是批量。
  • 最近变更:发布、配置、数据、依赖。

2. 用关联 ID 串起来

  • 从网关日志拿 traceId。
  • 在应用日志里查同一 traceId。
  • 查数据库、缓存、MQ 的相关操作。
  • 按时间排序,还原调用链。

3. 看错误模式

  • 异常堆栈、错误码、超时、重试。
  • 是否集中在某个实例、某个接口、某个用户。
  • 是否和发布、流量、数据量相关。

4. 查数据库状态

  • 订单状态、金额、库存是否符合预期。
  • 是否有重复数据、脏数据、锁等待。
  • 事务是否提交/回滚。

5. 形成假设并验证

  • 在测试环境复现。
  • 加日志或断点验证假设。
  • 修复后加回归用例。

关系型数据库排查

慢查询

MySQL:

-- 开启慢查询日志
SET GLOBAL slow_query_log = 'ON';
SET GLOBAL long_query_time = 1;

-- 查看慢查询
SHOW VARIABLES LIKE 'slow_query_log_file';

PostgreSQL:

-- 使用 pg_stat_statements
SELECT query, calls, total_exec_time, mean_exec_time
FROM pg_stat_statements
ORDER BY total_exec_time DESC
LIMIT 10;

执行计划

EXPLAIN ANALYZE
SELECT *
FROM orders
WHERE user_id = 1001
  AND status = 'pending'
ORDER BY created_at DESC
LIMIT 20;

重点看:

  • 是否走索引
  • 扫描行数
  • 回表次数
  • 排序和临时表
  • 预估行数和实际行数差异

索引问题

常见索引失效:

  • 对字段做函数运算:WHERE DATE(created_at) = '2026-10-18'
  • 隐式类型转换:字符串字段用数字查询
  • 前导模糊匹配:LIKE '%abc'
  • OR 条件部分字段无索引
  • 联合索引不满足最左前缀
  • 数据分布导致优化器放弃索引

锁和事务

MySQL:

SHOW PROCESSLIST;
SHOW ENGINE INNODB STATUS;
SELECT * FROM information_schema.innodb_trx;

PostgreSQL:

SELECT * FROM pg_stat_activity WHERE state != 'idle';
SELECT * FROM pg_locks;

关注:

  • 长事务
  • 行锁/表锁等待
  • 死锁
  • 连接数打满
  • 未提交事务

数据一致性

  • 唯一约束、外键约束是否生效。
  • 事务隔离级别是否符合预期。
  • 并发下是否出现超卖、重复下单、金额不一致。
  • 幂等键和唯一索引是否覆盖。

常见 bug 模式

现象可能原因
订单重复创建缺幂等键、重试、并发
库存超卖非原子扣减、锁范围不对
金额不一致计算精度、优惠券叠加、事务回滚
接口偶发 500连接池耗尽、超时、空指针
列表慢缺索引、大偏移、N+1
数据查不到事务未提交、读写分离延迟、缓存脏数据
死锁加锁顺序不一致、长事务
连接数打满连接未释放、池太小、慢查询

一个排查示例

现象:用户下单后订单一直显示“待支付”,但支付平台已扣款。

  1. 用订单号查应用日志,拿到 traceId。
  2. 按 traceId 查网关、订单服务、支付服务日志。
  3. 发现支付回调到达,但订单服务更新状态时抛了唯一键冲突。
  4. 查数据库:orders 表有重复的支付流水号,说明回调重复处理。
  5. 查代码:回调没有幂等校验,重试时重复插入。
  6. 修复:支付流水号加唯一索引,回调先查后写,放在同一事务。
  7. 回归:模拟重复回调,验证只处理一次。

最佳实践

  • 日志必须带 traceId 和业务 ID。
  • 错误日志包含上下文,但不要泄露敏感信息。
  • 慢查询、连接池、锁等待要有监控和告警。
  • 关键业务状态变更记录审计日志。
  • 排查时先看时间线,再看异常,再看数据。
  • 修复后补回归用例和监控指标。

面试回答模板

我会先用 traceId、用户 ID、订单号把网关、应用、数据库和 MQ 的日志串起来,按时间线还原调用链,重点看异常、超时、重试和数据状态。数据库侧会看慢查询、执行计划、索引、锁等待和事务,确认是查询慢、锁冲突还是数据不一致。定位后先复现,再修复,最后补回归用例和监控告警。日志本身要结构化、带关联 ID、脱敏,并接入集中检索和告警。