【安全与故障排查】06-【复盘】生产数据库删库事故:RTO4小时恢复纪实
【复盘】生产数据库删库事故RTO 4小时恢复纪实专栏安全 故障排查难度专家标签事故复盘数据库恢复RTO灾备MySQL前言2024年某周五下午4点一条误操作的DROP DATABASE让我们的生产数据库消失了。这是那4小时的完整记录希望所有DBA和运维工程师都读一遍。事故起因一名新员工在执行数据库迁移脚本时将测试环境的数据库名写错在生产数据库上执行了DROP DATABASE prod_db。-- 原本应该在测试库执行DROPDATABASEtest_db;-- 实际在生产库执行了DROPDATABASEprod_db;-- 包含5000万条数据时间线时间操作16:03误操作执行数据库消失16:05应用报错告警触发业务中断16:08值班工程师登录确认数据库丢失16:15启动紧急响应通知DBA、架构师、业务负责人16:30确认备份文件可用制定恢复方案17:00开始从全量备份恢复18:30全量恢复完成开始应用binlog增量19:45数据恢复到16:03业务验证数据完整20:10业务全面恢复实际RTO: 4小时7分钟恢复过程详解第一步停止写入保存现场# 立刻停止业务写入防止binlog被覆盖systemctl stop application# 备份当前binlogcp/var/lib/mysql/mysql-bin.* /data/recovery/# 查看最后的binlog文件和位置mysql-eSHOW MASTER STATUS\G第二步从备份恢复全量数据# 查找最近的全量备份ls-lt/backup/mysql/|head-5# 确认使用2024-xx-xx_00:00_full.sql.gz# 恢复全量备份约需要1.5小时gunzip-c/backup/mysql/full.sql.gz|mysql-uroot-p# 检查数据量mysql-eSELECT COUNT(*) FROM prod_db.orders;# 5000万 - N条N为事故到上次备份之间的新增数据第三步应用 binlog 追回增量数据# 从全量备份的binlog位置到事故发生时间点应用增量mysqlbinlog\--start-position12345678\--stop-datetime2024-XX-XX 16:02:59\/data/recovery/mysql-bin.000021\/data/recovery/mysql-bin.000022|\mysql-uroot-p# 验证数据量应该恢复到接近事故前mysql-eSELECT COUNT(*) FROM prod_db.orders;事故根因分析权限过大新员工拥有生产数据库的DROP权限无二次确认执行危险 DDL 没有任何确认机制测试生产环境混淆脚本硬编码数据库名无环境变量保护改进措施-- 1. 最小权限原则新员工只给只读权限REVOKEALLON*.*FROMnewuser%;GRANTSELECTONprod_db.*TOnewuser%;-- 2. 添加SQL审计使用Percona audit pluginINSTALL PLUGIN audit_logSONAMEaudit_log.so;-- 3. 关键操作需要DBA二次确认-- 流程提交工单 → DBA review → 双人执行# 4. 改善备份策略# 之前全量备份每天1次binlog 7天# 改后全量备份每天2次binlog 30天每小时上传OSS# 目标RPO 30分钟# 5. 生产数据库配置 super_read_onlymysql-eSET GLOBAL super_read_onlyON;# 所有写操作需要先关闭此选项提供操作窗口结语这次事故最贵的教训备份是一切恢复的基础。没有可用的备份任何技术都救不了你。每季度测试一次备份可恢复性是运维的最低标准。