问题场景
系统环境
测试环境:
- OS: CentOS 7
- DB Version: MariaDB 10.0.23
- PT Version: pt-table-checksum 2.2.18
- 主从环境
- Master: 192.168.0.17:53309
- Slave: 192.168.0.18:3309
问题
在使用pt-table-checksum配置主从校验的时候,本地和生产环境都可以正常校验,而在测试环境校验的时候,却输出以下警告信息:1
2Cannot connect to h=192.168.0.18,p=...,u=pt_table_check
Diffs cannot be detected because no slaves were found. Please read the --recursion-method documentation for information.
pt-table-checksum无法连接从库。
由于没有发现从库,数据校验时无法实时检测从库与主库的数据是否一致(DIFFS
列始终为0
),需要通过--recursion-method
选项指定其他的方式来搜索、连接从库(此处--recursion-method
使用的是默认值processlist,hosts
)。
原因
执行的详细命令及输出如下:1
2
3
4
5
6shell> ./bin/pt-table-checksum --socket=/var/lib/mysql/mysql.sock --user=pt_table_check --password='checksum123' --tables=road_to_dba.test1 --replicate=percona_schema.checksums --no-check-binlog-format --no-check-replication-filters
Cannot connect to h=192.168.0.18,p=...,u=pt_table_check
Diffs cannot be detected because no slaves were found. Please read the --recursion-method documentation for information.
TS ERRORS DIFFS ROWS CHUNKS SKIPPED TIME TABLE
09-21T20:57:37 0 0 972 1 0 0.033 road_to_dba.test1
虽然在校验时pt-table-checksum没有连接到从库,但校验能够在主库正常运行,而且能够通过复制传递到从库。校验完成后,在从库也可以通过checksums表查询到数据校验不一致的表信息。
本着严(qiang)谨(po)的(zheng)态度,决定还是对于上述警告信息彻底解决掉。经过分析,具体原因如下:
- 默认情况下,pt-table-checksum使用的从库连接参数,是从主库的连接参数继承而来的,包括用户名(
--user
)、密码(--password
)、端口(--port
)等。 - 在本次校验中,没有显式指定从库的用户名(
--slave-user
),密码(--slave-password
),及端口。 - 所以,在没有显式指定从库的连接参数的情况下,默认是,主库和从库的用户名、密码、端口是相同的;但是在我的测试环境中,主从环境的端口是不同的。所以导致pt-table-checksum虽然搜索到了从库,但是无法连接从库(
Cannot connect to h=192.168.0.18,p=...,u=pt_table_check
),紧接着报没有发现从库的错误。
由于pt-table-checksum没有参数可以用来指定从库的端口,所以使用dsn方式来指定从库的连接信息(--recursion-method dsn=D=percona,t=dsns,h=host,P=3309,u=username,p=passwd
)。
dsn是什么
首先介绍俩名词:
- dsn方法:
dsn
是参数--recursion-method
的一个参数值。注意是dsn,不是dns… - DSN:
DSN
,即DATA SOURCE NAME,数据源名称。DSN
包含从库的各个连接参数(user
、password
、port
等),由逗号分隔的多个option=value
字符串组成。
如:h=host,P=3309,u=username,p=passwd
。
dsn方法是指将从库的DSN信息存储在表(DSN表)里,然后将该表和DSN信息赋值给dsn,作为--recursion-method
的参数值。
格式如:--recursion-method dsn=D=percona,t=dsns,h=host,P=3309,u=username,p=passwd
。
当指定pt-table-checksum的--recursion-method
参数值为dsn时,它只会连接和检测这些指定的从库。当从库的MySQL用户名、密码、端口与主库不相同时,也可以通过dsn的方式来指定。
DSN的部分选项如下:
- D
DSN表所在的数据库名。- h
从库的host。- p
小写p,从库的密码。当密码包括逗号(,
)时,需要使用反斜杠转义。- P
大写P,从库的端口。- S
连接使用的socket文件。- t
存储DSN信息的DSN表名。- u
从库的MySQL用户名。
每一个选项和其值的形式为option=value
,=
的前后不能空格,如果选项值有空格,则必须使用引号引起来。
将DSN作为--recursion-method
的参数值时,必须包含D
和t
选项;或者只包含t
选项,同时DSN表指定数据库前缀(如percona.dsns
)。
DSN表结构如下:1
2
3
4
5
6CREATE TABLE `dsns` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`parent_id` int(11) DEFAULT NULL,
`dsn` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
);
存储在表中的DSNs以id
值排序,但是这里可以忽略id
和parent_id
列,只需将从库的DSN信息存储在dsn
列即可。存储的DSN格式如前面在命令行上指定DSN一样,如:h=host,P=3309,u=username,p=passwd
。
DSN的详细介绍可参考Percona官方文档:https://www.percona.com/doc/percona-toolkit/2.2/dsn_data_source_name_specifications.html
解决问题
上面绕的有点晕。。。其实只需要知道如何使用dsn指定从库连接信息即可。
下面通过指定--recursion-method
为dsn的方式,解决测试环境在数据校验时无法连接从库的问题。
在主库新建DSN表
1
2
3
4
5
6CREATE TABLE `percona_schema.dsns` (
`id` int(11) NOT NULL AUTO_INCREMENT,
`parent_id` int(11) DEFAULT NULL,
`dsn` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
);这里为了测试,和主库的MySQL账号区分开,新建了一个账号
pt_table_check2
专用于连接从库
主库账号是pt_table_check
1
GRANT SELECT, PROCESS, SUPER, REPLICATION SLAVE ON *.* TO pt_table_check2@'192.168.0.%' IDENTIFIED BY 'checksum123';
将从库的DSN信息写入DSN表
1
INSERT INTO percona_schema.dsns(dsn) VALUES ("h=192.168.0.18,P=3309,u=pt_table_check2,p=checksum123");
在主库使用dsn方式,重新运行pt-table-checksum进行校验
1
2
3
4shell> ./bin/pt-table-checksum --socket=/var/lib/mysql/mysql.sock --user=pt_table_check --password='checksum123' --tables=road_to_dba.test1 --replicate=percona_schema.checksums --no-check-binlog-format --no-check-replication-filters --recursion-method dsn=t=percona_schema.dsns,h=192.168.0.18,P=3309,u=pt_table_check2,p=checksum123
TS ERRORS DIFFS ROWS CHUNKS SKIPPED TIME TABLE
09-21T21:22:30 0 1 972 1 0 0.273 road_to_dba.test1
从第4步可以看到,pt-table-checksum已经能够检测到从库,并且检测到主从数据不一致(DIFFS = 1
)。
问题解决。
无法连接/检测从库的影响
虽然在使用pt-table-checksum时,如果无法连接/检测到从库,仍可以完成主从一致性校验。但是,这样可能会产生一些其他的问题,如下:
- pt-table-checksum在执行校验时,无法实时检测主从的数据是否一致。即,输出的
DIFFS
列始终为0。 - 无法检测到从库是否有使用复制过滤,可能会造成从库复制卡住。
- 当某个表在主库上作为一个分块进行校验时,无法检测其在从库的数据量,当该表在从库的数据量很大时,会造成从库负载过高。
- 无法检测到从库的复制延迟状态,造成从库复制延迟过大。