delete误删行
Flashback工具通过闪回把数据恢复回来。
Flashback恢复数据的原理,是修改binlog的内容,拿回原库重放。前提是,确保binlog_format=row 和binlog_row_image=FULL。
具体操作
- 恢复出一个备份,或者找一个从库作为临时库,在这个临时库上执行这些操作
- 将确认过的临时库的数据,恢复回主库。可能由于发现数据问题的时间晚了一点儿,就导致已经在之前误操作的基础上,业务代码逻辑又继续修改了其他数据。所以,如果这时候单独恢复这几行数据,而又未经确认的话,就可能会出现对数据的二次破坏。
用truncate /drop table和drop database命令删除的数据记录的binlog还是statement格式。binlog里面就只有一个truncate/drop 语句,这些信息是恢复不出数据的。
truncate/drop误删库/表
需要使用全量备份,加增量日志的方式了。这个方案要求线上有定期的全量备份,并且实时备份binlog。
- 取最近一次全量备份,假设这个库是一天一备,上次备份是当天0点;
- 用备份恢复出一个临时库;
- 从日志备份里面,取出凌晨0点之后的日志;
- 把这些日志,除了误删除数据的语句外,全部应用到临时库。
跳过误操作方法:
如果原实例没有使用GTID模式,只能在应用到包含12点的binlog文件的时候,先用-stop-position参数执行到误操作之前的日志,然后再用–start-position从误操作之后的日志继续执行;
如果实例使用了GTID模式,就方便多了。假设误操作命令的GTID是gtid1,那么只需要执行set gtid_next=gtid1;begin;commit; 先把这个GTID加到临时实例的GTID集合,之后按顺序执行binlog的时候,就会自动跳过误操作的语句。
预防
搭建延迟复制备库
- 延迟复制的备库是一种特殊的备库,通过 CHANGE MASTER TO MASTER_DELAY = N命令,可以指定这个备库持续保持跟主库有N秒的延迟。
只要发现了这个误操作命令,这个命令就还没有在这个延迟复制的备库执行。这时候到这个备库上执行stop slave,再通过之前介绍的方法,跳过误操作命令,就可以恢复出需要的数据。
账号分离
- 我们只给业务开发同学DML权限,而不给truncate/drop权限。如果业务开发人员有DDL需求的话,也可以通过开发管理系统得到支持。
- 即使是DBA团队成员,日常也都规定只使用只读账号,必要的时候才使用有更新权限的账号。
制定操作规范
- 在删除数据表之前,必须先对表做改名操作。然后,观察一段时间,确保对业务无影响以后再删除这张表。
- 改表名的时候,要求给表名加固定的后缀(比如加_to_be_deleted),然后删除表的动作必须通过管理系统执行。并且,管理系删除表的时候,只能删除固定后缀的表