高可用方案
最后更新: 2026-01-22
作者: MySQL Team
页面目录
第十五章:高可用方案
15.1 高可用概述
可用性指标
| 可用性 | 年停机时间 |
|---|---|
| 99% | 3.65天 |
| 99.9% | 8.76小时 |
| 99.99% | 52.6分钟 |
| 99.999% | 5.26分钟 |
高可用组件
┌──────────────────────────────────────────────────┐
│ Load Balancer │
│ (读写分离/负载均衡) │
└─────────────────────┬───────────────────────────┘
│
┌─────────────┼─────────────┐
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Master │──▶│ Slave 1 │──▶│ Slave 2 │
└─────────┘ └─────────┘ └─────────┘
15.2 主从切换
手动主从切换
-- 1. 从库停止复制
STOP SLAVE;
-- 2. 确认从库已同步
SHOW SLAVE STATUS\G
-- 确保 Slave_IO_Running 和 Slave_SQL_Running 都是 Yes
-- 确保 Seconds_Behind_Master = 0
-- 3. 重置从库复制
RESET SLAVE ALL;
-- 4. 将从库提升为新主库
RESET MASTER;
-- 5. 配置其他从库指向新主库
CHANGE MASTER TO MASTER_HOST='new_master_ip', MASTER_AUTO_POSITION=1;
START SLAVE;
-- 6. 修改应用连接字符串
自动故障转移
-- MySQL Group Replication 自动故障转移
-- 查看组成员
SELECT * FROM performance_schema.replication_group_members;
15.3 MySQL Group Replication
组复制原理
┌──────────────────────────────────────┐
│ Group Replication (Paxos) │
│ ┌─────────┐ ┌─────────┐ ┌─────────┐│
│ │ Server1 │ │ Server2 │ │ Server3 ││
│ │ Primary │ │Primary │ │Primary ││
│ └────┬────┘ └────┬────┘ └────┬────┘│
│ └───────────┴───────────┘ │
└──────────────────────────────────────┘
配置 Group Replication
# Server1 配置
[mysqld]
server-id = 1
gtid_mode = ON
enforce_gtid_consistency = ON
binlog_checksum = NONE
master_verify_checksum = OFF
slave_parallel_workers = 4
slave_parallel_type = LOGICAL_CLOCK
transaction_write_set_extraction = XXHASH64
group_replication_group_name = "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee"
group_replication_start_on_boot = OFF
group_replication_local_address = "192.168.1.101:33061"
group_replication_group_seeds = "192.168.1.101:33061,192.168.1.102:33061,192.168.1.103:33061"
group_replication_bootstrap_group = OFF
启动 Group Replication
-- 安装插件
INSTALL PLUGIN group_replication SONAME 'group_replication.so';
-- 创建复制账号
SET GLOBAL group_replication_recovery_get_pubkey_key = 1;
CREATE USER 'repl'@'%' IDENTIFIED BY 'repl_password';
GRANT BACKUP_ADMIN ON *.* TO 'repl'@'%';
GRANT GROUP_REPLICATION_STREAM ON *.* TO 'repl'@'%';
FLUSH PRIVILEGES;
-- 启动组复制(第一个节点需要 bootstrap)
SET GLOBAL group_replication_bootstrap_group = ON;
START GROUP_REPLICATION;
SET GLOBAL group_replication_bootstrap_group = OFF;
-- 其他节点加入
START GROUP_REPLICATION;
查看组状态
SELECT * FROM performance_schema.replication_group_members;
SELECT * FROM performance_schema.replication_group_member_stats;
15.4 MySQL Router
安装配置
# 安装 MySQL Router
yum install mysql-router
# 配置
mysqlrouter --bootstrap root@192.168.1.101 \
--directory /etc/mysqlrouter \
--conf-use-sockets
# 启动
mysqlrouter -c /etc/mysqlrouter/mysqlrouter.conf &
读写分离配置
[router]
bind_address = 0.0.0.0
bind_port = 6446
read_only = false
[routing:readwrites]
bind_address = 0.0.0.0
bind_port = 6446
destinations = 192.168.1.101:3306,192.168.1.102:3306
mode = read-write
protocol = classic
[routing:readonly]
bind_address = 0.0.0.0
bind_port = 6447
destinations = 192.168.1.103:3306,192.168.1.104:3306
mode = read-only
protocol = classic
应用连接
# 读写分离端口
mysql -h mysql_router_ip -P 6446 -u app -p
# 只读端口
mysql -h mysql_router_ip -P 6447 -u app -p
15.5 Keepalived + VIP
原理
┌──────────────┐
│ VIP │ 虚拟IP 192.168.1.100
└──────┬───────┘
│
┌────────────┴────────────┐
│ Keepalived │
└──────┬───────────────────┘
│
┌──────┴──────┐
▼ ▼
┌────────┐ ┌────────┐
│Master │ │ Slave │
│ 192.168│ │ 192.168│
│ .1.101│ │ .1.102│
└────────┘ └────────┘
Keepalived 配置
# /etc/keepalived/keepalived.conf
global_defs {
router_id MySQL_HA
}
vrrp_instance VI_1 {
state BACKUP
interface eth0
virtual_router_id 51
priority 100
nopreempt
advert_int 1
virtual_ipaddress {
192.168.1.100/24 dev eth0
}
track_script {
chk_mysql
}
}
virtual_server 192.168.1.100 3306 {
delay_loop 2
lb_algo rr
lb_kind DR
persistence_timeout 50
protocol TCP
real_server 192.168.1.101 3306 {
weight 1
notify_down /root/mysql_down.sh
TCP_CHECK {
connect_timeout 3
nb_get_retry 3
delay_before_retry 3
connect_port 3306
}
}
}
检测脚本
#!/bin/bash
# /root/mysql_down.sh
pkill mysqlrouter
systemctl stop mysqld
exit 0
15.6 ProxySQL
安装配置
# 安装
yum install proxysql
# 启动
systemctl start proxysql
配置 ProxySQL
-- 连接管理接口(默认 6032)
mysql -u admin -padmin -h 127.0.0.1 -P 6032
-- 添加 MySQL 服务器
INSERT INTO mysql_servers (hostgroup_id, hostname, port, comment)
VALUES (10, '192.168.1.101', 3306, 'Master');
INSERT INTO mysql_servers (hostgroup_id, hostname, port, comment)
VALUES (20, '192.168.1.102', 3306, 'Slave1');
INSERT INTO mysql_servers (hostgroup_id, hostname, port, comment)
VALUES (20, '192.168.1.103', 3306, 'Slave2');
-- 添加用户
INSERT INTO mysql_users (username, password, default_hostgroup)
VALUES ('app', 'AppPass123!', 10);
-- 配置读写分离规则
INSERT INTO mysql_query_rules (rule_id, active, match_digest, destination_hostgroup, comment)
VALUES (1, 1, '^SELECT.*FOR UPDATE', 10, 'Write');
INSERT INTO mysql_query_rules (rule_id, active, match_digest, destination_hostgroup, comment)
VALUES (2, 1, '^SELECT', 20, 'Read');
-- 保存配置
LOAD MYSQL SERVERS TO RUNTIME;
LOAD MYSQL USERS TO RUNTIME;
LOAD MYSQL QUERY RULES TO RUNTIME;
SAVE MYSQL SERVERS TO DISK;
SAVE MYSQL USERS TO DISK;
SAVE MYSQL QUERY RULES TO DISK;
ProxySQL 连接
# 应用连接(默认 6033)
mysql -h proxysql_ip -P 6033 -u app -pAppPass123!
15.7 监控告警
关键监控指标
| 指标 | 告警阈值 | 说明 |
|---|---|---|
| 可用性 | down | 服务不可用 |
| 主从延迟 | > 30s | 复制延迟过大 |
| 连接数 | > 80% max | 连接数接近上限 |
| 磁盘使用 | > 80% | 磁盘空间不足 |
| 慢查询数 | > 10/min | 慢查询增多 |
| 锁等待 | > 100 | 锁等待过多 |
| 缓冲池命中率 | < 95% | 缓存命中率低 |
Prometheus + Grafana
# prometheus.yml
scrape_configs:
- job_name: 'mysql'
static_configs:
- targets: ['mysql_exporter:9104']
常用监控 SQL
-- 连接数
SHOW STATUS LIKE 'Threads_connected';
SHOW VARIABLES LIKE 'max_connections';
-- 查询缓存命中率
SHOW STATUS LIKE 'Qcache_hits';
SHOW STATUS LIKE 'Qcache_inserts';
-- 临时表使用
SHOW STATUS LIKE 'Created_tmp%';
-- 锁等待
SHOW STATUS LIKE 'Innodb_row_lock%';
-- 缓冲池
SHOW ENGINE INNODB STATUS;
15.8 本章小结
✅ 高可用目标:99.99% 以上可用性
✅ 主从切换:手动和自动故障转移
✅ Group Replication:多主复制,自动选主
✅ MySQL Router:读写分离,连接池
✅ Keepalived + VIP:高可用 VIP 漂移
✅ ProxySQL:SQL 级读写分离和负载均衡
✅ 监控告警:关键指标实时监控
附录 A:常用命令速查
-- 连接数据库
mysql -u root -p -h localhost -P 3306
-- 数据库操作
SHOW DATABASES;
USE db_name;
SHOW TABLES;
DESC table_name;
-- 用户操作
CREATE USER 'user'@'host' IDENTIFIED BY 'pass';
GRANT ALL ON db.* TO 'user'@'host';
FLUSH PRIVILEGES;
-- 复制操作
SHOW MASTER STATUS;
SHOW SLAVE STATUS\G
CHANGE MASTER TO ...;
START/STOP SLAVE;
-- 性能分析
EXPLAIN SELECT * FROM ...;
SHOW PROCESSLIST;
SHOW STATUS LIKE '%';
SHOW VARIABLES LIKE '%';
附录 B:错误代码速查
| 错误代码 | 说明 | 解决方案 |
|---|---|---|
| 1045 | 拒绝访问 | 检查用户名密码 |
| 1049 | 未知数据库 | 检查数据库名 |
| 1062 | 重复键冲突 | 检查唯一索引 |
| 1146 | 表不存在 | 检查表名大小写 |
| 1451 | 外键约束 | 先删除子表数据 |
| 1452 | 外键不存在 | 添加外键记录 |
| 1205 | 锁等待超时 | 优化长事务 |
| 1213 | 死锁 | 重试事务 |
🎉 教程完成!
本教程涵盖了 MySQL 从入门到精通的全部核心内容,包括:
- 基础操作(安装、配置、SQL)
- 进阶特性(索引、事务、存储过程)
- 运维管理(备份、复制、监控)
- 故障处理(问题诊断、性能优化)
- 高级应用(高可用、安全加固)