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';
这会推进主从事务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;
不一致1:
update 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 |--和主库不一致
+------+---------+--------+--------------+
不一致2:truncate table test110; 100w行,有主键
不一致3:drop 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"
上面使用的是--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出现,所以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
本文说明,主要技术内容来自互联网技术大佬的分享,还有一些自我的加工(仅仅起到注释说明的作用)。如有相关疑问,请留言,将确认之后,执行侵权必删