CentOS7 MySQL5.7 主从复制最终版搭建流程(避坑完整版)

说明:

my.cnf是 MySQL 的 "总开关 + 总设置"

本流程完全基于你实际遇到的问题优化(含 socket 路径、服务崩溃、UUID 重复、数据不一致、中文支持等所有坑的解决方案),小白可直接复制命令执行,全程无冗余步骤。

一、环境说明

角色 服务器 IP 系统版本 MySQL 版本 核心密码(统一设置,避免混淆)
主库(Master) 192.168.200.100 CentOS7 5.7.x MySQL 登录密码:Mysql123!;复制用户密码:Repl123@
从库(Slave) 192.168.200.101 CentOS7 5.7.x MySQL 登录密码:Mysql123!;复制用户密码:Repl123@

二、前置准备(主库 + 从库都要执行)

1. 关闭防火墙和 SELINUX(避免端口拦截)

复制代码
# 关闭防火墙(永久生效)
systemctl stop firewalld
systemctl disable firewalld

# 关闭SELINUX(临时+永久)
setenforce 0
sed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/config

2. 安装 MySQL5.7 并解决启动 / 连接问题

复制代码
# 安装依赖
yum install -y libaio-devel wget

# 下载并安装MySQL yum源
wget https://dev.mysql.com/get/mysql57-community-release-el7-11.noarch.rpm
rpm -ivh mysql57-community-release-el7-11.noarch.rpm
yum install -y mysql-community-server

# 创建数据目录并授权(避免权限报错)
mkdir -p /data/mysql /var/lib/mysql
chown -R mysql:mysql /data/mysql /var/lib/mysql
chmod -R 755 /data/mysql /var/lib/mysql

# 初始化MySQL(生成临时密码)
mysqld --initialize --user=mysql --datadir=/data/mysql

# 替换systemd启动脚本(解决启动后崩溃问题)
cat > /usr/lib/systemd/system/mysqld.service << EOF
[Unit]
Description=MySQL Server
After=network.target
[Service]
User=mysql
Group=mysql
ExecStart=/usr/sbin/mysqld --defaults-file=/etc/my.cnf
Restart=on-failure
LimitNOFILE=65535
[Install]
WantedBy=multi-user.target
EOF

# 重新加载配置并启动MySQL
systemctl daemon-reload
systemctl start mysqld
systemctl enable mysqld

# 解决socket路径不匹配问题(一劳永逸)
ln -s /var/lib/mysql/mysql.sock /tmp/mysql.sock

# 查看临时密码并修改为永久密码(Mysql123!)
temp_pwd=$(grep "temporary password" /data/mysql/localhost.localdomain.err | awk '{print $NF}')
mysql -uroot -p"$temp_pwd" --socket=/var/lib/mysql/mysql.sock -e "ALTER USER 'root'@'localhost' IDENTIFIED BY 'Mysql123!';"

# 验证登录(成功进入mysql>即为正常)
mysql -uroot -pMysql123!

三、主库(192.168.200.100)配置

1. 修改主库配置文件(开启 binlog + 字符集)

复制代码
cat > /etc/my.cnf << EOF
[mysqld]
server-id=1  # 主库唯一ID,不可与从库重复
log-bin=mysql-bin  # 开启二进制日志(主从核心)
datadir=/data/mysql
socket=/var/lib/mysql/mysql.sock
symbolic-links=0
log-error=/data/mysql/localhost.localdomain.err
pid-file=/data/mysql/localhost.localdomain.pid
binlog-ignore-db=mysql  # 忽略同步系统库
binlog-ignore-db=information_schema
# 中文支持配置
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
init_connect='SET NAMES utf8mb4'
[client]
default-character-set=utf8mb4
[mysql]
default-character-set=utf8mb4
EOF

# 重启主库使配置生效
systemctl restart mysqld

2. 创建复制用户并授权

复制代码
# 登录主库,创建repl用户(仅允许从库IP访问)
mysql -uroot -pMysql123! -e "
CREATE USER 'repl'@'192.168.200.101' IDENTIFIED BY 'Repl123@';
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.200.101';
FLUSH PRIVILEGES;
"

3. 锁定主库并备份数据

复制代码
# 锁定主库(禁止写入,保证备份一致性)
mysql -uroot -pMysql123! -e "FLUSH TABLES WITH READ LOCK;"

# 新开终端,备份主库所有数据
mysqldump -uroot -pMysql123! --all-databases --lock-all-tables > /root/master_backup.sql

# 查看主库binlog状态(记录File和Position,后续从库要用)
mysql -uroot -pMysql123! -e "show master status;"
# 示例输出:File=mysql-bin.000001,Position=154(以实际值为准)

# 解锁主库(备份完成后恢复写入)
mysql -uroot -pMysql123! -e "UNLOCK TABLES;"

# 把备份文件传到从库
scp /root/master_backup.sql root@192.168.200.101:/root/

四、从库(192.168.200.101)配置

1. 修改从库配置文件(开启中继日志 + 字符集)

复制代码
cat > /etc/my.cnf << EOF
[mysqld]
server-id=2  # 从库唯一ID,不可与主库重复
relay-log=mysql-relay-bin  # 开启中继日志(主从核心)
datadir=/data/mysql
socket=/var/lib/mysql/mysql.sock
symbolic-links=0
log-error=/data/mysql/localhost.localdomain.err
pid-file=/data/mysql/localhost.localdomain.pid
log-slave-updates=0  # 禁止从库写入binlog
replicate-ignore-db=mysql  # 与主库一致,忽略系统库
replicate-ignore-db=information_schema
# 中文支持配置
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
init_connect='SET NAMES utf8mb4'
[client]
default-character-set=utf8mb4
[mysql]
default-character-set=utf8mb4
EOF

# 重启从库使配置生效
systemctl restart mysqld

2. 解决 UUID 重复问题(关键避坑)

复制代码
# 停止从库服务
systemctl stop mysqld

# 删除旧UUID文件(重启后自动生成新UUID)
rm -f /data/mysql/auto.cnf

# 重启从库
systemctl start mysqld

# 验证UUID(主库和从库UUID不同即为成功)
mysql -uroot -pMysql123! -e "SELECT @@server_uuid;"

3. 导入主库备份数据

复制代码
# 导入主库备份(确保主从数据一致)
mysql -uroot -pMysql123! < /root/master_backup.sql

4. 配置主从连接并启动同步

复制代码
# 登录从库,执行同步配置(替换File和Position为从主库记录的值)
mysql -uroot -pMysql123! -e "
CHANGE MASTER TO
MASTER_HOST='192.168.200.100',
MASTER_USER='repl',
MASTER_PASSWORD='Repl123@',
MASTER_LOG_FILE='mysql-bin.000001',  # 主库show master status的File值
MASTER_LOG_POS=154;  # 主库show master status的Position值
"

# 启动从库同步
mysql -uroot -pMysql123! -e "START SLAVE;"

5. 处理重复创建用户错误(必做)

复制代码
# 跳过"重复创建repl用户"的SQL错误(备份已导入用户,binlog重复执行)
mysql -uroot -pMysql123! -e "
STOP SLAVE;
SET GLOBAL sql_slave_skip_counter=1;
START SLAVE;
"

五、最终验证(从库执行,确认成功)

1. 检查主从同步状态(核心验证)

复制代码
# 两个线程都为Yes即为成功
mysql -uroot -pMysql123! -e "show slave status\G;" | grep "Slave_IO_Running\|Slave_SQL_Running"

✅ 成功输出:

复制代码
Slave_IO_Running: Yes
Slave_SQL_Running: Yes

2. 验证中文数据同步(功能验证)

复制代码
# 主库执行:创建测试数据(含中文)
mysql -uroot -pMysql123! -e "
CREATE DATABASE IF NOT EXISTS test_sync;
USE test_sync;
CREATE TABLE IF NOT EXISTS student (id INT PRIMARY KEY AUTO_INCREMENT, name VARCHAR(20));
INSERT INTO student (name) VALUES ('测试主从同步'), ('小白中文测试');
"

# 从库执行:查询是否同步成功(中文正常显示无乱码)
mysql -uroot -pMysql123! -e "SELECT * FROM test_sync.student;"

✅ 成功输出:

复制代码
+----+------------------+
| id | name             |
+----+------------------+
|  1 | 测试主从同步     |
|  2 | 小白中文测试     |
+----+------------------+

六、后续优化(提升稳定性,可选但推荐)

1. 从库设置只读(避免误操作)

复制代码
mysql -uroot -pMysql123! -e "
SET GLOBAL read_only=1;
SET GLOBAL super_read_only=1;
"

2. 主库设置 binlog 过期清理(避免磁盘占满)

复制代码
mysql -uroot -pMysql123! -e "
SET GLOBAL expire_logs_days=7;
PURGE BINARY LOGS BEFORE DATE_SUB(NOW(), INTERVAL 7 DAY);
"

3. 创建同步监控脚本(快速检查状态)

复制代码
cat > /root/check_repl.sh << EOF
#!/bin/bash
result=\$(mysql -uroot -pMysql123! -e "show slave status\G;" | grep "Slave_IO_Running\|Slave_SQL_Running")
echo "主从同步状态(\$(date)):"
echo "\$result"
echo "\$result" | grep -q "No" && echo "⚠️  同步异常!执行:mysql -uroot -pMysql123! -e 'show slave status\G;' | grep 'Last_IO_Error\|Last_SQL_Error' 查看错误"
EOF
chmod +x /root/check_repl.sh

总结:

按以上流程执行后,主从复制已完全搭建成功,具备以下特性:

  1. 主从通信正常(IO+SQL 线程双 Yes);
  2. 数据实时同步(主库增删改自动同步到从库);
  3. 支持中文存储(无乱码、无插入报错);
  4. 避开所有坑(socket 路径、服务崩溃、UUID 重复、数据不一致等)。

日常使用直接在主库操作,从库自动同步,无需额外干预!

相关推荐
恋猫de小郭1 小时前
Android Studio Otter 2 Feature 发布,最值得更新的 Android Studio
android·前端·flutter
走在路上的菜鸟1 小时前
Android学Dart学习笔记第十二节 函数
android·笔记·学习·flutter
没有了遇见1 小时前
Android + Google Play:老项目适配实战指南
android·google
怀君2 小时前
Uniapp——开发Android插件教程
android·uni-app
Lei活在当下2 小时前
【Perfetto从入门到精通】1. 初识 Perfetto
android·性能优化·架构
用户41659673693552 小时前
深度解析 Android 权限机制:从清单注册到 Android 14 适配实战
android
Nerve3 小时前
GalleryPicker:一个基于 Android 官方 Photo Picker API 封装的现代图片/视频选择库
android
伐尘5 小时前
【MySQL】MySQL 有效利用 profile 分析 SQL 语句的执行过程
android·sql·mysql
Haha_bj5 小时前
七、Kotlin——扩展(Extensions)
android·kotlin