31 | 误删数据后除了跑路,还能怎么办?

drop table 命令,通过 binlog 传所有从库级联从库,整个集群都执行

一、误删行

第 24 篇文章 delete 误删行,Flashback 恢复,binlog 拿回原库重放。前提binlog_format=rowbinlog_row_image=FULL

1.  insert , binlog event类型是 Write_rows event,改成 Delete_rows event 

2.  delete ,Delete_rows event 改为 Write_rows event;

3.   Update_rows ,binlog 记录数据行修改前、后值,对调

不是一个,而是多个,下面三个事务:

(A)delete ...(B)insert ...(C)update ...

Flashback 工具解析 binlog 后,写回主库命令:顺序调过来再执行

(reverse C)update  ...(reverse B)delete  ...(reverse A)insert  ...

1.1 不在主库上执行

恢复出备份临时库,临时库恢复回主库

主库变更往往是有关联的。发现数据问题的时间晚了,之前误操作基础上,又继续修改其他数据。单独恢复这几行数据,未经确认的话,二次破坏

1.2 事前预防建议:

1.  sql_safe_updates = on。delete 或update 没写 where 条件,或where 里没包含索引执行报错

2.  上线前, SQL 审计

1.3 sql_safe_updates=on小表数据全部删掉,怎么办?

(1)delete加上 where 条件,delete 全表很慢,需生成回滚日志、写 redo、写 binlog

(2)truncate table 或者 drop table ,性能好,没法通过 Flashback 恢复

即使binlog_format=row执行这三个命令时, binlog 还是 statement 格式。只有truncate/drop 语句,不能恢复

二、误删库 /

2.1 恢复条件 &流程:

条件:(1)定期全量备份,加增量日志,(2)实时备份 binlog

1.  最近一次全量备份(一天一备,上次 0 点, 中午 12 点误删库),恢复临时库

2.  binlog日志备份,取出凌晨 0 点之后日志应用临时库(除误删除语句)

图 1 数据恢复流程 -mysqlbinlog 方法  

2.2操作

1.  加速:临时库上多个库,用 mysqlbinlog 命令时,加–database 参数指定误删表所在避免其他库日志

2.  跳过 12 点误操作语句 binlog

原实例没用 GTID ,误操作之前–stop-position,再–start-position 误操作后日志执行;

用GTID 模式,误操作命令 GTID 是 gtid1,执行 set gtid_next=gtid1;begin;commit; 先把GTID 加到临时实例 GTID 集合,按顺序执行 binlog 时自动跳过误操作。

2.3 不够快原因&办法:

1. 误删表,重放表, mysqlbinlog 不能指定只解析一个表日志;

2. 解析日志单线程。第 26 篇文章并行复制的方法,用不上。

加速方法:恢复临时库后,临时实例设置成线上备库的从库

start slave 前,执行change replication filter replicate_do_table = (tbl_name) 命令,临时库只同步误操作表; 用上并行复制加速

图 2 数据恢复流程 -master-slave 方法

虚线,备库删除binlog ,从 binlog 备份系统中找,再放回备库中。

需要binlog 从master.000005 开始的,备库上最小master.000007,少两个binlog文件。binlog 备份系统中找。 放回:

1.  备份系统下载 master.000005 和master.000006 这两个文件,放备库日志目录

2.  日志目录下的 master.index 文件,开头加两行“./master.000005”和“./master.000006”;

3.  重启备库,让备库重新识别,正常同步

不可能备份无限,设定日志保留天数。做成自动化工具,经常演练。

三、延迟复制备库

“恢复时间不可控”:备份特别大,误操作时间距离全量备份时间长,一周一备,第 6 天发生误操作

搭建延迟复制的备库

延迟复制备库: CHANGE MASTER TO MASTER_DELAY = N 命令,备、主库 N 秒延迟。

N = 3600,1 小时内发现,备库上执行 stop slave,跳过误操作,恢复数据,缩短时间。

四、预防误删库 / 表的方法

(1)不给 truncate/drop 权限。只读账号,

(2)制定操作规范:

删表之前,改表名(加固定后缀_to_be_deleted),确保无影响

管理系统执行。只能删除固定后缀表。

五、rm 删除数据

删某节点:HA 系统开始工作,选新主库,节点恢复接入集群

全军覆没:备份跨机房(跨城市)。

小结

预防远比处理意义大:定期检查备份

show grants 看权限,过大降低权限;和 DBA 商量备份周期、是否创建延迟复制的备库

误删数据事件,什么方法恢复数据呢?经验?

从浏览器拷贝文本执行(不规范),SQL 截断(还可能乱码),执行出错。

开发和执行不是一个人,开发把脚本及 md5 放git 上,发给执行同学,执行命令之前,确认 md5。

评论1

修改生产数据,或者添加索引优化,先写好四个脚本:验证、执行、备份、回滚脚本

升级mongodb,备份数据文件时,备份指向数据文件的软连接(当时没注意是软连接),删除后,备份数据文件恢复数据找不到文件,才发现备份的是软连接,

解决办法:备份节点恢复chatrr +i 命令给所有重要文件增加了 i 权限属性, root 用户都无法直接删除。

评论2

误truncate表:

1、创建同版本空mysql实例,建名字+结构一样表

2、discardtablespace

3、之前备份集 innobackupex --apply-log 记录binlog位置(用innobackupex备份的)。还原后找到误操作表的.ibd文件,copy到新实例对应位置

4、创建mysql实例上import tablespace

5、用mysqlbinlog 处理增量数据,导出 再导入

评论3

更新少条件,全表更新,用的是pg,当时dba说没发恢复。业务核心表,6000多条。有本地缓存,更新会发通知刷新,不要刷缓存。浏览器一个地址下去,内存数据全部返回浏览了。。。

你可能感兴趣的:(31 | 误删数据后除了跑路,还能怎么办?)