mysql主主同步,主从同步数据不⼀致问题解决
问题起源:
1. mysql数据库同步过程中经常会因为某种错误导致同步出错⽽暂停,此时使⽤show slave status\G命令能查看到错误数据此
时Slave_SQL_Running: No,为了解决这个问题⼀般使⽤如下命令解决
stop slave;
set global sql_slave_skip_counter =1;
start slave;
有时候忽略⼀次错误还不⾏,需要忽略很多,那么忽略错误过程中就会出现数据不⼀致的问题(有些正常数据被忽略了)
2. 某个服务器异常宕机导致部分SQL未同步
如何解决:
为了保证不同mysql服务器之间的数据⼀致,可以采⽤如下的⼀个⼯具集合Percona-toolkit
他有2个⼯具:pt-table-checksum和pt-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 www.percona/downloads/percona-toolkit/2.2.18/tarball/percona-toolkit-2.2.
#解压缩
tar -xvf percona-toolkit_2.2.
#进⼊⽬录
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 :表的⾏数。
mysql下载不了怎么办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个库来回切换着同步⼀样可以解决问题。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论