上篇文章介绍了单机环境下的MySQL主从异步复制和主从半同步复制的搭建过程。搭建过程很简单,可是在实际使用过程当中,更多的是解决问题,本篇文章将介绍一下MySQL主从复制中常见的问题以及如何定位问题和如何解决问题。
1、从库复制延迟问题mysql
一、可能的缘由以下
(1)主从服务器处于不一样的网络之中,因为网络延迟致使;
(2)主从服务器的硬件配置不一样,从服务器的硬件配置(包括内存,CPU,网卡等)远低于主服务器;
(3)主库上有大量的写入操做,致使从库没法实时重放主库上的binlog;
(4)主库上存在着大事务操做或者慢SQL,致使从库在应用主库binlog的过程过慢,造成延迟;
(5)数据库实例的参数配置问题致使,如:从库开启了binlog,或者配置了每次事务都去作刷盘操做;sql
二、主从同步延迟问题判断
(1)根据从库上的状态参数判断数据库
mysql-server-3307> SHOW SLAVE STATUS \G
在输出结果中找到Seconds_Behind_Master参数,这个参数表示的是从库上的IO线程和SQL线程相差的时间,而后根据该参数值判断,这个值只是初步判断,不能由这个值来下结论,有以下几种状况:
a、0:表示无延迟,理想状态;
b、NULL:表示从库上的IO线程和SQL线程中,有某一个线程出现问题,能够再次查看Slave_IO_Running和Slave_SQL_Running的值是否都为Yes;
c、大于0:表示主从已经出现延迟,这个值越大,表示从库和主库之间的延迟越严重;
d、小于0:这个值在官方文档中没有说明,一般不会出现。若是出现,那恭喜你中奖了,撞见MySQL的bug了;安全
(2)根据主从库上面当前应用的二进制日志文件名称或者重放日志的位置来判断
① 同时打开两个MySQL的命令行窗口,分别打开主库和从库,在第一个窗口上执行查看主库当前状态的命令服务器
mysql-server-3306> SHOW MASTER STATUS \G *************************** 1. row *************************** File: mysql-bin.000017 Position: 120 Binlog_Do_DB: Binlog_Ignore_DB: Executed_Gtid_Set: 1 row in set (0.00 sec)
② 在第二个从库的命令行窗口执行以下命令网络
mysql-server-3307> SHOW SLAVE STATUS \G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event ... Connect_Retry: 60 Master_Log_File: mysql-bin.000017 Read_Master_Log_Pos: 120 Relay_Log_File: relay-log.000016 Relay_Log_Pos: 283 Relay_Master_Log_File: mysql-bin.000017 Slave_IO_Running: Yes Slave_SQL_Running: Yes ... Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 120 Relay_Log_Space: 613 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 ... Seconds_Behind_Master: 0 ... Replicate_Ignore_Server_Ids: Master_Server_Id: 3 Master_UUID: 2dbbf79b-5d9f-11e8-8004-000c29e28409 Master_Info_File: /mysql_data/3307/data/master.info SQL_Delay: 0 SQL_Remaining_Delay: NULL
③ 比较从库上的Master_Log_File和Relay_Master_Log_File文件之间是否有差别
a、若是有差别,则说明主从延迟很严重;
b、若是没有差别,则比较Read_Master_Log_Pos和Exec_Master_Log_Pos的差别,这俩参数分别表示从库当前读取到的主库的二进制日志文件位置点和已经执行到的位置点;
c、若是上述输出都没有差别,能够经过主库上"show master status"和从库上"show slave status"的结果做比较。主要比较主库的"File"和从库的"Master_Log_File",主库上的"Position"和从库上的"Read_Master_Log_Pos";并发
三、主从延迟解决办法
(1)判断是否因为网络致使
方法:测试主从库之间的网络延迟,好比测试ping延迟。同时能够检查主从同步的时候是否使用了主库的域名来同步,而域名解析速度可能会特别慢。或者使用其余测试工具;
(2)判断是否因为硬件环境致使
方法:确认主从库的硬件配置是否相差较大,若是配置参数相差较大,能够排查从库上的CPU,内存,IO使用率来判断是否由于硬件配置致使;
(3)判断是否在主库上有大量的DML操做
方法:能够再主库上经过"show full processlist"命令查看当前正在执行的sql,查看是否有大量正在执行的SQL,或者观察主库的CPU和内存使用率,判断是否有高并发操做;
(4)判断是否有慢SQl,能够再主库上临时打开慢SQL记录,临时打开方法以下异步
#开启慢SQL功能并查看是否生效 mysql-server-3306> SET @@GLOBAL.slow_query_log = ON; mysql-server-3306> SHOW VARIABLES LIKE 'slow_query_log'; #设置慢SQL的时间并查看是否生效,单位为s,表示大于多少秒的SQL会被记录 mysql-server-3306> SET @@GLOBAL.long_query_time = 5; mysql-server-3306> SHOW VARIABLES LIKE 'long_query_time'; #设置慢SQL记录日志路径并查看是否生效。注意,这个目录必须对MySQL用户有读写权限 mysql-server-3306> SET @@GLOBAL.slow_query_log_file = '/mysql_data/mysql-slow.log'; mysql-server-3306> SHOW VARIABLES LIKE 'slow_query_log_file';
(5)检查从服务器参数配置是否合理
① 查看从库是否开启了binlog日志,从库上执行以下命令查看高并发
mysql-server-3307> SHOW VARIABLES LIKE 'log_bin';
若是开启了binlog日志,并且从库未充当其余库的主库时,能够将从库上的binlog关闭,不然会增长从库负担,每次重放完成主库的binlog还要记录到自身的binlog工具
② 查看从库上的sync_binlog参数的值,这个参数表示的是事务提交多少次以后,由MySQL来将binlog_cache中的数据刷新到磁盘,有如下几种值:
0:表示事务提交以后,MySQL不作刷新binlog_cache到磁盘的操做,而是由操做系统来定时自动完成刷盘操做,这种操做对性能损耗最少,可是也最不安全;
n:表示提交n次事务以后,由MySQL将binlog_cache中的数据刷新到磁盘,若是开启,会对性能有必定程度的损耗。因此,从库上若是延迟很严重,能够考虑将该参数的值设为0;
mysql-server-3307> SET @@GLOBAL.sync_binlog = 0; mysql-server-3307> SHOW VARIABLES LIKE 'sync_binlog'; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | sync_binlog | 0 | +---------------+-------+ 1 row in set (0.00 sec)
③ 若是从库中要同步的数据库使用的是InnoDB存储引擎,能够查看innodb_flush_log_at_trx_commit参数。这个参数表示事务执行完成以后,多久的频率刷新一第二天志到磁盘上,可用的值有以下几种:
0:表示MySQL会将日志缓冲区中的数据每秒一次地写入日志文件中,而且日志文件的刷盘操做同时进行。该模式下在事务提交的时候,不会主动触发写入磁盘的操做,效率最搞,可是安全性也比较低,可能会丢失数据;
1:每一次事务提交都须要把日志写入磁盘,这个过程是特别耗时的操做;
2:每一次事务提交以后,不会自动触发日志刷盘的操做,而是由操做系统来决定何时来作刷新日志的操做,在操做系统挂了的状况下才会丢失数据;
若是在主从延迟很是严重的状况下,能够将从库的该参数设置为0,以提升从库上重放主库二进制日志的效率。
mysql-server-3307> SET @@GLOBAL.innodb_flush_log_at_trx_commit = 0; mysql-server-3307> SHOW VARIABLES LIKE 'innodb_flush_log_at_trx_commit'; +--------------------------------+-------+ | Variable_name | Value | +--------------------------------+-------+ | innodb_flush_log_at_trx_commit | 0 | +--------------------------------+-------+ 1 row in set (0.00 sec)
注意:上述设计到修改MySQL数据库实例的操做中,修改以后会马上生效,可是重启实例以后,会失效,若是要永久修改,则须要编辑mysql配置文件,而后重启。
至此,主从复制延迟的常见缘由就介绍完毕,还有更多其余缘由须要实际问题实际解决,此处并未提到,欢迎你们评论提出!下篇文章将介绍MySQL数据库的数据备份与恢复!
后续文章将更新在我的小站上,欢迎查看。