关键词:percona-toolkit 工具包中包含 pt-table-checksum工具,在线验证主从一致性
【1】percona-toolkit 工具包
【1.1】percona-toolkit下载
下载地址:
https://www.percona.com/downloads/percona-toolkit/LATEST/
linux下载/windows直接点击下载 percona-toolkit-3.1.0_x86_64.tar.gz
【1.2】percona-toolkit 安装
#(1)安装perl,需要本地或者网络yum源,参考:yum源配置 yum -y install perl-devel perl-Digest-MD5 perl-DBI perl-DBD-MySQL perl-IO-Socket-SSL.noarch perl-Time-HiRes
#(2)编译安装
需求
* Perl v5.8 or newer
* Bash v3 or newer
* Core Perl modules like Time::HiRes
# perl --version |head -2 #检查perl版本
# bash --version #检查bash版本
快速安装步骤(缺省/usr/local/bin路径下,过程略)
# tar zxvf percona-toolkit-<version>.tar.gz
# cd percona-toolkit-<version>
# perl Makefile.PL (安装到非缺省目录 perl Makefile.PL PREFIX=${HOME})
# make
# make test
# make install
【2】pt-table-checksum工具
(经常会有环境BUG,有时候死活跑不出来)
【2.1】pt-table-checksum的应用场景
(1)数据库迁移后验证数据
(2)主从复制出现问题,需要修复
(3)不小心误操作,主从数据库高反了,产生了错误的数据。
(4)定期校验数据
【2.2】基本使用
基本使用参考:https://blog.csdn.net/jswangchang/article/details/79501553?tdsourcetag=s_pctim_aiomsg
详细参数参考:https://www.xin3721.com/ArticleMySQL/mysql14224.html
官方资料:https://www.percona.com/doc/percona-toolkit/LATEST/pt-table-checksum.html
生产环境下使用经验:https://segmentfault.com/a/1190000004309169
使用方法:
pt-table-checksum [OPTIONS] [DSN]
pt-table-checksum
:在主(master)上通过执行校验的查询对复制的一致性进行检查,对比主从的校验值,从而产生结果。
如何知道自己有哪些从库呢?show slave hosts;
DSN指向的是主的地址,该工具的退出状态不为零,如果发现有任何差别,或者如果出现任何警告或错误,更多信息请查看官方资料。
(1)对比一个表
pt-table-checksum --nocheck-replication-filters --replicate=yggl.checksums --databases=yggl --tables=salary h=127.0.0.1,u=root,p=123456,P=3306
详细使用务必参考: http://www.xuchanggang.cn/archives/938.html
【2.3】常见报错
(1)Diffs cannot be detected because no slaves were found
不能自动找到从库,确认processlist或host或dsns方式用对了。
建议在从库的配置文件中加上
report_host = MASTER_HOST
report_port = 13306
注: (1)在有些情况下,recursion-method如果不设会报错:Diffs cannot be detected because no slaves were found.
其参数有四:processlist/hosts/dsn=DSN/no,用来决定查找slave的方式是show full processlist还是show slave hosts还是命令行直接指定还是压根就不准备找从库,具体见下面参数介绍
(2)主从的端口必须一致,如果不一致就需要用DSN方法进行指定,否则会报找不到从库的错误,如果能连到从库服务器但没有指定端口,默认会寻找3306端口
案例: https://bbs.csdn.net/topics/390531787
问题:
我在使用pt-table-checksum检查主从数据是否一致遇到的问题:
一个主,两个从
主:192.168.11.50 端口3306
从1:192.168.11.64 端口3306
从2:192.168.11.74 端口3307
pt-table-checksum可以很容易检查从1的数据是否一致,但是从2因为端口是3307,连接不上,如何解决?
解决:
在Master机的test库加入
CREATE TABLE `dsns` ( `id` int(11) NOT NULL AUTO_INCREMENT, `parent_id` int(11) DEFAULT NULL, `dsn` varchar(255) NOT NULL, PRIMARY KEY (`id`) );
– 写入从库信息
INSERT INTO dsns (parent_id,dsn) values(1,'h=192.168.11.64,u=checksums,p=123456,P=3306');
– 如果有多个从库,就插入多条记录.
INSERT INTO dsns (parent_id,dsn) values(1,'h=192.168.11.74,u=checksums,p=123456,P=3307');
执行pt-table-checksum命令时多加下面的参数即可。
--recursion-method=dsn=h=192.168.11.103,D=test,t=dsns
(3)被检查的主从binlog_format必须为statement,如果不是statement-based,那就添加参数--no-check-binlog-format来避开binlog格式检查
(4)检查结果会输出到默认建立的percona库中的checksums表中,并会输出统计信息到屏幕,diffs列展示主从数据不一致的块的数目,如果都是0,恭喜,数据是一致的
(2)Cannot connect to h=slave1.*.com,p=...,u=percona_user 可以在pt-table-checksum命令前加PTDEBUG=1来看详细的执行过程,如端口、用户名、权限错误。
(3)Waiting for the --replicate table to replicate to XXX 问题出在 percona.checksums
表在从库不存在,根本原因是没有从主库同步过来,所以看一下从库是否延迟严重。
(4)Pausing because Threads_running=25 反复打印出类似上面停止检查的信息。
这是因为当前数据库正在运行的线程数大于默认25,pt-table-checksum 为了减少对库的压力暂停检查了。等数据库压力过了就好了,或者也可以直接 Ctrl+C 终端,
下一次加上--resume继续执行,或者加大--max-load=值。
(5)字符集问题
Error checksumming table Error executing checksum query: DBD::mysql::st execute failed: Illegal mix of collations 12-17T14:48:04 Error checksumming table d_ec_cs.t_online_cs: Error executing checksum query: DBD::mysql::st execute failed: Illegal mix of collations for operation 'concat_ws' [for Statement "REPLACE INTO `percona`.`ali_checksum` (db, tbl, chunk, chunk_index, lower_boundary, upper_boundary, this_cnt, this_crc) SELECT ?, ?, ?, ?, ?, ?, COUNT(*) AS cnt, COALESCE(LOWER(CONV(BIT_XOR(CAST(CRC32(CONCAT_WS('#', `f_cs_id`, `f_corp_id`, `f_valid`, `f_show_name`, `f_online_msg`, `f_offline_msg`, `f_show_mobile`, `f_group_id`, `f_qq`, `f_show_qq`, `f_msn`, `f_show_msn`, `f_sms_online`, `f_scheme`, `f_tel`, `f_telno`, `f_show_tel`, `f_contact`, `f_mobile`, `f_position`, `f_other1`, `f_other2`, `f_other_text1`, `f_other_text2`, `f_email`, `f_qq_first`, `f_qq_first_type`, `f_aids_open`, `f_aids_qq`, `f_aids_crmqq`, `f_aids_yahoo`, `f_aids_skype`, `f_aids_aliww`, `f_aids_msn`, `f_aids_alibaba`, `f_aids_alitrade`, CONCAT(ISNULL(`f_show_name`), ISNULL(`f_group_id`), ISNULL(`f_qq`), ISNULL(`f_show_qq`), ISNULL(`f_sms_online`), ISNULL(`f_other_text1`), ISNULL(`f_other_text2`), ISNULL(`f_email`)) )) AS UNSIGNED)), 10, 16)), 0) AS crc FROM `d_ec_cs`.`t_online_cs` /*checksum table*/" with ParamValues: 0='d_ts_profile', 1='t_user_account', 2=1, 3=undef, 4=undef, 5=undef] at /usr/bin/pt-table-checksum line 10520.
是个bug,暂时无法解决,Illegal mix of collations for operation 'concat_ws'。
【3】pt-table-checksum最佳实践
【3.1】检查主从数据的一致性情况:
pt-table-checksum [OPTIONS] [DSN]。
pt-table-checksum:在主上通过执行校验的查询对复制的一致性进行检查,对比主从的校验值,从而产生结果。
DSN指向的是主的地址,该工具的退出状态不为零,如果发现有任何差别,或者如果出现任何警告或错误,不指定任何参数,会直接对本地的所有数据库的表进行检查。
如pt-table-checksum u=root,p=123456
注意事项如下:
(1).测试需要一个既能登录主库,也能登录从库,而且还能同步数据库的账号;
(2).只能指定一个host,必须为主库的IP;
(3).在检查时会向表加S锁;
(4).运行之前需要从库的同步IO和SQL进程是YES状态。
mysql> GRANT SELECT, PROCESS, SUPER, REPLICATION SLAVE ON *.* TO 'checksums'@'x.x.x.x' IDENTIFIED BY ‘xxxx’;
(5).如果在配置主从时,忽略复制mysql库时,需要在 主上 和 从上 都执行上面的授权语句
[root@mysql-master1 ~]# pt-table-checksum h=’172.16.10.53′,u=’checksums’,p=’checksums’,P=3306 -d test_0109
–nocheck-replication-filters –replicate=test_checksum.checksums –nocheck-binlog-format –nocheck-plan –recursion-method=hosts Waiting to check replicas for differences: 0% 00:00 remain TS ERRORS DIFFS ROWS CHUNKS SKIPPED TIME TABLE 01-12T14:39:51 0 0 0 1 0 0.024 test_0109.broker 01-12T14:39:51 0 0 4 1 0 0.010 test_0109.check_conistent 01-12T14:39:51 0 0 0 1 0 0.012 test_0109.partner_alert_rule 01-12T14:39:51 0 1 0 1 0 0.266 test_0109.proc_test 01-12T14:39:51 0 1 529 1 0 0.021 test_0109.project
类似如下图:
参数说明:
TS :完成检查的时间。
ERRORS :检查时候发生错误和警告的数量。
DIFFS :0表示一致,1表示不一致。当指定–no-replicate-check时,会一直为0,当指定–replicate-check-only会显示不同的信息。
ROWS :表的行数。
CHUNKS :被划分到表中的块的数目。
SKIPPED :由于错误或警告或过大,则跳过块的数目。
TIME :执行的时间。
TABLE :被检查的表名。
参数意义:
–nocheck-replication-filters :不检查复制过滤器,建议启用。后面可以用–databases来指定需要检查的数据库。
–no-check-binlog-format : 不检查复制的binlog模式,要是binlog模式是ROW,则会报错。
–replicate-check-only :只显示不同步的信息。
–replicate= :把checksum的信息写入到指定表中,建议直接写到被检查的数据库当中。
–databases= :指定需要被检查的数据库,多个则用逗号隔开。
–tables= :指定需要被检查的表,多个用逗号隔开
–recursion-method=: 主机信息
h=172.16.10.53 :Master的地址
u=checksums :用户名
p=checksums :密码
P=3306 :端口
通过DIFFS是1可以看出主从的表数据不一致。通过查看从库上的 test_checksum.checksums 表可以看到主从库的检验信息。
mysql> select * from test_checksum.checksums;
+———–+——————–+——-+————+————-+—————-+—————-+———-+———-+————+————+———————+
| db | tbl | chunk | chunk_time | chunk_index | lower_boundary | upper_boundary | this_crc | this_cnt | master_crc | master_cnt | ts |
+———–+——————–+——-+————+————-+—————-+—————-+———-+———-+————+————+———————+
| test_0109 | broker | 1 | 0.005901 | NULL | NULL | NULL | 0 | 0 | 0 | 0 | 2015-01-12 14:39:51 |
| test_0109 | check_conistent | 1 | 0.000484 | NULL | NULL | NULL | 709a8dc | 4 | 709a8dc | 4 | 2015-01-12 14:39:51 |
| test_0109 | partner_alert_rule | 1 | 0.000825 | NULL | NULL | NULL | 0 | 0 | 0 | 0 | 2015-01-12 14:39:51 |
| test_0109 | proc_test | 1 | 0.000439 | NULL | NULL | NULL | 652c8c22 | 99 | 0 | 0 | 2015-01-12 14:39:51 |
| test_0109 | project | 1 | 0.006852 | NULL | NULL | NULL | 0 | 0 | 862da9de | 529 | 2015-01-12 14:39:51 |
+———–+——————–+——-+————+————-+—————-+—————-+———-+———-+————+————+———————+
通过上面的 this_crc <> master_crc 更能清楚的看出他们的不一致了,通过chunk知道是这个张表的哪个块上的记录出现不一致。
要是主的binlog模式是Row 则会报错:
Replica db2 has binlog_format ROW which could cause pt-table-checksum to break replication.
Please read “Replicas using row-based replication” in the LIMITATIONS section of the tool’s documentation.
If you understand the risks, specify –no-check-binlog-format to disable this check.
指定–replicate-check-only参数会在前一次pt-table-checksum检验的数据之上比较(不会再执行计算),显示出数据不一致的SLAVE主机名
【3.2】修复主从数据不一致的情况
通过上面的工具,我们检测出主从之间数据不一致的情况,那此时我们应该如何处理呢?
percona提供了pt-table-sync 用于修复主从数据的一致性
pt-table-sync [OPTIONS] DSN [DSN]。
pt-table-sync: 高效的同步MySQL表之间的数据,他可以做单向和双向同步的表数据。他可以同步单个表,也可以同步整个库。它不同步表结构、索引、或任何其他模式对象。所以在修复一致性之前需要保证他们表存在。
继续上面的复制环境,主和从的表数据不一致,需要修复
pt-table-sync –print –replicate=test_checksum.checksums h=172.16.10.53,u=checksums,p=checksums,P=3306 h=172.16.10.55,u=checksums,p=checksums,P=3306
// 先MASTER的IP,再SLAVE的IP
// 以上是打印出同步语句,如果不一致数据较多,不需要打印出这些语句;
参数意义参考:
–replicate= :指定通过pt-table-checksum得到的表,这2个工具差不多都会一直用。
–databases= : 指定执行同步的数据库,多个用逗号隔开。
–tables= :指定执行同步的表,多个用逗号隔开。
–sync-to-master :指定一个DSN,即从的IP,他会通过show processlist或show slave status 去自动的找主。
h=127.0.0.1 :服务器地址,命令里有2个ip,第一次出现的是M的地址,第2次是Slave的地址。
u=root :帐号。
p=123456 :密码。
–print :打印,但不执行命令。
–execute :执行命令。
执行数据修复:
pt-table-sync –execute –replicate=test_checksum.checksums h=172.16.10.53,u=checksums,p=checksums,P=3306 h=172.16.10.55,u=checksums,p=checksums,P=3306
此时,再检测主从数据一致性,发现主从数据已经一致了:
[root@mysql-master1 ~]# pt-table-checksum h=’172.16.10.53′,u=’checksums’,p=’checksums’,P=3306 -d test_0109
–nocheck-replication-filters –replicate=test_checksum.checksums –nocheck-binlog-format –nocheck-plan –recursion-method=hosts TS ERRORS DIFFS ROWS CHUNKS SKIPPED TIME TABLE 01-12T14:54:16 0 0 0 1 0 0.018 test_0109.broker 01-12T14:54:16 0 0 4 1 0 0.008 test_0109.check_conistent 01-12T14:54:16 0 0 0 1 0 0.008 test_0109.partner_alert_rule 01-12T14:54:16 0 0 0 1 0 0.016 test_0109.proc_test 01-12T14:54:16 0 0 529 1 0 0.273 test_0109.project
附:
以下错误处理方式:
(1).要是表中没有唯一索引或则主键则会报错:
Can’t make changes on the master because no unique index exists at /usr/local/bin/pt-table-sync line 10591.
(2).要是从库有的数据,而主库没有,那这个数据怎么处理?
会给出删除SLAVE多余数据,和修复SLAVE缺失数据的SQL语句。
(3).该工具执行检查表动作,检查连接的帐号需要有很高的权限,在一般权限上需要加SELECT, PROCESS, SUPER, REPLICATION SLAVE等权限。
pt-table-checksm 配合pt-table-sync使用,在执行pt-table-sync数据同步之前,一定要执行pt-table-checksm命令检查。
(4).手动执行pt-table-checksum时会出现Diffs cannot be detected because no slaves were found. Please read the –recursion-method documentation for information.
从字面意思上看是,主库找不到从数据库。只需要在从库配置文件/具体目录/my.cnf中添加
report_host=slave_ip
report_port=slave_port
即可。
也可以在pt-table-checksum –recursion-method=hosts
默认是通过show processlist 找到host的值或show slave hosts 找到host的值。
【3.3】我的实践
(1)检查同步
在主库/从库都可以运行
pt-table-checksum --nocheck-replication-filters --replicate=test.checksum --databases=test h=127.0.0.1,u=root,p=123456,P=3306 --no-check-binlog-format
#pt-table-checksum --nocheck-replication-filters --replicate=test.checksum --databases=test h='主库IP',u='root',p='123456',P=3306 --no-check-binlog-format --recursion-method=processlist
(2)构造问题
在从库插入一条数据。因为之前插入了一条数据ID为5,但删除掉了,所以这里再插入一条数据,id自动变成了6
主库数据如下:
(3)再次检查
发现已经有误差了。
(4)使用 pt-table-sync 修复
左边的h 是主库,右边的 h 是从库
pt-table-sync --print --replicate=test.checksum h=127.0.0.1,u=root,p=123456,P=3306 h=192.168.1.201,u=root,p=123456,P=3306
Errors in command-line arguments: 必须要有以下3个选项其中一个,否则会报错。
* Specify at least one of --print, --execute or --dry-run
这里使用了 --print ,所以会自动打印出来,因为我们这里是,从库比主库数据多。
所以这里给出的是删除从库多余数据的SQL;
然后执行后,解决
pt-table-sync --execute --replicate=test.checksum h=127.0.0.1,u=root,p=123456,P=3306 h=192.168.1.201,u=root,p=123456,P=3306
【4】percona-toolkit工具包下的所有工具
【4.1】官网文档
官网说明参考:https://www.percona.com/doc/percona-toolkit/LATEST/index.html
【4.2】主要工具介绍
如果是非源码安装或源码安装是未指定路径,缺省情况下所有的pt相关的工具位于/usr/bin目录下,以pt-开头。
获取有关命令行的帮助信息,直接在shell提示符下输入命令行与--hlep即可。如: /usr/bin/pt-upgrade --help
# ls -hltr /usr/bin/pt-*
pt-upgrade
#该命令主要用于对比不同mysql版本下SQL执行的差异,通常用于升级前进行对比。
#会生成SQL文件或单独的SQL语句在每个服务器上执行的结果、错误和警告信息等。
pt-online-schema-change
#功能为支持在线变更表构,且不锁定原表,不阻塞原表的DML操作。
#该特性与Oracle的dbms_redefinition在线重定义表原理基本类似。
pt-mysql-summary
#对连接的mysql服务器生成一份详细的配置情况以及sataus信息
#在尾部也提供当前实例的的配置文件的信息
pt-mext
#并行查看SHOW GLOBAL STATUS的多个样本的信息。
#pt-mext会执行你指定的COMMAND,并每次读取一行结果,把空行分割的内容保存到一个一个的临时文件中,最后结合这些临时文件并行查看结果。
pt-kill
#Kill掉符合指定条件mysql语句
pt-ioprofile
#pt-ioprofile的原理是对某个pid附加一个strace进程进行IO分析
pt-fingerprint
#用于生成查询指纹。主要将将sql查询生成queryID,pt-query-digest中的ID即是通过此工具来完成的。
#类似于Oracle中的SQL_ID,涉及绑定变量,字面量等
pt-find
#用与查找mysql表并执行指定的命令,类似于find命令
pt-fifo-split
#模拟切割文件并通过管道传递给先入先出队列而不用真正的切割文件
pt-deadlock-logger
#用于监控mysql服务器上死锁并输出到日志文件,日志包含发生死锁的时间、死锁线程id、死锁的事务id、发生死锁时事务执行时间等详细信息。
pt-archiver
#将mysql数据库中表的记录归档到另外一个表或者文件
#该工具具只是归档旧的数据,对线上数据的OLTP查询几乎没有影响。
#可以将数据插入另外一台服务器的其他表中,也可以写入到一个文件中,方便使用load data infile命令导入数据。
pt-agent
#基于Percona Cloud的一个客户端代理工具
pt-visual-explain
#用于格式化explain的输出
pt-variable-advisor
#用于分析mysql系统变量可能存在的一些问题,可以据此评估有关参数的设置正确与否。
pt-stalk
#用于收集mysql数据库故障时的相关信息便于后续诊断处理。
pt-slave-delay
#用于设定从服务器落后于主服务器的时间间隔。
#该命令行通过启动和停止复制sql线程来设置从落后于主指定时间。
pt-sift
#用于浏览pt-stalk生成的文件。
pt-show-grants
#将当前实例的用户权限全部输出,可以用于迁移数据库过程中重建用户。
pt-query-digest
#用于分析mysql服务器的慢查询日志,并格式化输出以便于查看和分析。
pt-pmp
#为查询程序执行聚合的GDB堆栈跟踪,先进性堆栈跟踪,然后将跟踪信息汇总。
pt-index-usage
#从log文件中读取查询语句,并用分析当前索引如何被使用。
#完成分析之后会生成一份关于索引没有被查询使用过的报告,可以用于分析报告考虑剔除无用的索引。
pt-heartbeat
#用于监控mysql复制架构的延迟。
#主要是通过在主库上的--update线程持续更新指定表上的一个时间戳,从库上--monitor线程或者--check线程检查主库更新的时间戳并与当前系统时间对比,得到延迟值。
pt-fk-error-logger
#将外键相关的错误信息记录到日志或表。
pt-duplicate-key-checker
#功能为从mysql表中找出重复的索引和外键,这个工具会将重复的索引和外键都列出来
#同时也可以生成相应的drop index的语句
pt-diskstats
#类似于iostat,打印磁盘io统计信息,但是这个工具是交互式并且比iostat更详细。可以分析从远程机器收集的数据。
pt-config-diff
#用于比较mysql配置文件和服务器变量
#至少2个配置源需要指定,可以用于迁移或升级前后配置文件进行对比
pt-align
#格式化输出
pt-slave-find
#连接mysql主服务器并查找其所有的从,然后打印出所有从服务器的层级关系。
pt-table-checksum
#用于校验mysql复制的一致性。
#该工具主要是高效的查找数据差异,如果存在差异性,可以通过pt-table-sync来解决。
#用户慢查询分析
#根据执行时间,锁时间,执行次数,等等综合分析