在MySQL主从复制过程中,常常需要对某些重要的表进行一致性检查。
由于主从数据在同步时存在一定的延迟,因此直接读取服务器数据的方式无法严格保证信息的一致性。在数据在同步完全结束之前,一直处于不断变化且并不完整的状态下。锁表的可能实现这个问题,但是性能又是需要考虑的。能对数据验证是最好的。MySQL的CHECKSUM TABLE指令对于小型列表来说完全够用,但规模庞大的列表往往需要“分块”处理,避免在校验过程中造成负载过高。
Percona工具Pt-table-checksum 是不锁表的。
基本语法:
Pt-table-checksum [options] [DSN]
举例:
pt-table-checksum--databases=monster --tables=abc --replicate-checkh=192.168.1.186,u=chk,p=XXXX,P=3308
这个工具是通过在master上执行一些 checksum queries 主要是使用CRC32函数来实现 可以参考 --funcion 参数,这个是最易于计算的,来检查主从复制的一致性,并将结果打印。如果主从数据不一样的话,会产生不一样的结果。
缺点:可能会增加服务器负载。
--explain 选项的时候,可以查看到工具是如何校验数据表的。
该工具在master上执行一些 checksum queries ,然后会复制到slave上。
同一时间它只会在一个表上进行操作,所以不会在开始之前做大量的工作,也不许积累太多的内存。
它能够在较大型的表上快速工作的原因是: it divides each table into chunks of rows。利用REPLACE..SELECT query来对每个chunk进行校验。而且它会动态调整chunk size(The tool keeps track of how quickly the server is able to execute the queries, and adjusts the chunks as it learns more about the server’s performance. 它使用一个指数衰减的加权平均保持稳定的块大小)。这样做避免了整个语句在表上运行一次。这样可以降低主从复制延迟的可能性。 在每个chunk上进行校验时,超时时间为0.5S。
动态调整chunk size 的大小用到的是一种叫做:’ nibbling’的技术。它会优先利用主键或者非唯一主键来进行分块或者其他的主键,如果没有索引的话,而且表不是很大的话,表会被氛围一个chunk。
该工具不会影响数据库的任何操作,包括复制。(就是不锁表的意思)pt-table-checksum detects replicas and connects to them automatically。当复制延迟太多的时候,该工具会自动暂停,直到slave 与master同步。如果复制失败的话,pt-table-checksum pauses and waits.并且不会有任何输出。
工具在执行的时候,它会执行一个explain在每个chunk上,如果太大的话,它会跳过。可以通过 –chunk-size-limit 进行限制。 If a table will be checksummed in a single chunk because it has a small number of rows, pt-table-checksum additionally verifies that the table isn’t oversized on replicas该工具会验证在slave上这个表不会太大。这个可以避免在master上表时空的,但是在slave上这个表很大。
有多种方式保证master负载不会太高。pt-table-checksum sets its session-level innodb_lock_wait_timeout to 1 second, so that if there is a lock wait, it will be the victim instead of causing other queries to time out.。负载过大,他会pause。pt-table-checksum will pause if there are more than 25 concurrently executing queries. You should probably set a sane value for your server with the option
如果pt-table-checksum 意外停止可以使用—resume 选项重启。
After pt-table-checksum finishes checksumming all of the chunks in a table, it pauses and waits for all detected replicas to finish executing the checksum queries. Once that is finished, it checks all of the replicas to see if they have the same data as the master, and then prints a line of output with the results. It will also print a progress report when it pauses to wait for replication to catch up, and when it is waiting to check replicas for differences from the master