问题说明
mysql
主从同步时难免出现问题导致数据不一致情况.此时需要手动将主从数据同步.
Maatkit
是一个开源的工具包,为mySQL
日常管理提供了帮助,它包含很多工具,这里主要说下面两个:
mk-table-checksum
: 用来检测master
和slave
上的表结构和数据是否一致的;mk-table-sync
: 在主从数据不一致时,用来修复数据的;先主后从有效保证表一致的工具,不必重载从表而能够保证一致。上面两个perl脚本在运行时都会锁表,表的大小取决于执行的快慢,勿在高峰期间运行,可选择凌晨
安装Maatkit
- 安装依赖
# 安装依赖
yum install perl-IO-Socket-SSL perl-DBD-MySQL perl-Time-HiRes perl perl-DBI -y
yum install perl-ExtUtils-Embed perl-ExtUtils-CBuilder perl-ExtUtils-MakeMaker -y
yum -y install perl-Digest-MD5
- 下载
maatkit
- 需要翻墙到官网下载:https://code.google.com/archive/p/maatkit/downloads
- 百度云盘下载地址:https://pan.baidu.com/s/1c1AufW8 (提取密码:
vbi1
)
- 安装
maatkit
# 解压进入目录
tar -zvxf maatkit-7540.tar.gz && cd maatkit-7540
[root@mysql01 maatkit-7540]# perl Makefile.PL
Checking if your kit is complete...
Looks good
Writing Makefile for maatkit
# 安装
make && make install
# 测试查看mk-相关命令
[root@mysql01 maatkit-7540]# mk-
mk-archiver mk-duplicate-key-checker mk-heartbeat mk-log-player mk-profile-compact mk-query-profiler mk-slave-move mk-table-sync mk-variable-advisor
mk-checksum-filter mk-error-log mk-index-usage mk-merge-mqd-results mk-purge-logs mk-show-grants mk-slave-prefetch mk-table-usage mk-visual-explain
mk-config-diff mk-fifo-split mk-kill mk-parallel-dump mk-query-advisor mk-slave-delay mk-slave-restart mk-tcp-model
mk-deadlock-logger mk-find mk-loadavg mk-parallel-restore mk-query-digest mk-slave-find mk-table-checksum mk-upgrade
工具使用
- 创建
mysql
检查帐号
-- 主从服务器上创建只有SELECT权限的帐号
mysql> GRANT SELECT ON *.* TO 'data_check'@'%' IDENTIFIED BY '123456';
Query OK, 0 rows affected (0.01 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.01 sec)
- 检查一致性
# 第一个h: 填写主库ip
# 第一个u: 主库授权的用户名
# 第一个p: 主库授权的密码
# 第二个h: 填写从库ip
# 第二个u: 从库授权的用户名
# 第二个p: 从库授权的密码
# 大写P: mysql的端口
[root@mysql01 maatkit-7540]# mk-table-checksum h=192.168.41.141,u=data_check,p=123456,P=3306 h=192.168.41.142,u=data_check,p=123456,P=3306
DATABASE TABLE CHUNK HOST ENGINE COUNT CHECKSUM TIME WAIT STAT LAG
test t_department 0 192.168.41.141 InnoDB NULL 83657212 0 0 NULL NULL
test t_department 0 192.168.41.142 InnoDB NULL 3344593131 0 0 NULL NULL
test testttt 0 192.168.41.141 InnoDB NULL 3722958311 0 0 NULL NULL
test testttt 0 192.168.41.142 InnoDB NULL 3722958311 0 0 NULL NULL
DATABASE TABLE CHUNK HOST ENGINE COUNT CHECKSUM TIME WAIT STAT LAG
mysql columns_priv 0 192.168.41.141 MyISAM NULL 0 0 0 NULL NULL
mysql columns_priv 0 192.168.41.142 MyISAM NULL 0 0 0 NULL NULL
mysql db 0 192.168.41.141 MyISAM NULL 2629905140 0 0 NULL NULL
mysql db 0 192.168.41.142 MyISAM NULL 2629905140 0 0 NULL NULL
mysql engine_cost 0 192.168.41.141 InnoDB NULL 2678612005 0 0 NULL NULL
...
# 参数-d(或者--database) 指定要检查的数据库,多个数据库之间用逗号隔开,如果不加-d,校验的是所有库;
# --count 会计算出表的行数
[root@mysql01 maatkit-7540]# mk-table-checksum h=192.168.41.141,u=data_check,p=123456,P=3306 h=192.168.41.142,u=data_check,p=123456,P=3306 --count -dtest
DATABASE TABLE CHUNK HOST ENGINE COUNT CHECKSUM TIME WAIT STAT LAG
test t_department 0 192.168.41.141 InnoDB 13 5e339d70 0 0 NULL NULL
test t_department 0 192.168.41.142 InnoDB 13 7a4c9153 0 0 NULL NULL
test testttt 0 192.168.41.141 InnoDB 8 41db7636 0 0 NULL NULL
test testttt 0 192.168.41.142 InnoDB 8 41db7636 0 0 NULL NULL
# 结果参数说明
# DATABASE 检查的库名
# TABLE: 检查的库中的表名
# CHUNK: checksum时的近似数值
# HOST: 主从MYSQL的地址
# ENGINE: 表引擎
# COUNT: 表的行数
# CHECKSUM: 校验值
# TIME: 所用时间
# WAIT: 等待时间
# STAT: MASTER_POS_WAIT()返回值
# LAG: slave的延时时间
# mk-checksum-filter过滤出不一样的结果
[root@mysql01 maatkit-7540]# mk-table-checksum h=192.168.41.141,u=data_check,p=123456,P=3306 h=192.168.41.142,u=data_check,p=123456,P=3306 --count -dtest | mk-checksum-filter
test t_department 0 192.168.41.141 InnoDB 13 5e339d70 0 0 NULL NULL
test t_department 0 192.168.41.142 InnoDB 13 7a4c9153 0 0 NULL NULL
- 修复主从不同步的数据
mk-table-sync
用来修复多个实例之间数据的不一致. mk-table-sync
的工作方式是:先一行一行检查主从库的表是否一样,如果哪里不一样,就执行删除,更新,插入等操作,使其达到一致。
由于上面在mk-table-checksum
检查时用的data_check
只有select
权限,权限太小,不能用于mk-table-sync
修复数据只用。
所以还需要在主库和从库数据库里创建用于mk-table-sync
修复数据之用的账号权限
mysql> GRANT ALL ON *.* to mksync@'%' identified by "123456";
Query OK, 0 rows affected (0.01 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
# 注意:主从数据库表和表结构必须一致,否则会报错!
# --print 显示同步需要执行的语句
# --execute 执行数据同步
# --charset=utf8mb4 设置字符集,避免从库乱码。
# --no-check-slave 如果不加这个参数,会提示报错,因为此工具默认不允许在从库上修改数据
# -t 指定同步的表名,多个表时可以在-t后加=号,即-t=tables1,tables2,..
# > /root/result 命令后面加上 > /root/result 将结果导出
[root@mysql01 maatkit-7540]# mk-table-sync --execute --charset=utf8mb4 --print --no-check-slave --databases test h=192.168.41.141,u=mksync,p=123456,P=3306 h=192.168.41.142,u=mksync,p=123456,P=3306
UPDATE `test`.`t_department` SET `department_name`='44', `parent_id`='0', `level`='1', `create_time`='2020-07-28 16:06:24', `update_time`='2020-07-28 16:06:24' WHERE `department_id`='3' LIMIT 1 /*maatkit src_db:test src_tbl:t_department src_dsn:A=utf8mb4,P=3306,h=192.168.41.141,p=...,u=mksync dst_db:test dst_tbl:t_department dst_dsn:A=utf8mb4,P=3306,h=192.168.41.142,p=...,u=mksync lock:0 transaction:1 changing_src:0 replicate:0 bidirectional:0 pid:3869 user:root host:mysql01*/;
# 修复之后检查主从,通过CHECKSUM可以看出,数据已经完全一样了
[root@mysql01 maatkit-7540]# mk-table-checksum h=192.168.41.141,u=data_check,p=check@123,P=3306 h=192.168.41.142,u=data_check,p=check@123,P=3306 --count -dtest
DATABASE TABLE CHUNK HOST ENGINE COUNT CHECKSUM TIME WAIT STAT LAG
test t_department 0 192.168.41.141 InnoDB 13 5e339d70 0 0 NULL NULL
test t_department 0 192.168.41.142 InnoDB 13 5e339d70 0 0 NULL NULL
test testttt 0 192.168.41.141 InnoDB 8 41db7636 0 0 NULL NULL
test testttt 0 192.168.41.142 InnoDB 8 41db7636 0 0 NULL NULL