MySQL 1主2从集群搭建(推荐GTID)
📋 环境规划
主库配置 (db-master - 192.168.7.10)
修改配置文件
# 编辑文件
vim /etc/my.cnf
# 在 [mysqld] 标签下添加:
[mysqld]
# 主库配置
server-id=1
log-bin=mysql-bin
binlog_format=ROW
# 不需要同步的数据库
binlog-ignore-db=sys
binlog-ignore-db=mysql
binlog-ignore-db=information_schema
binlog-ignore-db=performance_schema
# 可选:指定需要同步的数据库
# binlog-do-db=school_db
# 重启Mysql服务
systemctl restart mysqld创建复制用户
-- 登录MySQL
mysql -uroot -p
-- 创建复制专用用户
CREATE USER 'repl'@'%' IDENTIFIED WITH mysql_native_password BY 'Repl123!';
-- 授予复制权限
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
-- 刷新权限
FLUSH PRIVILEGES;记录日志位点
# 日志位点
SHOW MASTER STATUS;
**输出示例**:
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 828 | | sys,mysql,... | |
+------------------+----------+--------------+------------------+-------------------+⚠️ 重要:记录下 File 和 Position 的值,配置从库时需要用到!
开放防火墙
# 开放3306端口
firewall-cmd --permanent --add-port=3306/tcp
firewall-cmd --reload
# 或直接关闭防火墙(测试环境)
systemctl stop firewalld
systemctl disable firewalld初始化测试数据
# 创建库
CREATE DATABASE IF NOT EXISTS school_db
DEFAULT CHARACTER SET utf8mb4
COLLATE utf8mb4_unicode_ci;
# 进入
USE school_db;
# 创建表
CREATE TABLE students (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50) NOT NULL,
age TINYINT UNSIGNED,
class_name VARCHAR(50),
created_at DATETIME DEFAULT CURRENT_TIMESTAMP
);
# 插入数据
INSERT INTO students(name, age, class_name) VALUES
('张三', 18, 'Q20班'),
('李四', 19, 'Q20班'),
('王五', 18, 'Q20班'),
('赵六', 20, 'Q20班'),
('孙七', 19, 'Q20班');从库配置 (db-slave1 - 192.168.7.20)
修改配置文件
# 编辑文件
vim /etc/my.cnf
# 在 [mysqld] 标签下添加:
[mysqld]
# 从库1配置
server-id=2
relay-log=mysql-relay
read_only=1
# 重启Mysql服务
systemctl restart mysqld测试主库连接
# 测试能否连接主库
mysql -urepl -pRepl123! -h 192.168.7.10 -P3306 -e "SELECT 1"如果能正常返回 1,说明连接正常。
配置主从连接
-- 登录MySQL
mysql -uroot -p
-- 停止已有的同步(如果有)
STOP SLAVE;
-- 配置主库信息
CHANGE MASTER TO
MASTER_HOST='192.168.7.10',
MASTER_PORT=3306,
MASTER_USER='repl',
MASTER_PASSWORD='Repl123!',
MASTER_LOG_FILE='mysql-bin.000001', -- 替换为主库实际的File
MASTER_LOG_POS=826; -- 替换为主库实际的Position
-- 启动同步
START SLAVE;验证同步状态
# 查询链接状态
SHOW SLAVE STATUS\G;
# 重点检查以下两项:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes从库配置 (db-slave2 - 192.168.7.30)
修改配置文件
# 编辑文件
vim /etc/my.cnf
# 在 [mysqld] 标签下添加:
[mysqld]
# 从库1配置
server-id=3
relay-log=mysql-relay
read_only=1
# 重启Mysql服务
systemctl restart mysqld测试主库连接
# 测试能否连接主库
mysql -urepl -pRepl123! -h 192.168.7.10 -P3306 -e "SELECT 1"配置主从连接
-- 登录MySQL
mysql -uroot -p
-- 配置主库信息(与从库1完全相同)
CHANGE MASTER TO
MASTER_HOST='192.168.7.10',
MASTER_PORT=3306,
MASTER_USER='repl',
MASTER_PASSWORD='Repl123!',
MASTER_LOG_FILE='mysql-bin.000001', -- 替换为主库实际的File
MASTER_LOG_POS=826; -- 替换为主库实际的Position
-- 启动同步
START SLAVE;验证同步状态
# 查询链接状态
SHOW SLAVE STATUS\G;
# 重点检查以下两项:
Slave_IO_Running: Yes
Slave_SQL_Running: Yes验证主从同步
在主库插入新数据
-- 在主库执行 (192.168.7.10)
USE school_db;
INSERT INTO students(name, age, class_name) VALUES ('刘八', 21, 'Q20班');
INSERT INTO students(name, age, class_name) VALUES ('陈九', 22, 'Q20班');在从库查询数据
-- 在从库1执行 (192.168.7.20)
USE school_db;
SELECT * FROM students;
-- 在从库2执行 (192.168.7.30)
USE school_db;
SELECT * FROM students;预期结果:两个从库都能看到新插入的数据。
📊 常用管理命令
查看同步状态
-- 查看从库状态
SHOW SLAVE STATUS\G;
-- 查看主库状态
SHOW MASTER STATUS;
-- 查看进程列表
SHOW PROCESSLIST;暂停/恢复同步
-- 暂停同步
STOP SLAVE;
-- 恢复同步
START SLAVE;
-- 重置同步(慎用)
STOP SLAVE;
RESET SLAVE;
START SLAVE;跳过错误(测试环境)
-- 跳过1个错误
STOP SLAVE;
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;
START SLAVE;
-- 或配置文件跳过所有错误(不推荐生产)
slave_skip_errors = ALL🔍 故障排查
问题1:Slave_IO_Running: No
可能原因:
网络不通
复制用户密码错误
防火墙阻止3306端口
解决方法:
# 检查网络
ping 192.168.7.10
# 检查端口
telnet 192.168.7.10 3306
# 检查防火墙(主库和从库)
systemctl status firewalld
# 开放端口
firewall-cmd --permanent --add-port=3306/tcp
firewall-cmd --reload
# 重新配置主从
STOP SLAVE;
CHANGE MASTER TO ...;
START SLAVE;问题2:Slave_SQL_Running: No
可能原因:
数据冲突(主键重复)
表不存在
解决方法:
-- 查看具体错误
SHOW SLAVE STATUS\G;
-- 查看 Last_SQL_Error 字段
-- 跳过错误
STOP SLAVE;
SET GLOBAL SQL_SLAVE_SKIP_COUNTER = 1;
START SLAVE;问题3:UUID冲突
原因:从库是克隆主库的虚拟机,auto.cnf 中的UUID相同。
解决方法:
# 删除auto.cnf
rm -f /var/lib/mysql/auto.cnf
# 重启MySQL
systemctl restart mysqld
# MySQL会自动生成新的UUID问题4:从库无法连接主库
# 检查主库是否允许远程连接
mysql -h 192.168.7.10 -uroot -p -e "SELECT host, user FROM mysql.user;"
# 检查复制用户是否存在
mysql -h 192.168.7.10 -uroot -p -e "SELECT host, user FROM mysql.user WHERE user='repl';"
# 重新创建复制用户
mysql -h 192.168.7.10 -uroot -p
DROP USER 'repl'@'%';
CREATE USER 'repl'@'%' IDENTIFIED WITH mysql_native_password BY 'Repl123!';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;
原创
MySQL 一主两从集群搭建
本文采用 CC BY-NC-SA 4.0 许可协议,转载请注明出处。
评论交流
欢迎留下你的想法