以下是线上搭建 MySQL 主从复制(Master-Slave)的详细方案,适用于生产环境,涵盖环境准备、配置步骤、验证及运维注意事项:
一、环境准备
1. 服务器规划
| 角色 | IP地址 | 操作系统 | MySQL版本 | 备注 |
|---|---|---|---|---|
| Master | 192.168.1.10 | CentOS 7 | 8.0.36 | 主库,业务写入节点 |
| Slave | 192.168.1.11 | CentOS 7 | 8.0.36 | 从库,只读,用于备份/查询 |
2. 前置条件
-
主从服务器 MySQL 版本一致(避免因版本差异导致的复制兼容性问题)。
-
主从服务器时间同步(建议通过 NTP 服务,
ntpd或chronyd)。 -
主库开启
binlog日志(主从复制依赖 binlog)。 -
主从服务器网络互通,Master 需开放 3306 端口(或自定义端口),Slave 能访问 Master 的该端口。
-
关闭或配置防火墙(
firewalld或iptables),允许主从通信:bash# Master 开放 3306 端口 firewall-cmd --zone=public --add-port=3306/tcp --permanent firewall-cmd --reload
二、Master 主库配置
1. 修改 MySQL 配置文件(my.cnf 或 mysqld.cnf)
配置文件路径通常为 /etc/my.cnf 或 /etc/mysql/mysql.conf.d/mysqld.cnf,添加以下参数:
ini
[mysqld]
# 开启 binlog,指定日志文件前缀
log_bin = /var/lib/mysql/mysql-bin
# 服务器唯一 ID(1-255,主从不能重复)
server-id = 10
# binlog 格式(推荐 row 模式,记录数据行变更,兼容性好)
binlog_format = ROW
# 不需要同步的数据库(可选,多个用逗号分隔)
binlog-ignore-db = information_schema
binlog-ignore-db = mysql
binlog-ignore-db = performance_schema
binlog-ignore-db = sys
# 自动清理 7 天前的 binlog(避免磁盘占满)
expire_logs_days = 7
# 同步时忽略主从的服务器 ID 冲突(可选)
log-slave-updates = 0
2. 重启 MySQL 服务
bash
systemctl restart mysqld
# 确认状态
systemctl status mysqld
3. 主库创建用于复制的账号
登录 Master MySQL,创建一个仅用于从库复制的账号(限制 IP 为 Slave 地址,增强安全性):
sql
-- 登录主库
mysql -u root -p
-- 创建复制账号(用户名:repl,密码:Repl@123456,允许从 192.168.1.11 连接)
CREATE USER 'repl'@'192.168.1.11' IDENTIFIED BY 'Repl@123456';
-- 授予复制权限
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.1.11';
-- 刷新权限
FLUSH PRIVILEGES;
4. 锁定主库并获取 binlog 信息
为避免配置期间主库数据变更,先锁定主库(仅禁止写入,允许读取):
sql
-- 锁定主库
FLUSH TABLES WITH READ LOCK;
-- 查看当前 binlog 文件名和位置(记录 File 和 Position,后续从库配置需要)
SHOW MASTER STATUS;
输出示例:
+------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+------------------+----------+--------------+------------------+-------------------+
| mysql-bin.000001 | 154 | | information_schema,mysql,performance_schema,sys | |
+------------------+----------+--------------+------------------+-------------------+
记录 File(如 mysql-bin.000001)和 Position(如 154)。
三、Slave 从库配置
1. 备份主库数据并恢复到从库
主库锁定后,通过 mysqldump 备份数据(确保从库初始数据与主库一致):
bash
# 在 Master 服务器执行,备份所有库(排除忽略的系统库)
mysqldump -u root -p --all-databases --ignore-db=information_schema --ignore-db=mysql --ignore-db=performance_schema --ignore-db=sys > master_data.sql
将备份文件传到 Slave 服务器:
bash
scp master_data.sql root@192.168.1.11:/tmp/
在 Slave 服务器恢复数据:
bash
# 登录 Slave MySQL,先创建与主库一致的数据库(如果有自定义库)
mysql -u root -p
CREATE DATABASE IF NOT EXISTS your_db;
exit
# 恢复数据
mysql -u root -p < /tmp/master_data.sql
恢复完成后,解锁主库(在 Master MySQL 中执行):
sql
UNLOCK TABLES;
2. 修改 Slave 配置文件(my.cnf)
ini
[mysqld]
# 从库唯一 ID(与主库不同)
server-id = 11
# 从库日志(可选,用于级联复制,即从库作为其他库的主库时需要)
relay_log = /var/lib/mysql/mysql-relay-bin
# 从库只读(禁止写入,增强数据一致性)
read_only = 1
# 忽略同步的数据库(与主库保持一致)
replicate-ignore-db = information_schema
replicate-ignore-db = mysql
replicate-ignore-db = performance_schema
replicate-ignore-db = sys
3. 重启 Slave MySQL 服务
bash
systemctl restart mysqld
systemctl status mysqld
4. 配置从库连接主库
登录 Slave MySQL,配置主从复制参数(使用主库的 binlog 信息和复制账号):
sql
-- 登录从库
mysql -u root -p
-- 停止从库复制进程(如果之前配置过)
STOP SLAVE;
-- 配置主库信息
CHANGE MASTER TO
MASTER_HOST = '192.168.1.10', -- 主库 IP
MASTER_USER = 'repl', -- 复制账号用户名
MASTER_PASSWORD = 'Repl@123456', -- 复制账号密码
MASTER_LOG_FILE = 'mysql-bin.000001', -- 主库 binlog 文件名(从 SHOW MASTER STATUS 获取)
MASTER_LOG_POS = 154; -- 主库 binlog 位置(从 SHOW MASTER STATUS 获取)
-- 启动从库复制进程
START SLAVE;
四、验证主从复制
1. 查看从库状态
在 Slave MySQL 中执行:
sql
SHOW SLAVE STATUS\G
重点关注以下两个参数,均为 Yes 表示复制正常:
Slave_IO_Running: Yes(从库 I/O 线程正常,负责读取主库 binlog 到本地 relay log)Slave_SQL_Running: Yes(从库 SQL 线程正常,负责执行 relay log 中的 SQL)
2. 数据同步测试
-
在 Master 中创建测试表并插入数据:
sqlCREATE DATABASE IF NOT EXISTS test_db; USE test_db; CREATE TABLE test_table (id INT PRIMARY KEY, name VARCHAR(20)); INSERT INTO test_table VALUES (1, 'test'); -
在 Slave 中查询,确认数据已同步:
sqlUSE test_db; SELECT * FROM test_table; -- 若输出 (1, 'test'),则复制成功
五、运维注意事项
-
binlog 管理:
- 主库定期清理 binlog(通过
expire_logs_days或手动PURGE BINARY LOGS),避免磁盘占满。 - 从库延迟时,不要轻易删除主库未同步的 binlog。
- 主库定期清理 binlog(通过
-
从库延迟监控:
- 关注
SHOW SLAVE STATUS中的Seconds_Behind_Master(延迟秒数),正常应为 0。 - 可通过 Prometheus + Grafana 监控主从延迟,设置告警阈值(如延迟 > 30 秒)。
- 关注
-
主从切换:
-
若主库故障,需手动将从库提升为主库:
sql-- 在 Slave 执行 STOP SLAVE; RESET SLAVE ALL; -- 清除主从配置 -- 从库设置为可写(如需) SET GLOBAL read_only = 0;
-
-
安全加固:
- 复制账号限制 IP(如
repl@192.168.1.11),避免全网访问。 - 定期更换复制账号密码。
- 主从库开启 SSL 加密复制(可选,增强传输安全性)。
- 复制账号限制 IP(如
-
版本升级:
- 升级时先升级从库,再升级主库(避免主库版本高于从库导致的兼容性问题)。
通过以上步骤,可搭建一套稳定的 MySQL 主从复制架构,实现数据备份和读写分离基础。生产环境中建议结合监控工具(如 Percona Monitoring and Management)实时跟踪复制状态。
在生产环境中,为了避免业务中断,通常需要在不停服的情况下搭建 MySQL 主从复制。核心思路是:通过在线备份主库数据(不锁表或仅短暂锁表),确保从库初始化数据与主库一致,同时记录主库的 binlog 位置,最终实现主从同步。以下是详细步骤:
mysql不停服主从复制
一、环境准备(同前,补充不停服关键点)
| 角色 | IP地址 | 操作系统 | MySQL版本 | 备注 |
|---|---|---|---|---|
| Master | 192.168.1.10 | CentOS 7 | 8.0.36 | 主库,业务正常运行 |
| Slave | 192.168.1.11 | CentOS 7 | 8.0.36 | 从库,全新安装或待同步 |
关键前提:
- 主库已开启
binlog(若未开启,需临时开启,但会重启 MySQL,建议提前规划)。 - 主从服务器时间同步(
chronyd或ntpd),网络互通(3306 端口开放)。 - 确保主库有足够磁盘空间用于备份(
mysqldump或xtrabackup备份文件)。
二、Master 主库配置(不停服核心步骤)
1. 确认主库 binlog 已开启
登录主库,检查 binlog 状态:
sql
mysql -u root -p
SHOW VARIABLES LIKE 'log_bin'; -- 若 Value 为 ON,说明已开启
SHOW VARIABLES LIKE 'server_id'; -- 确保 server_id 已设置(非 0)
若未开启 binlog,需修改 my.cnf 并重启主库(会短暂停服,建议避开业务高峰):
ini
[mysqld]
log_bin = /var/lib/mysql/mysql-bin
server-id = 10 # 主库唯一 ID
binlog_format = ROW # 推荐 row 模式
重启后再次确认 binlog 已开启。
2. 创建复制账号(不停服)
在主库创建用于从库复制的账号(限制从库 IP,避免安全风险):
sql
-- 登录主库
mysql -u root -p
-- 创建账号(用户名 repl,允许从 192.168.1.11 连接)
CREATE USER 'repl'@'192.168.1.11' IDENTIFIED BY 'Repl@123456';
-- 授予复制权限
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.1.11';
-- 刷新权限
FLUSH PRIVILEGES;
3. 在线备份主库数据(核心:不锁表或短暂锁表)
为避免锁表影响业务,推荐使用 Percona XtraBackup (支持热备份,不锁表),或 mysqldump 加 --single-transaction 参数(适用于 InnoDB 引擎,非阻塞备份)。
方案 1:使用 Percona XtraBackup(推荐,适合大库)
XtraBackup 是开源工具,支持 InnoDB 热备份,备份过程不锁表,适合生产环境。
-
安装 XtraBackup(主库执行):
bash# 安装依赖 yum install -y https://repo.percona.com/yum/percona-release-latest.noarch.rpm percona-release enable-only tools release yum install -y percona-xtrabackup-80 # 对应 MySQL 8.0 -
全量备份主库(不锁表,后台执行):
bash# 创建备份目录 mkdir -p /data/backup/mysql_full chown -R mysql:mysql /data/backup # 执行备份(记录 binlog 位置,后续从库需要) xtrabackup --user=root --password=你的主库密码 --backup --target-dir=/data/backup/mysql_full/备份完成后,查看备份目录下的
xtrabackup_binlog_info文件,记录 binlog 文件名 和 Position (例如:mysql-bin.000003 156),这是主从同步的起点。
方案 2:使用 mysqldump(适合小库,简单易用)
mysqldump 加 --single-transaction 参数可实现 InnoDB 引擎的非阻塞备份(MyISAM 仍会锁表,需注意)。
-
备份主库数据并记录 binlog 位置 :
bash# 先获取当前 binlog 位置(备份开始时的状态) mysql -u root -p -e "SHOW MASTER STATUS\G" > /tmp/master_status.txt # 备份所有库(--single-transaction 确保 InnoDB 一致性,不锁表) mysqldump -u root -p --all-databases --single-transaction --flush-logs --master-data=2 > /data/backup/master_data.sql--flush-logs:备份后刷新 binlog,生成新的 binlog 文件(便于后续定位)。--master-data=2:在备份文件中记录 binlog 位置(注释状态,不执行),可打开master_data.sql查看(搜索CHANGE MASTER TO)。
三、Slave 从库配置(基于主库备份恢复)
1. 初始化从库(确保与主库版本一致)
从库需安装与主库相同版本的 MySQL,且初始状态为空(若已有数据,需先清理):
bash
# 停止从库 MySQL
systemctl stop mysqld
# 清理默认数据目录(注意:会删除所有数据,谨慎操作)
rm -rf /var/lib/mysql/*
2. 恢复主库备份到从库
若使用 XtraBackup 备份:
-
将备份文件传到从库:
bashscp -r /data/backup/mysql_full root@192.168.1.11:/data/backup/ -
在从库恢复备份:
bash# 准备备份(确保数据一致性) xtrabackup --prepare --target-dir=/data/backup/mysql_full/ # 恢复到从库数据目录 xtrabackup --copy-back --target-dir=/data/backup/mysql_full/ # 修改权限(MySQL 需有权限访问) chown -R mysql:mysql /var/lib/mysql/
若使用 mysqldump 备份:
-
将备份文件传到从库:
bashscp /data/backup/master_data.sql root@192.168.1.11:/tmp/ -
在从库恢复数据:
bash# 启动从库 MySQL(确保数据目录为空) systemctl start mysqld # 恢复备份(若备份文件大,可加 & 后台执行) mysql -u root -p < /tmp/master_data.sql
3. 配置从库 my.cnf
ini
[mysqld]
server-id = 11 # 从库唯一 ID,与主库不同
relay_log = /var/lib/mysql/mysql-relay-bin # 中继日志
read_only = 1 # 从库只读(root 可写,若需严格只读,可设置 super_read_only=1)
replicate-ignore-db = information_schema # 忽略系统库(可选)
replicate-ignore-db = mysql
replicate-ignore-db = performance_schema
replicate-ignore-db = sys
重启从库 MySQL:
bash
systemctl restart mysqld
4. 配置从库连接主库(关键:使用备份时的 binlog 位置)
登录从库 MySQL,设置主从同步参数:
sql
mysql -u root -p
-- 停止可能存在的复制进程
STOP SLAVE;
-- 配置主库信息(替换为实际值)
CHANGE MASTER TO
MASTER_HOST = '192.168.1.10', -- 主库 IP
MASTER_USER = 'repl', -- 复制账号
MASTER_PASSWORD = 'Repl@123456', -- 复制密码
MASTER_LOG_FILE = 'mysql-bin.000003', -- 备份时记录的 binlog 文件名
MASTER_LOG_POS = 156; -- 备份时记录的 Position
-- 启动从库复制
START SLAVE;
四、验证主从同步(不停服验证)
1. 检查从库状态
在从库执行:
sql
SHOW SLAVE STATUS\G
重点关注:
Slave_IO_Running: Yes(I/O 线程正常,负责拉取主库 binlog)Slave_SQL_Running: Yes(SQL 线程正常,负责执行中继日志)Seconds_Behind_Master: 0(无延迟,若为 NULL 或正值,需排查问题)
2. 业务数据验证
在主库执行写入操作(模拟业务):
sql
-- 主库创建测试数据
CREATE DATABASE IF NOT EXISTS test_sync;
USE test_sync;
CREATE TABLE t1 (id INT PRIMARY KEY, name VARCHAR(20));
INSERT INTO t1 VALUES (1, '不停服同步测试');
在从库查询,确认数据已同步:
sql
USE test_sync;
SELECT * FROM t1; -- 若返回 (1, '不停服同步测试'),则成功
五、关键注意事项(不停服场景)
-
备份期间的数据一致性:
- XtraBackup 或
mysqldump --single-transaction仅保证 InnoDB 引擎的一致性,MyISAM 表仍会锁表(建议业务尽量使用 InnoDB)。 - 若有 MyISAM 表,需在业务低峰期执行,或短暂锁表(
FLUSH TABLES WITH READ LOCK)后备份,锁表时间越短越好。
- XtraBackup 或
-
主库 binlog 保留:
- 从备份完成到从库启动同步前,主库的 binlog 不能被删除(否则从库会因缺少 binlog 导致同步失败)。
- 临时关闭主库的 binlog 自动清理(
SET GLOBAL expire_logs_days = 0;),同步正常后再恢复。
-
从库延迟处理:
- 若从库延迟(
Seconds_Behind_Master增大),检查主库写入压力是否过大,或从库配置(如innodb_buffer_pool_size)是否过低。 - 可通过
pt-query-digest分析主库慢查询,优化后减少从库压力。
- 若从库延迟(
-
安全加固:
- 复制账号密码使用强密码,并定期更换。
- 主从通信建议开启 SSL 加密(在
CHANGE MASTER TO中添加MASTER_SSL=1)。
-
监控配置:
- 部署监控工具(如 Percona PMM、Zabbix),监控
Slave_IO_Running、Slave_SQL_Running和延迟时间,设置告警(如延迟 > 60 秒)。
- 部署监控工具(如 Percona PMM、Zabbix),监控
通过以上步骤,可在不中断主库业务的情况下完成 MySQL 主从复制搭建,适用于生产环境的平滑扩容或灾备需求。核心是利用热备份工具确保数据一致性,并精准记录 binlog 位置作为同步起点。