MySQL主从同步机制与同步延时问题追查过程

前言

作为一名DBA,在工作中会经常遇到一些MySQL主从同步延迟的问题,这些同步慢的问题,其实原因非常多,可能是因为主从的网络问题导致,可能是因为网络带宽问题导致,可能是因为大事务导致,也可能是因为单线程复制导致的延迟。

今天遇到一个问题,Mysql持续报错,主从同步延时数过大或错误。所以这篇文章给大家分享下主从同步的机制原理以及问题排查思路。

故障表现

最直观的表现为:

?


1

2

3

4

5

6

7

mysql> show slave status\G;

 // 状态一

 Seconds_Behind_Master: NULL

 // 状态二

 Seconds_Behind_Master: 0

 // 状态三

 Seconds_Behind_Master: 79

连续查询,大部分时间该属性值=0,偶发性出现Null或者79等延时值。导致观察主从同步延时的监控持续报警。

故障原因及解决方案

多台备机的server-id一致,导致主机无法长时间同某一台备机连接,进而无法正常同步。

修改server-id后,重启数据库恢复。

主从同步机制

MySQL的主从同步,又称为复制(replication),是一种内置的高可用高性能集群解决方案,主要功能有:

  • 数据分布:同步不需要很大带宽,可以实现多数据中心复制数据。
  • 读取的负载均衡:通过服务器集群,可以通过DNS轮询、Linux LVS等GSLB(全局负载均衡)方式,降低主服务器的读压力。
  • 数据库备份:复制是备份的一部分,但并不能代替备份。还需要与快照相结合。
  • 高可用性和故障转移:从服务器可以快速切换为主服务器,减少故障的停机时间和恢复时间。

主从同步分为3步:

  1. 主服务器(master)把数据更改记录到二进制日志(binlog)中。
  2. 从服务器(slave)把主服务器的二进制日志复制到自己的中继日志(relay log)中。
  3. 从服务器重做中继日志中的日志,把更改应用到自己的数据库上,达到数据的一致性。

主从同步是一个异步实时的同步,会实时的传输,但存在执行上的延时,如果主服务器压力很大,延时也会相应扩大。

通过上面的图,可以看到一共需要3个线程:

  1. 主服务器的日志传送线程:负责将二进制日志增量传送到备机
  2. 从服务器的I/O线程:负责读取主服务器的二进制日志,并保存为中继日志
  3. 从服务器的SQL线程,负责执行中继日志

查看MySQL线程

我们可以使用show full processlist;命令来查看MySQL的状态:

主机的状态:

备机的状态:

可以看到,我的集群架构为1台主机、4台备机,所以在主机中有4个同步线程(已经发送所有的binlog数据到备机,等待binlog日志更新),1个查看命令线程(show full processlist)。在备机中有1个查看命令线程,1个I/O线程(等待主机发送同步数据事件),1个SQL线程(已经读取了所有中继日志,等待I/O线程来更新它)。

查看同步状态

因为主从同步是异步实时的,也就是会存在延时的情况,我们可以通过show slave status;来查看备机上的同步延时:

在主从同步中我们需要关注的一些属性,已经给大家标红了:

  • Slave_IO_State: 当前I/O线程的状态
  • Master_Log_File: 当前同步的主服务器的二进制文件
  • Read_Master_Log_Pos: 当前同步的主服务器的二进制文件的偏移量,单位为字节,如图中为已经同步了12.9M(13630580/1024/1024)的内容
  • Relay_Master_Log_File: 当前中继日志同步的二进制文件
  • Slave_IO_Running: 从服务器中I/O线程的运行状态,YES为运行正常
  • Slave_SQL_Running: 从服务器中SQL线程的运行状态,YES为运行正常
  • Exec_Master_Log_Pos: 表示同步完成的主服务器的二进制日志偏移量
  • Seconds_Behind_Master: 表示从服务器数据比主服务器落后的持续时长

同样可以通过show master status;命令来查看主服务器的运行状态:

正常运行的主从同步状态:

Slave_IO_Running: YES
Slave_SQL_Running: YES
Seconds_Behind_Master: 0

问题排查

在理解了主从同步的机制后,再来看今天遇到的问题,通过查看备机状态,我们观察在三种状态下的几个关键属性值:

?


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

mysql> show slave status\G;

#状态一:

 Slave_IO_State: Reconnecting after a failed master event read

 Slave_IO_Running: No

 Slave_SQL_Running: Yes

 Seconds_Behind_Master: NULL

#状态二:

 Slave_IO_State: Waiting for master to send event

 Slave_IO_Running: Yes

 Slave_SQL_Running: Yes

 Seconds_Behind_Master: 0

#状态三:

 Slave_IO_State: Queueing master event to the relay log

 Slave_IO_Running: Yes

 Slave_SQL_Running: Yes

 Seconds_Behind_Master: 636

通过MySQL主从复制线程状态转变,我们可以看到三种状态的不同含义:

?


1

2

3

4

5

6

7

8

9

10

# 状态一

# 线程正尝试重新连接主服务器,当连接重新建立后,状态变为Waiting for master to send event。

Reconnecting after a failed master event read

# 状态二

# 线程已经连接上主服务器,正等待二进制日志事件到达。如果主服务器正空闲,会持续较长的时间。如果等待持续slave_read_timeout秒,则发生超时。此时,线程认为连接被中断并企图重新连接。

Waiting for master to send event

# 状态三

# 线程已经读取一个事件,正将它复制到中继日志供SQL线程来处理。

Queueing master event to the relay log

在这里,我们可以猜测,由于某些原因,从服务器不断的和主服务器进行断开并尝试重连,重连成功后又再次断开。

我们再看看主机的运行情况:

发现问题出在10.144.63.*和10.144.68.*两台机器上,我们查看其中一台的错误日志:

190214 11:33:20 [Note] Slave: received end packet from server, apparent master shutdown: 
190214 11:33:20 [Note] Slave I/O thread: Failed reading log event, reconnecting to retry, log ‘mysql-bin.005682‘ at postion 13628070

拿到关键字Slave: received end packet from server, apparent master shutdown: Google搜索一下,在文章Confusing MySQL Replication Error Message中可以看到原因为两台备机的server-id重复。

One day it happen to me, and took me almost an hour to find that out.
Moving foward I always use a base my.cnf to I copy to any other server and the first thing is to increase the server-id.
Could MySQL just use the servername intead of a numeric value?

问题修复

定位了问题,我们确认下是否重复,发现两台备机的该字段确实相同:

?


1

2

3

4

5

6

7

vim my.cnf

#replication

log-bin=mysql-bin

# 这个随机数字相同导致的

server-id=177230069

sync_binlog=1

更改一个其他不同的数字,保存,重启MySQL进程,报警恢复。

总结

最终来看,这个问题的解决非常简单,但从刚开始的迷茫到最后的思路清晰,都是我们排查问题所常见的,这篇文章的主要收获是让你明白主从同步的机制和追查问题的思路,希望下次我们都能很快的解决主从同步带给我们的问题。

好了,以上就是这篇文章的全部内容了,希望本文的内容对大家的学习或者工作具有一定的参考学习价值,如果有疑问大家可以留言交流,谢谢大家对脚本之家的支持。

原文地址:https://www.cnblogs.com/HKROnline-SyncNavigator/p/10971471.html

时间: 2024-08-04 17:16:16

MySQL主从同步机制与同步延时问题追查过程的相关文章

线程的同步机制:同步代码块&同步方法

解决存在的线程安全问题:打印车票时出现重票,错票 使用同步代码块的解决方案 TestWindow2 package com.aff.thread; /* 使用实现Runnable接口的方式,售票 存在线程安全问题: 打印车票时出现重票,错票 1.原因:由于一个线程在操作共享数据过程中,未执行完毕的情况下, 另外的线程参与进来了,导致共享数据存在了安全问题 2.解决想法:让一个线程操作共享数据完毕后,其他进程才有机会参与共享数据的使用 3.java的解决方案: 线程的同步机制 方式一:同步代码块

MySQL主从同步与主主同步

MySQL复制: MySQL内建的复制功能是构建大型,高性能应用程序的基础.将MySQL的数据分布到多个系统上去,这种分布的机制,是通过将mysql的某一台主机的数据复制到其它主机(slave)上,并重新执行一遍来实现. 复制过程中一个服务器充当主服务器,而一个或多个其它服务器充当从服务器.主服务器将更新写入二进制日志文件,并维护文件的一个索引以跟踪日志循坏,这些日志可以记录发送到从服务器的更新.当一个从服务器 连接主服务器时,它通知主服务器从服务器在日志中读取的最后一次成功更新的位置.从服务器

Linux 内核的同步机制,第 1 部分 + 第二部分(转)

http://blog.csdn.net/jk198310/article/details/9264721  原文地址: Linux 内核的同步机制,第 1 部分 一. 引言 在现代操作系统里,同一时间可能有多个内核执行流在执行,因此内核其实象多进程多线程编程一样也需要一些同步机制来同步各执行单元对共享数据的访问.尤其是在多处理器系统上,更需要一些同步机制来同步不同处理器上的执行单元对共享的数据的访问.在主流的Linux内核中包含了几乎所有现代的操作系统具有的同步机制,这些同步机制包括:原子操作

线程的同步机制

1 线程安全问题的原因:由于一个线程在操作共享数据过程中,未执行完毕的情况下,另外的线程有参与进来,导致共享数据存在安全问题 2 解决方法:必须让一个线程操作共享数据完毕以后,其它线程才有机会参与共享数据的操作 3 java如何实现线程的安全,现成的同步机制 synchronized(同步监视器){  //需要被同步的代码块(操作共同数据的代码)} 同步监视器:右任何一个类的对象充当,哪个线程获取此监视器,就执行大括号里被同步的代码 1)同步代码块 class Window2 implement

Linux内核同步机制

http://blog.csdn.net/bullbat/article/details/7376424 Linux内核同步控制方法有很多,信号量.锁.原子量.RCU等等,不同的实现方法应用于不同的环境来提高操作系统效率.首先,看看我们最熟悉的两种机制——信号量.锁. 一.信号量 首先还是看看内核中是怎么实现的,内核中用struct semaphore数据结构表示信号量(<linux/semphone.h>中): [cpp] view plaincopyprint? struct semaph

Java中的闪光点:ThreadLocal是线程Thead的局部变量,可替代同步机制的设计,值得学习和研究

线程局部变量ThreadLocal,是Java支持的一种线程安全机制,目的是解决多线程的并发问题. 具体来讲,就是多个线程访问该实例对象的变量时,该实例对象将其存储为键值对的形式,保证各个线程(键)分别对应一份该变量值(值),从而保证多线程变量值得安全访问. ThreadLocal与同步机制比较 同步机制:用锁机制保证同一时间只有一个线程访问变量(用时间换空间),变量是多线程共享的,设计时要缜密分析什么时候读写?什么时候锁定?什么时候释放? ThreadLocal:提供每个线程一个独立的变量副本

轻量级的同步机制——volatile语义详解(可见性保证+禁止指令重排)

1.关于volatile volatile是java语言中的关键字,用来修饰会被多线程访问的共享变量,是JVM提供的轻量级的同步机制,相比同步代码块或者重入锁有更好的性能.它主要有两重语义,一是保证多个线程对共享变量访问的可见性,二防止指令重排序. 2.语义一:内存可见性 2.1 一个例子 public class TestVolatile { public static void main(String[] args) throws InterruptedException { ThreadD

slave断电,mysql主从奔溃恢复从服务至正常

本想连照片一起上传的,这样更直观:很遗憾照片无法上传,但是也无法阻止我发文!!! slave上操作: [[email protected] mysql]# tail slave.err 160121 21:44:43 [Note] Event Scheduler: Purging the queue. 0 events 160121 21:44:43 [Note] Error reading relay log event: slave SQL thread was killed 160121

如何实现 MySQL 的读写分离?MySQL 主从复制原理的是啥?如何解决 MySQL 主从同步的延时问题?

高并发这个阶段,肯定是需要做读写分离的,啥意思?因为实际上大部分的互联网公司,一些网站,或者是 app,其实都是读多写少.所以针对这个情况,就是写一个主库,但是主库挂多个从库,然后从多个从库来读,那不就可以支撑更高的读并发压力了吗? 如何实现 MySQL 的读写分离? 其实很简单,就是基于主从复制架构,简单来说,就搞一个主库,挂多个从库,然后我们就单单只是写主库,然后主库会自动把数据给同步到从库上去. MySQL 主从复制原理的是啥? 主库将变更写入 binlog 日志,然后从库连接到主库之后,