一、背景介绍
数据库DML操作,会产生对应的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
#重启,修改配置文件后都需要重启
三、不足改进
主要有两点:
1、上面是主从异步复制的时序图。mysql的sql处理流程中,默认对于从库的操作是异步的,就是在发生sql执行时,写入binlog后,主库不管从库对binlog的读写动作,不管它成功与否,都会直接提交事务,完成自身的一个写操作。那么就会发生主库宕机,从库未同步到binlog的信息,就丢失的问题。
解决: 半同步复制,在提交事务,写入磁盘前,进行等待,等待从库对主库的binlog读写完成。如下图:
2、从上文的主从原理图中,我们可以看到从库的IO线程及SQL线程是单线程的,那么当主库的变化很频繁时,从库的同步压力就会变大。如何来优化呢?
解决:并行复制,利用事务组概念。