# MySQL主从复制搭建教程
MySQL主从复制是数据库高可用和读写分离的重要方案,本文详细介绍MySQL 8.0主从复制的搭建过程。
## 一、主从复制原理
MySQL主从复制基于二进制日志(binlog)实现,主要包含三个线程:
1. **Binlog Dump线程**:Master节点将binlog发送给Slave
2. **I/O线程**:Slave节点接收Master的binlog并写入中继日志(relay log)
3. **SQL线程**:Slave节点读取中继日志并执行SQL语句
复制过程:
- Master记录数据变更到binlog
- Slave的I/O线程请求binlog
- Master的Dump线程发送binlog
- Slave的I/O线程写入relay log
- Slave的SQL线程执行relay log中的SQL
## 二、环境准备
服务器规划:
- Master: 192.168.1.10:3306
- Slave: 192.168.1.11:3306
系统要求:
- 操作系统:CentOS 7+ / Ubuntu 18.04+
- MySQL版本:MySQL 8.0+
- 网络:服务器之间网络互通
- 防火墙:开放3306端口
## 三、安装MySQL
CentOS安装:
# 下载MySQL 8.0仓库
wget https://dev.mysql.com/get/mysql80-community-release-el7-3.noarch.rpm
rpm -ivh mysql80-community-release-el7-3.noarch.rpm
# 安装MySQL
yum install -y mysql-server
# 启动MySQL
systemctl start mysqld
systemctl enable mysqld
# 查看临时密码
grep 'temporary password' /var/log/mysqld.log
Ubuntu安装:
# 更新软件源
apt-get update
# 安装MySQL
apt-get install -y mysql-server
# 启动MySQL
systemctl start mysql
systemctl enable mysql
## 四、配置Master节点
编辑Master配置文件 `/etc/my.cnf`:
[mysqld]
# 服务器ID,必须唯一
server-id = 1
# 启用二进制日志
log-bin = mysql-bin
# binlog格式,建议使用ROW
binlog-format = ROW
# 需要复制的数据库
binlog-do-db = mydb
# 不需要复制的数据库
binlog-ignore-db = mysql
binlog-ignore-db = information_schema
binlog-ignore-db = performance_schema
binlog-ignore-db = sys
# binlog过期时间,默认7天
expire_logs_days = 7
# binlog大小限制
max_binlog_size = 100M
# GTID模式(推荐)
gtid-mode = ON
enforce-gtid-consistency = ON
重启MySQL:
## 五、创建复制用户
登录MySQL:
创建复制用户:
-- 创建复制用户
CREATE USER 'repl'@'192.168.1.11' IDENTIFIED BY 'Repl@2024';
-- 授权复制权限
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.1.11';
-- 刷新权限
FLUSH PRIVILEGES;
-- 查看Master状态
SHOW MASTER STATUS;
记录下 `File` 和 `Position` 的值,配置Slave时需要使用。
## 六、配置Slave节点
编辑Slave配置文件 `/etc/my.cnf`:
[mysqld]
# 服务器ID,必须唯一且不能与Master相同
server-id = 2
# 启用中继日志
relay-log = mysql-relay-bin
# 中继日志索引
relay-log-index = mysql-relay-bin.index
# 只读模式(可选)
read-only = 1
# 超级用户可写(可选)
super-read-only = 0
# GTID模式(推荐)
gtid-mode = ON
enforce-gtid-consistency = ON
重启MySQL:
## 七、配置主从复制
登录Slave MySQL:
执行以下命令:
-- 停止复制(如果之前配置过)
STOP SLAVE;
-- 配置Master信息
CHANGE MASTER TO
MASTER_HOST='192.168.1.10',
MASTER_USER='repl',
MASTER_PASSWORD='Repl@2024',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=154;
-- 启动复制
START SLAVE;
-- 查看复制状态
SHOW SLAVE STATUS\G
检查以下两个关键参数:
- `Slave_IO_Running: Yes` - I/O线程运行正常
- `Slave_SQL_Running: Yes` - SQL线程运行正常
如果都是Yes,说明主从复制配置成功!
## 八、使用GTID模式配置(推荐)
如果使用GTID模式,配置更简单:
在Slave上执行:
-- 停止复制
STOP SLAVE;
-- 配置Master信息(使用GTID)
CHANGE MASTER TO
MASTER_HOST='192.168.1.10',
MASTER_USER='repl',
MASTER_PASSWORD='Repl@2024',
MASTER_AUTO_POSITION = 1;
-- 启动复制
START SLAVE;
-- 查看复制状态
SHOW SLAVE STATUS\G
## 九、验证主从复制
在Master上创建测试数据:
-- 创建数据库
CREATE DATABASE mydb;
USE mydb;
-- 创建表
CREATE TABLE users (
id INT AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(50),
email VARCHAR(100)
);
-- 插入数据
INSERT INTO users (name, email) VALUES ('张三', 'zhangsan@example.com');
INSERT INTO users (name, email) VALUES ('李四', 'lisi@example.com');
-- 查询数据
SELECT * FROM users;
在Slave上验证:
-- 查看数据库
SHOW DATABASES;
-- 查询数据
USE mydb;
SELECT * FROM users;
如果Slave上能看到相同的数据,说明主从复制正常!
## 十、监控主从复制
查看Slave状态:
关键指标:
- `Slave_IO_Running` - I/O线程状态
- `Slave_SQL_Running` - SQL线程状态
- `Seconds_Behind_Master` - 延迟时间(0表示无延迟)
- `Last_IO_Error` - I/O线程错误信息
- `Last_SQL_Error` - SQL线程错误信息
- `Executed_Gtid_Set` - 已执行的GTID集合
查看Master状态:
查看binlog信息:
SHOW BINARY LOGS;
SHOW BINLOG EVENTS IN 'mysql-bin.000001' LIMIT 10;
## 十一、常见问题处理
### 1. 复制延迟
查看延迟时间:
SHOW SLAVE STATUS\G
-- 查看 Seconds_Behind_Master
解决方法:
- 优化Slave硬件配置
- 减少Slave上的写操作
- 使用并行复制(MySQL 5.7+)
- 调整 `slave_parallel_workers` 参数
### 2. 复制中断
查看错误信息:
SHOW SLAVE STATUS\G
-- 查看 Last_IO_Error 和 Last_SQL_Error
跳过错误(谨慎使用):
-- 跳过一个事务
SET GLOBAL sql_slave_skip_counter = 1;
START SLAVE;
### 3. 主键冲突
在Slave配置中添加:
# /etc/my.cnf
slave-skip-errors = 1062
### 4. 连接失败
检查网络连通性:
ping 192.168.1.10
telnet 192.168.1.10 3306
检查防火墙:
# CentOS
firewall-cmd --add-port=3306/tcp --permanent
firewall-cmd --reload
# Ubuntu
ufw allow 3306/tcp
## 十二、主从切换
当Master故障时,可以将Slave提升为Master:
1. 停止Slave复制:
STOP SLAVE;
RESET SLAVE ALL;
2. 修改Slave为可写:
SET GLOBAL read_only = OFF;
3. 更新应用配置,连接到新的Master
4. 将原Master配置为Slave(如果恢复)
## 十三、读写分离
应用层实现读写分离:
Python示例:
import pymysql
# 写操作(Master)
master_conn = pymysql.connect(
host='192.168.1.10',
user='root',
password='password',
database='mydb'
)
# 读操作(Slave)
slave_conn = pymysql.connect(
host='192.168.1.11',
user='root',
password='password',
database='mydb'
)
# 写入
with master_conn.cursor() as cursor:
cursor.execute("INSERT INTO users (name, email) VALUES (%s, %s)", ('王五', 'wangwu@example.com'))
master_conn.commit()
# 读取
with slave_conn.cursor() as cursor:
cursor.execute("SELECT * FROM users")
results = cursor.fetchall()
print(results)
## 十四、备份策略
### Master备份
全量备份:
mysqldump -u root -p --all-databases --single-transaction --master-data=2 > backup.sql
增量备份(基于binlog):
mysqlbinlog --start-datetime="2024-01-01 00:00:00" mysql-bin.000001 > incremental.sql
### Slave备份
Slave可以用于备份,不影响Master性能:
mysqldump -u root -p --all-databases --single-transaction > slave_backup.sql
## 十五、性能优化
### Master优化
# /etc/my.cnf
# 增大binlog缓存
binlog_cache_size = 4M
# 增大binlog大小
max_binlog_size = 500M
# 启用GTID
gtid-mode = ON
enforce-gtid-consistency = ON
### Slave优化
# /etc/my.cnf
# 并行复制
slave_parallel_workers = 4
slave_parallel_type = LOGICAL_CLOCK
# 增大中继日志
max_relay_log_size = 500M
# 减少复制延迟
slave_pending_jobs_size_max = 128M
## 十六、安全加固
1. **使用SSL加密复制**
# Master配置
ssl-ca = /etc/mysql/ssl/ca.pem
ssl-cert = /etc/mysql/ssl/server-cert.pem
ssl-key = /etc/mysql/ssl/server-key.pem
# Slave配置
MASTER_SSL=1
MASTER_SSL_CA=/etc/mysql/ssl/ca.pem
2. **限制复制用户权限**
-- 只授予必要的权限
GRANT REPLICATION SLAVE ON *.* TO 'repl'@'192.168.1.11';
3. **定期更换复制密码**
ALTER USER 'repl'@'192.168.1.11' IDENTIFIED BY 'NewPassword@2024';
## 十七、最佳实践
1. **使用GTID模式**:更易于管理和故障恢复
2. **定期监控**:监控复制状态和延迟
3. **备份策略**:定期备份Master和Slave
4. **测试切换**:定期演练主从切换
5. **文档记录**:记录配置和变更
6. **版本一致**:Master和Slave版本尽量一致
7. **时间同步**:确保服务器时间同步
8. **网络优化**:确保网络稳定和带宽充足
## 总结
MySQL主从复制是数据库高可用的重要方案,通过本文的介绍,你应该能够:
1. 理解MySQL主从复制的原理
2. 成功搭建MySQL主从复制
3. 监控和维护主从复制
4. 处理常见问题
5. 实现读写分离
6. 进行备份和恢复
记住:在生产环境中,务必做好充分的测试和监控!
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。