一、背景
因为某些修改造成了表的主从不一致,所以需要备份表恢复数据,物理机大家都有很多种做法,但是因为aws rds限制了账户的权限,所以这里用不到普通的办法,想了一阵想到一种可行性的方法,暂时没有发现隐患,或者更好的办法,如果有大佬知道的话,欢迎随时指教
二、步骤
1.查看主库二进制状态(主库执行)
# 记录当前的二进制和pos点,mysql-bin.123,111
show master status
2.等待一段时间,确定所要备份的表没有还未执行完的大事务,开始备份 这里可以用多种方式,我使用的为mysqlpump
mysqlpump -uuser -ppassword -hhost --set-gtid-purged=off --default-parallelism 4 -B db --include-tables=table1,table2 >bak.sql
3.等待一段时间观察所对应的表没有未完成的大事务,停止主从,记录位置
# 记录Relay_Master_Log_File,Exec_Master_Log_Pos,mysql-bin.456,222
CALL mysql.rds_stop_replication;
show slave status\G
4.用binlog2sql或者其他方式将这段日志转换成sql
python3 binlog2sql.py -hhost -P3306 -uuser -p -d db -t table1 table2 --start-file 'mysql-bin.123' --start-position=111 --stop-file='mysql-bin.456' --stop-position=222 > add.sql
5.将insert into 转换为 insert ignore into
sed -i "s/INSERT/Insert ignore /g" add.sql
6.将sql文件应用到从库
mysql -hhost -Pport -uuser -p -B db <bak.sql
mysql -hhost -Pport -uuser -p -B db <add.sql
7.启动复制
CALL mysql.rds_start_replication;
到此问题解决
三、可优化的地方
因为是线上库,为了最短时间影响,这里做了以下几部分处理
1.从库创建备份库
create database db_bak
2.将备份sql文件和追加sql文件改为备份库
sed -i "s/\`db\`/\`db_bak\`/g" *.sql
3.将文件还原到备份库
mysql -hhost -Pport -uuser -p -B db <bak.sql
mysql -hhost -Pport -uuser -p -B db <add.sql
4.利用alter 切换库名
alter db.table1 rename db_bak.table1_bak;
alter db_bak.table1 rename db.table1;
alter db.table2 rename db_bak.table2_bak;
alter db_bak.table2 rename db.table2;