前面已经提到了mysql主从环境下数据一致性检查:mysql主从同步(3)-percona-toolkit工具(数据一致性监测、延迟监控)使用梳理
今天这里再介绍另一种Mysql数据一致性自动检测工具:Maatkit。(不过Maatkit工具现在已经不维护了,推荐还是使用percona-toolkit工具吧!)
Maatkit是一个开源的工具包,为mySQL日常管理提供了帮助,它包含很多工具,这里主要说下面两个:
1)mk-table-checksum 用来检测master和slave上的表结构和数据是否一致的;
2)mk-table-sync 在主从数据不一致时,用来修复数据的;先主后从有效保证表一致的工具,不必重载从表而能够保证一致。
上面两个perl脚本在运行时都会锁表,表的大小取决于执行的快慢,勿在高峰期间运行,可选择凌晨。
-----------------------------------------------------------------------------------------------------
下面记录了这一操作过程:
基本信息:
master:192.168.1.101
slave:192.168.1.102
版本:mysql5.6
同步的库:huanqiu、huanpc
Maatkit安装过程:(主库和从库服务器上都可以安装,因为数据一致性检查操作在主库或从库机器上都可以运行;建议主从机器上都安装)
1)安装该工具依赖的软件包
[root@master-server src]# yum install perl-IO-Socket-SSL perl-DBD-MySQL perl-Time-HiRes perl perl-DBI -y
2)maatkit下载安装 [需要*到官网下载:https://code.google.com/archive/p/maatkit/downloads]
百度云盘下载地址:https://pan.baidu.com/s/1c1AufW8 (提取密码:vbi1)
[root@master-server ~]# tar -zvxf maatkit-7540.tar.gz && cd maatkit-7540
[root@master-server maatkit-7540]# perl Makefile.PL
Checking if your kit is complete...
Looks good
Writing Makefile for maatkit
------------------------------------------------------------------------------------------------------------
如有报错:
Can't locate ExtUtils/MakeMaker.pm in @INC (@INC contains: /usr/local/lib64/perl5 /usr/local/share/perl5 /usr/lib64/perl5/vendor_perl /usr/share/perl5/vendor_perl /usr/lib64/perl5 /usr/share/perl5 .) at Makefile.PL line 1.
BEGIN failed--compilation aborted at Makefile.PL line 1.
解决办法:
[root@slave-server maatkit-4334]# yum install perl-ExtUtils-Embed perl-ExtUtils-CBuilder perl-ExtUtils-MakeMaker -y
------------------------------------------------------------------------------------------------------------
[root@master-server maatkit-4334]# make && make install
[root@master-server ~]# mk- //按TAB键补全,可以查看到Maatkit的所有命令
mk-archiver mk-find mk-parallel-dump mk-show-grants mk-table-sync
mk-checksum-filter mk-heartbeat mk-parallel-restore mk-slave-delay mk-table-usage
mk-config-diff mk-index-usage mk-profile-compact mk-slave-find mk-tcp-model
mk-deadlock-logger mk-kill mk-purge-logs mk-slave-move mk-upgrade
mk-duplicate-key-checker mk-loadavg mk-query-advisor mk-slave-prefetch mk-variable-advisor
mk-error-log mk-log-player mk-query-digest mk-slave-restart mk-visual-explain
mk-fifo-split mk-merge-mqd-results mk-query-profiler mk-table-checksum
安装完成后,一定要在被校验的主从服务器上创建只有SELECT权限的帐号(最好保持主从上创建的账号和密码一样,方便操作)
mysql> GRANT SELECT ON *.* TO 'data_check'@'%' IDENTIFIED BY 'check@123';
Query OK, 0 rows affected (0.01 sec) mysql> flush privileges;
Query OK, 0 rows affected (0.01 sec)
使用mk-table-checksum检查主从数据一致性
1)在主库服务器上运行数据一致性检查操作(也可以在从库服务器上进行数据一致性检查操作,命令跟下面一样)
[root@master-server ~]# mk-table-checksum h=192.168.1.101,u=data_check,p=check@123,P=3306 h=192.168.1.102,u=data_check,p=check@123,P=3306
DATABASE TABLE CHUNK HOST ENGINE COUNT CHECKSUM TIME WAIT STAT LAG
mysql columns_priv 0 192.168.1.101 MyISAM NULL 0 0 0 NULL NULL
mysql columns_priv 0 192.168.1.102 MyISAM NULL 0 0 0 NULL NULL
mysql db 0 192.168.1.101 MyISAM NULL 4197331717 0 0 NULL NULL
mysql db 0 192.168.1.102 MyISAM NULL 4197331717 0 0 NULL NULL
mysql event 0 192.168.1.101 MyISAM NULL 0 0 0 NULL NULL
mysql event 0 192.168.1.102 MyISAM NULL 0 0 0 NULL NULL
mysql func 0 192.168.1.101 MyISAM NULL 0 0 0 NULL NULL
mysql func 0 192.168.1.102 MyISAM NULL 0 0 0 NULL NULL
mysql general_log 0 192.168.1.101 CSV NULL 0 0 0 NULL NULL
mysql general_log 0 192.168.1.102 CSV NULL 0 0 0 NULL NULL
mysql help_category 0 192.168.1.101 MyISAM NULL 2621154011 0 0 NULL NULL
mysql help_category 0 192.168.1.102 MyISAM NULL 2621154011 0 0 NULL NULL
mysql help_keyword 0 192.168.1.101 MyISAM NULL 2791798352 0 0 NULL NULL
mysql help_keyword 0 192.168.1.102 MyISAM NULL 578891347 0 0 NULL NULL
mysql help_relation 0 192.168.1.101 MyISAM NULL 3733405838 0 0 NULL NULL
mysql help_relation 0 192.168.1.102 MyISAM NULL 1649042165 0 0 NULL NULL
mysql help_topic 0 192.168.1.101 MyISAM NULL 1795841156 0 0 NULL NULL
mysql help_topic 0 192.168.1.102 MyISAM NULL 2642710534 0 0 NULL NULL
mysql innodb_index_stats 0 192.168.1.101 InnoDB NULL 1853713685 0 0 NULL NULL
mysql innodb_index_stats 0 192.168.1.102 InnoDB NULL 213249811 0 0 NULL NULL
mysql innodb_table_stats 0 192.168.1.101 InnoDB NULL 2028951538 0 0 NULL NULL
mysql innodb_table_stats 0 192.168.1.102 InnoDB NULL 4163315044 0 0 NULL NULL
mysql ndb_binlog_index 0 192.168.1.101 MyISAM NULL 0 0 0 NULL NULL
mysql ndb_binlog_index 0 192.168.1.102 MyISAM NULL 0 0 0 NULL NULL
mysql plugin 0 192.168.1.101 MyISAM NULL 0 0 0 NULL NULL
mysql plugin 0 192.168.1.102 MyISAM NULL 0 0 0 NULL NULL
mysql proc 0 192.168.1.101 MyISAM NULL 0 0 0 NULL NULL
mysql proc 0 192.168.1.102 MyISAM NULL 0 0 0 NULL NULL
mysql procs_priv 0 192.168.1.101 MyISAM NULL 0 0 0 NULL NULL
mysql procs_priv 0 192.168.1.102 MyISAM NULL 0 0 0 NULL NULL
mysql proxies_priv 0 192.168.1.101 MyISAM NULL 3956276869 0 0 NULL NULL
mysql proxies_priv 0 192.168.1.102 MyISAM NULL 2040113179 0 0 NULL NULL
mysql servers 0 192.168.1.101 MyISAM NULL 0 0 0 NULL NULL
mysql servers 0 192.168.1.102 MyISAM NULL 0 0 0 NULL NULL
mysql slave_master_info 0 192.168.1.101 InnoDB NULL 0 0 0 NULL NULL
mysql slave_master_info 0 192.168.1.102 InnoDB NULL 0 0 0 NULL NULL
mysql slave_relay_log_info 0 192.168.1.101 InnoDB NULL 0 0 0 NULL NULL
mysql slave_relay_log_info 0 192.168.1.102 InnoDB NULL 0 0 0 NULL NULL
mysql slave_worker_info 0 192.168.1.101 InnoDB NULL 0 0 0 NULL NULL
mysql slave_worker_info 0 192.168.1.102 InnoDB NULL 0 0 0 NULL NULL
mysql slow_log 0 192.168.1.101 CSV NULL 0 0 0 NULL NULL
mysql slow_log 0 192.168.1.102 CSV NULL 0 0 0 NULL NULL
mysql tables_priv 0 192.168.1.101 MyISAM NULL 0 0 0 NULL NULL
mysql tables_priv 0 192.168.1.102 MyISAM NULL 0 0 0 NULL NULL
mysql time_zone 0 192.168.1.101 MyISAM NULL 0 0 0 NULL NULL
mysql time_zone 0 192.168.1.102 MyISAM NULL 0 0 0 NULL NULL
mysql time_zone_leap_second 0 192.168.1.101 MyISAM NULL 0 0 0 NULL NULL
mysql time_zone_leap_second 0 192.168.1.102 MyISAM NULL 0 0 0 NULL NULL
mysql time_zone_name 0 192.168.1.101 MyISAM NULL 0 0 0 NULL NULL
mysql time_zone_name 0 192.168.1.102 MyISAM NULL 0 0 0 NULL NULL
mysql time_zone_transition 0 192.168.1.101 MyISAM NULL 0 0 0 NULL NULL
mysql time_zone_transition 0 192.168.1.102 MyISAM NULL 0 0 0 NULL NULL
mysql time_zone_transition_type 0 192.168.1.101 MyISAM NULL 0 0 0 NULL NULL
mysql time_zone_transition_type 0 192.168.1.102 MyISAM NULL 0 0 0 NULL NULL
mysql user 0 192.168.1.101 MyISAM NULL 882367917 0 0 NULL NULL
mysql user 0 192.168.1.102 MyISAM NULL 883514797 0 0 NULL NULL
DATABASE TABLE CHUNK HOST ENGINE COUNT CHECKSUM TIME WAIT STAT LAG
huanqiu checksums 0 192.168.1.101 InnoDB NULL 1230819712 0 0 NULL NULL
huanqiu checksums 0 192.168.1.102 InnoDB NULL 3864574229 0 0 NULL NULL
huanqiu haha 0 192.168.1.101 InnoDB NULL 1378115040 0 0 NULL NULL
huanqiu haha 0 192.168.1.102 InnoDB NULL 1378115040 0 0 NULL NULL
DATABASE TABLE CHUNK HOST ENGINE COUNT CHECKSUM TIME WAIT STAT LAG
huanpc checksums 0 192.168.1.101 InnoDB NULL 2427682155 0 0 NULL NULL
huanpc checksums 0 192.168.1.102 InnoDB NULL 289696409 0 0 NULL NULL
huanpc heihei 0 192.168.1.101 InnoDB NULL 1446184115 0 0 NULL NULL
huanpc heihei 0 192.168.1.102 InnoDB NULL 1956266704 0 0 NULL NULL
上面命令中参数解释:
第一个h: 填写主库ip
第一个u: 主库授权的用户名
第一个p: 主库授权的密码
第二个h: 填写从库ip
第二个u: 从库授权的用户名
第二个p: 从库授权的密码
P: mysql的端口
上面的命令所示检查主从的所有库的数据一致性;一般我们检查的是同步的库。这就需要添加参数:
-d(或者--database) 后接数据库名,注意后面不需要加=号,多个数据库之间用逗号隔开,比如-dhuanqiu,huanpc;如果不加-d,校验的是所有库;
--count 会计算出表的行数
如下操作:
[root@master-server ~]# mk-table-checksum h=192.168.1.101,u=data_check,p=check@123,P=3306 h=192.168.1.102,u=data_check,p=check@123,P=3306 -dhuanqiu --count //针对单个库huanqiu,检查主从数据一致性
DATABASE TABLE CHUNK HOST ENGINE COUNT CHECKSUM TIME WAIT STAT LAG
huanqiu checksums 0 192.168.1.101 InnoDB 1 705c5e2e 0 0 NULL NULL
huanqiu checksums 0 192.168.1.102 InnoDB 1 f163e1ff 0 0 NULL NULL
huanqiu haha 0 192.168.1.101 InnoDB 4 481dfe49 0 0 NULL NULL
huanqiu haha 0 192.168.1.102 InnoDB 5 ecb4850b 0 0 NULL NULL
[root@master-server ~]# mk-table-checksum h=192.168.1.101,u=data_check,p=check@123,P=3306 h=192.168.1.102,u=data_check,p=check@123,P=3306 -dhuanpc --count //针对单个库huanpc,检查主从数据一致性
DATABASE TABLE CHUNK HOST ENGINE COUNT CHECKSUM TIME WAIT STAT LAG
huanpc checksums 0 192.168.1.101 InnoDB 1 5af891e 0 0 NULL NULL
huanpc checksums 0 192.168.1.102 InnoDB 1 96d7dfcf 0 0 NULL NULL
huanpc heihei 0 192.168.1.101 InnoDB 6 a12d47d 0 0 NULL NULL
huanpc heihei 0 192.168.1.102 InnoDB 7 5681c480 0 0 NULL NULL
[root@master-server ~]# mk-table-checksum h=192.168.1.101,u=data_check,p=check@123,P=3306 h=192.168.1.102,u=data_check,p=check@123,P=3306 -dhuanqiu,huanpc --count //针对多个库huaniu、huanpc,检查主从数据一致性
DATABASE TABLE CHUNK HOST ENGINE COUNT CHECKSUM TIME WAIT STAT LAG
huanqiu checksums 0 192.168.1.101 InnoDB 1 705c5e2e 0 0 NULL NULL
huanqiu checksums 0 192.168.1.102 InnoDB 1 f163e1ff 0 0 NULL NULL
huanqiu haha 0 192.168.1.101 InnoDB 4 481dfe49 0 0 NULL NULL
huanqiu haha 0 192.168.1.102 InnoDB 5 ecb4850b 0 0 NULL NULL
DATABASE TABLE CHUNK HOST ENGINE COUNT CHECKSUM TIME WAIT STAT LAG
huanpc checksums 0 192.168.1.101 InnoDB 1 5af891e 0 0 NULL NULL
huanpc checksums 0 192.168.1.102 InnoDB 1 96d7dfcf 0 0 NULL NULL
huanpc heihei 0 192.168.1.101 InnoDB 6 a12d47d 0 0 NULL NULL
huanpc heihei 0 192.168.1.102 InnoDB 7 5681c480 0 0 NULL NULL
上述结果中的参数解释:
DATABASE: 检查的库名
TABLE: 检查的库中的表名
CHUNK: checksum时的近似数值
HOST: 主从MYSQL的地址
ENGINE: 表引擎
COUNT: 表的行数
CHECKSUM: 校验值
TIME: 所用时间
WAIT: 等待时间
STAT: MASTER_POS_WAIT()返回值
LAG: slave的延时时间
mk-checksum-filter过滤工具的使用
如果只想知道huanqiu库中哪些表不是一致的,那么只需要加一个管道符即可,如下:
[root@master-server ~]# mk-table-checksum h=192.168.1.101,u=data_check,p=check@123,P=3306 h=192.168.1.102,u=data_check,p=check@123,P=3306 -dhuanqiu --count | mk-checksum-filter //如下表示huanqiu库下只有haha表的数据,主从不一致
huanqiu checksums 0 192.168.1.101 InnoDB 1 705c5e2e 0 0 NULL NULL
huanqiu checksums 0 192.168.1.102 InnoDB 1 f163e1ff 0 0 NULL NULL
huanqiu haha 0 192.168.1.101 InnoDB 4 481dfe49 0 0 NULL NULL
huanqiu haha 0 192.168.1.102 InnoDB 5 ecb4850b 0 0 NULL NULL
[root@master-server ~]# mk-table-checksum h=192.168.1.101,u=data_check,p=check@123,P=3306 h=192.168.1.102,u=data_check,p=check@123,P=3306 -dhuanpc --count | mk-checksum-filter //如下表示huanqiu库下只有haha表的数据,主从不一致
huanpc checksums 0 192.168.1.101 InnoDB 1 5af891e 0 0 NULL NULL
huanpc checksums 0 192.168.1.102 InnoDB 1 96d7dfcf 0 0 NULL NULL
huanpc heihei 0 192.168.1.101 InnoDB 6 a12d47d 0 0 NULL NULL
huanpc heihei 0 192.168.1.102 InnoDB 7 5681c480 0 0 NULL NULL
[root@master-server ~]# mk-table-checksum h=192.168.1.101,u=data_check,p=check@123,P=3306 h=192.168.1.102,u=data_check,p=check@123,P=3306 -dhuanqiu,huanpc --count | mk-checksum-filter //如下表示huanqiu库下只有haha表的数据,主从不一致
huanqiu checksums 0 192.168.1.101 InnoDB 1 705c5e2e 0 0 NULL NULL
huanqiu checksums 0 192.168.1.102 InnoDB 1 f163e1ff 0 0 NULL NULL
huanqiu haha 0 192.168.1.101 InnoDB 4 481dfe49 0 0 NULL NULL
huanqiu haha 0 192.168.1.102 InnoDB 5 ecb4850b 0 0 NULL NULL
huanpc checksums 0 192.168.1.101 InnoDB 1 5af891e 0 0 NULL NULL
huanpc checksums 0 192.168.1.102 InnoDB 1 96d7dfcf 0 0 NULL NULL
huanpc heihei 0 192.168.1.101 InnoDB 6 a12d47d 0 0 NULL NULL
huanpc heihei 0 192.168.1.102 InnoDB 7 5681c480 0 0 NULL NULL
使用mk-table-sync修复主从不同步的数据
顾名思义,mk-table-sync用来修复多个实例之间数据的不一致。它可以让主从的数据修复到最终一致,也可以使通过应用双写或多写的多个不相关的数据库实例修复到一致。同时它还内部集成了pt-table-checksum的校验功能,可以一边校验一边修复,也可以基于pt-table-checksum的计算结果来进行修复。
mk-table-sync工作原理
1)单行数据checksum值的计算
计算逻辑与pt-table-checksum一样,也是先检查表结构,并获取每一列的数据类型,把所有数据类型都转化为字符串,然后用concat_ws()函数进行连接,由此计算出该行的checksum值。checksum默认采用crc32计算。
2)数据块checksum值的计算
同pt-table-checksum工具一样,pt-table-sync会智能分析表上的索引,然后把表的数据split成若干个chunk,计算的时候以chunk为单位。可以理解为把chunk内所有行的数据拼接起来,再计算crc32的值,即得到该chunk的checksum值。
3)坏块检测和修复
前面两步,pt-table-sync与pt-table-checksum的算法和原理一样。再往下,就开始有所不同:
pt-table-checksum只是校验,所以它把checksum结果存储到统计表,然后把执行过的sql语句记录到binlog中,任务就算完成。语句级的复制把计算逻辑传递到从库,并在从库执行相同的计算。pt-table-checksum的算法本身并不在意从库的延迟,延迟多少都一样计算(有同事对此不理解,可以参考我的前一篇文章),不会影响计算结果的正确性(但是我们还是会检测延迟,因为延迟太多会影响业务,所以总是要加上—max-lag来限流)。
pt-table-sync则不同。它首先要完成chunk的checksum值的计算,一旦发现主从上同样的chunk的checksum值不同,就深入到该chunk内部,逐行比较并修复有问题的行。其计算逻辑描述如下(以修复主从结构的数据不一致为例,业务双写的情况修复起来更复杂—因为涉及到冲突解决和基准选择的问题,限于篇幅,这里不介绍):
1)对每一个从库,每一个表,循环进行如下校验和修复过程。
2)对每一个chunk,在校验时加上for update锁。一旦获得锁,就记录下当前主库的show master status值。
3)在从库上执行select master_pos_wait()函数,等待从库sql线程执行到show master status得到的位置。以此保证,主从上关于这个chunk的内容均不再改变。
4)对这个chunk执行checksum,然后与主库的checksum进行比较。
5)如果checksum相同,说明主从数据一致,就继续下一个chunk。
6)如果checksum不同,说明该chunk有不一致。深入chunk内部,逐行计算checksum并比较(单行checksum比较过程与chunk的比较过程一样,单行实际是chunk的size为1的特例)。
7)如果发现某行不一致,则标记下来。继续检测剩余行,直到这个chunk结束。
8)对找到的主从不一致的行,采用replace into语句,在主库执行一遍以生成该行全量的binlog,并同步到从库,这会以主库数据为基准来修复从库;对于主库有的行而从库没有的行,采用replace在主库上插入(必须不能是insert);对于从库有而主库没有的行,通过在主库执行delete来删除(pt-table-sync强烈建议所有的数据修复都只在主库进行,而不建议直接修改从库数据;但是也有特例,后面会讲到)。
9)直到修复该chunk所有不一致的行。继续检查和修复下一个chunk。
10)直到这个从库上所有的表修复结束。开始修复下一个从库。
重要选项
--print 显示同步需要执行的语句
--execute 执行数据同步
--charset=utf8 设置字符集,避免从库乱码。
实例说明:
mk-table-sync的工作方式是:先一行一行检查主从库的表是否一样,如果哪里不一样,就执行删除,更新,插入等操作,使其达到一致。
通过上面mk-table-checksum的检查结果可以看出,同步的两个库huanqiu和huanpc的数据并不一致,这时就可以使用mk-table-sync进行数据修复了。
数据修复命令如下:(如果mysql端口是默认的3306,则下面命令中的P=3306可以省略)
由于上面在mk-table-checksum检查时用的data_check只有select权限,权限太小,不能用于mk-table-sync修复数据只用。
所以还需要在主库和从库数据库里创建用于mk-table-sync修复数据之用的账号权限
mysql> GRANT ALL ON *.* to mksync@'%' identified by "sync@123";
Query OK, 0 rows affected (0.01 sec) mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
[root@master-server lib]# mk-table-sync --execute --charset=utf8 --print --no-check-slave --databases huanqiu,huanpc h=192.168.1.101,u=mksync,p=sync@123,P=3306 h=192.168.1.102,u=mksync,p=sync@123,P=3306
UPDATE `huanpc`.`checksums` SET `chunk_time`='0.002821', `chunk_index`=NULL, `lower_boundary`=NULL, `upper_boundary`=NULL, `this_crc`='5681c480', `this_cnt`='7', `master_crc`='5681c480', `master_cnt`='7', `ts`='2017-01-12 14:29:14' WHERE `db`='huanpc' AND `tbl`='heihei' AND `chunk`='1' LIMIT 1 /*maatkit src_db:huanpc src_tbl:checksums src_dsn:A=utf8,P=3306,h=192.168.1.101,p=...,u=mksync dst_db:huanpc dst_tbl:checksums dst_dsn:A=utf8,P=3306,h=192.168.1.102,p=...,u=mksync lock:0 transaction:1 changing_src:0 replicate:0 bidirectional:0 pid:13702 user:root host:master-server*/;
DELETE FROM `huanpc`.`heihei` WHERE `member`='90' LIMIT 1 /*maatkit src_db:huanpc src_tbl:heihei src_dsn:A=utf8,P=3306,h=192.168.1.101,p=...,u=mksync dst_db:huanpc dst_tbl:heihei dst_dsn:A=utf8,P=3306,h=192.168.1.102,p=...,u=mksync lock:0 transaction:1 changing_src:0 replicate:0 bidirectional:0 pid:13702 user:root host:master-server*/;
UPDATE `huanqiu`.`checksums` SET `chunk_time`='0.002495', `chunk_index`=NULL, `lower_boundary`=NULL, `upper_boundary`=NULL, `this_crc`='ecb4850b', `this_cnt`='5', `master_crc`='ecb4850b', `master_cnt`='5', `ts`='2017-01-12 14:27:45' WHERE `db`='huanqiu' AND `tbl`='haha' AND `chunk`='1' LIMIT 1 /*maatkit src_db:huanqiu src_tbl:checksums src_dsn:A=utf8,P=3306,h=192.168.1.101,p=...,u=mksync dst_db:huanqiu dst_tbl:checksums dst_dsn:A=utf8,P=3306,h=192.168.1.102,p=...,u=mksync lock:0 transaction:1 changing_src:0 replicate:0 bidirectional:0 pid:13702 user:root host:master-server*/;
DELETE FROM `huanqiu`.`haha` WHERE `id`='90' LIMIT 1 /*maatkit src_db:huanqiu src_tbl:haha src_dsn:A=utf8,P=3306,h=192.168.1.101,p=...,u=mksync dst_db:huanqiu dst_tbl:haha dst_dsn:A=utf8,P=3306,h=192.168.1.102,p=...,u=mksync lock:0 transaction:1 changing_src:0 replicate:0 bidirectional:0 pid:13702 user:root host:master-server*/;
上面那条命令执行后,再次检查主从数据,发现主从已经同步:
[root@master-server ~]# mk-table-checksum h=192.168.1.101,u=data_check,p=check@123,P=3306 h=192.168.1.102,u=data_check,p=check@123,P=3306 -dhuanqiu,huanpc --count
DATABASE TABLE CHUNK HOST ENGINE COUNT CHECKSUM TIME WAIT STAT LAG
huanqiu checksums 0 192.168.1.101 InnoDB 1 705c5e2e 0 0 NULL NULL
huanqiu checksums 0 192.168.1.102 InnoDB 1 705c5e2e 0 0 NULL NULL
huanqiu haha 0 192.168.1.101 InnoDB 3 b9b29a07 0 0 NULL NULL
huanqiu haha 0 192.168.1.102 InnoDB 3 b9b29a07 0 0 NULL NULL
DATABASE TABLE CHUNK HOST ENGINE COUNT CHECKSUM TIME WAIT STAT LAG
huanpc checksums 0 192.168.1.101 InnoDB 1 5af891e 0 0 NULL NULL
huanpc checksums 0 192.168.1.102 InnoDB 1 5af891e 0 0 NULL NULL
huanpc heihei 0 192.168.1.101 InnoDB 7 22a57b1c 0 0 NULL NULL
huanpc heihei 0 192.168.1.102 InnoDB 7 22a57b1c 0 0 NULL NULL 或者加mk-checksum-filter
[root@master-server ~]# mk-table-checksum h=192.168.1.101,u=data_check,p=check@123,P=3306 h=192.168.1.102,u=data_check,p=check@123,P=3306 -dhuanqiu,huanpc --count | mk-checksum-filter
[root@master-server ~]#
-------------------------------------------------------------------------------------------------------------------
如有报错:
DBD::mysql::db do failed: Access denied; you need (at least one of) the SUPER privilege(s) for this operation [for Statement "/*!50105 SET @@binlog_format="STATEMENT"*/"] at /usr/local/bin/mk-table-sync line 8568.
Issuing rollback() due to DESTROY without explicit disconnect() of DBD::mysql::db handle ;host=192.168.1.101;port=3306;mysql_read_default_group=client at /usr/local/bin/mk-table-sync line 8568.
解决办法:安装DBI和DBD-MySQL
下载地址:
http://ftp.cuhk.edu.hk/pub/packages/perl/CPAN/authors/id/T/TI/TIMB/
http://search.cpan.org/dist/DBD-mysql/
或者百度云盘下载:https://pan.baidu.com/s/1miv0S8g (提取密码:fh24)
[root@master-server src]# tar -zvxf DBI-1.634.tar.gz
[root@master-server src]# cd DBI-1.634
[root@master-server DBI-1.634]# perl Makefile.PL
[root@master-server DBI-1.634]# make && make install
[root@master-server src]# tar -zvxf DBD-mysql-4.041_01.tar.gz
[root@master-server src]# cd DBD-mysql-4.041_01
[root@master-server DBD-mysql-4.041_01]# perl Makefile.PL --mysql_config=/usr/local/mysql/bin/mysql_config //主库mysql安装路径/usr/local/mysql
[root@master-server DBD-mysql-4.041_01]# make
[root@master-server DBD-mysql-4.041_01]# make install
--------------------------------------------------------------------------------------------------------------------
这里要说明一下:
主从数据库表和表结构必须一致,否则会报错!
--no-check-slave这个参数,如果不加这个参数,会提示报错,因为此工具默认不允许在从库上修改数据,但这里为了不在主库上dump出来,再到从库上导入进去,加了这个参数。
特别注意的是:
1)如果想要看下到底哪些数据不同步,可以这样做:(如果不跟-t参数,就是说同步整个库的所有表的数据)
mk-table-sync --execute --charset=utf8 --print --no-check-slave --databases huanqiu,huanpc h=192.168.1.101,u=mksync,p=sync@123,P=3306 h=192.168.1.102,u=mksync,p=sync@123,P=3306 > /root/result
2)如果有好几个从库的话,建议分开同步,除非几个从库的checksum一样!
因为每个从库同步的步调不一定都一致,如果几个从库一块同步的话,很容易造成主键冲突,导致主从同步中断。
举个例子来说:
主库:192.168.1.101
从库1: 192.168.1.102
从库2: 192.168.1.103
从库3: 192.168.1.104
建议(分开同步,一个个操作):
mk-table-sync --execute --charset=utf8 --print --no-check-slave -d huanqiu -t haha h=192.168.1.101,u=mksync,p=sync@123,P=3306 h=192.168.1.102,u=mksync,p=sync@123,P=3306 > /root/result1
mk-table-sync --execute --charset=utf8 --print --no-check-slave -d huanqiu -t haha h=192.168.1.101,u=mksync,p=sync@123,P=3306 h=192.168.1.103,u=mksync,p=sync@123,P=3306 > /root/result2
mk-table-sync --execute --charset=utf8 --print --no-check-slave -d huanqiu -t haha h=192.168.1.101,u=mksync,p=sync@123,P=3306 h=192.168.1.104,u=mksync,p=sync@123,P=3306 > /root/result3
不建议(放在一起同步):
mk-table-sync --execute --charset=utf8 --print --no-check-slave -d huanqiu -t haha h=192.168.1.101,u=mksync,p=sync@123,P=3306 h=192.168.1.102,u=mksync,p=sync@123,P=3306 h=192.168.1.103,u=mksync,p=sync@123,P=3306 h=192.168.1.104,u=data_check,p=check@123,P=3306 > /root/result
4)为了减少重复操作,也可以一次同步好几个表,多个表时可以在-t后加=号,即-t=tables1,tables2,table3...比如:
mk-table-sync --execute --charset=utf8 --print --no-check-slave -d huanqiu -t=haha,heihei,hehe,name h=192.168.1.101,u=data_check,p=check@123,P=3306 h=192.168.1.102,u=mksync,p=sync@123,P=3306 > /root/result