主从复制原理
MySQL 主从复制涉及到三个线程,一个运行在主节点(log dump thread),其余两个(I/O thread , SQL thread)运行在从节点,如下图所示:
上面两张图是一样的,大家觉得那张比较好理解就看哪一张。
主节点 log dump 线程
当从节点连接主节点时,主节点会为其创建一个 log dump 线程,用于发送和读取 bin-log 的内容。在读取 bin-log 中的操作时,log dump 线程会对主节点上的 bin-log 加锁,当读取完成,在发送给从节点之前,锁会被释放。主节点会为自己的每一个从节点创建一个 log dump 线程。
从节点 I/O线程
当从节点上执行 start slave
命令之后,从节点会创建一个 I/O 线程用来连接主节点,请求主库中更新的 bin-log 。I/O 线程接收到主节点的 binlog dump 进程发来的更新之后,保存在本地 relay-log(中继日志)中。
从节点 SQL 线程
SQL 线程负责读取 relay-log 中的内容,解析成具体的操作并执行,最终保证主从数据的一致性。
对于每一个主从连接,都需要这三个进程来完成。当主节点有多个从节点时,主节点会为每一个当前连接的从节点建一个 log dump 进程,而每个从节点都有自己的I/O进程,SQL进程。从节点用两个线程将从主库拉取更新和执行分成独立的任务,这样在执行同步数据任务的时候,不会降低读操作的性能。比如,如果从节点没有运行,此时 I/O 进程可以很快从主节点获取更新,尽管 SQL 进程还没有执行。如果在 SQL 进程执行之前从节点服务停止,至少 I/O 进程已经从主节点拉取到了最新的变更并且保存在本地 relay 日志中,当服务再次运行起来之后,就可以完成数据的同步。
要实施复制,首先必须打开 Master 端的 binary log(bin-log)功能,否则无法实现。
因为整个复制过程实际上就是 Slave 从 Master 端获取该日志然后再在自己身上完全按顺序的执行日志中所记录的各种操作。如下图所示:
复制的基本过程
- 在从节点上执行
start slave
命令开启主从复制开关,开始进行主从复制。从节点上的 I/O 进程链接主节点,并请求从指定日志文件的指定位置(或者从最开始的日志)之后的日志内容。
- 主节点接收到来自从节点的 I/O 请求后,通过负责复制的 I/O 进程(log dump)根据请求信息读取指定日志指定位置之后的日志信息,返回给从节点。返回信息中除了日志所包含的信息之外,还包括本次返回的信息的 bin-log file ,以及 bin-log position(bin-log中的下一个指定更新位置)。
- 从节点的 I/O 进程接收到主节点发送过来的日志内容、日志文件及位置点后,将接收到的日志内容更新到本机的 relay-log (中继日志)的文件(Mysql-relay-bin.xxx)的最末端,并将读取到的binary log(bin-log)文件名和位置保存到 master-info 文件中,以便在下一次读取的时候能够清楚的告诉 Master “我需要从某个 bin-log 的哪个位置开始往后的日志内容,请发给我”。
- Slave 的 SQL 线程检测到 relay-log 中新增加了内容后,会将 relay-log 的内容解析成在主节点上实际执行过 SQL 语句,然后在本数据库中按照解析出来的顺序执行,并在 relay-log.info 中记录当前应用中继日志的文件名和位置点。