一、环境及问题:
两台redhat 服务器A和B 上各跑着mysql5.6, 互为主备,使用虚地址对外提供服务。虚地址一直在A主机上,某天单独连B库发现,数据与A库不一致,一开始以为认为更改,但是人为更改也会同步至另外一个库的啊,所以应该是同步出问题导致的。
二、原因及解决
原因:
在A库上执行show slave status,查看Slave_IO_Running 和Slave_SQL_Running都是YES,在B库上查看这两个也是YES,至少数据库是同步的。
但是在B库上执行show slave status,发现Seconds_Behind_Master很大,算下来2天多,根据两个库的数据更新时间字段来看,正好差2天多。
应该是同步延时导致的数据不一致。
解决:
本想着重启下两个库,看看是否能解决,但想着这也不是根本办法,时间长了还会同步延时的,继续查找。。。
执行show processlist 查看线程,select * from information_schema.processlist where command <> 'sleep' 发现A库上一直有update XXtabele 的语句执行,该语句为业务的正常操作。
show index from database.tables(表名)查看该表,没有建索引。update该表的时候应该是全表扫描,比较耗时。
对该表增加组合索引,延时问题解决。
三、mysql主备同步原理(拷贝别人的哈)
mysql在主库上记录binlog。在准备提交事务完成数据更新前,主库把数据更新的事件记录到binlog中。 mysql通过上面说的binlog用3个线程来实现主从同步,master上的Binlog Dump Thread
, slave上的Slave I/O Thread
和Slave SQL Thread
- Slave I/O Thread: I/O线程跟主库建立一个普通的客户端连接,并请求从指定日志文件的指定位置(或者从最开始的日志)之后的日志内容, 存到relaylog中, 然后将读取到的主库binlog的文件名和位置记录到master-info文件中
- Binlog Dump Thread: 读取主库上的binlog中的事件,根据请求信息读取制定日志指定位置之后的日志信息,返回给
Slave I/O Thread
。返回信息中除了日志所包含的信息之外,还包括本次返回的信息已经到Master端的binlog文件的名称以及binlog的位置。 - Slave SQL Thread: 从relaylog中读取事件并且在从库执行,从而实现从库的更新