对误删数据分类的话,有
1.delete 误删行
2.drop table 或者truncate table 语句误删表
3.使用drop database 误删数据库
4.使用rm命令误删整个MYSQL实例
一,误删行
一下操作前置条件是:binlog的格式是row,并且binglog_row_image是FULL,表示记录数据修改前后完整信息。
如何恢复
使用Flashback工具修改binlog文件,然后放到原库进行重放。
如果误操作是delete语句,binlog event type就会是Delete_rows ,只需要改成Write_rows 就好了
如果误操作是insert语句,binlog event type 就是 Write_rows,改成Delete_rows即可
如果误操作是Update,binlog里面记录了数据行修改前和修改后的值,只要对调这两行的位置即可。
如何预防误删行
将sql_safe_updates(sql安全更新)设置为on,这样设置的话,对于delete和update语句,必须有where并且where条件里必须包含索引字段才会正常执行。
二,误删表
如果使用delete删除整个表的数据就太慢了,因为要生成redolog,undolog,binlog。
直接使用drop table或者truncate table以及drop database 直接删除整表,只需要生成binlog就行了,不过数据无法恢复,因为DDL语句不管binlog_format是row还是statement,在binlog里面存的都是语句,不会记录image。
如何恢复表
前置条件:线上有定期的全量备份,并且实时备份binlog。
全量备份是数据库备份方案中的一种,另外两种是增量备份和差异备份。
全量备份:备份某一时刻的数据库所有数据
增量备份:第一次是做全量备份,后续的每次都只备份与上一次备份的数据相比增加或者修改的数据。
差异备份:第一次也是做全量备份,后续的每次都是备份与第一次的全量备份的数据的差异。
第一种恢复表的方式
通过找到最近的一次全量备份创建出一个临时实例,假设在今天中午12点执行的误删表操作,而最近一次全量备份是0点,那么是这个临时实例就拥有0点时数据库的完整数据,然后再把从0点开始一直到误操作前所有的被误删表所在库的binlog都在临时实例上重放,这样就得到了执行误删表之前的完整数据。
注意
1.在使用mysqlbinlog重放binlog时,通过参数-database指定误删表所在的库。为什么不直接指定误删的表?因为mysqlbinlog工 具并不能指定只解析一个表的日志
2.如何跳过误操作对应的binlog?
1.使用-stop-position, -start-position手动跳过
2.将对应的GTID加到临时实例的gtid_set中,临时实例就不会执行这个binlog,具体操作是首先设置gtid 为误操作对应的gtid,然后开始一个空事务并提交。具体语句是:
set gtid_next=gtid1;begin;commit;
3.使用mysqlbinlog重放binlog,就不能使用并行复制了,并行复制是主库从库之间的
针对不能指定恢复的表并且不能并行复制诞生了第二种恢复表的方式。
第二种恢复表的方式
唯一不同的是,全量备份得到临时实例后,恢复后续的数据不是通过用mysqlbinlog解析binlog并重放,而是将临时实例作为备库的从库,这样就会同步备库的binlog,同样需要跳过误操作binlog。
这样的好处是:
1.在start slave之前,先通过执行 change replication filter replicate_do_table = (tbl_name) 命令(过滤tbl_name表),就可以让临时库只同步误操作的表;
2.可以使用并行复制技术。
需要注意的是
如果备库中没有了临时实例需要的binlog,要去binlog备份中找对应的binlog文件复制到备库的日志目录下,然后将binlog文件名放入备库日志目录下的binlog-index中去。重启备库让备库重新识别刚加的binlog文件。此时临时实例与备库建立主备关系,就可以正常同步了。
延迟复制备库
如果最近一次全量备份与误操作的时间间隔较长,那么通过全量备份来恢复数据是非常慢的。
MYSQL5.6引入了延迟复制备库,也就是搭建主库之间存在一个较大的延迟的延迟复制备库,如1个小时,那么你在误操作之后的1个小时内如果发现了,就可以让备库及时跳过误操作。就可以恢复需要的数据。
预防误删库/表的方法
1.账号分离,不同的成员使用不同权限的账号
2.制定操作规范
三,rm删除数据
对于一个高可用集群架构来说,就算一个节点被rm了,HA也会选举出一个新的主库。