• mysql主主同步,主从同步数据不一致问题解决


    问题起源:

    1. mysql数据库同步过程中经常会因为某种错误导致同步出错而暂停,此时使用show slave statusG命令能查看到错误数据此时Slave_SQL_Running: No,为了解决这个问题一般使用如下命令解决
    stop slave;
    set global sql_slave_skip_counter =1;
    start slave;  
    

    有时候忽略一次错误还不行,需要忽略很多,那么忽略错误过程中就会出现数据不一致的问题(有些正常数据被忽略了)

    1. 某个服务器异常宕机导致部分SQL未同步

    如何解决:

    为了保证不同mysql服务器之间的数据一致,可以采用如下的一个工具集合Percona-toolkit
    他有2个工具:pt-table-checksumpt-table-sync
    pt-table-checksum:用于检测2个数据库之间哪些表的数据不一致
    pt-table-sync:用于修复数据不一致的表或者库

    这里需要注意的地方是:必须选择一个库作为参考,强烈建议选择主库作为参考,主库和从库数据不一致时把主库的数据同步到从库达到一致。如果既要把主库的部分表同步到从库 又要想把从库的部分数据同步到主库(主主同步时会有此需求)则需要采取特殊手段,后面有说明

    第一步:安装工具集Percona-toolkit

    工具集请安装在主库的服务器上面

    #安装依赖包
    yum install perl perl-DBI perl-DBD-MySQL perl-IO-Socket-SSL perl-Time-HiRes perl-Digest-MD5 perl-ExtUtils-MakeMaker -y
    #下载工具集
    wget https://www.percona.com/downloads/percona-toolkit/2.2.18/tarball/percona-toolkit-2.2.18.tar.gz 
    #解压缩
    tar -xvf percona-toolkit_2.2.18.tar.gz
    #进入目录
    cd percona-toolkit-2.2.18/
    #执行perl脚本
    perl Makefile.PL
    #编译
    make
    #安装
    make install
    

    第二步:执行命令进行检测

    通过使用pt-table-checksum命令来进行检测,注意检测时需要指定一个表(表名可自定义),这个表用来记录差异点 为后续同步数据作为参考,这里假设要检测test数据库里面的table1表是否不同步。
    pt-table-checksum --nocheck-binlog-format --nocheck-replication-filters --replicate=test.checksums --databases=test --tables=table1 --host=172.16.0.21 --port=3306 --user=check_user --password=123456
    关于以上命令的解释如下:

    --nocheck-replication-filters :不检查复制过滤器,建议启用,这样我们可以自定义检查哪个数据库的数据,否则将会检查mysql所有被同步的数据库。
    --no-check-binlog-format      : 不检查复制的binlog模式,要是binlog模式是ROW,则会报错。
    --replicate-check-only :只显示不同步的信息,根据情况可加可不加,不加就会显示全部表的信息。
    --replicate=    :把checksum的信息写入到指定表中,建议直接写到被检查的数据库当中。 
    --databases=    :指定需要被检查的数据库,多个则用逗号隔开,建议一个一个检查。
    --tables=       :指定需要被检查的表,多个用逗号隔开
    --host=         :Master的地址
    --user=         :用户名,也可以使用root用户,或者自己创建用户赋予查询,修改,删除,同步权限,注意数据库权限也要赋予
    --password=     :密码
    --Port=         :端口
    

    在主库服务器执行以上命令之后 test数据库里面多了一个表checksums记录了哪些表不同步的信息。同时执行命令后命令输出如下信息:

    # A software update is available:
    #   * The current version for Percona::Toolkit is 3.0.5
    
                TS ERRORS  DIFFS     ROWS  CHUNKS SKIPPED    TIME TABLE
    09-02T11:59:07      0      1  1266622      14       0   5.983 test.table1
    [root@db-001-server ~]# 
    

    部分字段的解释如下

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

    以上结果中DIFFS为1代表主库和从库之间的数据有差异,接下来就是如何修复差异数据,我们使用另一个命令:pt-table-sync

    pt-table-sync h=172.16.0.21,u=check_user,p=123456,P=3306 --databases=test --tables=table1 --replicate=test.checksums --print
    

    上面命令里面的参数和之前的pt-table-checksum命令里面的一样,只是使用了简写的方式,注意最后一个参数 --print 这个很重要 这个--print会先把要执行修复操作的SQL文打印出来并不真正执行,用户可以查看SQL文。这里需要说一下 pt-table-sync修复数据差异的原理:
    这个命令首先会根据pt-table-checksum命令比较的结果也就是checksums表的记录去自动生成相关的SQL文,比如主库表里面多了一条记录则会生成一个SQL文 类似于 replace into table1(xx,xx,xx) values(yy,yy,yy)
    这里使用replace into就是有记录则删除再插入,无记录则直接插入,这样一来主库执行了该条SQL之后记录不变,但是因为主从同步的原因从库也会执行这条记录,这样就能够达到主库和从库数据一致了。需要注意一个前提就是表必须有主键才行
    如果主库里面没有了某条记录而从库里面还有记录 因为我们要参考主库作为最终依据则此时使用命令会生成DELETE FROM TABLE1 WHERE ID = XX的SQL文(记住这个原理,后续有用处)

    如果确认SQL没问题想执行修复 只需要执行如下语句(把--print替换成了 --execute)

    pt-table-sync h=172.16.0.21,u=check_user,p=123456,P=3306 --databases=test --tables=table1 --replicate=test.checksums --execute
    

    修复完毕之后可以重新执行一下pt-table-checksum命令看是否一致了。

    以上便是解决主从不同步的方式,如果想要解决多张表则只需要在--tables后面指定多张表,如果想要修复整个库则只需要去掉--tables则默认检查整个数据库的所有表

    主主同步留下的一个问题:如果部分表想要参考另一个库的数据,该如何做?

    这个问题是我自己亲身遇到的,我的mysql数据库做的是主主同步,A,B两个数据库互为主库双向同步。因此发现数据不一致时需要保持两个库的数据汇总操作
    我是这样解决的:
    首先在A库服务器上面执行完pt-table-checksum之后执行pt-table-sync发现里面有DELETE SQL文,意思是要删除某些数据,因为此时A库里面部分数据比B库少,那么怎么办呢,这里我单独提取了DELETE SQL文的主键,然后去B库查询这些数据并复制成INSERT 语句(使用Navicat工具的同学应该知道有这个功能,把查询到的数据复制成插入SQL文),然后我把这些插入SQL文改成replace into的方式(只需要替换insert为replace即可) 然后在B库执行这些SQL文,此时A库的这个表就拥有这些数据了。
    那么重新执行pt-table-checksum之后执行pt-table-sync 打印出来的SQL文只剩下replace into了 这时可以放心执行修复了。这只是一种思路用于数据量不大的情况。如果数据量大该怎么办呢?可以在B库服务器安装工具集然后执行同样的操作并且复制出replace into sql文在B库执行。A B2个库来回切换着同步一样可以解决问题。

  • 相关阅读:
    Matrix Walk CodeForces
    String Typing CodeForces
    Zebras CodeForces
    【OCP-12c】2019年CUUG OCP 071考试题库(74题)
    【OCP-12c】2019年CUUG OCP 071考试题库(73题)
    【OCP题库-12c】最新CUUG OCP 071考试题库(72题)
    【OCP题库-12c】最新CUUG OCP 071考试题库(71题)
    【OCP题库-12c】最新CUUG OCP 071考试题库(70题)
    【OCP题库-12c】最新CUUG OCP 071考试题库(69题)
    【OCP题库】最新CUUG OCP 12c 071考试题库(68题)
  • 原文地址:https://www.cnblogs.com/bcde/p/15218328.html
Copyright © 2020-2023  润新知