今天接到开发报障,某业务库出现大量重复数据。据开发描述,负责写数据的程序并没有出现循环,不应该会出现如此多重复数据!于是,开始了故障排查。。。
这个业务的数据库是双主模式的,分别在两个master上查看slave
status。由于写点只在亚太点,上海真如点无读写,纯粹做备份而已。在亚太点show
slave status竟然发现亚太点有延迟!!!
这是怎么回事?真如点根本就不是写点,写点全部在亚太点,怎么可能会出现亚太点追不上上海真如点,出现同步延迟???
在真如点上查看binlog
ls -lthr
/data/mysql_6302_binlog/
-rw-rw---- 1 mysql mysql
101M Sep 25 21:04 mysql-bin.003343
-rw-rw---- 1 mysql mysql
101M Sep 25 21:05 mysql-bin.003344
-rw-rw---- 1 mysql mysql
101M Sep 25 21:06 mysql-bin.003345
-rw-rw---- 1 mysql mysql
101M Sep 25 21:07 mysql-bin.003346
-rw-rw---- 1 mysql mysql
101M Sep 25 21:08 mysql-bin.003347
-rw-rw---- 1 mysql mysql
101M Sep 25 21:08 mysql-bin.003348
-rw-rw---- 1 mysql mysql
101M Sep 25 21:09 mysql-bin.003349
-rw-rw---- 1 mysql mysql
101M Sep 25 21:11 mysql-bin.003350
-rw-rw---- 1 mysql mysql
101M Sep 25 21:12 mysql-bin.003351
-rw-rw---- 1 mysql mysql
101M Sep 25 21:13 mysql-bin.003352
-rw-rw---- 1 mysql mysql
101M Sep 25 21:14 mysql-bin.003353
. . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . .
My God
! binlog一分钟产生一个,这也太吓人了吧
在亚太点查看binlog
ls -lthr
/data/mysql_6302_binlog/
-rw-rw---- 1 mysql mysql
101M Sep 25 20:27 mysql-bin.003306
-rw-rw---- 1 mysql mysql
101M Sep 25 20:28 mysql-bin.003307
-rw-rw---- 1 mysql mysql
101M Sep 25 20:29 mysql-bin.003308
-rw-rw---- 1 mysql mysql
101M Sep 25 20:30 mysql-bin.003309
-rw-rw---- 1 mysql mysql
101M Sep 25 20:31 mysql-bin.003310
-rw-rw---- 1 mysql mysql
101M Sep 25 20:32 mysql-bin.003311
-rw-rw---- 1 mysql mysql
101M Sep 25 20:33 mysql-bin.003312
-rw-rw---- 1 mysql mysql
101M Sep 25 20:34 mysql-bin.003313
-rw-rw---- 1 mysql mysql
101M Sep 25 20:35 mysql-bin.003314
-rw-rw---- 1 mysql mysql
101M Sep 25 20:36 mysql-bin.003315
. . . . . . . . . . . . . .
. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .
. . . . . .
亚太点同样是一分钟产生一个binlog。。。。。。
在真如点查看binlog内容
/usr/local/mysql_6302/bin/mysqlbinlog
/data/mysql_6302_binlog/mysql-bin.003353 | tail
-200
(这里截取一部分binlog内容)
我们可以看到server id 为 1069330。猜想这个server
id应该是亚太点的server
id(因为数据是从亚太点同步过来的)。查看亚太点的sever
id :
cat
/data1/mysql_6302/my.cnf | grep server-id
server-id = 13577444
亚太点的server-id是13577444呀,并不是1069330啊!
查看亚太点的binlog
/usr/local/mysql_6302/bin/mysqlbinlog
/data/mysql_6302_binlog/mysql-bin.003315 | tail
-200
(同样截取一部分binlog内容)
在亚太点看到的server id也是1069330。查看真如点的server
id:
cat
/data1/mysql_6302/my.cnf | grep server-id
server-id = 9911840
真如点的server-id是9911840,不是1069330
!
现在问题很明显了,这个server-id对应的数据库的binlog在两个主之间传来传去,形成了一个死循环。亚太点将这个server-id对应的binlog通过主从复制传递给真如点,由于是双主模式,故真如点也会将这些binlog传递给亚太点。如果在正常的双主模式下,亚太点看到binlog对应的server-id是自己,那么它就不会去执行binlog内容。而此时这个server-id既不是亚太点的,也不是真如点的,所以它们都会执行这些binlog内容。如此,反反复复地执行,也就导致了数据库出现许多重复数据了!
那这个server id到底是从哪里来的呢?回想一下,这个业务的库,是从原来另外一个库迁移过来的。原来的主从架构如下:
原来的主从架构中,亚太点作为server-id=1069330这个主库的从库,又作为真如点的主库,是一种级联架构。
更改之后的架构如下:
更改后的架构,亚太点和真如点为双主架构,业务方已经将业务切到亚太点。Server-id=1069330的库不再读写。读写已经切换到亚太点。
在更改主从架构的过程中,需要做的一个步骤是在亚太点重新change
mater to 指到真如点。但是由于在change master
to之前没有reset
slave-->stop slave,故导致Server-id=1069330的主库的binlog在亚太点和真如点之间循环传递,然后出现大量重复数据,并且binlog产生量很大,一分钟一个!如果遇到这种情况,解决方法就是在亚太点reset
slave,重新change
master 到真如点,确认问题是否解决的关键点是查看新的binlog是否还有server-id=1069330的内容。
总结:DBA需要的是拥有谨慎、小心的态度,一个很小的细节没有注意到,就很可能导致出现大问题,在每一个操作之前,都需要进行小心确认,确保无误之后方可操作。假设上述业务是核心业务,出现大量重复数据,那么造成的后果难以想象!