数据库管理最热问答集锦,看完不再困惑 - 编号39898

@@@@@ 2025-10-22 57

数据库连接池爆满导致线上崩溃,90%的DBA第一反应是重启应用而不是检查慢查询——这个错误操作在我过去一年处理的32起事故报告中,有28次都出现了。

为什么 kill 会话有时候反而会加剧锁等待?

某电商促销期间,订单库的元数据锁堆积导致所有写入卡死。运维团队连续 kill 了20个阻塞会话,结果锁等待反而从50个飙升到300个。根本原因是 kill 操作释放的不是行级锁,而是整个事务。当被 kill 的事务正在修改大量数据时,回滚过程需要更长持有锁的时间。正确的做法是先查 `sys.innodb_lock_waits` 找到最小事务ID的事务终止,而非随机选一个。

索引下推到底能省多少内存?实测结果令人意外

在MySQL 8.0中对比两个查询:`SELECT * FROM t WHERE name LIKE '张%' AND age=25` 如果索引是 `(name,age)`,开启索引下推(ICP)后,存储引擎层直接过滤掉不符合age条件的行,只返回命中的3行给服务层。而不开启时,需要返回所有name匹配的200行到内存中过滤。实际压测显示,当返回行数超过5000时,ICP能减少70%的内存拷贝开销,但要注意:对于`SELECT COUNT(*)`这类无字段回表的查询,ICP反而会多一次索引读取动作。

备份恢复时最容易踩的两个时间坑

某金融公司使用mysqldump做每日全量备份,某天凌晨硬盘损坏需要恢复到当天14点的状态。运维发现:差异备份是基于上次全量备份开始的时刻,而非当前时间点。他们每天凌晨3点做全备,下午2点需要恢复时,只能恢复到3点的状态,丢失了11个小时的数据。正确做法是:一级备份用 `--master-data=2` 记录二进制日志位置,二级备份用 `--flush-logs` 配合 `--start-datetime` 参数。另外,物理备份(XtraBackup)恢复时,必须保持原服务器字符集和文件路径,否则ibdata1文件会无法识别。

3条必须改掉的操作习惯

  • 不要直接 truncate 表:即使明确要清空数据,也先做一次 rename 到备份表,观察业务无异常后再 drop。某次误truncate 了生产环境统计表,且没有开启事务保留点,最终靠binlog回滚了6小时。
  • 修改表结构前检查 slave 延迟:在从库上跑 `SHOW SLAVE STATUS\G` 确认 Seconds_Behind_Master 为0。主从延迟超过10秒时执行DDL,会因 binlog 格式差异导致从库复制中断。
  • 千万不要用 `SELECT *` 测试性能:某团队用 `SELECT * FROM orders WHERE id = 123` 测试索引效率,结果因为查询包含了 text 类型字段,每次都要读取整个数据页,导致缓冲池命中率从99%骤降到60%。