一、背景介绍

数据库DML操作,会产生对应的sql语句,那么只要让从库也同样执行一遍,是不是就可以达到跟主库状态一致的效果了呢?——即实现主从复制。

那么主从复制就是要解决这个过程。

二、主从原理

首先来一张主从复制的原理图:

mysql主从动态切换 mysql主从切换原理_sql

原理解读:

1、当主库发生Data changes时,需要有个地方来记录DML的语句,那就是Binary log了,对应的就是下文中配置文件的log_bin=mysql-bin指定binlog的文件名,sync-binlog=1开启binlog功能。

log_bin=mysql-bin
server-id=1
sync-binlog=1#启用binlog同步
binlog-ignore=xx#不同步的对象

2、然后我们看到Master-Slave之间是通过IO Thread进行读写联通的,交互的主要是binlog的信息。Slave从Master读取到binlog的内容;

3、在Slave中,IO 线程会接着write到自身的Relay log中。Relay log的作用就是用于sql语句的回放。对应的就是从库的配置

server-id=2
read_only=1
relay_log=mysql-relay

4、Relay log传给SQL Thread,在Slave中执行回放的sql,从而达到主从一致的目的。

下面是完整的主从配置。

#my.cnf,主库配置
log_bin=mysql-bin
server-id=1
sync-binlog=1#启用binlog同步
binlog-ignore=xx#不同步的对象
#重启
systemctl restart mysqld
#主库授权,进入数据库
mysql -uroot -p123456
grant replication slave on *.* to 'root'@'%' identified by '123456';
grant all privileges on *.* to 'root'@'%' identified by '123456';
flush privileges;
show master status;#查看主库信息 binlog文件名称,当前的position,每次有变动,position都会变化,同步只会从配置的节点之后开始之前的信息不会同步
vi /etc/my.cnf
#从库配置 
server-id=2
read_only=1
relay_log=mysql-relay
#重启,修改配置文件后都需要重启

三、不足改进

主要有两点:

mysql主从动态切换 mysql主从切换原理_数据库_02

1、上面是主从异步复制的时序图。mysql的sql处理流程中,默认对于从库的操作是异步的,就是在发生sql执行时,写入binlog后,主库不管从库对binlog的读写动作,不管它成功与否,都会直接提交事务,完成自身的一个写操作。那么就会发生主库宕机,从库未同步到binlog的信息,就丢失的问题。

解决: 半同步复制,在提交事务,写入磁盘前,进行等待,等待从库对主库的binlog读写完成。如下图:

mysql主从动态切换 mysql主从切换原理_mysql主从动态切换_03

2、从上文的主从原理图中,我们可以看到从库的IO线程及SQL线程是单线程的,那么当主库的变化很频繁时,从库的同步压力就会变大。如何来优化呢?

解决:并行复制,利用事务组概念。