前言
MySQL同步功能由3个线程(master上1个,slave上2个)来实现,简单的说就是:master发送日志一个,slave接收日志一个,slave运行日志一个。
主从延迟判断的方法,通常有两种方法:Seconds_Behind_Master和pt-heartbeat
1.Seconds_Behind_Master
通过监控show slave statusG命令输出的Seconds_Behind_Master参数的值来判断,是否有发生主从延时。
mysql> show slave statusG; *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: Master_User: Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000022 Read_Master_Log_Pos: 879720441 Relay_Log_File: ***-relay-bin.000011 Relay_Log_Pos: 250520472 Relay_Master_Log_File: mysql-bin.000022 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: retail Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 879720441 Relay_Log_Space: 565133487 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 0 Master_SSL_Verify_Server_Cert: No Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 0 Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 2 1 row in set (0.00 sec)
解释一下 show slave status 中重要的几个参数:
Slave_IO_Running: I/O线程是否被启动并成功地连接到主服务器上。
Slave_SQL_Running: SQL线程是否被启动。
Seconds_Behind_Master:其值可能为NULL、0、大于0
Seconds_Behind_Master
的计算规则是:从库当前的时间戳 - 从库SQL线程当前正在执行的事件记录的主库的时间戳
- 当从库sql线程上没有事件被执行时,
Seconds_Behind_Master
的值为0,表示主从复制良好,可以认为延迟不存在。 Seconds_Behind_Master
有可能为NULL值,当SQL线程或IO线程没有在执行,或者IO线程在执行但连不上主库时。
1.1.Seconds_Behind_Master可能带来的问题:
我们都知道的relay-log和主库的bin-log里面的内容完全一样,在记录sql语句的同时会被记录上当时的ts,所以比较参考的值来自于binlog,其实主从没有必要与NTP进行同步,也就是说无需保证主从时钟的一致。你也会发现,其实比较真正是发生在io_thread与sql_thread之间,而io_thread才真正与主库有关联,于是,问题就出来了,当主库I/O负载很大或是网络阻塞,io_thread不能及时复制binlog(没有中断,也在复制),而sql_thread一直都能跟上io_thread的脚本,这时Seconds_Behind_Master的值是0,也就是我们认为的无延时,但是,实际上不是,你懂得。这也就是为什么大家要批判用这个参数来监控数据库是否发生延时不准的原因,但是这个值并不是总是不准,如果当io_thread与master网络很好的情况下,那么该值也是很有价值的。之前,提到Seconds_Behind_Master这个参数会有负值出现,我们已经知道该值是io_thread的最近跟新的ts与sql_thread执行到的ts差值,前者始终是大于后者的,唯一的肯能就是某个event的ts发生了错误,比之前的小了,那么当这种情况发生时,负值出现就成为可能。
2.pt-heartbeat
其工作原理为:
- 在主库上创建一张表,然后由一个进程间隔一定时间不断地去更新这张表记录的当前主库的时间戳
- 由另一个进程间隔一定时间不断地去从库查询这张表记录的主库时间戳,再跟当前时间戳相减得到主从复制的延迟