MYSQL 主从同步详解
作者: 稀土掘金 更新时间:2021-01-22 15:08:29 原文链接
关于MYSQL主从同步
什么是MYSQL的主从复制
主从复制是指将一个服务器作为主服务器,所有的数据更新操作都在主服务器进行,并且将主服务器的数据同步到一个或多个从服务器,保证从服务器和主服务器的数据一致。
为什么需要主从复制
高可用,主从复制实现了数据的热备份,可以有效避免单点故障导致的数据丢失。
高性能,可以用来实现读写分离,提高MYSQL服务的并发性能。
MYSQL主从复制原理
主节点 binlog,主从复制的基础是主库记录数据库的所有变更记录到 binlog。binlog 是数据库服务器启动的那一刻起,保存所有修改数据库结构或内容的一个文件。
主节点 log dump 线程,当 binlog 有变动时,log dump 线程读取其内容并发送给从节点。
从节点 I/O线程接收 binlog 内容,并将其写入到 relay log 文件中。
从节点的SQL 线程读取 relay log 文件内容对数据更新进行重放,最终保证主从数据库的一致性。
注:主从节点使用 binglog 文件 + position 偏移量来定位主从同步的位置,从节点会保存其已接收到的偏移量,如果从节点发生宕机重启,则会自动从 position 的位置发起同步。
MYSQL主从复制的模式
1、异步模式(默认方式)
异步模式下,主节点执行完客户端提交的事务后立即提交事务并返回给客户端,并不关心 log dump 线程是否成功地将将此次事务写进 binglog 并且发送给从库。假如执行事务的主线程提交事务后,log dump 线程还未来得及写入 binlog,此时系统宕机,则会造成 binglog 中没有保存刚才提交的事务,造成主从数据不一致。
优点:异步模式下,主线程不用关系同步操作,性能最好。
缺点:可能导致主从数据的不一致。
2、半同步复制
半同步方式,当主库在执行完客户端提交的事务后不是立即提交事务,而是等待 log dump 线程将此次事务同步到binlog 发送给从库,并且至少一个从库成功保存到其relay log中,此时主库的才提交事务并返回客户端。
优点:相比于异步模式,半同步方式一定程度上保证了数据同步的可靠性。
缺点:增加了主库响应客户端的延时,延时至少为一个 TCP/IP 的往返时间,即 binglog 发送给从库至收到从库的响应时间。
3、全同步复制
全同步方式,当主库在执行完客户端提交的事务后,必须等待此次的binlog发送给从库,并且所有从库成功地执行完该事务后,主库才能返回客户端。其与半同步复制的区别如下:
半同步下,主库等待binlog写入到从库的relay log即可返回,全同步方式下,必须等到从库执行事务成功。
半同步下,至少一个从库响应后主库即可返回客户端,全同步下必须等待所有的从库返回。
优点:对比半同步复制方式,全同步复制方式数据一致性的可靠性进一步提高
缺点:执行事务时,主库需要等待所有的从库执行成功后才能返回,所以会大大提高主库的响应时间。
MYSQL主从复制搭建
1、环境准备
操作系统:centos 7
MYSQL:mysql 8.0
主库地址:192.168.44.101
从库地址:192.168.44.102
Centos 下安装 mysql 的方式在此不再介绍
2、主库配置
(1)配置 my.cnf
[mysqld]
server-id = 1
复制代码
(2)重启主库
systemctl restart mysqld
登录 mysql,执行show master status;
File:binglog 文件名
Position:binlog 文件偏移量,等于binglog文件大小(字节数)
Binlog_Do_DB:要同步的数据库。不设置的话默认同步所有的数据库,包括 mysql 默认的数据库。
Binlog_Ignore_DB:不需要同步的数据库。
(3)处于数据安全的考虑,添加专门用于主从复制的用户,并仅授予其复制的权限创建用户
CREATE USER 'replication_user'@'%' IDENTIFIED BY '123456';
复制代码
(4)授予其复制权限
GRANT replication slave on.
to 'replication_user'@'%' WITH GRANT OPTION;
flush privileges;
复制代码
(5)设置 replicarion_user 远程连接的密码验证方式
ALTER USER 'replication_user'@'%' IDENTIFIED WITH mysql_native_password BY '123456';
复制代码
3、从库配置
(1)配置 my.cnf
[mysqld]
server-id = 2
复制代码
重启从库 systemctl restart mysqld
(2)指定主库
mysql> change master to
master_host='192.168.44.101',
master_user='replication_user',
master_port=3306,
master_password='123456',
master_log_file='binlog.000004',
master_log_pos=156;
复制代码
master_log_file:要同步的 binlog 文件。
master_log_pos:从哪个位置开始同步。
一般情况下,我们需要保证主从库的初始数据一致(可以通过 dump 的方式手动同步),然后从这个一致状态为起始位置开始自动主从同步。
(3)开启从库
mysql> start slave;
复制代码
(4)查看从节点状态
show slave status\G;
复制代码
Slave_IO_Running:从库的IO线程,用来接收master发送的binlog,并将其写入到中继日志relag log
Slave_SQL_Running:从库的SQL线程,用来从relay log中读取并执行binlog。Slave_IO_Running、Slave_SQL_Running:这两个进程的状态需全部为 YES,只要有一个为 NO,则复制就会停止。
Master_Log_File:要同步的主库的binlog文件名。
Read_Master_Log_Pos:已同步的位置,即同步的 binlog 文件内的字节偏移量,该值会随着主从同步的进行而不断地增长。
Relay_Log_File:从库的中继日志文件,对接收到的主库的 binlog 进行缓冲。从库的SQL线程不断地从 relay log 中读取 binlog 并执行。
Relay_Log_Pos:relay log 中已读取的位置偏移量。
Seconds_Behind_Master: 主从同步延时, 值为 0 为正常情况,正值表示已经出现延迟,数字越大从库落后主库越多。
4、主从同步测试
在主库建表并插入数据
CREATE DATABASE test CHARACTER SET utf8mb4;
USE test;
CREATE TABLEperson
(id
int NOT NULL AUTO_INCREMENT,name
varchar(255) NOT NULL,age
int NOT NULL,
PRIMARY KEY (id
)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
复制代码
插入两条数据:
INSERT INTOtest
.person
(id
,name
,age
) VALUES ('1', '小明', '28');
INSERT INTOtest
.person
(id
,name
,age
) VALUES ('2', '李华', '30');
复制代码
在从库查询
mysql> SELECT * FROM person;
+-----+--------+-----+
| id | name | age |
+-----+--------+-----+
| 1 | 小明 | 28 |
| 2 | 李华 | 30 |
+-----+--------+-----+
2 rows in set (0.00 sec)
复制代码
可以看到我们创建的 test 数据库 person 表和表中的数据都成功同步到了从库。