轻松入门MySQL主从复制原理

什么是MySQL主从复制

MySQL 主从复制是指数据可以从一个MySQL数据库服务器主节点复制到一个或多个从节点。MySQL 默认采用异步复制方式,这样从节点不用一直访问主服务器来更新自己的数据,数据的更新可以在远程连接上进行,从节点可以复制主数据库中的所有数据库或者特定的数据库,或者特定的表,主节点数据变化时,可以实时的同步的从节点中。

基于二进制文件的复制

MySQL主从复制是基于二进制日志文件的方式,当master服务器有变化时以“事件”的形式写入二进制文件,二进制日志中的信息会根据记录的数据库变化以不同的日志格式存储,slave服务器读取二进制日志,并在自己的数据库中执行二进制日志中的事件。

主从复制线程

MySQL复制功能使用三个主线程来实现,一个在master服务器上,两个在slave服务器上:

  • Binary log dump thread(二进制日志转储线程)

    当从节点连接时,主节点创建一个线程将二进制日志内容发送到从节点,这个线程在主节点的show processlist输出中标识为Binlog转储线程。

  • Replication I/O thread(IO线程)

    当在从节点上发出START SLAVE语句时,从节点会创建一个I/O线程,该线程连接到主节点,并要求它发送其二进制日志中记录的更新。
    I/O线程读取主节点的Binlog转储线程发送的更新,并将它们复制到本地文件中,这些文件构成了从节点的relay log(中继日志)。
    在SHOW SLAVE STATUS的输出中,该线程的状态显示为Slave_IO_running。

  • Replication SQL thread (SQL线程)

    从节点创建一个SQL线程来读取I/O线程写入的中继日志,并执行其中包含的事务。

主从复制原理

  • master服务器将数据的改变记录二进制binlog日志,当master上的数据发生改变时,则将其改变写入二进制日志中;
  • slave服务器会在一定时间间隔内对master二进制日志进行探测其是否发生改变,如果发生改变,则开始一个I/OThread请求master二进制事件
  • 同时主节点为每个从服务启动一个dump线程,用于向其发送二进制事件,I/O线程读取二进制的更新,并保存至从节点本地的Relay Log中,从节点再通过SQL线程从Relay Log中读取二进制日志,在本地重放,使得其数据和主节点的保持一致,最后I/OThread和SQLThread将进入睡眠状态,等待下一次被唤醒。

百度找的图片,帮助理解!
轻松入门MySQL主从复制原理_第1张图片

轻松入门MySQL主从复制原理_第2张图片

从节点分离读取、执行

从节点使用两个线程从主节点文件中分离读取、执行,并将它们执行到独立的任务中。因此,即使执行事务的过程较慢,读取事务的任务也不会变慢。例如,如果从节点一段时间没有运行,那么当从节点重新启动时,它的I/O线程可以快速地从主节点获取所有二进制日志内容,即使SQL线程远远落后于它。如果从节点在SQL线程执行所有获取的语句之前停止,那么I/O线程至少已经获取了所有内容,并存储在本地的副本中继日志中,以便在下次从节点启动时执行。

三个主要复制线程在SHOW PROCESSLIST中的显示

主节点上的 Binlog Dump线程

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

从节点上的 IO和SQL线程

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

线程的状态

Binlog Dump线程

  • Finished reading one binlog; switching to next binlog

    该线程已经读完了一个二进制日志文件,并正在准备读取下一个二进制日志文件。

  • Master has sent all binlog to slave; waiting for more updates

    主节点已经把所有的二进制文件更新发送到从节点,并等待新的更新。

  • Sending binlog event to slave

    正在向从节点发送二进制文件事件。

  • Waiting to finalize termination

    线程停止时发生的非常短暂的状态。

I/O线程

  • Checking master version

    建立到源的连接之后,状态非常短暂。

  • Connecting to master

    线程正在尝试连接到源。

  • Queueing master event to the relay log

    该线程已读取事件,并将其复制到中继日志,以便SQL线程可以处理它。

  • Reconnecting after a failed binlog dump request

    线程正在尝试重新连接到源。

  • Reconnecting after a failed master event read

    线程正在尝试重新连接到源。再次建立连接后,状态变为 Waiting for master to send event。

  • Registering slave on master

    建立与源的连接后非常短暂发生的状态。

  • Requesting binlog dump

    建立到源的连接之后,状态非常短暂。线程从请求的二进制日志文件名和位置开始,向源发送对其二进制日志内容的请求。

  • Waiting for its turn to commit

    如果slave_preserve_commit_order 启用了副本线程等待较早的工作线程提交的状态 。

  • Waiting for master to send event

    线程已连接到源并正在等待二进制日志事件到达。如果源处于空闲状态,这可能会持续很长时间。如果等待持续 slave_net_timeout几秒钟,则会发生超时。此时,线程认为连接已断开,并尝试重新连接。

  • Waiting for master update

    之前的初始状态Connecting to master。

  • Waiting for slave mutex on exit

    在线程停止时短暂发生的状态。

  • Waiting for the slave SQL thread to free enough relay log space

    您使用的是非零 relay_log_space_limit 值,并且中继日志的大小已经足够大,以致它们的合并大小超过了该值。I / O线程正在等待,直到SQL线程通过处理中继日志内容释放足够的空间,以便它可以删除一些中继日志文件。

  • Waiting to reconnect after a failed binlog dump request

    如果二进制日志转储请求失败(由于断开连接),则线程在休眠时进入此状态,然后尝试定期重新连接。重试之间的间隔可以使用该CHANGE MASTER TO语句指定 。

  • Waiting to reconnect after a failed master event read

    读取时发生错误(由于断开连接)。CHANGE MASTER TO在尝试重新连接之前,该线程处于休眠状态的语句所设置的秒数 (默认为60)。

SQL线程

  • Making temporary file (append) before replaying LOAD DATA INFILE

    该线程正在执行一条LOAD DATA语句,并将数据追加到一个临时文件中,该临时文件包含副本从中读取行的数据。

  • Making temporary file (create) before replaying LOAD DATA INFILE

    该线程正在执行一条LOAD DATA语句,并正在创建一个临时文件,其中包含副本从中读取行的数据。如果原始LOAD DATA语句是由运行低于MySQL 5.0.3的MySQL版本的源记录的,则只能遇到此状态 。

  • Reading event from the relay log

    该线程已从中继日志中读取一个事件,以便可以处理该事件。

  • Slave has read all relay log; waiting for more updates

    该线程已处理了中继日志文件中的所有事件,现在正在等待I / O线程将新事件写入中继日志。

  • Waiting for an event from Coordinator

    使用多线程副本(slave_parallel_workers大于1),副本工作线程之一正在等待来自协调器线程的事件。

  • Waiting for slave mutex on exit

    线程停止时发生的非常短暂的状态。

  • Waiting for Slave Workers to free pending events

    当Workers处理的事件的总大小超过slave_pending_jobs_size_max 系统变量的大小时,将发生此等待操作 。当大小降至此限制以下时,协调器将恢复调度。仅当slave_parallel_workers设置为大于0时,才会出现此状态 。

  • Waiting for the next event in relay log

    之前的初始状态Reading event from the relay log。

  • Waiting until MASTER_DELAY seconds after master executed event

    SQL线程已读取事件,但正在等待副本延迟过去。延迟设置 MASTER_DELAY为 CHANGE MASTER TO。

半同步复制

除了内置的异步复制,MySQL 5.7还支持一个由插件实现的半同步复制接口。

异步复制的问题

MySQL复制默认是异步的。主节点将事件写入二进制日志,从节点在准备好事件时请求它们。主节点不知道副本是否已经检索并处理了事务,也不保证任何事件会到达任何从节点。使用异步复制时,如果主节点崩溃,则它提交的事务可能没有传输到任何从节点。在这种情况下,如果故障转移把一个从节点提升为主节点,则将造成数据丢失。

完全同步的问题

使用完全同步复制时,当主节点提交事务时,所有从节点也必须在主节点返回执行事务的会话之前提交事务。完全同步复制意味着可以在任何时间从主节点到任何从节点进行故障转移。完全同步复制的缺点是在完成一个事务时可能会有很多延迟。

半同步的优势

半同步复制介于异步复制和全同步复制之间。主节点等待,直到至少有一个从节点收到并记录了事件(所需的从节点数量是可配置的),然后提交事务。主节点不等待所有从节点确认接收,也不需要事件已经在从节点端完全执行并提交。因此,半同步复制可以保证,如果主节点崩溃,它提交的所有事务都已传输到至少一个从节点。
与异步复制相比,半同步复制提供了更好的数据完整性,因为当提交成功返回时,我们知道数据至少存在于两个地方。在半同步主节点收到所需数量的从节点的确认信息之前,事务将保持不提交。
与完全同步复制相比,半同步复制更快,因为可以对它进行配置,以平衡数据完整性需求(确认接收事务的从节点数量)和提交速度(由于需要等待从节点,提交速度较慢)。

与异步复制相比,半同步复制的性能影响是提高数据完整性的权衡。减速的程度至少是将提交发送到从节点并等待从节点确认接收的TCP/IP往返时间。这意味着半同步复制最适合在快速网络上进行近距离服务器通信,而最不适合在慢速网络上进行远程服务器通信。

半同步复制操作如下

  • 当它连接到源时,从节点指示它是否具有半同步能力。
  • 如果主节点启用了半同步复制、并且至少有一个从节点也启动了半同步复制,那么主节点的事务提交将会等待,直到至少有一个半同步从节点确认已收到所有事件的事务,或者直到超时。
  • 只有在事件被写入到其中继日志并刷新到磁盘之后,从节点才会确认接收到事务的事件。
  • 如果在没有任何从节点确认事务的情况下发生超时,则主节点恢复为异步复制。当至少有一个半同步复制赶上时,主节点复制将返回到半同步复制。
  • 主节点和从节点都必须启用半同步复制。如果在主节点禁用了半同步复制,或者在主节点启用了半同步复制但从节点没有启用,则主节点依然使用异步复制。

最后附上主从环境搭建文章,有兴趣的朋友也可以自己动手尝试搭建一下。MySQL主从环境搭建

你可能感兴趣的:(MySQL,mysql)