Linux 下MySql主从数据库的环境搭建
测试环境:两台服务器,Mysql版本 8.0,linux版本:Ubuntu 20.04.3;
1.在两台服务器上安装MySql;
2.选一台作为主服务器,在主服务器上以root用户进入Mysql,执行以下语句:
CREATE USER 'testUser'@'%' IDENTIFIED WITH 'caching_sha2_password' BY '123456';
GRANT REPLICATION SLAVE ON *.* TO 'testUser'@'%';
FLUSH PRIVILEGES;
创建了一个testUser用户,并授予testUser用户在任意主机上作为复制从服务器的权限。
注:我使用的插件是caching_sha2_password,没有使用mysql_native_password,是因为后续我的从服务器有报错:Plugin mysql_native_password reported: ''mysql_native_password' is deprecated and will be removed in a future release. Please use caching_sha2_password instead';所以我又换成了caching_sha2_password。
3.主服务器配置:
3.1修改配置文件
编辑 MySQL 配置文件 my.cnf
(路径通常为 /etc/mysql/my.cnf
或 /etc/my.cnf
)
添加以下内容:
[mysqld]
server-id = 1 # 唯一标识主库(建议用 IP 末段)
log-bin = mysql-bin # 启用二进制日志
binlog-format = ROW # 推荐使用 ROW 格式
binlog-do-db = mydb # 指定同步的数据库(可选,不配置则同步所有库)
expire_logs_days = 7 # 自动清理 7 天前的 binlog
gtid_mode = ON # 启用 GTID(可选,简化主从切换)
enforce_gtid_consistency = ON # 强制 GTID 一致性
3.2重启mysql服务
service mysql restart
3.3查看主库状态
SHOW MASTER STATUS;
输出示例:
4.从服务器配置
4.1修改配置my.cnf文件
[mysqld]
server-id = 2 # 唯一标识从库
relay-log = mysql-relay-bin # 启用中继日志
read-only = 1 # 从库设为只读(避免误写)
log-slave-updates = ON # 记录从库的更新(级联复制需要)
gtid_mode = ON # 与主库一致(如果主库启用 GTID)
enforce_gtid_consistency = ON
4.2重启mysql服务:
service mysql restart
4.3配置主从复制链路
方式一:传统复制(基于 binlog 文件名和位置)
CHANGE MASTER TO
MASTER_HOST='主服务的IP',
MASTER_USER='testUser', --用户名
MASTER_PASSWORD='123456',--密码
get_master_public_key=1,
MASTER_LOG_FILE='mysql-bin.000001', -- 主库 SHOW MASTER STATUS 中的 File
MASTER_LOG_POS=785; -- 主库 SHOW MASTER STATUS 中的 Position
方式二:GTID 复制(推荐)
CHANGE MASTER TO
MASTER_HOST='主服务器Ip',
MASTER_USER='testUser',--用户名
MASTER_PASSWORD='123456',--密码
get_master_public_key=1,
MASTER_AUTO_POSITION = 1;
4.4启动从库复制线程(执行SQL语句)
SHOW SLAVE STATUS;
关键字段说明:
-
Slave_IO_Running
:必须为Yes
(表示 IO 线程正常) -
Slave_SQL_Running
:必须为Yes
(表示 SQL 线程正常) -
Last_IO_Error
和Last_SQL_Error
:检查是否有错误信息 -
Seconds_Behind_Master
:从库延迟时间(单位:秒)
如果Slave_IO_Running字段不为True,则需要检查日志排查错误:
5.常见错误排查:
5.1在从服务器上执行以下语句:
sudo tail -n 100 /var/log/mysql/error.log
5.2 错误排查
错误1:
Replica I/O for channel '': Fatal error: The replica I/O thread stops because source and replica have equal MySQL server UUIDs; these UUIDs must be different for replication to work. Error_code: MY-013117
问题原因
-
MySQL 每个实例的
server-uuid
必须全局唯一,若主从库的 UUID 相同,复制会直接失败。 -
此问题通常发生在以下场景:
-
直接复制了主库的 MySQL 数据目录到从库(如克隆虚拟机镜像或备份恢复后未修改 UUID)。
-
手动修改了
auto.cnf
文件导致主从 UUID 重复。
-
解决方法:
步骤 1:停止从库 MySQL 服务:
service mysql stop
步骤2:删除或修改 auto.cnf
文件
定位到 MySQL 数据目录下的 auto.cnf
文件(默认路径为 /var/lib/mysql/auto.cnf
)
删除该文件,重启后mysql服务后,会重新生成一个新的
步骤3:启动mysql服务,重启主从复制(执行以下SQL语句)
-- 在从库执行
STOP SLAVE;
RESET SLAVE ALL; -- 清除旧的复制配置-- 重新配置主从复制(根据实际参数填写)
CHANGE MASTER TOMASTER_HOST='主库IP',MASTER_USER='用户名',MASTER_PASSWORD='密码',MASTER_AUTO_POSITION=1; -- 如果使用 GTID 复制START SLAVE;
步骤4,重新检查状态(执行以下SQL语句)
SHOW SLAVE STATUS
错误2
Replica I/O for channel '': Got fatal error 1236 from source when reading data from binary log: 'Replica has more GTIDs than the source has, using the source's SERVER_UUID. This may indicate that the the last binary log file was truncated or lost, e.g., after a power failure when sync_binlog != 1. The source may have rolled back transactions that were already replicated to the replica. Replicate any transactions that source has rolled back from replica to source, and/or commit empty transactions on source to account for transactions that have been committed on source but are not included in GTID_EXECU', Error_code: MY-013114
错误原因:
主库的 binlog 中缺少从库已接收并记录的 GTID 事务(例如主库执行了 RESET MASTER
、手动删除了 binlog 文件,或主库崩溃后未正确持久化事务)
解决方法:
步骤1:
登录主库,查看当前 GTID 集合:
SHOW GLOBAL VARIABLES LIKE 'gtid_executed';
-- 示例输出:gtid_executed = 3a9d1a1a-1a1a-11eb-8a3a-000c29a3a3a3:1-100
登录从库,查看从库的 GTID 集合:
如果从库和主库的gtid_executed不一致,则可以强制从库与主库 GTID 一致:
如下:
RESET MASTER; -- 清空从库的 GTID 执行记录
SET @@GLOBAL.gtid_purged = '主库的 gtid_executed 值';
-- 例如:
SET @@GLOBAL.gtid_purged = '3a9d1a1a-1a1a-11eb-8a3a-000c29a3a3a3:1-100';
步骤2:重启主从复制(执行以下SQL语句)的
-- 在从库执行
STOP SLAVE;
RESET SLAVE ALL; -- 清除旧的复制配置-- 重新配置主从复制(根据实际参数填写)
CHANGE MASTER TOMASTER_HOST='主库IP',MASTER_USER='用户名',MASTER_PASSWORD='密码',MASTER_AUTO_POSITION=1; -- 如果使用 GTID 复制START SLAVE;
这个时候,在主库上新建一个Table并插入一条数据,如果正常的话,从库上也会相应的多出一个Table和新插入的数据。
其它:主库配置优化项(可选,有些上面已经配置了)
[mysqld]
sync_binlog = 1 # 确保每次事务提交都同步 binlog 到磁盘
expire_logs_days = 7 # 保留最近 7 天的 binlog
gtid_mode = ON
enforce_gtid_consistency = ON