环境
MySQL: MySQL 5.6.27
OS: centos 6.6
tool: pt-table-checksum 2.2.15
它能做什么
业界最流行的MySQL主从数据对比工具,数据一致性检测最好的的工具,没有之一
如何使用
./pt-table-checksum -hxx -P 3306 -u backup -p backup --no-check-binlog-format --databases=xx_db,yy_db,zz_db --no-check-replication-filters
如何找到不一致的地方
* slave上执行:
SELECT db, tbl, SUM(this_cnt) AS total_rows, COUNT(*) AS chunks
FROM percona.checksums
WHERE (
master_cnt <> this_cnt
OR master_crc <> this_crc
OR ISNULL(master_crc) <> ISNULL(this_crc))
GROUP BY db, tbl;
原理
大致的原理网上都能看到,这里会描述几个核心的点
这里假设就一个库,一张表,100条记录
pt-table-checksum进行比对的时候,不是一条条记录比的,而是一个个chunk进行对比
这里我们将100条记录分为10个chunk,一个chunk 10条记录。
每个chunk对比完后,再进行下一个chunk对比,直到全部结束。所以,这里我们就以一个chunk来描述下面的原理即可
- master> /!50108 SET @@binlog_format := 'STATEMENT'/ 设置binlog-format为statement
- master> SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ 这是隔离级别为RR,利用RR的特性让数据在这一刻静止,就不用加锁了。
- master> checksums表:REPLACE INTO select设置this_cnt, this_crc(传递到slave,这其实设置slave每个chunk的cnt,crc),算法来自:COALESCE(LOWER(CONV(BIT_XOR(CAST(CRC32(
主键
) AS UNSIGNED)), 10, 16)), 0) - slave> 当同步追上后,开始执行REPLACE INTO select,然后设置slave每个chunk的cnt,crc
- master> checksums表:update master_cnt,master_crc ,这是设置master每个chunk的cnt,crc
- slave> 当同步追上后,开始执行update master_cnt,master_crc ,这是设置master每个chunk的cnt,crc
以上,基本完成。 接下来只需要去checksums表中找 master_cnt <> this_cnt or OR master_crc <> this_crc 的记录就行
常问的问题
- 一般在什么场景下使用pt-table-checksum?会在生产环境的master上用吗?
- 如果不太在乎master和slave之间的一致性的话,在master上设置ROW模式后,就基本可以保证数据一致了。
- pt-table-checksum虽然很智能,但还是会对服务器造成一定的影响,所以一般不会用在master上,除非迫不得已
- 一般检查数据一致性,我们都会在两台slave上进行对比,如果两台slave ok,基本就ok了
- 听说该工具只对statement格式有用,如果是row格式,还能检查一致性吗?为什么?
- 如果是row模式,pt-table-checksum会报错,但是加上--no-check-binlog-format 即可
- 此工具会自动设置row-format=statement,所以用户不用担心。即便设置row,也没事
- 它是怎么做到master和slave的记录对比的,master不是一直再更新吗?会有锁吗?
- 详细原理,请看上面的原理分析。
- master一直再更新没错,但是不会有锁,利用RR隔离级别的特性就能保证当前事务的数据是不会变的
- RR隔离级别是什么鬼?为什么能够保证当前事务的数据不变呢?
- 可参看之前的分享: SELECT 你知多少
缺陷
- 如果master和slave直接的表结构不一致,目前是没办法检测出来的
* 场景
master:table xx( A int,B char)
slave: table xx( A int)
pt-table-checksum 无法检测B字段。。。
重要
- 风险1
这里设置了SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ 直到对比完成,才结束这个session.
那这样意味什么呢?意味着如果这个session不结束,这个事务对应的undo一直不会被purge,会导致undo不断变大,即ibdata会一直变大。
措施:尽量在低峰期执行
- 风险2
这里是通过RR隔离级别来保证select CRC的值一致的,那么如果RR被破坏了呢?
没错,这样的对比,很容易被DDL所破坏。
措施:DDL是可以人为控制时间窗口和周期的