Skip to the content.

MySql 主从复制原理

可以先看下MySQL主从服务搭建

自己动手搭建下,印象比较深刻。

直观的展示

Master processlist

登录masterMySql服务器,执行命令show processlist,展示线程列表。

mysql> show processlist;
+----+------+--------------------+------+-------------+-------+-----------------------------------------------------------------------+------------------+
| Id | User | Host               | db   | Command     | Time  | State                                                                 | Info             |
+----+------+--------------------+------+-------------+-------+-----------------------------------------------------------------------+------------------+
|  6 | xp   | master1:52865      | NULL | Binlog Dump | 28604 | Master has sent all binlog to slave; waiting for binlog to be updated | NULL             |
|  8 | root | localhost:61860    | NULL | Query       |     0 | init                                                                  | show processlist |
+----+------+--------------------+------+-------------+-------+-----------------------------------------------------------------------+------------------+

这里展示的有两个线程

咱们再来看看Slave的线程列表

Slave processlist

登录slave MySql服务器,执行命令show processlist,展示线程列表。

mysql> show processlist;
+----+-------------+-----------------+------+---------+-------+-----------------------------------------------------------------------------+------------------+
| Id | User        | Host            | db   | Command | Time  | State                                                                       | Info             |
+----+-------------+-----------------+------+---------+-------+-----------------------------------------------------------------------------+------------------+
|  7 | system user |                 | NULL | Connect | 28875 | Waiting for master to send event                                            | NULL             |
|  8 | system user |                 | NULL | Connect |  6283 | Slave has read all relay log; waiting for the slave I/O thread to update it | NULL             |
| 11 | root        | localhost:27662 | NULL | Query   |     0 | init                                                                        | show processlist |
+----+-------------+-----------------+------+---------+-------+-----------------------------------------------------------------------------+------------------+
3 rows in set (0.00 sec)

这里展示了三个线程,Id分别为7,8,11。

整体看

Master 只有一个关于复制的线程

Slave 有两个关于复制的线程

Master和Slave的线程是如何配合一起工作的

图解

  1. Master 会将更改的数据写到二进制日志中,也就是binary log。

  2. Slave启动IO线程,IO线程跟主库建立一个普通的客户端连接,然后在主库上启动一个binlog dump线程,这个binlog dump线程在上面也可以看到,这个binlog dump线程会读取主库上二进制日志中的事件。他不会对事件进行轮询,如果该线程追赶上了主库,它将进入sleep状态,直到主库发送信号量通知binlog dump线程有新的事件产生,这样binlog dump线程就会被唤醒,然后将事件记录到Relay log中。

  3. Slave SQL线程,读取Relay log,然后重放到数据库表中,就完成了复制。

复制格式

binlog_format=statement/row/mixed

基于语句statement的复制

这个其实就是SQL语句复制,如果主库上执行update user set age=age+1 where id = 1,那么到从库上也会执行相同的语句,这就是基于语句的复制。

这个也是MySQL5.0之前复制模式。

优点

缺点

基于行 row的复制

这种方式会将真实的数据记录到二进制日志中。

MySQL5.1之后才开始有的

优点

缺点

mixed

就是statement和row的相结合。

复制加速

master 一个 binlog dump线程 slave 一个 存放relay log线程 slave 另一个 relay log 重放到数据库表线程

从这三个线程着手,最好实现的是重放线程(relay)。

全同步&半同步&异步

这里简单来说下这三个的区别。 主要根据这个图,进行阐述。

MySQL replication by default is asynchronous https://dev.mysql.com/doc/refman/5.7/en/replication-semisync.html#:~:text=MySQL%20replication%20by%20default%20is,will%20ever%20reach%20any%20replica.

参考资料