MySQL
的主从复制(Master-Slave Replication
)是一种数据复制解决方案,将主数据库的DDL
和DML
操作通过二进制日志传到从库服务器中,然后在从库上对这些日志重新执行(也叫重做),从而是的从库和主库的数据保存同步。
MySQL
支持将数据从一个MySQL
服务器(主服务器)复制到一个或多个其他MySQL
服务器(从服务器),从库同时也可以作为其他从服务器的主库,实现链状复制。
MySQL
主从复制的优点主要包含以下三个方面:
主库出现问题,可以快速切换到从库提供服务;
实现读写分离,降低主库的访问压力;
可以在从库中执行备份,以避免备份期间影响主库服务;
需要注意的是,MySQL
的主从复制是异步的,这意味着从服务器的数据可能会与主服务器的数据存在一定的延迟。因此,在使用主从复制时,需要根据具体的业务场景和需求来选择合适的配置和策略。
从上图来看,主从复制分成三步:
Master
主库在事务提交时,会把数据变更记录在二进制日志文件Binlog
中;
从库读取主库的二进制日志文件Binlog
,写入到从库的中继日志Relay Log
;
Slave
重做中继日志中的事件,将改变数据更新同步到从库中;
准备两台虚拟机,需要提前安装好MySQL
数据库(必须要开启二进制日志)。如下所示:
主从库 | IP地址 |
---|---|
主库 | 192.168.233.137 |
从库 | 192.168.233.138 |
1)修改主库服务器的MySQL
核心配置文件/etc/mysql/mysql.conf.d/mysqld.cnf
,并添加如下配置信息:
[mysqld]
...
# 开启二进制日志(必须)
log-bin = mysql-bin
# MySQL服务ID,保证整个集群环境中唯一,默认为1(必须)
server-id = 1
# 二进制日志格式,默认ROW(可选)
binlog_format = ROW
# 忽略的数据,不需要同步的数据库
# binlog-ignore-db = mysql
# 指定同步的数据库
# binlog-do-db = db01
2)重启MySQL
服务器。
systemctl restart mysql
3)登录MySQL
数据库,创建远程连接的账号,并授予主从复制权限。
# 创建zking用户,并设置密码,该用户可在任意主机连接该MySQL服务
create user 'zking'@'%' identified with mysql_native_password by 'zking1234';
# 为'zking'@'%'用户分配主从复制权限
grant replication slave on *.* to 'zking'@'%';
4)通过指令,查看二进制日志坐标
show master status;
字段含义说明:
字段 | 说明 |
---|---|
File | 当前正在写入的二进制日志文件名 |
Position | 当前正在写入的二进制日志文件的位置 |
Binlog_Do_DB | 指定需要写入二进制日志的数据库名 |
Binlog_Ignore_DB | 指令不需要写入二进制日志的数据库名 |
1)修改从库服务器的MySQL
核心配置文件/etc/mysql/mysql.conf.d/mysqld.cnf
,并添加如下配置信息:
[mysqld]
...
# 开启二进制日志(必须)
log-bin = mysql-bin
# MySQL服务ID,保证整个集群环境中唯一,默认为1(必须)
server-id = 2
# 二进制日志格式,默认ROW(可选)
binlog_format = ROW
# 是否只读,1代表只读,0代表读写
read-only = 1
2)重启MySQL
服务器。
systemctl restart mysql
3)登录MySQL
数据库,设置主库配置。
MySQL8.0.23
之前的版本,执行如下SQL
语句:
change master to master_host='xxx.xxx.xxx.xxx',master_user='xxx',master_password='xxx',master_log_file='xxx',master_log_pos=xxx;
MySQL8.0.23
之后的版本,执行如下SQL
语句:
change replication source to source_host='xxx.xxx.xxx.xxx',source_user='xxx',source_password='xxx',source_log_file='xxx',source_log_pos=xxx;
参数说明:
参数名 | 含义 | 8.0.23之前 |
---|---|---|
source_host | 主库IP地址 | master_host |
source_user | 连接主库的用户名 | master_user |
source_password | 连接主库的密码 | master_password |
source_log_file | binlog日志文件名 | master_log_file |
source_log_pos | binlong日志文件位置 | master_log_pos |
4)开启同步操作
# 8.0.22之后
start replica;
# 8.0.22之前
start slave;
5)查看主从同步状态
# 8.0.22之后
show replica status;
# 8.0.22之前
show slave status;
上述图中显示Slave_IO_Running: No
,很明显主从复制开启失败。经过问题分析之后,发现是虚拟机是克隆的,导致主库和从库的MySQL
的server id
都是一样的。解决方案:修改任意主库和从库的server id
即可解决问题。
修改/var/lib/mysql/auto.cnf
文件。将server-uuid
属性修改为唯一值即可。
[auto] server-uuid = 任意uuid
修改完毕保存并退出,最后重启MySQL
服务后,并再次登录MySQL
查看主从复制是否成功。
1)登录主库MySQL
,并执行以下SQL
语句:
# 切换数据库
use db1;
# 创建数据表t_student
create table t_student(sid int primary key auto_increment,sname varchar(20) not null,sage int default 0,ssex varchar(2) default '1');
# 批量添加数据
insert into t_student(sname,sage,ssex) values('张三',26,'男'),('王五',22,'女'),('小七',23,'女');
2)登录从库MySQL
,查看主从复制结果:
# 切换数据库
use db1;
# 查看是否存在t_student表
show tables;
# 查看t_student表中是否存在数据
select * from t_student;
存在数据即MySQL
主从复制同步成功。