Mysql 系列 | 误删数据

误删数据是数据库操作过程中不可避免会遇到的问题。

误删分为几种,误删行、误删库/表、误删整个实例。

遇到问题就要分析原因,并对症下药解决问题。

误删行

使用 delete 语句误删数据行。

此时可以用 Flashback 工具通过闪回恢复数据。

  • 原理是修改 binlog 内容,拿回原库重放,前提是确保 binlog_format=row binlog_row_image=FULL

  • 对于 insert 语句,binlog event 类型 Write_rows event => Delete_rows event

  • 对于 delete 语句,Delete_rows event => Delete_rows event

  • 对于 update 语句,将 binlog 中记录的修改前后的值对调即可

  • 涉及多个事务时,将事务顺序调过来再执行

误删库/表

delete 删除全表数据,需要生成回滚日志、redolog、binlog会很慢,应该优先考虑 truncate 或 drop。

此时 binlog 中只有一个 truncate/drop 语句,无法恢复出删除前的数据。

这种情况下,要使用全量备份和增量日志。要求线上有定期的全量备份,并且实时备份 binlog

  • 取最近一次全量备份,恢复出一个临时库

  • 从日志备份中取出全量备份后的日志,除了误删数据语句外,全部应用到临时库

    • 临时库有多个数据库时,mysqlbinlog 命令配合 -database 参数,指定误操作所在库

    • 配合 -stop-position 参数设置执行的开始和结束位置

事前预防

误删数据要及时处理,更重要的是做到事前预防

  • 设置 sql_safe_updates=on 一旦忘记在 delete 或者 update 语句中写 where 条件,或者条件中没有包含索引字段,这条语句执行就会报错

  • 代码上线前,必须进行 SQL 审计

  • 定期检查备份的有效性

  • 把数据恢复功能做成自动化工具,并且经常拿出来演练

  • 考虑搭建延迟复制的备库

  • 账号分离,严格给不同人员分配不同权限,尽量减少删除操作,必要时才使用有更新权限的账号

  • 指定操作规范,避免写错要删除的表名。比如删除前必须先修改表名为规定的后缀,确保对业务无影响后再删除固定后缀的表


posted @ 2022-10-06 19:24  菜乌  阅读(227)  评论(0编辑  收藏  举报