
上个月我给客户数据库做清理,一条DELETE语句忘了加WHERE条件,三千多条订单记录瞬间没了。那一刻我手都是凉的。这篇复盘一下当时的处理流程,希望能帮到同样踩坑的人。
第一反应千万别慌,更别重启服务。MySQL的binlog开着的话,数据还有救。我先查了binlog状态,确认log_bin=ON,然后立刻把数据库设为只读,防止新数据覆盖。这一步决定了后面能不能恢复。
接着用mysqlbinlog把误删时间段的日志导出来,找到那条DELETE语句,把binlog里记录的行内容反过来转成INSERT。这里有个坑:binlog格式如果是statement,只能看到语句本身,行数据得靠备份;row格式才能精确恢复每一行。所以建库的时候,binlog_format=ROW一定要设上。
折腾到凌晨两点,终于把三千多条记录恢复了2900多条,剩下的几十条因为主键冲突没导进去,手工补齐。客户第二天早上看到数据都在,长舒一口气。我后来在服务器上写了个脚本,每天凌晨自动把binlog归档到对象存储,保留30天。
这次事故教会我三件事。第一,任何批量操作之前,先SELECT COUNT(*)看一眼影响行数;第二,DELETE之前先SELECT出来备份成临时表;第三,也是最重要的——别在生产库上直接跑SQL,先复制一个测试库验证。
现在我的习惯是:危险操作全部包在事务里,先BEGIN,确认无误再COMMIT;每条DELETE都强制带LIMIT。多花十秒钟,省掉一个不眠夜。希望看到这篇的站长,永远用不上这些经验。
还木有评论哦,快来抢沙发吧~