通过复制来恢复误删的库

admin 2024-05-13 612 阅读 0评论

在前面,我们讲了MySQL执行delete误删除数据恢复。但是这种方式没办法恢复drop相关的误操作。

这一节内容,我们来聊一下,基于复制的数据恢复方法。delete、update、drop等误操作,都可以恢复。

大致过程是:

误操作后,把上一次全备导入到新的MySQL,再把这个新的MySQL配置成误操作数据库的从库。
然后让SQL线程同步到误操作的前一个事务,这样,从库的数据就是误操作前一刻的数据了,比如我们误删除了某个库,就把这个库的数据导回到原来的数据库,就能完成恢复。

1 准备阶段

新建测试库表并写入数据

create database recover;use recover;
CREATE TABLE test_recover (id int NOT NULL AUTO_INCREMENT,a int NOT NULL,PRIMARY KEY (id)) ENGINE=InnoDB CHARSET=utf8mb4;
insert into test_recover values (1,1),(2,2);

创建备份用户

CREATE USER `u_xtrabackup`@`localhost` IDENTIFIED WITH MYSQL_NATIVE_PASSWORD BY 'Ijnbgt@123';GRANT SELECT, RELOAD, PROCESS, SUPER, LOCK TABLES,BACKUP_ADMIN ON *.* TO `u_xtrabackup`@`localhost`;

在源实例进行全量备份

cd /data/backupxtrabackup --defaults-file=/data/mysql/conf/my.cnf -uu_xtrabackup -p'Ijnbgt@123' --backup --stream=xbstream --target-dir=./ >/data/backup/xtrabackup.xbstream

2 写入增量并模拟误操作

模拟增量数据写入

use recoverinsert into test_recover values (3,3);

模拟误操作删库

drop database recover;

3 为误操作的MySQL配置一套从库

在另外的机器R上准备一个新的MySQL实例,跟误操作的MySQL版本一致(平时建议是在每个机房为每一个版本准备一个临时用于恢复的MySQL实例)。

把全备传到机器R上。

scp xtrabackup.xbstream 192.168.12.162:/data/backup/recover

关闭R上的MySQL实例

清空R上MySQL实例的数据目录和Binlog目录

rm /data/mysql/data/* -rfrm /data/mysql/binlog/* -rf

并把全备恢复到R上的MySQL中

cd /data/backup/recoverxbstream -x < xtrabackup.xbstreamxtrabackup --prepare --target-dir=./xtrabackup --defaults-file=/data/mysql/conf/my.cnf --copy-back --target-dir=./chown -R mysql.mysql /data/mysql

动R上的MySQL。

将R上的MySQL配置成原实例的从库,但不要开启复制

stop slave;
reset slave;
change master tomaster_host='192.168.12.161',master_user='repl',master_password='Uid_dQc63',master_auto_position = 1;

这里一定要注意:不要启动!不要启动!不要启动!

只要我们不启动,三体人就无法定位到地球的具体位置,地球便可以相安无事。如果启动了 , 三体人将会定位地球的位置并进行入侵,占领我们的地球,后果不堪设想。

不对,搞串了~~

因为启动复制,会同步主库的所有操作,也包括误操作,这样,这个从库的数据,还是没有误删除库的数据。

4 确定误操作事务的GTID

找到回档时间点对应的 Binlog 文件

通过下面命令确定误操作事务的GTID

cd /data/mysql/binlogcp mysql-bin.000065 /data/backup/cd /data/backup/mysqlbinlog mysql-bin.000065 --start-datetime='2023-07-31 22:00:00'  --stop-datetime='2023-07-31 22:50:00'  --base64-output=decode-rows -v  >/data/backup/1.sql

再来查看/data/backup/1.sql里的内容:

......SET @@SESSION.GTID_NEXT= '3e58c925-b396-11ed-9d79-000c2965ac6b:14524559'/*!*/;......use `martin`/*!*/;......DROP TABLE `recover` /* generated by server */......

说明误操作事务的GTID为:3e58c925-b396-11ed-9d79-000c2965ac6b:14524559。

5 R上的MySQL同步到误操作前一个事务

先启动IO线程

start slave io_thread;

再启动SQL线程到误操作前一个事务

start slave sql_thread  until sql_before_gtids='3e58c925-b396-11ed-9d79-000c2965ac6b:14524559';

再来查看复制状态

show slave status\G

如果IO线程是Yes,SQL线程是No。就表示复制已经同步到误操作前一个事务了。

当然,需要我们确定一下,当前数据是否为误操作之前那个时间点的数据

select * from recover.test_recover;

这个也可以找业务一起来确定一下。

再清空复制关系

stop slave;reset slave;

6 数据恢复

备份R机器MySQL的数据,再导入原实例。操作如下:

mysqldump -u'root' -p --set-gtid-purged=off -B recover >recover.sqlscp recover.sql 192.168.12.161:/data/backup/

再到原来的实例,确定recover库是没有的,导入误删除的库

mysql -uroot -p <recover.sql

确定数据是否恢复,可以找某张表进行确定,比如:

select * from recover.test_recover;

这个例子中,如果查询的数据有3行,说明恢复成功。

到这里,整个恢复过程就完成了。

当然,这种数据恢复方案,还是挺耗时间的,在后面,我们会再写一篇恢复文章,通过延迟从库来恢复数据,这种方式,恢复速度会快很多。

喜欢就支持以下吧
点赞 0

发表评论

快捷回复: 表情:
aoman baiyan bishi bizui cahan ciya dabing daku deyi doge fadai fanu fendou ganga guzhang haixiu hanxiao zuohengheng zhuakuang zhouma zhemo zhayanjian zaijian yun youhengheng yiwen yinxian xu xieyanxiao xiaoku xiaojiujie xia wunai wozuimei weixiao weiqu tuosai tu touxiao tiaopi shui se saorao qiudale qinqin qiaoda piezui penxue nanguo liulei liuhan lenghan leiben kun kuaikule ku koubi kelian keai jingya jingxi jingkong jie huaixiao haqian aini OK qiang quantou shengli woshou gouyin baoquan aixin bangbangtang xiaoyanger xigua hexie pijiu lanqiu juhua hecai haobang caidao baojin chi dan kulou shuai shouqiang yangtuo youling
提交
评论列表 (有 0 条评论, 612人围观)

最近发表

热门文章

最新留言

热门推荐

标签列表