pt-table-checksum用来检测主从数据库上的数据一致性,其原理是通过在主库上运行一系列的MySQL函数计算每个表的散列值,并利用主从关系将相同的操作在从服务器上重放(基于statement格式的binlog),从而获取到主从服务器上的散列值然后比较散列值判定主从数据是否一致。

对于表中的单行数据,先检查每一列的数据类型,然后将所有的数据类型转换为字符串,再使用concat_ws()函数进行连接,然后根据连接后得到的字符串计算出checksum的值,默认的checksum算法为crc32。

对于数据量较大的表,如果单次计算整表的checksum值,会导致主库性能压力和主从延迟,因此会根据chunk_size和chunk_time等参数来对表进行拆分为多个chunk,计算chunk时,将该chunk中所有行的数据拼接起来进行checksum计算。

=================================================

操作原理

在开始checksum计算时,会先修改binlog_format为STATEMENT,使得主库上进行的计算操作在从库上重放。
/*!50108 SET @@binlog_format := 'STATEMENT'*/

然后对表数据拆分为chunk进行checksum计算,由于使用STATEMENT的二进制格式,主库和从库都会进行分别计算,如果主库数据不一致,则会导致this_cnt和this_crc两列的数据不同。
如下面对`testdb1`.`tb1001`表的`id` >= '4621' and `id` <= '158655'作为一个chunk进行checksum计算并插入到目标表的语句
REPLACE INTO `pt`.`checksums` (db, tbl, chunk, chunk_index, lower_boundary, upper_boundary, this_cnt, this_crc)
SELECT 'testdb1', 'tb1001', '3', 'PRIMARY', '4621', '158655',
COUNT(*) AS cnt,
COALESCE(LOWER(CONV(BIT_XOR(CAST(CRC32(CONCAT_WS('#', `id`,`c1`, `c6`, `c3`,
CONCAT(ISNULL(`c1`), ISNULL(`c6`), ISNULL(`c3`)))) AS UNSIGNED)), 10, 16)),) AS crc
FROM `testdb1`.`tb1001`
FORCE INDEX(`PRIMARY`)
WHERE ((`id` >= '4621'))
AND ((`id` <= '158655')) /*checksum chunk*/

然后获取主库的上该chunk的计算值this_cnt和this_crc,将这两值更新到master_crc和master_cnt列中
SELECT this_crc, this_cnt FROM `pt`.`checksums` WHERE db = 'testdb1' AND tbl = 'tb1001' AND chunk = '3';
UPDATE `pt`.`checksums` SET chunk_time = '0.266288', master_crc = '8580b9c2', master_cnt = '90552' WHERE db = 'testdb1' AND tbl = 'tb1001' AND chunk = '3'

上面更新操作传递到从库上后,从库上的`pt`.`checksums` 表便拥有主库的checksum值和从库自己的checksum值,因此在从库上将master_crc和master_cnt列与this_cnt和this_crc两列进行对比即可以判断该chunk段数据是否有差异。

=================================================

使用要求

1、对执行检查的账户,需要有SELECT, PROCESS, SUPER, REPLICATION SLAVE的权限

GRANT ALL ON *.* TO TO 'checksum_user'@'%' IDENTIFIED BY 'checksums_pwd';

2、主从复制正常

=================================================

常用参数:

--host=<MASTER_HOST> 			##主库IP
--port=<MASTER_PORT> ##主库端口
--user=<MASTER_USER> ##主库用户
--password=<MASTER_PASSWORD> ##用户密码
--replicate=test.checksums ##checksum结果存放的表
--databases=<check_database> ##要检查的数据库名
--nocheck-replication-filters ##忽略replication-do-db规则
--check-replication-filters ##如果设置replication-do-db规则,则不进行checksum
--ignore-databases=<ignore_database_name> ##不检查的数据库
--tables=<table_name> ##需要检查的表
--ignore-tables=<ignore_table_name> ##不检查的表
--recursion-method=<methon_name> ##processlist,hosts,默认使用SHOW PROCESSLIST来获取从库信息

=================================================

常用脚本:

## 检查除test和mysql以外所有数据库,并将检查结果放入到percona_db.checksum_result
pt-table-checksum \
--host="127.0.0.1" \
--port=3358 \
--user="checksum_user" \
--password="checksums_pwd" \
--recursion-method="processlist" \
--nocheck-binlog-format \
--nocheck-plan \
--nocheck-replication-filters \
--replicate=percona_db.checksum_result\
--set-vars="innodb_lock_wait_timeout=120" \
--ignore-databases="test,mysql"
## 查看表级别是否存在数据不一致
## pt-table-checksum命令执行成功后,在从库上查询 SELECT db AS database_name,
tbl AS table_name,
SUM(this_cnt) AS total_rows, COUNT(*) AS chunks
FROM `percona_db`.`checksum_result`
WHERE ( master_cnt <> this_cnt
OR master_crc <> this_crc
OR ISNULL(master_crc) <> ISNULL(this_crc) )
GROUP BY db, tbl;
## 查看chunk级别是否存在数据不一致
## pt-table-checksum命令执行成功后,在从库上查询
SELECT *
FROM `percona_db`.`checksum_result`
WHERE ( master_cnt <> this_cnt
OR master_crc <> this_crc
OR ISNULL(master_crc) <> ISNULL(this_crc) );

=================================================

使用DNS方式

recursion-method有四种参数:

1、processlist,在主库上使用SHOW PROCESSLIST方式查询从库信息
2、hosts,在主库上使用SHOW SLAVE HOSTS方式查询从库信息
3、dsn,使用DSN方式获取从库信息
4、no,不考虑

DSN(Data Source Name),数据源名称,DSN包含数据库连接信息,使用逗号将多个连接参数分割。

D: DSN表所在的数据库名。
h: 从库的host。
p: 从库的密码。当密码包括逗号(,)时,需要使用反斜杠转义。
P: 从库的端口。
S: 连接使用的socket文件。
t: 存储DSN信息的DSN表名。
u: 从库的MySQL用户名。

假设当前有服务器信息:

主库:192.168.1.101:3358

从库:192.168.1.102:3359

Canel:192.168.1.102:3360

由于当前有从库和Canel都从主库请求日志,且端口不同,如果只希望检查主从之间的数据一致,则可以使用DSN方式。

首先在主库上创建表并录入要检查从库的信息:

CREATE DATABASE percona_db;

CREATE TABLE percona_db.slave_dsn (
`id` int(11) NOT NULL AUTO_INCREMENT,
`parent_id` int(11) DEFAULT NULL,
`dsn` varchar(255) NOT NULL,
PRIMARY KEY (`id`)
);

INSERT INTO percona_db.slave_dsn(dsn)
VALUES('h=192.168.1.102,P=3359,u=checksum_user,p=checksums_pwd');

使用DSN方式进行检查

pt-table-checksum \
--host="192.168.1.101" \
--port=3358 \
--user="checksum_user" \
--password="checksums_pwd" \
--recursion-method dsn=D=percona_db,t=slave_dsn \
--nocheck-binlog-format \
--nocheck-plan \
--nocheck-replication-filters \
--replicate=percona_db.checksum_result \
--set-vars="innodb_lock_wait_timeout=120" \
--ignore-databases="test,mysql"

Percona Toolkit之pt-table-checksum学习的更多相关文章

  1. Percona Toolkit mysql辅助利器

    1 PT介绍 Percona Toolkit简称pt工具—PT-Tools,是Percona公司开发用于管理MySQL的工具,功能包括检查主从复制的数据一致性.检查重复索引.定位IO占用高的表文件.在 ...

  2. Percona Toolkit工具使用

    Percona Toolkit简称pt工具-PT-Tools,是Percona公司开发用于管理MySQL的工具,功能包括检查主从复制的数据一致性.检查重复索引.定位IO占用高的表文件.在线DDL等 下 ...

  3. RDS for MySQL 如何使用 Percona Toolkit

    Percona Toolkit 包含多种用于 MySQL 数据库管理的工具. 下面介绍常用的 pt-online-schema-change  和  pt-archiver 搭配 RDS MySQL ...

  4. Percona Toolkit工具集介绍

    部署mysql工具是一个非常重要的部分,所以工具的可靠性和很好的设计非常重要.percona toolkit是一个有30多个mysql工具的工具箱.兼容mysql,percona server,mar ...

  5. Want to archive tables? Use Percona Toolkit’s pt-archiver--转载

    原文地址:https://www.percona.com/blog/2013/08/12/want-to-archive-tables-use-pt-archiver/ Percona Toolkit ...

  6. Percona Toolkit工具连接MySQL 8报错的解决方案

    使用Percona Toolkit的工具连接MySQL 8.x数据库时,会遇到类似"failed: Plugin caching_sha2_password could not be loa ...

  7. Centos 安装Percona Toolkit工具集

    1.下载 下载地址:   https://www.percona.com/downloads/percona-toolkit/LATEST/ [root@bogon ~]# wget https:// ...

  8. NXP ARM Vector Table CheckSum

    Signature Creator for NXP Cortex-M Devices Algorithm for creating the checksum The reserved Cortex-M ...

  9. Percona Toolkit 使用

    安装 percona-toolkit perl Makefile.PL make make test make install 默认安装到 /usr/local/bin 目录下 可能需要 DBI-1. ...

随机推荐

  1. 每天CSS学习之text-overflow

    text-overflow是CSS3的一个属性,其作用是当文本溢出包含它的元素时,应该裁剪还是将多余的字符用省略号来表示. 该属性一般和overflow:hidden属性一起使用. text-over ...

  2. 四:FAQ附录(容器交互,镜像交互,镜像导出)

    1.交互式运行容器的方法: 1>-it进入到操作系统中: 2>另开一个cmd验证: 3>这是在image之上多了一个可写的从:可以运行centos的命令做一些事(touch .yum ...

  3. 十七. Python基础(17)--正则表达式

    十七. Python基础(17)--正则表达式 1 ● 正则表达式 定义: Regular expressions are sets of symbols that you can use to cr ...

  4. [Leetcode 881]船救人 Boats to Save People 贪心

    [题目] The i-th person has weight people[i], and each boat can carry a maximum weight of limit. Each b ...

  5. 几大principal

    1.A class should have only one reason to change. 一个类只负责一件事 2.高层抽象不依赖低层实现

  6. 深入理解java虚拟机---java虚拟机内存管理(六)

    java虚拟机栈的理解 虚拟机栈就是我们所熟知的栈内存,栈内存属于线程独有的.而在栈内存中的局部变量表中存储的引用类型只是存储对象的内存地址.对象的创建在堆内存中,即对象在线程共享区中. 局部变量表: ...

  7. Centos7部署kubectl命令行工具(五)

    1.准备二进制包 [root@linux-node1 ~]# cd /usr/local/src/kubernetes/client/bin [root@linux-node1 bin]# cp ku ...

  8. 对称加密-java实现

    主要步骤如下: 1.利用SecretKeyFactory.getInstance("加密算法")创建密钥工厂,加密算法如"DES","AES" ...

  9. netty源码理解补充 之 DefaultChannelPipeline到底是个啥

  10. Nginx日志和http模块相关变量

    $arg_PARAMETER #HTTP 请求中某个参数的值,如/index.php?site=www.ttlsa.com,可以用$arg_site 取得 www.ttlsa.com 这个值. $ar ...