Mysql数据同步工具pt-table-sync

背景

percona公司的 pt-table-checksum和pt-table-sync,前者用来实现主从复制数据一致性的校验,后者实现数据修复,将数据修复到一致。

本次讨论的是主从架构,不包括双主

对于是主主复制架构来说,变更操作必须在目标端数据库进行,在变更的同时需要指定选项–no-bin-log,即变更的操作不写入binlog中,否则变更操作会反向复制到另一台主库中执行变更操作,造成数据的不一致。

分为三种情况

有主键或是唯一键(本文内容)

没有主键或是唯一键(可以在主从库上添加)

有外键(不讨论)

局限性

使用基于行的复制的副本
pt-table-sync与--sync-to-masteror--replicate选项一起使用时,需要基于语句的复制。因此,binlog_format=STATEMENT如果需要,它将在主服务器上进行会话设置。为此,该用户必须具有SUPER特权。
(我们需要提供一个具有SUPER特权的用户)
例如
GRANTUPDATE,INSERT,DELETE,SELECT,PROCESS, SUPER, REPLICATION SLAVE ON *.* TO 'hangxing'@'MasterIP'identified by'PASSWORD';
GRANTALL ON test.* TO'hangxing'@'MasterIP' IDENTIFIED BY 'PASSWORD';

1.有主键或是唯一键

这会推进主从事务ID的增大

采用replace into来修复主从不一致,必须保证被replace的表上有主键或唯一键,否则replace into退化成insert into,起不到修复的效果。

如果表上具有唯一键(主键)时,对于主从复制架构来说,最理想的做法是指定选项--replicate或--sync-to-master将同步需要执行的变更语句放在主库上执行,并将变更的操作通过主从复制传递给从库来执行。如果表上没有唯一键,则变更只好在从库进行,但前提需指定选项--no-check-slave。

测试

主从环境下,5.7.26

主库

表结构
CREATE TABLE `Employee` (
  `Id` int(11) DEFAULT NULL,
  `Name` varchar(255) DEFAULT NULL,
  `Salary` int(11) DEFAULT NULL,
  `DepartmentId` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4
Master1[localhost:17262] {msandbox} (test) > select * from Employee;
+------+-------+--------+--------------+
| Id   | Name  | Salary | DepartmentId |
+------+-------+--------+--------------+
|    1 | Joe   |  85000 |            1 |
|    2 | Henry |  80000 |            2 |
|    3 | Sam   |  60000 |            2 |
|    4 | Max   |  90000 |            1 |
|    5 | Janet |  69000 |            1 |
|    6 | Randy |  85000 |            1 |
|    7 | Will  |  70000 |            1 |
+------+-------+--------+--------------+

从库

从库更新部分数据,使得主从出现数据不一致
set sql_log_bin = 0;

不一致1update  Employee set Name = 'Tom Tom' where ID = 7;
update  Employee set Name = 'mao zi' where ID = 6;

slave1 [localhost:17262] {msandbox} (test) > select * from Employee;
+------+---------+--------+--------------+
| Id   | Name    | Salary | DepartmentId |
+------+---------+--------+--------------+
|    1 | Joe     |  85000 |            1 |
|    2 | Henry   |  80000 |            2 |
|    3 | Sam     |  60000 |            2 |
|    4 | Max     |  90000 |            1 |
|    5 | Janet   |  69000 |            1 |
|    6 | mao zi  |  85000 |            1 |--和主库不一致
|    7 | Tom Tom |  70000 |            1 |--和主库不一致
+------+---------+--------+--------------+

不一致2truncate table test110; 100w行,有主键
不一致3drop table k1;

set sql_log_bin = 1;

执行同步

--sync-to-master 填写从库信息h=192.168.66.133,P=17262,u=msandbox

pt-table-sync h=192.168.66.133,P=17262,u=msandbox --charset=utf8 --ask-pass --databases=test --tables=Employee,test110 --sync-to-master --transaction --verbose --dry-run

如果--transaction指定,则不锁表。而是通过开始和提交事务来实现锁定和解锁

先测试
始终先测试与--dry-run和同步--print。需要先给Employee表添加主键

 alter table Employee add primary key(Id);

在这里插入图片描述
再次执行
使从库的数据和主库一致 --sync-to-master,则DSN主机对应的为从库的连接串

--dry-run改为--execute

pt-table-sync h=192.168.66.133,P=17262,u=msandbox --charset=utf8 --ask-pass --databases=test --tables=Employee,test110 --sync-to-master --transaction --verbose --execute

执行结果
# Syncing A=utf8,P=17262,h=192.168.66.133,p=...,u=msandbox
# DELETE REPLACE INSERT UPDATE ALGORITHM START    END      EXIT DATABASE.TABLE
#      0       2      0      0 Chunk     16:05:46 16:05:46 2    test.Employee
#      0 1000000      0      0 Chunk     16:05:46 16:18:04 2    test.test110

以上信息显示从库更新的信息(数据从主库来) 1.test.Employee 2行 2.test.test110 100w行 其实还有3.创建了k1表(只是没显示出来)

建议pt-table-checksum验证

pt-table-checksum --nocheck-binlog-format --nocheck-plan --nocheck-replication-filters --replicate=test.checksums  --defaults-file=/usr/local/sandboxes/msb_5_7_26/master/my.sandbox.cnf --socket=/tmp/mysql_sandbox17261.sock --user=msandbox --password='123456' --recursion-method="processlist"

另个一参数–replicate

上面使用的是--sync-to-master + 从库信息 (完成主库数据到从库上的目的) 下面介绍使用--replicate + 主库信息 (完成主库数据到从库上的目的)

如果是只指定选项–replicate,则DSN主机对应的为主库的连接串,在这之前选项–replicate指定的表有保存之前数据不一致的校验结果,可以先通过工具pt-table-checksum进行校验,否则并不会进行同步变更修复。(LT,pt-table-checksum会在库中新建percona.checksums表记录,也可自定义–replicate=test.checksums)

1.先使用pt-table-checksum校验

2.再次执行同步操作

--replicate='test.checksums' 注意这里的库是自定义的,默认是percona.checksums
pt-table-sync h=192.168.66.133,P=17261,u=msandbox --charset=utf8 --ask-pass --databases=test --tables=Employee,test110 --replicate='test.checksums' --transaction --verbose --execute

报错信息

存疑,跳过它往下看(应该是pt-table-checksum校验的问题)

Cannot connect to A=utf8,P=17262,h=node-2,p=...,u=msandbox

同步之前,在从库制造不一致数据,执行前关闭set sql_log_bin = 0;执行后开启set sql_log_bin = 1; 清空了4张表
在这里插入图片描述

同时指定选项–sync-to-master和–replicate

因为选项--sync-to-master出现,所以DSN主机对应的为从库的连接串,默认之前还是没有进行校验。

pt-table-sync h=192.168.66.133,P=17262,u=msandbox --charset=utf8 --ask-pass --databases=test --tables=Employee,test110 --replicate='test.checksums' --sync-to-master --transaction --verbose  --execute

在这里插入图片描述

总结

只指定选项–sync-to-master
因为有多个DSN主机,必须确保所列出DSN主机均为从库,否则工具报错退出。

只指定选项–replicate (待测试)
如果只指定选项–replicate,也必须之前做过校验操作。

同时指定选项–sync-to-master和–replicate
当同时指定这两个选项时,DSN主机只允许有一个,否则工具报错退出。

例外

不指定选项--sync-to-master和--replicate
因为都不指定这两个选项,所以DSN主机的顺序必须格外注意,最好是先写主库再写从库,或者根据同步的方向来确定。同时如果需要做同步变更修复的表上没有唯一键(主键),最好都指定选项--no-check-slave直接在从库进行变更修复。

摘录

# pt-table-sync h=192.168.58.3,P=3306,u=admin h=192.168.58.5,P=3306,u=admin --charset=utf8 --ask-pass --databases=employees --tables=employees_ptsync --transaction --verbose --execute
Enter password for 192.168.58.3:
Enter password for 192.168.58.5:

# Syncing A=utf8,P=3306,h=192.168.58.5,p=...,u=admin
# DELETE REPLACE INSERT UPDATE ALGORITHM START    END      EXIT DATABASE.TABLE
Can't make changes on A=utf8,P=3306,h=192.168.58.5,p=...,u=admin because it's a slave. See the documentation section 'REPLICATION SAFETY' for solutions to this problem. at /usr/bin/pt-table-sync line 10878.  while doing employees.employees_ptsync on 192.168.58.5
#      0       0      0      0 0         15:19:19 15:19:19 1    employees.employees_ptsync

-- 加上选项--no-check-slave
# pt-table-sync h=192.168.58.3,P=3306,u=admin h=192.168.58.5,P=3306,u=admin --charset=utf8 --ask-pass --databases=employees --tables=employees_ptsync --no-check-slave --transaction --verbose --execute
Enter password for 192.168.58.3:
Enter password for 192.168.58.5:

# Syncing A=utf8,P=3306,h=192.168.58.5,p=...,u=admin
# DELETE REPLACE INSERT UPDATE ALGORITHM START    END      EXIT DATABASE.TABLE
#      0       0      0    252 Chunk     15:20:45 15:20:52 2    employees.employees_ptsync

可以看出如果在从库进行变更修复,执行的是UPDATE操作。

工具同步执行操作的输出解析如下:

字段名 说明
DELETE 删除的行数
REPLACE 替换的行数
INSERT 插入的行数
UPDATE 更新的行数
ALGORITHM 校验使用的算法
START 执行开始的时间
END 执行结束的时间
EXIT 退出状态码
DATABASE.TABLE 涉及的数据库.表

关于退出状态码的说明如下:

STATUS MEANING
0 工具没有执行同步变更操作并成功退出。(Success)
1 工具出现内部错误。(Internal error)
2 至少有一张表校验有不一致并进行同步变更修复。(At least one table differed on the destination)
3 状态1和状态2共同出现的情况。(Combination of 1 and 2)

执行成功,退出状态码是2

以上摘录https://www.cnblogs.com/dbabd/p/10690429.html#autoid-3-1-0
link
建议读者阅读,因为包含详细的执行流程

开启两个会话连接,一个会话负责校验同步,一个会话负责持续检查服务器状态信息;
连接DSN主机对应的主库,检查当前服务器负载信息,参数设置信息,关闭自动提交功能;
设置二进制日志格式为STATEMENT,设置会话级别隔离级别为REPEATABLE READ;
检查当前连接用户的权限,检查操作表是否被外键约束;
通过主键或唯一键(如有)对表进行chunk上边界和下边界的确定,以便更好进行chunk分块操作;
表被分成多个chunk进行校验和同步修复,chunk大小由选项–chunk-size控制;
完成所有的chunk校验和同步修复,退出。

pt-table-sync工具作为一款高效的数据同步工具,通常与pt-table-checksum工具一起使用,但是它涉及到数据的更改,在使用时最好先进行测试之后再对线上服务器进行操作,虽然对生产服务器的性能影响服务较小,但是在进行校验分析的同时会对操作的表行执行FOR UPDATE语句进行锁定,所以尽量选择在业务低峰期进行操作,同时避免在高并发场景下进行操作数据以免造成阻塞。

本文只说明了pt-table-sync工具的单向同步方式,其实它也支持双向同步,只是有许多限制条件并且也处在一个测试功能的阶段,更多关于pt-table-sync的说明可以参考官方说明:pt-table-sync

link

注意内容参考一下博文
link

本文说明,主要技术内容来自互联网技术大佬的分享,还有一些自我的加工(仅仅起到注释说明的作用)。如有相关疑问,请留言,将确认之后,执行侵权必删

猜你喜欢

转载自blog.csdn.net/baidu_34007305/article/details/112944448
今日推荐