MySQL 高可用架构实践:备份策略、主从复制与读写分离
一、数据备份的重要性与分类
在生产环境中,数据的安全性至关重要,任何数据的丢失都可能产生严重后果。
常见的数据丢失原因包括程序错误、人为误操作、运算错误、磁盘故障以及自然灾害等。
从物理与逻辑角度,数据库备份可分为两类:
-
物理备份:直接备份数据库操作系统的物理文件(如数据文件、日志文件等)
- 冷备份(脱机备份):在关闭数据库时进行
- 热备份(联机备份):数据库运行时进行,依赖于日志文件
- 温备份:数据库锁定表结构(可读不可写)时进行
-
逻辑备份:备份数据库逻辑组件(如表、视图等数据库对象)
二、常见备份方法与操作示例
1. 物理冷备份
物理冷备份在数据库关闭状态下直接打包数据文件,速度快且恢复简单。
bash
# 备份(推荐写法)
systemctl stop mysqld # 先停止服务
cd /usr/local/mysql/data
mkdir /mysql_bak
tar czf /mysql_bak/mysql-backup-$(date +%F).tar.gz *
systemctl start mysqld # 备份完成后启动服务
# 恢复操作
systemctl stop mysqld
tar xzf /mysql_bak/mysql-backup-2025-10-15.tar.gz -C /usr/local/mysql/data/
chown -R mysql:mysql /usr/local/mysql/data
systemctl start mysqld
2. 逻辑备份(mysqldump)
逻辑备份适用于跨版本迁移或部分数据恢复。
bash
# 备份单个数据库
mysqldump -u root -p school > /mysql_bak/school.sql #school库为自定义库举例
# 备份多个数据库
mysqldump -u root -p --databases school mysql > /mysql_bak/school-mysql.sql
# 备份所有数据库
mysqldump -u root -p --opt --all-databases > /mysql_bak/all.sql
# 备份特定表
mysqldump -u root -p school info > /mysql_bak/info.sql
# 恢复数据
mysql> source /mysql_bak/info.sql
3. 增量备份与二进制日志
增量备份基于二进制日志实现,适用于频繁更新的生产环境。
bash
# 启用二进制日志
vim /etc/my.cnf
[mysqld]
log-bin=mysql-bin #添加在mysqld段末尾
# 重启服务
systemctl restart mysqld.service
#先进行完整性备份
mysqldump -uroot -p school > /opt/school.sql
# 刷新日志
mysqladmin -uroot -p flush-logs
#新产生的mysql-bin.000002只记录上次刷新后的操作
ls /usr/local/mysql/data/
auto.cnf client-cert.pem ibdata1 ibtmp1 mysql-bin.000002 private_key.pem server-cert.pem
ca-key.pem client-key.pem ib_logfile0 mysql mysql-bin.index public_key.pem server-key.pem
ca.pem ib_buffer_pool ib_logfile1 mysql-bin.000001 performance_schema school sys
# 查看二进制日志内容
mysqlbinlog --no-defaults --base64-output=decode-rows -v /usr/local/mysql/data/mysql-bin.000003
# 插入新数据生产增量备份
mysql> insert into info (name,score,address,hobby) values ('小刚',75,'武汉',1);
# 刷新日志
mysqladmin -uroot -p flush-log
#新产生mysql-bin.000003日志记录insert操作
ls /usr/local/mysql/data/
auto.cnf client-cert.pem ibdata1 ibtmp1 mysql-bin.000002 performance_schema school sys
ca-key.pem client-key.pem ib_logfile0 mysql mysql-bin.000003 private_key.pem server-cert.pem
ca.pem ib_buffer_pool ib_logfile1 mysql-bin.000001 mysql-bin.index public_key.pem server-key.pem
# 恢复增量日志
mysqlbinlog --no-defaults /usr/local/mysql/data/mysql-bin.000003 | mysql -uroot -p
# 恢复时如果被拒绝,是有其他mysql进程占用了
三、主从复制原理与部署
主从复制架构概述
主从复制通过二进制日志实现数据同步,主要用于数据冗余、灾难恢复和负载均衡。

复制过程分为三步:
- Master将事务写入二进制日志
- Slave I/O线程读取Master二进制日志并写入中继日志
- Slave SQL线程重放中继日志中的事件
1. 时间同步
通过时间戳实现业务的一致性
bash
# 所有节点
ntpdate ntp1.aliyun.com
date -R
systemctl disable firewalld --now
setenforce 0
2. 主服务器配置(master)
bash
# 编辑配置文件
vim /etc/my.cnf
server-id = 11
log-bin = master-bin
log-slave-updates = true
# 创建复制用户
mysql> GRANT REPLICATION SLAVE ON *.* TO 'myslave'@'192.168.108.%' IDENTIFIED BY '123456';
mysql> FLUSH PRIVILEGES;
# 查看主服务器状态
mysql> show master status;
3. 从服务器配置(slave)
bash
# 避免UUID冲突(克隆环境)
systemctl stop mysqld
rm -f /usr/local/mysql/data/auto.cnf
systemctl start mysqld
# 编辑配置文件
vim /etc/my.cnf
server-id = 22
relay-log = relay-log-bin
relay-log-index = slave-relay-bin.index
# 配置主从关系
mysql> change master to
master_host='192.168.108.101',
master_user='myslave',
master_password='123456',
master_log_file='master-bin.000001',
master_log_pos=604;
# 启用并查询
mysql> start slave;
mysql> show slave status\G;
查询结果如下:

4. 主从同步验证
在主服务器创建测试数据:
sql
mysql> CREATE DATABASE school;
mysql> USE school;
mysql> CREATE TABLE student (
id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,
name VARCHAR(20) NOT NULL,
age TINYINT UNSIGNED,
gender ENUM('M','F') DEFAULT 'M'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
mysql> INSERT INTO student (name, age) VALUES ('李华', 20);
在从服务器验证数据同步:
sql
mysql> SELECT * FROM school.student;
四、读写分离架构实现
1. Amoeba中间件部署
Amoeba作为代理层,实现读写请求的自动分发。
bash
# 安装Java环境
chmod +x jdk-6u14-linux-x64.bin
./jdk-6u14-linux-x64.bin
mv jdk1.6.0_14/ /usr/local/jdk1.6
# 配置环境变量
export JAVA_HOME=/usr/local/jdk1.6
export AMOEBA_HOME=/usr/local/amoeba
export PATH=$PATH:$AMOEBA_HOME/bin
# 安装Amoeba
tar zxvf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/
chmod -R 755 /usr/local/amoeba/
2. 数据库权限配置
在所有MySQL节点创建Amoeba访问用户:
sql
mysql> GRANT ALL ON *.* TO test@'192.168.108.%' IDENTIFIED BY '123.com';
3. Amoeba配置优化
xml
<!-- amoeba.xml 配置 -->
<property name="user">amoeba</property>
<property name="password">123456</property>
<property name="defaultPool">master</property>
<property name="writePool">master</property>
<property name="readPool">slaves</property>
<!-- dbServers.xml 配置 -->
<dbServer name="master" parent="abstractServer">
<property name="ipAddress">192.168.108.101</property>
</dbServer>
<dbServer name="slave1" parent="abstractServer">
<property name="ipAddress">192.168.108.102</property>
</dbServer>
<dbServer name="slave2" parent="abstractServer">
<property name="ipAddress">192.168.108.103</property>
</dbServer>
4. 读写分离测试
停止从服务器复制进程后,通过客户端验证读写分离:
sql
-- 客户端连接Amoeba
mysql -u amoeba -p123456 -h 192.168.108.110 -P8066
-- 查询操作(轮询从服务器)
mysql> SELECT * FROM school.student;

五、实验拓扑与架构说明
| 主机名 | IP地址 | 角色说明 |
|---|---|---|
| mysql-master | 192.168.108.101 | MySQL主服务器 |
| mysql-slave01 | 192.168.108.102 | MySQL从节点1 |
| mysql-slave02 | 192.168.108.103 | MySQL从节点2 |
| amoeba | 192.168.108.110 | 读写分离代理层 |
| mysql-client | 192.168.108.111 | 应用客户端 |


六、关键注意事项
- 时间同步:所有节点需保持时间一致,避免数据不一致问题
- UUID冲突:克隆环境需删除auto.cnf文件重新生成UUID
- 防火墙配置:确保3306和8066端口通信正常
- 权限管理:合理控制复制账号和代理账号的访问权限
- 监控维护:定期检查主从同步状态和代理层连接情况