MySQL同步实现细节

翻译自MySQL 5.5 Reference Manual

MySQL同步是使用三个线程实现的,一个在主服务器上,两个在从服务器上:

  • 二进制日志转储线程(Binlog dump thread)。当从服务器连接时,主服务器创建一个线程用来把二进制日志的内容发给从服务器。在主服务器SHOW PROCESSLIST的输出信息中,它被显示为Binlog Dump。
    binlog dump线程在主服务器的二进制文件上取得一个锁(acquires a lock),用来读取每一个要发给从服务器的事件。读取事件后,锁便会被释放,而不管事件有没有发送给从服务器。
  • 从服务器I/O线程(Slave I/O thread)。当从服务器运行START SLAVE语句时,会创建一个I/O线程。这个I/O线程会连接主服务器,要求主服务器发送记录在二进制日志中的数据库更新信息。
    从服务器的I/O线程读取主服务器Binlog Dump线程发过来的数据库更新信息,并把它们拷贝到本地文件,也就是从服务器的中继日志(relay log)中。
    这一线程的状态,在SHOW SLAVE STATUS的输出信息中显示为Slave_IO_running,在SHOW STATUS的输出信息中显示为Slave running。
  • 从服务器SQL线程(Slave SQL thread)。从服务器读取I/O线程生成的中继日志,并执行包含在日志中的事件。

在上面的描述中,每个主/从服务器连接都有3个线程。如果一个主服务器有多个从服务器,它会给每个连接着的从服务器都创建一个binlog dump线程。每一个从服务器都有自己的I/O和SQL线程。

从服务器使用两个线程把读取服务器的更新信息和执行这些更新信息这两个过程独立开来。这样不会因为语句执行速度慢,而拖慢读语句的任务。例如,如果从服务器有段时间没有运行了,当开始运行时,它的I/O线程可以从主服务器迅速获取所有的二进制日志内容,即使SQL线程的执行速度远远地落在后面。如果从服务器在SQL线程执行完所有更新语句前就停止运行了,至少I/O线程已经取回了所有的更新语句的内容,并安全地储存在本地的中继日志上,从服务器下次运行时可以立即执行。这使得主服务器可以更及时清理二进制日志,因为不需要再等着从服务器获取它们了。

SHOW PROCESSLIST语句提供了同步时主服务器和从服务器的状态信息。关于主服务器状态的信息,参考Section 8.12.5.5, “Replication Master Thread States”,从服务器状态,参考Section 8.12.5.6, “Replication Slave I/O Thread States”Section 8.12.5.7, “Replication Slave SQL Thread States”

下面说明SHOW PROCESSLIST语句输出信息中,三个线程如何显示。

在主服务器上,SHOW PROCESSLIST的输出类似下面这样:

mysql> SHOW PROCESSLIST\G
*************************** 1. row ***************************
     Id: 2
   User: root
   Host: localhost:32931
     db: NULL
Command: Binlog Dump
   Time: 94
  State: Has sent all binlog to slave; waiting for binlog to
         be updated
   Info: NULL

这里,线程2是一个为已连接从服务器服务的Binlog Dump同步线程。State信息指出所有未完成的更新已经发给了从服务器,主服务器在等待新更新的产生。如果在主服务器上看不到Binlog Dump线程,意味着同步没有运行;也就是说,当前没有连接从服务器。

在主服务器上,SHOW PROCESSLIST的输出类似下面这样:

mysql> SHOW PROCESSLIST\G
*************************** 1. row ***************************
     Id: 10
   User: system user
   Host:
     db: NULL
Command: Connect
   Time: 11
  State: Waiting for master to send event
   Info: NULL
*************************** 2. row ***************************
     Id: 11
   User: system user
   Host:
     db: NULL
Command: Connect
   Time: 11
  State: Has read all relay log; waiting for the slave I/O
         thread to update it
   Info: NULL

State信息显示线程10是I/O线程,正在与主服务器通信;线程11是SQL线程,正在处理中继日志中存储的更新信息。在执行SHOW PROCESSLIST语句的时候,两个线程都处于空闲状态,等待进一步的更新。

Time的值显示从服务器比主服务器晚了多少时间。请参考Section B.13, “MySQL 5.5 FAQ: Replication”。如果经过了足够多的时间,Binlog Dump线程一直没有活动,主服务器会认为slave已经断开连接了。对其他类型的客户端连接,超时的时间吗长度取决于net_write_timeout和net_retry_count的值。关于这一点的更多信息,参考Section 5.1.4, “Server System Variables”

SHOW SLAVE STATUS语句提供了从服务器同步过程的更多信息。参考Section 16.1.4.1, “Checking Replication Status”

Visits: 481

此条目发表在Linux分类目录,贴了标签。将固定链接加入收藏夹。

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注

15 + 4 =