本文共 5672 字,大约阅读时间需要 18 分钟。
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线程写入的中继日志,并执行其中包含的事务。
百度找的图片,帮助理解!
从节点使用两个线程从主节点文件中分离读取、执行,并将它们执行到独立的任务中。因此,即使执行事务的过程较慢,读取事务的任务也不会变慢。例如,如果从节点一段时间没有运行,那么当从节点重新启动时,它的I/O线程可以快速地从主节点获取所有二进制日志内容,即使SQL线程远远落后于它。如果从节点在SQL线程执行所有获取的语句之前停止,那么I/O线程至少已经获取了所有内容,并存储在本地的副本中继日志中,以便在下次从节点启动时执行。
主节点上的 Binlog Dump线程
mysql> SHOW PROCESSLIST\G*************************** 1. row *************************** Id: 2 User: root Host: localhost:32931 db: NULLCommand: 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: NULLCommand: Connect Time: 11 State: Waiting for master to send event Info: NULL*************************** 2. row *************************** Id: 11 User: system user Host: db: NULLCommand: 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往返时间。这意味着半同步复制最适合在快速网络上进行近距离服务器通信,而最不适合在慢速网络上进行远程服务器通信。
最后附上主从环境搭建文章,有兴趣的朋友也可以自己动手尝试搭建一下。
转载地址:http://wmlrb.baihongyu.com/