Mysql主从复制的实现细节(二)从服务器探究
先前我们探究了主从复制中的主服务器,现在我们来看一下从服务器在整个系统中是如何工作的。
在主服务器探究这篇文章中我们提到过,在一次主从复制过程中需要用到三个线程:Binlog dump 线程、Slave I/O 线程和Slave SQL线程,其中Binlog dump 线程在主服务器上面,剩下的两个线程是在从服务器上面工作的。
这两个线程在从服务器上面的工作流程如下图所示
对于这两个线程随着从服务器开启slave而产生
mysql> START SLVAE;
然后使用
Mysql> SHOW SLAVE STATUS\G
查看这两个线程情况
……
Master_Log_File: mysql-bin.000003
Read_Master_Log_Pos: 1264
Relay_Log_File: localhost-relay-bin.000002
Relay_Log_Pos: 878
Relay_Master_Log_File: mysql-bin.000003
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
……
上面结果中的 Slave_IO_Running:Yes和Slave_SQL_Running:Yes表示这两个线程正在运行。
然后我们在从服务器上面使用命令
mysql> SHOW PROCESSLIAT\G
显示如下结果(记为 结果一)
*************************** 1. row ***************************
Id: 22
User: system user
Host:
db: NULL
Command: Connect
Time: 4
State: Waiting for master to send event
Info: NULL
*************************** 2. row ***************************
Id: 23
User: system user
Host:
db: NULL
Command: Connect
Time: 4
State: Slave has read all relay log; waiting for the slave I/O thread to update it
Info: NULL
从State信息可以看出Id 22是I/O线程,正在等待主服务器发送更新的内容;Id 23是Slave SQL线程,已经读取了relay log 文件中所有更新的内容,正在等待I/O线程更新该文件。
使用命令停止slave机制
mysql> STOP SLVAE;
然后我们再次查看会发现结果如下
……
Master_Log_File: mysql-bin.000003
Read_Master_Log_Pos: 1264
Relay_Log_File: localhost-relay-bin.000002
Relay_Log_Pos: 878
Relay_Master_Log_File: mysql-bin.000003
Slave_IO_Running: No
Slave_SQL_Running: No
……
说明这两个线程已经停止了运行。此时再次使用 SHOW PROCESSLIST\G命令,则没有结果显示
Slave I/O线程
Slave I/O 线程去连接主服务器的Binlog dump 线程并要求其发送binlog日志中记录的更新的操作,然后它将Binlog dump 线程发送的数据拷贝到从服务器上(也就是本地)的文件relay log中。
当然要查看此线程是否运行,除了上面介绍的方法,还可以使用
mysql> SHOW SLAVE LIKE ‘Slave_running’;
这时如果出现下面的结果说明该线程正在运行
+-----------------+-------------------+
| Variable_name | Value |
+-----------------+-------------------+
| Slave_running | ON |
+-----------------+-------------------+
在上述结果一中我们可以看到1.row即是Slave I/O线程的信息,其State: Waiting for master to send event 表示正在等待主服务器发送内容。当然State不止这一个值,它还有其它的值,下面列出了State的所有的值
1. Waiting for master update
在连接到主服务器之前的初始状态
2. Connecting to master
该线程正在连接主服务器,当然如果我们的网络环境优异的话,此状态我们几乎是看不到的
3. Checking master version
这个状态发生的时间也非常短暂,该状态在该线程和主服务器建立连接之后发生。
4. Registering slave on master
在主服务器上面注册从服务器,每当有新的从服务器连接进来以后都要在主服务器上面进行注册
5. Requesting binlog dump
向主服务器请求binlog日志的拷贝
6. Waiting to reconnect after a failed binlog dump request
如果5中失败,则该线程进入睡眠状态,此时State就是这个值,等待着去定期重新连接主服务器,那这个周期的大小可以通过CHANGE MASTER TO 来指定
7. Reconnecting after a failed binlog dump request
去重新连接主服务器
8. Waiting for master to send event
此值就是我们上述结果所显示的,正常情况下我们查看的时候一般都是这个值。其具体表示是这个线程已经和主服务器建立了连接,正在等待主服务器上的binlog 有更新,如果主服务器的Binlog dump线程一直是空闲的状态的话,那此线程会等待很长一段时间。当然也不是一直等待下去,如果时间达到了slave_net_timeout规定的时间,会发生等待超时的情况,在这种情况下I/O线程会重新去连接主服务器
9. Queueing master event to the relay log
该线程已经读取了Binlog dump线程发送的一个更新事件并且正在将其拷贝到relay log文件中
10. Waiting to reconnect after a failed master event read
当该线程读取Binlog dump 线程发送的更新事件失败时,该线程进入睡眠状态等待去重新连接主服务器,这个等待的时间默认是60秒,当然这个值也可以通过CHANGE MASTER TO来设置
11. Reconnecting after a failed master event read
该线程去重新连接主服务器,当连接成功以后,那这个State的值会改变为 Waiting for master to send event
12. Waiting for the Slave SQL thread to free enough relay log space
relay log space的大小是通过relay_log_space_limit来设定的,随着relay logs变得越来越大所有的大小合起来会超过这个设定值。这时该线程会等待SQL线程释放足够的空间删除一些relay log文件
13. Waiting for slave mutex on exit
当线程停止的时候会短暂的出现该情况
以上就是State可能会出现的值,以及都是在什么情况下出现。
Slave SQL线程
Slave SQL线程是在从服务器上面创建的,主要负责读取由Slave I/O写的relay log文件并执行其中的事件
在上述结果一中2.row即是Slave SQL线程的信息,同样有一个State表示该线程的当前状态。
下面也列出了State所有可能出现的情况
1. Waiting for the next event in relay log
该状态是读取relay log之前的初始状态
2. Reading event from the relay log
该状态表示此线程已经在relay log中读取了一个事件准备执行
3. Making temp file
该状态表示此线程正在执行LOAD_DATA_INFILE并且正在创建一个临时文件来保存从服务器将要读取的数据
4. Slave has read all relay log; waiting for the slave I/O thread to update it
该线程已经处理完了relay log中的所有事件,现在正在等待slave I/O线程更新relay log文件
5. Waiting for slave mutex on exit
当线程停止的时候会短暂的出现该情况
上面是对从服务器上的两个线程的简单的介绍,在运行过程中我们会发现这两个线程都离不开的文件就是relay log文件,下面我们简单介绍一下relay log文件。
relay log文件
relay log 和 主服务器上的bin log很相似,都是一系列的文件,这些文件包括那些包含描述数据库改变的操作事件的文件和索引文件,这个索引文件是relay logs文件的名称集合。
relay log 文件和 bin log文件一样,也是二进制文件,不能直接查看,需要使用mysql自带工具mysqlbinlog查看。
] # mysqlbinlog mysql安装路径/data/relay-log文件
当然其索引文件的内容我们是可以直接使用 vim查看的。
对于relay logs 文件的名称的命名规则默认使用的是 host_name-relay-bin.nnnnnn,以我的系统来说,其文件名默认为localhost-relay-bin.000001。对于索引文件的命名规则为host_name-relay-bin.index,同样在我的系统中的名称为localhost-relay-bin.index。这两个名称是可以通过—relay-log 和 –relay-log-index来改变的,其使用方式如下
# mysqld_safe –user=mysql –relay-log=文件名 –relay-log-index=新索引文件名 &
在这里如果改变这两个名称的话,可能会引起‘不能打开relay log’文件和‘在初始化relay log 过程中不能发现目标log’等错误。这也算是mysql设计的一个bug,没有什么好的解决办法,如果我们不想使用默认的文件名称的话,唯一的办法就是我们可以预料到从服务器的主机名称可能在将来会发生改变,在开始初始化从服务器的时候就使用以上两个选项指定文件名,这样就可以使文件名不再依赖于服务器的主机名。
对于这些relay log文件并不是一直在增加的,当Slave SQL线程执行完一个relay log文件中所有的事件并且不再需要它的时候会把改relay log文件删除。由于是Slave SQL线程来做这些事情,所以也没有什么明确的规则来指定如何删除relay log文件
以上的所有内容大概描述了主从复制系统中从服务器的主要工作流程。
参考内容 mysql官方文档
相关文章
使用 Mysqldump 备份 MySQL 中的数据
发布时间:2023/05/09 浏览次数:192 分类:MySQL
-
本篇文章将介绍如何使用 mysqldump 只备份数据。 在这里,我们将探讨 --no-create-info 、--compact 、--skip-triggers 和 --no-create-db 选项。
更新 MySQL 表中的主键
发布时间:2023/05/09 浏览次数:61 分类:MySQL
-
本篇文章介绍如何更新 MySQL 表中的主键。 我们将使用 ALTER 命令对主键进行任何更改。更新 MySQL 表中的主键 我们可以在多种情况下更新 MySQL 表中的主键。
在 MySQL 中获取命令历史记录
发布时间:2023/05/09 浏览次数:150 分类:MySQL
-
本文重点介绍了在 Windows 和 Linux 中获取我们已执行的 MySQL 命令历史记录的各种方法。MySQL命令历史
Oracle 的 decode 函数在 MySQL 中的等价物
发布时间:2023/05/09 浏览次数:115 分类:MySQL
-
本篇文章介绍了三种替代实现,我们可以将它们用作 MySQL 中 Oracle 的 decode() 函数的等价物。 为此,我们将使用 IF()、CASE 以及 FIELD() 和 ELT() 的组合。
使用 Ubuntu 连接远程 MySQL 服务器的不同方法
发布时间:2023/05/09 浏览次数:97 分类:MySQL
-
在本文中我们将学习如何使用 Ubuntu 连接远程 MySQL 服务器来操作数据以及启动和停止 MySQL 服务器。
在 Linux 中安装 MySQL 客户端
发布时间:2023/05/09 浏览次数:72 分类:MySQL
-
在 Linux 中安装 MySQL 客户端的命令。Linux 和 Unix 等环境作为命令行界面工作,仅在命令的帮助下运行。
在 MySQL 中转换为十进制
发布时间:2023/05/09 浏览次数:150 分类:MySQL
-
有时,我们可能需要将一种数据类型转换为另一种数据类型。 下面是我们如何使用带有 DECIMAL(M,D) 的 CAST() 和 CONVERT() 函数在 MySQL 中转换为十进制。
在 MySQL 中获取当前日期和时间
发布时间:2023/05/09 浏览次数:145 分类:MySQL
-
本篇文章我们将学习 NOW()、CURRENT_TIMESTAMP()(也写为 CURRENT_TIMESTAMP)和 SYSDATE() 来获取 MySQL 中的当前日期和时间。 我们还将看到这三个功能之间的比较。在 MySQL 中获取当前日期和时间
更改 MySQL 服务器中的 max_allowed_packet Size
发布时间:2023/05/09 浏览次数:142 分类:MySQL
-
本篇文章介绍如何更改 MySQL 服务器中的 max_allowed_packet 大小。 为了了解这一点,我们将使用两个操作系统,Windows 10 和 Linux (Ubuntu)。