“主”指的是MySQL主服务器(master),负责写请求。“从”指的是MySQL从服务器(slave),负责读请求。主从同步指的是将主服务器上的数据同步至从服务器。
2.为什么需要主从同步?
针对大流量,一台服务器已经不能满足要求。这个时候往往是将MySQL集群部署,但是这样会存在数据一致性的问题,即客户端相同的请求,访问不同的节点,如何能够得到相同的访问结果。通常的部署架构有一主多从和多主多从。
一主多从,主服务器负责写请求,从服务器负责读请求,从服务器的数据同步自主服务器。每台服务器都拥有所有的数据,因此可以解决数据一致性问题。使用多台服务器共同来处理请求,也达到了负责均衡的效果,之所以从服务器比主服务器多,原因是实际生产中,读请求远多于写请求。
多主多从,一主多从在业务量大的时候,主库的写入速度就会成为性能瓶颈。这个时候可以使用分库分表,让数据分布在多个master中,每个master又有多个从库,负责写请求。那么client端在请求数据时,怎么知道数据在哪个节点上呢?对于分库分表,每个表都会有一个字段作为分库键,中间件(比如MyCat)在查询时会根据分库键计算出数据在哪一个库上。
<mycat:schema xmlns:mycat="http://io.mycat/"> <!--逻辑库,物理层面由db1、db2、db3组成--> <schema name="TESTDB" checkSQLschema="false" sqlMaxLimit="100"> <!--逻辑表,由不同的数据库中的表组成--> <table name="t_user" dataNode="dn1,dn2,dn3" rule="crc32slot" /> </schema> <!--dataNode,可以理解为一个master和他的从库组成的一个逻辑节点--> <dataNode name="dn1" dataHost="localhost1" database="db1" /> <dataNode name="dn2" dataHost="localhost1" database="db2" /> <dataNode name="dn3" dataHost="localhost1" database="db3" /> <!--dataNode的连接信息--> <dataHost name="localhost1" maxCon="1000" minCon="10" balance="0" writeType="0" dbType="mysql" dbDriver="native" switchType="1" slaveThreshold="100"> <!--主节点(master节点)--> <writeHost host="hostM1" url="localhost:3306" user="root" password="root"> <!--从节点(slave节点)--> <readHost host="hostS2" url="192.168.1.200:3306"user="root"password="root" /> </writeHost> </dataHost> </mycat:schema>
3.主从同步如何使用?
3.1 配置主节点
- 配置log_bin和server_id
在/etc/my.cnf中增加如下配置
log-bin=mysql-bin # binlog名称
server-id=1 # 服务器id
- 创建复制账号
create user 'data_copy'@'%' identified by 'Test@1234'; # 创建复制账号
grant FILE on *.* to 'data_copy'@'192.168.126.132' identified by 'Test@1234'; # 授予复制账号FILE权限,允许从库IP访问主库
grant replication slave on *.* to 'data_copy'@'192.168.126.132' identified by 'Test@1234'; # 授予账号主从同步权限
flush privileges; # 刷新权限
- 重启服务器
service mysql start
- 查看主服务器状态
3.2 配置从节点
- 配置server_id
在/etc/my.cnf中增加如下配置
server-id=2 # 服务器id
- 重启服务器
service mysql start
- 在从节点上配置主节点信息
stop slave;
# 设置当前服务器对应的master change master to master_host='192.168.126.134', master_user='data_copy' ,master_password='Test@1234', master_log_file='mysql-bin.000005' ,master_log_pos=0; start slave;
- 查看从节点状态
show slave status \G;
4.主从同步的原理
4.1 主从同步的步骤
如上图,复制主要分为以下几个步骤:
1.主库将数据的更改记录到二进制文件中(binary log)
2.从库连接主库,此时会在从库上创建两个线程:I/O线程和SQL线程,在主库上创建一个线程:Binlog Dump线程。可以在主库和从库上使用 SHOW PROCESSLIST命令查看
Binlog Dump线程
I/O线程和SQL线程
3.Binlog Dump线程会将Binlog中的事件发送给从库
4.从库中的I/O线程接收到事件后,将事件写入relay log
5.SQL线程重放relay log中的事件,达到将主库的数据复制到从库的目的
从以上的步骤可以看出,这种复制架构将事件获取和事件重放完全解耦开来。是典型的生产者和消费者模式的运用,mysql主线程负责生产Binlog,Binlog Dump线程负责消费;I/O线程负责生产relay log,SQL线程消费relay log。
4.2 主从同步原理
基于语句的复制
基于语句的复制,binlog会记录造成数据或者表结构更改的语句,从库重放事件时,相当于把这些语句再执行一遍。
基于行的复制
基于行的复制,binlog直接记录更改后的数据
这两种模式各有优劣,mysql会在这两种模式之间动态切换。
5.主从同步的延迟问题
由于主从同步是异步的,难免会存在主从同步延迟问题,一般情况下这种延迟可以忽略,但是对于数据一致性要求比较高的场景,就必须想办法解决。
1.对于不能容忍半点数据不一致的情况:强制读主库
2.对于可以稍微容忍不一致的情况:可以在卸库完成后,sleep 500m后再读取