高可用方案

最后更新: 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)
  • 进阶特性(索引、事务、存储过程)
  • 运维管理(备份、复制、监控)
  • 故障处理(问题诊断、性能优化)
  • 高级应用(高可用、安全加固)