MySQL 主从复制详解:部署与进阶配置
一、MySQL 主从复制介绍
1.1 什么是主从复制
MySQL 主从复制是指将主库的 DDL 和 DML 操作通过二进制日志(binlog)传到从库服务器中,然后在从库上对这些日志重新执行(重做),从而使得从库和主库的数据保持一致。
MySQL 支持灵活的复制架构:
- 一台主库可同时向多台从库复制
- 从库也可作为其他从服务器的主库,实现链状复制
2.2 思路详解:
在主服务器(master)上:
启用二进制日志
选择一个唯一的server-id
创建具有复制权限的用户
在从服务器(slave)上:
启用中继日志
(二进制日志可开启,也可不开启)
选择一个唯一的server-id
连接至主服务器,并开始复制
二、MySQL 主从复制实现步骤
2.1 环境说明
主机名 | IP 地址 | 操作系统 | MySQL 版本 |
---|---|---|---|
master | 192.168.2.200 | rhel7.9 | 源码安装 mysql8.0.40 |
rep1 | 192.168.2.129 | rhel7.9 | 源码安装 mysql8.0.40 |
源码部署 MySQL8.0.40(主从库均需执行)
2.2初始化配置
注意:如果是重新配置 MySQL 实例,或者需要重新初始化时,需要先清理原有数据
# 停止服务
[root@master ~]# /etc/init.d/mysqld stop
# 清理原有数据(仅重新初始化时使用)
[root@master ~]# rm -rf /data/mysql/*
# 查看配置文件确认数据目录设置
[root@master ~]# cat /etc/my.cnf
[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
# 配置启动脚本
[root@master ~]# cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
# 设置环境变量
[root@master ~]# echo "export PATH=\$PATH:/usr/local/mysql/bin" >> /etc/profile
[root@master ~]# source /etc/profile
# 创建运行用户和数据目录
[root@master ~]# useradd -M -s /sbin/nologin mysql
[root@master ~]# mkdir -p /data/mysql && chown -R mysql:mysql /data/
# 初始化数据库
[root@master ~]# mysqld --initialize --user=mysql # 记录临时密码
# 启动服务并修改密码
[root@master ~]# /etc/init.d/mysqld start
[root@master ~]# mysqladmin -uroot -p password '123' # 替换为实际密码
# 登录验证
[root@master ~]# mysql -uroot -p123
2.2 配置主从同步
(1)主库配置(192.168.2.200)
# 修改配置文件
[root@master ~]# vim /etc/my.cnf
[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
server_id=200 # 唯一标识
log-bin=binlog # 开启二进制日志
# 重启数据库
[root@master ~]# /etc/init.d/mysqld restart
# 创建同步账号
[root@master ~]# mysql -uroot -p123
mysql> create user 'rep'@'%' identified by 'rep123';
mysql> grant replication slave on *.* to 'rep'@'%';
mysql> show grants for 'rep'@'%'; # 验证权限
# 锁表设置只读(备份前操作)
mysql> flush tables with read lock;
# 查看主库状态(记录文件名和Position)
mysql> show master status;
+---------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+---------------+----------+--------------+------------------+-------------------+
| binlog.000002 | 1022 | | | |
+---------------+----------+--------------+------------------+-------------------+
#注意:如果想要重置主库,可以使用reset master
# 备份主库数据
mysqldump -uroot -p -A -B |gzip > /server/backup/mysql_bak.$(date +%F).sql.gz
# 解锁表
mysql> unlock tables;
# 将备份数据传到从库
scp /server/backup/mysql_bak.2025-09-05.sql.gz 192.168.2.129:/server/backup
(2)从库配置(192.168.2.129)
# 修改配置文件
[root@rep1 ~]# cat /etc/my.cnf
[mysqld]
datadir=/data/mysql
socket=/data/mysql/mysql.sock
server_id=129 # 唯一标识,与主库不同
# 重启数据库
[root@rep1 ~]# /etc/init.d/mysqld restart
# 还原主库备份数据
# cd /server/backup/
# gzip -d mysql_bak.2025-08-07.sql.gz
# mysql -uroot -p < mysql_bak.2025-08-07.sql
# 3. 配置同步参数
mysql> CHANGE REPLICATION SOURCE TO
SOURCE_HOST='192.168.2.200',
SOURCE_USER='rep',
SOURCE_PASSWORD='rep123',
SOURCE_LOG_FILE='binlog.000002', # 主库show master status显示的文件名
SOURCE_LOG_POS=1022, # 主库show master status显示的Position值
SOURCE_SSL=1;
# 4. 启动同步
mysql> start replica;
# 5. 检查同步状态
mysql> show replica status\G
# 确保以下两个参数为Yes
# Slave_IO_Running: Yes
# Slave_SQL_Running: Yes
(3)验证主从同步
# 主库创建测试数据库
[root@master ~]# mysql -uroot -p -e 'create database test1;'
# 从库查看是否同步
[root@rep1 ~]# mysql -uroot -p -e 'show databases;'
# 应能看到test1数据库
三、主从复制进阶配置
3.1 延时同步
延时同步可解决误操作导致的数据丢失问题,配置方法:
# 配置从库延时300秒同步
mysql> stop replica;
mysql> CHANGE REPLICATION SOURCE TO SOURCE_DELAY = 300;
mysql> start replica;
# 查看延时配置
mysql> show replica status\G
# 查看SQL_Delay: 300 确认配置生效
误操作恢复流程:
发现误操作后立即停止 SQL 线程:
stop slave sql_thread;
找到误删前relay log的起点和终点
show replica status\G
查找误操作在 relay log 中的位置:
show relaylog events in "slave1-relay-bin.000002";
备份误操作前的 relay log:
mysqlbinlog --start-position=323 --stop-position=1053 /data/mysql/slave1-relay-bin.000002 > /tmp/relay.sql
恢复数据:
mysql -uroot -p -e 'source /tmp/relay.sql'
解除从库身份:
stop replica;
reset replica all;
3.2 GTID 复制
GTID(全局事务 ID)为每个提交的事务唯一 ID,简化同步位置管理。
配置 GTID 复制:
# 主从库均执行以下步骤
# 1. 检查并启用GTID一致性检查
mysql> set global enforce_gtid_consistency=warn; # 检查兼容性
mysql> set global enforce_gtid_consistency=on;
# 2. 逐步切换GTID模式
mysql> set global gtid_mode=OFF_PERMISSIVE;
mysql> set global gtid_mode=ON_PERMISSIVE;
# 3. 等待匿名事务完成
mysql> show status like 'ongoing_anonymous_transaction_count';
# 确保Value为0
# 4. 启用GTID模式
mysql> set global gtid_mode=ON;
# 5. 从库切换到GTID同步
mysql> stop replica;
mysql> change master to master_auto_position=1;
mysql> start replica;
mysql> show replica status \G
Replica_IO_Running: Yes
Replica_SQL_Running: Yes
3.3 半同步复制
半同步复制确保主库在收到至少一个从库的 ACK 确认后才完成事务提交,提高数据安全性。
主库配置:
# 安装插件
mysql> install plugin rpl_semi_sync_master soname 'semisync_master.so';
# 启用半同步
mysql> set global rpl_semi_sync_master_enabled=1;
# 设置超时时间(毫秒)
mysql> set global rpl_semi_sync_master_timeout=3000;
从库配置:
# 安装插件
mysql> install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
# 启用半同步
mysql> set global rpl_semi_sync_slave_enabled=1;
# 重启IO线程
mysql> STOP REPLICA IO_THREAD;
mysql> START REPLICA IO_THREAD;
四、生产环境常用配置
忽略指定数据库的 binlog 记录:
[mysqld] binlog_ignore_db="information_schema" binlog_ignore_db="mysql" binlog_ignore_db="test"
从库开启 binlog(级联复制):
[mysqld] log-slave-updates # 从库同步的事务记录到自己的binlog log_bin = mysql-bin expire_logs_days = 7 # 日志保留7天
从库只读设置:
[mysqld] read-only innodb_read_only = 1
总结
MySQL 主从复制是构建高可用、高并发数据库系统的基础,通过本文介绍的方法可以实现基本的主从同步架构。在实际生产环境中,还需根据业务需求选择合适的复制模式(异步 / 半同步 / 全同步)、合理配置 GTID 和延时同步,以平衡数据一致性、性能和安全性。定期监控主从同步状态,确保数据同步正常,是保障系统稳定运行的关键