目录

一.背景说明

在很多情况下,主从复制的中断可能仅仅是由于一张表或几张表的数据不一致导致,这时如果数据量较大,我们重新搭建一个从库耗时会较长,通常我们会考虑单独把这张表或这几张表拷贝出来进行一个数据还原操作,有以下几种可行的方式

  1. 在主库锁定这张表做可传输表空间还原到从库
  2. 在主库锁定这张表导出数据导入到从库
  3. ​使用备份恢复工具+MySQL复制特性实现从库恢复​

以下内容主要针对方案3的逻辑进行验证

二.测试环境

IP

角色

库表

10.186.61.162

Master

sbtest.sbtest1,2,3,4

10.186.61.162

slave

sbtest.sbtest1,2,3,4

三.测试流程

  1. 使用sysbench导入4张测试表,每张100W左右即可
  2. 使用sysbench持续压测数据
  3. 在从库drop sbtest4这张表,导致复制报错
  4. 使用mysqldump/mydumper/xtrabackup任意方式在主库备份sbtest4单表(能记录GTID或pos就行)
  5. 从库复制开启Replication Filters功能将sbtest4排除
  6. 使用start slave sql_thread UNTIL SQL_BEFORE_GTIDS方式将数据继续同步到备份点(备份GTID+1)
  7. 等待复制完毕后,关闭Replication Filters并执行普通的start slave sql_thread操作完成恢复

四.测试步骤

4.1 灌入数据/持续压测数据

create database sbtest;

sysbench /usr/local/share/sysbench/oltp_read_write.lua --mysql-socket=/data/mysql/data/mysql_3306.sock --mysql-user=root --mysql-password='xxxx' --mysql-db=sbtest --table-size=1000000 --tables=4 --threads=4 --db-ps-mode=disable --report-interval=2 --max-requests=0 --time=600 --percentile=95 prepare / run

4.2 从库误操作删除一张表

drop table sbtest.sbtest4;
show slave status\G
-- SQL线程出现1146错误
-- 错误日志worker线程报错:'sbtest.sbtest4' doesn't exist

4.3 单独备份sbtest4并传到从库恢复

## 备份单表
mydumper --tables-list=sbtest.sbtest4 --outputdir=/data/mysql/backup/sbtest

## 传输到从库
scp -r /data/mysql/backup/sbtest root@10.186.61.197:/data/mysql/backup/

## 还原到从库(myloader默认不记binlog)
myloader --directory=/data/mysql/backup/sbtest/

4.4 从库开启复制过滤

在还原到备份节点前,使复制操作不会异常

CHANGE REPLICATION FILTER REPLICATE_WILD_IGNORE_TABLE=('sbtest.sbtest4');

4.4 启动复制并指定UNTIL SQL_BEFORE_GTIDS

## 查看备份文件中记录的GTID值
cat /data/mysql/backup/sbtest/metadata
Started dump at: 2021-01-04 05:53:07
SHOW MASTER STATUS:
Log: mysql-bin.000002
Pos: 32371983
GTID:56929ffe-5d09-11ea-bb4e-02000aba3da2:1-136841

## UNTIL SQL_BEFORE_GTIDS指定的GTID值为备份文件中的GTID值+1
## 注意主需要指定结束点即可,无需指定如1-136842这种形式
start slave UNTIL SQL_BEFORE_GTIDS='56929ffe-5d09-11ea-bb4e-02000aba3da2:136842';

4.5 取消过滤规则,重新开启正常复制

待数据同步到​​GTID:136842​​点后会自动停止,重新配置过滤规则取消后复制恢复正常

stop slave;
CHANGE REPLICATION FILTER REPLICATE_WILD_IGNORE_TABLE=();
start slave;