• 1
  • 2
  • 3
  • 4
  • 5
mysql数据库问题 首 页  »  帮助中心  »  数据库  »  mysql数据库问题
Mysql主从复制的实现细节:从服务器探究
发布日期:2016-4-24 20:4:54

  先前我们已经探究了主从复制中的主服务器,现在我们来看一下从服务器在整个系统中是如何工作的。

  在主服务器探究这篇文章中我们提到过,在一次主从复制过程中需要用到三个线程: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文件。