MySQL主从同步

时间:2022-12-04 15:08:00

       “主”指的是MySQL主服务器(master),负责写请求。“从”指的是MySQL从服务器(slave),负责读请求。主从同步指的是将主服务器上的数据同步至从服务器。

2.为什么需要主从同步?

      针对大流量,一台服务器已经不能满足要求。这个时候往往是将MySQL集群部署,但是这样会存在数据一致性的问题,即客户端相同的请求,访问不同的节点,如何能够得到相同的访问结果。通常的部署架构有一主多从和多主多从。

一主多从,主服务器负责写请求,从服务器负责读请求,从服务器的数据同步自主服务器。每台服务器都拥有所有的数据,因此可以解决数据一致性问题。使用多台服务器共同来处理请求,也达到了负责均衡的效果,之所以从服务器比主服务器多,原因是实际生产中,读请求远多于写请求。

MySQL主从同步

 多主多从,一主多从在业务量大的时候,主库的写入速度就会成为性能瓶颈。这个时候可以使用分库分表,让数据分布在多个master中,每个master又有多个从库,负责写请求。那么client端在请求数据时,怎么知道数据在哪个节点上呢?对于分库分表,每个表都会有一个字段作为分库键,中间件(比如MyCat)在查询时会根据分库键计算出数据在哪一个库上。

 MySQL主从同步

<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

  • 查看主服务器状态

MySQL主从同步

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;

MySQL主从同步 

4.主从同步的原理

4.1 主从同步的步骤

MySQL主从同步

 

  如上图,复制主要分为以下几个步骤:

1.主库将数据的更改记录到二进制文件中(binary log)

2.从库连接主库,此时会在从库上创建两个线程:I/O线程和SQL线程,在主库上创建一个线程:Binlog Dump线程。可以在主库和从库上使用 SHOW PROCESSLIST命令查看

Binlog Dump线程

MySQL主从同步

 

I/O线程和SQL线程

 MySQL主从同步

 

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后再读取