MySQL 误删补救
本文将介绍 MySQL 中误删数据的补救方法。
一、注意事项
代码上线前需要经过 SQL 审计
误删后的补救应该在从库上执行,待确认后再恢复回主库
为了避免误删行,应该将 sql_safe_updates 参数设为 on,强制要求 delete 或 update 语句加上 where 条件
为了避免误删库 / 表,可以
对于开发人员,只给 DML 权限
对于 DBA 人员,规定日常只使用只读账号
删除表之前,先做表改名操作,待观察一段时间发现没有问题后再进行删除
可以加上固定的 deleted 后缀
删除表时,只允许管理系统执行
并且只允许删除固定后缀的表
二、误删行
如果使用 delete 语句误删了数据行,可以通过 Flashback 工具通过闪回把数据恢复。
Flashback 恢复数据的原理是:修改 binlog 的内容,拿到数据库中重放。
需要注意的是:
- 需要确保数据库 binlog_format=row 和 binlog_row_image=FULL
- 对于单个语句,具体做法是:
- 对于 insert 语句,对应的 binlog event 类型是 Write_rows event,把它改成 Delete_rows event
- 对于 delete 语句,将 Delete_rows event 改为 Write_rows event
- 对于 update 语句,binlog 里面记录了数据行修改前和修改后的值,对调这两行的位置
- 如果涉及到多条语句,应该倒序执行
三、误删库 / 表
此时,需要采用全量备份 + 增量日志,要求线上有定期的全量备份,并且实时备份 binlog。
具体恢复流程为:
- 取最近的一次全量备份
- 用全量备份恢复出一个临时库
- 从 binlog 备份中,取出最近一次全量备份至今的 binlog 日志
- 将这些 binlog 日志(除了误删库 / 表的语句)应用到临时库中
四、rm 删除
对于一个有高可用机制的 MySQL 集群来说,最不怕的就是 rm 删除数据了。只要不是恶意地把整个集群删除,而只是删掉了其中某一个节点的数据的话,HA 系统就会开始工作,选出一个新的主库,从而保证整个集群的正常工作。
五、延迟复制从库
从 MySQL 5.6 开始,允许配置延迟复制从库,它是一种特殊的备库,能够和主库保持 “延迟同步”。
假如把延迟设为 1 个小时,当主库上有数据被误删时,只需要在 1 个小时内发现并停止主从复制,便可以获得一个没有被误删的备用数据库。
参考
- MySQL 技术内幕
- MySQL 实战 45 讲
- MySQL 是怎样运行的:从根儿上理解 MySQL