Chinaunix首页 | 论坛 | 博客
  • 博客访问: 668806
  • 博文数量: 220
  • 博客积分: 0
  • 博客等级: 民兵
  • 技术积分: 1961
  • 用 户 组: 普通用户
  • 注册时间: 2014-11-04 21:54
文章分类

全部博文(220)

文章存档

2018年(1)

2015年(140)

2014年(79)

我的朋友

分类: Mysql/postgreSQL

2014-12-18 09:50:48

摘要:

      工作上需要把一个从库提升为主库,但对从库和主库的数据一致性不能保证一样,所以就利用 pt-table-checksum 工作来检查主从的一致性(之前写过用1.0.1的版本可以进行操作的文章,但是在新版本操作就不行了,只能重新来过)以及通过 pt-table-sync 如何修复这些不一致的数据。

前提:

下载地址: wget 

安装方法:perl Makefile.PL;make;make install

使用方法:

pt-table-checksum [OPTIONS] [DSN]

  在主上 通过执行校验的查询 对复制的一致性进行检查,对比主从的校验值,从而产生结果。 DSN指向的是主的地址, 该工具的退出状态不为零,如果发现有任何差别,或者如果出现任何警告或错误,更多信息请见官网。 
不制定任何参数,会直接对本地的所有数据库的表进行检查。

pt-table-checksum -S /var/run/mysqld/mysqld.sock

现在开始使用它,检查主从状态: 
表信息:

 View Code



  1. 主库:
  2. root@localhost : rep_test 04:17:29>select * from test1;
  3. +----+------+
  4. | id | name |
  5. +----+------+
  6. | 1 | a |
  7. | 2 | b |
  8. | 3 | c |
  9. | 4 | d |
  10. +----+------+
  11. 4 rows in set (0.00 sec)

  12. 从库:
  13. dba@192.168.200.201 : rep_test 04:17:25>select * from test1;
  14. +----+------+
  15. | id | name |
  16. +----+------+
  17. | 1 | a |
  18. | 2 | b |
  19. | 4 | d |
  20. +----+------+
  21. 3 rows in set (0.00 sec)


执行:


  1. zhoujy@zhoujy:~$ pt-table-checksum --nocheck-replication-filters --replicate=rep_test.checksums --databases=rep_test --tables=test1 h=127.0.0.1,u=root,p=123456,P=3306
  2.             TS ERRORS DIFFS ROWS CHUNKS SKIPPED TIME TABLE
  3. 05-08T16:21:06 0 1 4 1 0 0.012 rep_test.test1

TS            :完成检查的时间。
ERRORS        :检查时候发生错误和警告的数量。
DIFFS         :0表示一致,1表示不一致。当指定--no-replicate-check时,会一直为0,当指定--replicate-check-only会显示不同的信息。 
ROWS          :表的行数。
CHUNKS        :被划分到表中的块的数目。
SKIPPED       :由于错误或警告或过大,则跳过块的数目。
TIME          :执行的时间。
TABLE         :被检查的表名。

参数的意义:

--nocheck-replication-filters :不检查复制过滤器,建议启用。后面可以用--databases来指定需要检查的数据库。 
--no-check-binlog-format : 不检查复制的binlog模式,要是binlog模式是ROW,则会报错。 
--replicate-check-only :只显示不同步的信息。 
--replicate=   :把checksum的信息写入到指定表中,建议直接写到被检查的数据库当中。  
--databases=   :指定需要被检查的数据库,多个则用逗号隔开。 
--tables=      :指定需要被检查的表,多个用逗号隔开 
h=127.0.0.1    :Master的地址 
u=root         :用户名
p=123456       :密码
P=3306         :端口 更多的参数请见官网,上面指出来的是常用的,对该场景够用的参数。

好了,命令介绍完了,一起解释下 上面 执行的效果: 
通过 DIFFS 是1 就可以看出主从的表数据不一致。怎么不一致呢? 通过 指定 --replicate=rep_test.checksums 参数,就说明把检查信息都写到了checksums表中。 
进入SLAVE相应的库中查看checksums表的信息:


  1. dba@192.168.200.201 : rep_test 05:19:13>select * from checksums\G;
  2. *************************** 1. row ***************************
  3.             db: rep_test
  4.            tbl: test1
  5.          chunk: 1
  6.     chunk_time: 0.000257
  7.    chunk_index: NULL
  8. lower_boundary: NULL
  9. upper_boundary: NULL
  10.       this_crc: b24c0933 #从的
  11.       this_cnt: 3 #从的
  12.     master_crc: f2890e1c #主的
  13.     master_cnt: 4 #主的
  14.             ts: 2013-05-08 17:18:18
  15. 1 row in set (0.00 sec)



通过上面的 this_crc <> master_crc 更能清楚的看出他们的不一致了 ,通过chunk知道是这个张表的哪个块上的记录出现不一致 。要是主的 binlog模式是Row 则会报错:

Replica db2 has binlog_format ROW which could cause pt-table-checksum to break replication.  
Please read "Replicas using row-based replication" in the LIMITATIONS section of the tool's documentation.  
If you understand the risks, specify --no-check-binlog-format to disable this check.

从错误信息得出,要是不改binlog模式的话,则 在 执行上面的命令时候要指定: 
--no-check-binlog-format ,即: 

pt-table-checksum  --nocheck-replication-filters --no-check-binlog-format --replicate=rep_test.checksums --databases=rep_test --tables=test1,test2  h=127.0.0.1,u=root,p=123456,P=3306

通过上面找到了这些不一致的数据表,如何同步数据呢?即如何 修复MySQL主从不一致的数据 ,让他们保持一致性呢?利用另外一个工具  。 

使用方法:

pt-table-sync [OPTIONS] DSN [DSN]

 : 高效的同步MySQL表之间的数据,他可以做单向和双向同步的表数据。他可以同步单个表,也可以同步整个库。它不同步表结构、索引、或任何其他模式对象。所以在修复一致性之前需要保证他们表存在。

接着上面的复制情况,主和从的test1数据不一致,需要修复, 
执行 


  1. root@zhoujy:~# pt-table-sync --replicate=rep_test.checksums h=127.0.0.1,u=root,p=123456 h=192.168.200.201,u=root,p=123456 --print
  2. REPLACE INTO `rep_test`.`test1`(`id`, `name`) VALUES ('3', 'c') /*percona-toolkit src_db:rep_test src_tbl:test1 src_dsn:h=127.0.0.1,p=...,u=root dst_db:rep_test dst_tbl:test1 dst_dsn:h=192.168.200.201,p=...,u=root lock:1 transaction:0 changing_src:rep_test.checksums replicate:rep_test.checksums bidirectional:0 pid:12285 user:root host:zhoujy*/


root@zhoujy:~# pt-table-sync --replicate=rep_test.checksums h=127.0.0.1,u=root,p=123456 h=192.168.200.201,u=root,p=123456 --print 
REPLACE INTO `rep_test`.`test1`(`id`, `name`) VALUES ('3', 'c') /*percona-toolkit src_db:rep_test src_tbl:test1 src_dsn:h=127.0.0.1,p=...,u=root dst_db:rep_test dst_tbl:test1 dst_dsn:h=192.168.200.201,p=...,u=root lock:1 transaction:0 changing_src:rep_test.checksums replicate:rep_test.checksums bidirectional:0 pid:12285 user:root host:zhoujy*/;

参数的意义:

--replicate=  :指定通过pt-table-checksum得到的表,这2个工具差不多都会一直用。 
--databases= : 指定执行同步的数据库,多个用逗号隔开。 
--tables= :指定执行同步的表,多个用逗号隔开。 
--sync-to-master : 
h=127.0.0.1服务器地址,命令里有2个ip,第一次出现的是M的地址,第2次是Slave的地址。
u=root        :帐号。
p=123456 :密码。 
--print  :打印,但不执行命令。 
--execute  :执行命令。 更多的参数请见官网,上面指出来的是常用的,对该场景够用的参数。

好了,命令介绍完了,一起解释下执行的效果:通过( --print )打印出来了修复数据的sql语句,可以手动的去从行执行,让他们数据保持一致性。那能否直接执行?当然可以,通过( -- execute ):

root@zhoujy:~# pt-table-sync --replicate=rep_test.checksums --databases=rep_test --tables=test2,test1 h=127.0.0.1,u=root,p=123456 h=192.168.200.201,u=root,p=123456 --execute root@zhoujy:~#

直接执行完毕了,查看数据表:

 View Code

  1. 主:
  2. root@localhost : rep_test 08:58:41>select * from test1;
  3. +----+------+
  4. | id | name |
  5. +----+------+
  6. | 1 | a |
  7. | 2 | b |
  8. | 3 | c |
  9. | 4 | d |
  10. +----+------+
  11. 4 rows in set (0.00 sec)

  12. 从:
  13. root@192.168.200.201 : rep_test 08:58:56>select * from test1;
  14. +----+------+
  15. | id | name |
  16. +----+------+
  17. | 1 | a |
  18. | 2 | b |
  19. | 3 | c |
  20. | 4 | d |
  21. +----+------+
  22. 4 rows in set (0.00 sec)

OK,数据已经保持一致了。不过建议还是用--print 打印出来的好,这样就可以知道那些数据有问题,可以人为的干预下。不然直接执行了,出现问题之后更不好处理。总之还是在处理之前做好数据的备份工作。

注意: 要是表中没有唯一索引或则主键则会报错:

Can't make changes on the master because no unique index exists at /usr/local/bin/pt-table-sync line 10591.

另外补充: 
要是从库有的数据,而主库没有,那这个数据怎么处理?在原先的基础上,在从上添加一条5记录。

  1. root@zhoujy:~# pt-table-sync --replicate=rep_test.checksums --databases=rep_test,test --tables=test2,test1 h=127.0.0.1,u=root,p=123456 h=192.168.200.201,u=root,p=123456 --print
  2. DELETE FROM `rep_test`.`test1` WHERE `id`='5' LIMIT 1

  3. /*percona-toolkit src_db:rep_test src_tbl:test1 src_dsn:h=127.0.0.1,p=...,u=root dst_db:rep_test dst_tbl:test1 dst_dsn:h=192.168.200.201,p=...,u=root lock:1 transaction:0 changing_src:rep_test.checksums replicate:rep_test.checksums bidirectional:0 pid:12343 user:root host:zhoujy*/;

  4. REPLACE INTO `rep_test`.`test1`(`id`, `name`) VALUES ('3', 'c')

  5. /*percona-toolkit src_db:rep_test src_tbl:test1 src_dsn:h=127.0.0.1,p=...,u=root dst_db:rep_test dst_tbl:test1 dst_dsn:h=192.168.200.201,p=...,u=root lock:1 transaction:0 changing_src:rep_test.checksums replicate:rep_test.checksums bidirectional:0 pid:12343 user:root host:zhoujy*/


从上面可以看到,直接把从库的有的数据给删除了,没有的数据进行插入。这样2边又保持了 一致性。

总结: 
该工具检查的表,需要表具有唯一索引或则主键,否则执行失败,而且检查连接的帐号需要有很高的权限,在一般权限行需要加 
SELECT, PROCESS, SUPER, REPLICATION SLAVE 等权限,测试方便我直接给了ALL的权限。



阅读(933) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~