zoukankan      html  css  js  c++  java
  • perconatoolkit 之 【pttablechecksum】、【pttablesync】说明

    摘要:

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

    前提:

    下载地址:wget www.percona.com/downloads/percona-toolkit/2.2.2/percona-toolkit-2.2.2.tar.gz

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

    使用方法:

    pt-table-checksum [OPTIONS] [DSN]

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

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

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

    View Code
    主库:
    root@localhost : rep_test 04:17:29>select * from test1;
    +----+------+
    | id | name |
    +----+------+
    |  1 | a    |
    |  2 | b    |
    |  3 | c    |
    |  4 | d    |
    +----+------+
    4 rows in set (0.00 sec)
    
    从库:
    dba@192.168.200.201 : rep_test 04:17:25>select * from test1;
    +----+------+
    | id | name |
    +----+------+
    |  1 | a    |
    |  2 | b    |
    |  4 | d    |
    +----+------+
    3 rows in set (0.00 sec)

    执行:

    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
                TS ERRORS  DIFFS     ROWS  CHUNKS SKIPPED    TIME TABLE
    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表的信息:

    dba@192.168.200.201 : rep_test 05:19:13>select * from checksums\G;
    *************************** 1. row ***************************
                db: rep_test
               tbl: test1
             chunk: 1
        chunk_time: 0.000257
       chunk_index: NULL
    lower_boundary: NULL
    upper_boundary: NULL 
          this_crc: b24c0933   #从的
          this_cnt: 3          #从的
        master_crc: f2890e1c   #主的
        master_cnt: 4          #主的
                ts: 2013-05-08 17:18:18
    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

    注意:

    要是在执行命令的过程遇到找不到从服务器的错误:

    Diffs cannot be detected because no slaves were found.  Please read the --recursion-method documentation for information.

    上面的提示信息很清楚,因为找不到从,所以执行失败。用参数--recursion-method 可以指定模式解决,关于--recursion-method参数的设置有:

    METHOD       USES
    ===========  =============================================
    processlist  SHOW PROCESSLIST
    hosts        SHOW SLAVE HOSTS
    cluster      SHOW STATUS LIKE 'wsrep\_incoming\_addresses'
    dsn=DSN      DSNs from a table
    none         Do not find slaves

    默认是通过show processlist 找到host的值或show slave hosts 找到host的值。那上面为什么会找不到从呢?

    个人猜测:测试下来是因为在同一个服务器上开启了2个实例互为主从,通过processlist 得到的 host 主从一样,但是没有,而 show slave hosts,因为从上没有指定所以也取不到需要的信息。解决办法:

    在从的配置文件里加:

    report_host = 192.168.200.25   #设置成本地地址

    这样在主上执行 show slave hosts 就有信息了:

    root@localhost : (none) 02:47:43>show slave hosts;
    +-----------+----------------+------+----------+------+-------------------+-----------+
    | Server_id | Host           | User | Password | Port | Rpl_recovery_rank | Master_id |
    +-----------+----------------+------+----------+------+-------------------+-----------+
    |         2 | 192.168.200.25 |      |          | 3307 |                 0 |         1 |
    +-----------+----------------+------+----------+------+-------------------+-----------+
    1 row in set (0.00 sec)

    最后再执行以上命令(多加--recursion-method=hosts 参数)

    zhoujy@zhoujy:~$ pt-table-checksum --recursion-method=hosts --no-check-binlog-format --nocheck-replication-filters  --replicate=aaa.checksums --databases=aaa --tables=test h=192.168.200.25,u=root,p=123456,P=3306
                TS ERRORS  DIFFS     ROWS  CHUNKS SKIPPED    TIME TABLE
    10-24T14:54:43      0      1        6       1       0   0.306 aaa.test

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

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

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

    接着上面的复制情况,主和从的test1数据不一致,需要修复,要是有中文的则需要加上:--charset=utf8,防止乱码。
    执行

    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 --charset=utf8 --print
    REPLACE INTO `rep_test`.`test1`(`id`, `name`) VALUES ('3', 'c')  
    #先M的IP,再S的IP
    /*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 :指定一个DSN,即从的IP,他会通过show processlist或show slave status 去自动的找主。
    h=127.0.0.1服务器地址,命令里有2个ip,第一次出现的是M的地址,第2次是Slave的地址。
    u=root        :帐号。
    p=123456      :密码。
    --print       :打印,但不执行命令。
    --execute     :执行命令。
    更多的参数请见官网,上面指出来的是常用的,对该场景够用的参数。

    上面的效果和这个一样:

    zhoujy@zhoujy:~$ pt-table-sync --sync-to-master h=192.168.200.201,u=root,p=123456 --databases=rep_test --tables=test1 --charset=utf8 --print
    REPLACE INTO `rep_test`.`test1`(`id`, `name`) VALUES ('3', 'c') 
    #用一个IP(SLAVE)就可以了。
    /*percona-toolkit src_db:rep_test src_tbl:test1 src_dsn:P=3306,h=192.168.200.25,p=...,u=root dst_db:rep_test dst_tbl:test1 dst_dsn:h=192.168.200.201,p=...,u=root lock:1 transaction:1 changing_src:1 replicate:0 bidirectional:0 pid:20122 user:zhoujy host:zhoujy*/;

    好了,命令介绍完了,一起解释下执行的效果:通过(--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
    主:
    root@localhost : rep_test 08:58:41>select * from test1;
    +----+------+
    | id | name |
    +----+------+
    |  1 | a    |
    |  2 | b    |
    |  3 | c    |
    |  4 | d    |
    +----+------+
    4 rows in set (0.00 sec)
    
    从:
    root@192.168.200.201 : rep_test 08:58:56>select * from test1;
    +----+------+
    | id | name |
    +----+------+
    |  1 | a    |
    |  2 | b    |
    |  3 | c    |
    |  4 | d    |
    +----+------+
    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记录。

    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
    DELETE FROM `rep_test`.`test1` WHERE `id`='5' LIMIT 1 

    /*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*/;
    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:12343 user:root host:zhoujy*/;

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

    要是在shell窗口不想显示的输入密码则可以添加:--ask-pass 参数,如:

    zhoujy@zhoujy:~$ pt-table-checksum  --nocheck-replication-filters --no-check-binlog-format  --replicate=rep_test.checksums --ask-pass --databases=rep_test --tables=test1,test2  h=127.0.0.1,u=root,P=3306
    Enter MySQL password: 
                TS ERRORS  DIFFS     ROWS  CHUNKS SKIPPED    TIME TABLE
    05-09T13:57:04      0      1        4       1       0   0.015 rep_test.test1
    05-09T13:57:04      0      1        1       1       0   0.010 rep_test.test2
    
    zhoujy@zhoujy:~$ pt-table-sync --replicate=rep_test.checksums  --ask-pass h=127.0.0.1,u=root h=192.168.200.201,u=root --print
    Enter password for 127.0.0.1: 
    Enter password for 192.168.200.201: 
    DELETE FROM `rep_test`.`test1` WHERE `id`='5' LIMIT 1;
    REPLACE INTO `rep_test`.`test1`(`id`, `name`) VALUES ('4', 'd') ;

     总结:
    该工具检查的表,需要检查连接的帐号需要有很高的权限,在一般权限行需要加
    SELECT, PROCESS, SUPER, REPLICATION SLAVE等权限,测试方便我直接给了ALL的权限,pt-table-checksum 和 pt-table-sync 一起互补使用,检查一定是在同步操作之前,更多的信息请见 这里 这里这里


    ~~~~~~~~~~~~~~~ 万物之中,希望至美 ~~~~~~~~~~~~~~~
  • 相关阅读:
    安装linux下文件搜索工具ANGRYsearch,与windows下Everything类似
    windows常用软件、Linux软件对比
    在linux下双击用wine软件的打开
    好用的Linux下PDF编辑批注软件PDF Studio Pro 11
    python multiprocessing.pool.apply_async 占用内存多 解决方法
    linux 版 Fiddler 抓包软件的安装
    安装linux下强大的文件搜索工具fsearch,与windows下Everything类似
    python3 删除空文件夹
    【廖雪峰老师python教程】——错误和调试
    【廖雪峰老师python教程】——OOP
  • 原文地址:https://www.cnblogs.com/zhoujinyi/p/3067045.html
Copyright © 2011-2022 走看看