MySQL 主从复制是一种数据同步技术,将一个 MySQL 数据库从一个服务器(称为主服务器)复制到其他服务器(称为从服务器)。在这个过程中,主服务器 (master) 将写操作记录在二进制日志中,并将日志传输到从服务器 (slave),从服务器 (slave) 则将其重做,保持与主服务器 (master) 数据的同步。MySQL 支持一台主库同时向多台从库进行复制,从库同时也可以作为其他从服务器的主库,实现链状复制。MySQL 主从复制是 MySQL 数据库自带的功能,无需借助第三方工具。

MySQL 主从复制过程分成三步:
- master 将改变记录到二进制日志 (binary log)。
- slave 将 master 的 binary log 拷贝到它的中继日志 (relay log)。
- slave 重新执行中继日志中的事件,将执行的事件应用到自己的数据库中。
MySQL主从复制原理图过程如下:


需要注意的是,因为 MySQL 主从复制是异步进行的,所以在数据同步期间可能会存在一些延迟。此外,需要确保主服务器和从服务器的 MySQL 版本号相同,以免出现不兼容的问题。
前期准备工作
1、首先提前准备好两台(或者多台)Linux 服务器,要求主服务器 (master) 与从服务器 (slave) 的 IP 地址、数据库中的 server_uuid 以及虚拟机的 MAC 地址不能相同。
1.1、分别查看主服务器虚拟机与从服务器虚拟机的 MAC 地址是否相同(相同则修改任意一个虚拟机的 MAC 地址即可)
如何修改虚拟机的MAC地址的相关操作可看这里:https://blog.csdn.net/weixin_56817591/article/details/131075423?spm=1001.2014.3001.5501
1.2、分别查看主服务器 (master) 与从服务器 (slave) 的 IP 地址是否相同(相同则修改任意一个 Linux 服务器 IP 地址即可)
ifconfig #查看本地IP地址
如何修改 Linux 服务器的 IP 地址的相关操作可看这里:https://blog.csdn.net/weixin_56817591/article/details/131075423?spm=1001.2014.3001.5501
1.3、分别查看主服务器 (master) 与从服务器 (slave) MySQL 数据库中 server_uuid 是否相同
登录主服务器管理员 MySQL 数据库
mysql -uroot -p密码
执行 SQL 语句,查看 server_uuid 中的值是否相同
show variables like '%server_uuid%';
如果相同,则删除任意一个 Linux 服务器 MySQL 数据库中的 server_uuid,并重新启动被删除的 MySQL 服务
退出 MySQL 登录后,执行下面语句
rm -rf /var/lib/mysql/auto.cnf #删除MySQL数据库中的server_uuid,删除后重启MySQL服务会自动生成新的server_uuid
systemctl restart mysqld #重启MySQL服务
[Linux拓展]:MySQL服务相关操作
#按Ctrl+d可退出MySQL登录
systemctl stop mysqld #停止MySQL服务
systemctl start mysqld # 启动MySQL服务
systemctl enable mysqld # 设置MySQL服务开机自启
2、需要保证主服务器 (master) 与从服务器 (slave) 的 Linux 服务器之间可以相互 ping 通
在主服务器 (master) 中 ping 从服务器 (slave) 的 IP 地址
在从服务器 (slave) 中 ping 主服务器 (master) 的 IP 地址
3、需要保证主服务器 (master) 与从服务器 (slave) 的 Linux 服务器 3306 端口开启或直接关闭防火墙
查看开放的端口
firewall-cmd --zone=public --list-ports
查看防火墙状态
systemctl status firewalld
[Linux拓展]:其他关于防火墙的操作
#查看防火墙状态
systemctl status firewalld 或者 firewall-cmd --state
#暂时关闭防火墙
systemctl stop firewalld
#永久关闭防火墙
systemctl disable firewalld
#开启防火墙
systemctl start firewalld
#开放指定端口
firewall-cmd --zone=public --add-port=开放指定的端口号/tcp --permanent
#关闭指定端口
firewall-cmd --zone=public --remove-port=关闭指定端口号/tcp --permanent
#立即生效
firewall-cmd --reload
4、分别检查主服务器 (master) 与从服务器 (slave) 的 MySQL 服务的运行状态,确保 MySQL 服务已经启动
systemctl status mysqld

主库配置(master)
第一步:修改主服务器 MySQL 数据库的配置文件 /etc/my.cnf
打开配置文件 /etc/my.cnf
vi /etc/my.cnf
修改配置文件/etc/my.cnf
#开启二进制日志
log-bin=mysql-bin
#[必须]指定服务器唯一id,默认为1,值范围为1~2^32−1。主库与从库的server-id不能重复
server_id=188
#是否只读,1 代表只读, 0 代表读写
read_only=0
default_authentication_plugin=mysql_native_password
#忽略的数据, 指不需要同步的数据库(按需)
#binlog-ignore-db=mysql
#指定同步的数据库(按需)
#binlog-do-db=db01
第二步:重启主服务器 MySQL 服务
systemctl restart mysqld
第三步: 登录主服务器管理员 MySQL 数据库,执行下面的 SQL 语句创建远程连接的账号,并给账号授予主从复制的权限
登录主服务器管理员 MySQL 数据库
mysql -uroot -p密码
执行SQL语句
#注意设置的密码需要符合大于8位,有大写字母,有特殊符号,不能是连续的
#如果想配置简单密码,可看下面的SQL[拓展],再来执行这里的SQL语句。这里我已经提前弄好了。
#创建用户并设置密码,%代表该用户可在任意主机连接该MySOL服务
CREATE USER '用户名'@'%' IDENTIFIED WITH mysql_native_password BY '用户密码';
GRANT REPLICATION SLAVE ON *.* TO '用户名'@'%'; #为该用户分配主从复制授权
FLUSH PRIVILEGES; #重新刷新权限
注意:上面SQL语句的作用是创建一个用户和密码,并且给用户授予 REPLICATION SLAVE 权限。常用于建立复制时所需要用到的用户权限,也就是 slave 必须被 master 授权具有该权限的用户,才能通过该用户复制主库数据。
查看创建的用户是否成功
#查看数据库中的所有用户
select user,host,Grant_priv,Super_priv from mysql.user;
#删除数据库中的指定用户
DROP USER '用户名'@'%'; #注意删除用户时,@后面可以是ip地址、localhost、%
[SQL扩展]:配置 MySQL 简单密码相关操作
# 设置MySQL的密码安全级别与密码长度
set global validate_password.policy=0; # 设置密码安全级别低
set global validate_password.length=4; # 设置密码长度最低为4位
flush privileges; #重新刷新权限
从库配置(slave)
第一步:修改从服务器 MySQL 数据库的配置文件 /etc/my.cnf
打开配置文件/etc/my.cnf
vi /etc/my.cnf
修改配置文件 /etc/my.cnf
#[必须]指定服务器唯一id,默认为1,值范围为1~2^32−1。主库与从库的server-id不能重复
server_id=189
#是否只读,1 代表只读, 0 代表读写
read_only=1
#relay_log文件位置定义,不定义的话默认是在data目录
relay_log = /var/lib/mysql/mysql-realay-bin
第二步:重启从服务器 MySQL 服务
systemctl restart mysqld
第三步: 登录主服务器 MySQL 数据库(master),执行下面 SQL 语句,记录下结果中 File 和 Position 的值
登录主服务器(master)mysql 数据库
mysql -uroot -p密码
执行sql语句
#注意:这里查看的是主服务器MySQL数据库(master)Master的状态,而不是从服务器。
#注意:执行完此SQL语句后不要在主服务器(master)中再执行任何操作,因为每一次查看主服务器MySQL数据库Master状态可能会发生改变。
show master status;
第四步: 登录从服务器(slave)MySQL 数据库,执行下面的 SQL 语句
登录从服务器(slave)mysql 数据库
mysql -uroot -p密码
执行sql语句
#停止slave同步线程(第一次配置可不执行该操作)
stop slave;
# master_host:主库的IP地址
# master_user:在主库中创建的用户名称
# master_password:在主库中创建的用户密码
# master_log_file:第三步中查看的主库Master的File状态码
# master_log_pos:第三步中查看的主库Master的Position状态码
#MySQL8.0.23之前的版本执行这个SQL语句
change master to master_host='192.168.188.188',master_user='xiaoming',master_password='123456',master_log_file='mysql-bin.000014',master_log_pos=157;
#MySQL8.0.23或者之后的版本执行这个SQL语句
CHANGE REPLICATION SOURCE TO SOURCE_HOST='192.168.188.188', SOURCE_USER='xiaoming',SOURCE_PASSWORD='123456', SOURCE_LOG_FILE='mysql-bin.000014',SOURCE_LOG_POS=157;
#启动slave同步线程
#MySQL8.0.22之前的版本执行这个SQL语句
start slave;
#MySQL8.0.22或者之后的版本执行这个SQL语句
start replica;

第五步:登录从服务器 MySQL 数据库,执行下面 SQL,查看从数据库的状态
show slave status\G;

如果 Slave_IO_Running 与 Slave_SQL_Running 这两个的状态同时为 Yes,则表示成功,否则表示不成功。
遇到的问题:
Slave_IO_Running: NO
找到从库 my.cnf 配置错误日志,查询原因。
查询到的错误为:the master has GTID_MODE = ON and this server has GTID_MODE = OFF. Error_code: MY-013117
主库为 ON 从库 OFF,两者必须相同才行。这里将从库设置为ON.
解决:
set global gtid_mode=OFF_PERMISSIVE;
set global gtid_mode=ON_PERMISSIVE;
set global enforce_gtid_consistency=on;
set global gtid_mode=ON;
VIA
MySQL(8)主从复制详细过程_mysql8 主从复制_简243的博客-CSDN博客
https://blog.csdn.net/weixin_56817591/article/details/131029316
深入探讨MySQL主从复制只读机制(mysql中主从复制只读)-数据库运维技术服务
https://www.dbs724.com/224494.html
主从复制Slave_IO_Running: NO Slave_SQL_Running: NO ,Slave failed to initialize relay log info struct解决办法_jerry-89的博客-CSDN博客
https://blog.csdn.net/eagle89/article/details/131570373
MySQL主从复制_mysql 主从复制 read_only_小樊同志的博客-CSDN博客
https://blog.csdn.net/fancy106/article/details/118310770
mysql主从复制_跟健哥做运维的博客-CSDN博客
https://blog.csdn.net/m0_73695023/article/details/130628080
轻松翻墙
https://gitlab.com/truth51/1/-/blob/main/README.md
好东西