一、集群缩容的背景与核心挑战

当业务规模缩减或者资源利用率不足时,MySQL集群缩容就成了必须面对的运维操作。但缩容不像扩容那么简单,你没法直接拔电源——数据安全性和服务连续性才是首要考虑的问题。

想象一下这样的场景:一个运行了两年的电商平台,促销季过后流量回归常态,6个节点的集群负载长期低于30%。这时候老板要求缩减到4个节点降低成本。如果操作不当,可能会导致:

  1. 数据不一致引发财务对账异常
  2. 连接闪断造成订单丢失
  3. 剩余节点负载激增引发雪崩
-- 示例:查看当前集群状态(MySQL Group Replication环境)
SELECT * FROM performance_schema.replication_group_members;
/*
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| CHANNEL_NAME              | MEMBER_ID                            | MEMBER_HOST | MEMBER_PORT | MEMBER_STATE |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
| group_replication_applier | d4b8a301-5e53-11ec-9e3f-00155d016101 | node1       |        3306 | ONLINE       |
| group_replication_applier | e2f7b402-5e53-11ec-9e3f-00155d016102 | node2       |        3306 | ONLINE       |
| group_replication_applier | f0a8c303-5e53-11ec-9e3f-00155d016103 | node3       |        3306 | ONLINE       |
| group_replication_applier | fe59d404-5e53-11ec-9e3f-00155d016104 | node4       |        3306 | ONLINE       |
| group_replication_applier | 0c0ae505-5e54-11ec-9e3f-00155d016105 | node5       |        3306 | ONLINE       |
| group_replication_applier | 1abb1606-5e54-11ec-9e3f-00155d016106 | node6       |        3306 | ONLINE       |
+---------------------------+--------------------------------------+-------------+-------------+--------------+
*/

二、标准缩容操作流程详解

2.1 前期准备工作

缩容就像做手术,术前检查必不可少。首先需要确认:

  1. 待移除节点的数据同步状态
  2. 业务连接分布情况
  3. 剩余节点的资源余量
-- 检查待移除节点(node6)的复制延迟(主从架构示例)
SHOW SLAVE STATUS\G
/*
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: node1
                  Master_User: repl_user
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000342
          Read_Master_Log_Pos: 76934203
               Relay_Log_File: node6-relay-bin.000145
                Relay_Log_Pos: 76934356
        Relay_Master_Log_File: mysql-bin.000342
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 76934203
              Relay_Log_Space: 76934567
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
*/

2.2 安全移除节点步骤

以MySQL InnoDB Cluster为例的标准操作流程:

  1. 首先将节点设置为只读模式
  2. 等待所有事务完成
  3. 执行集群节点移除
  4. 验证集群健康状态
-- 步骤1:设置只读
SET GLOBAL super_read_only=ON;
SET GLOBAL read_only=ON;

-- 步骤2:查看活跃事务(需要确保为0)
SELECT * FROM performance_schema.events_transactions_current WHERE STATE='ACTIVE';

-- 步骤3:从集群移除节点(在管理节点执行)
SELECT group_replication_remove_member('node6:3306');

-- 步骤4:验证状态
SELECT * FROM performance_schema.replication_group_members;

三、不同架构的特殊处理

3.1 主从复制架构

传统主从架构需要特别注意:

  1. 先停止从库复制线程
  2. 在主库清除复制账户
  3. 更新中间件配置
-- 在从库执行
STOP SLAVE;
RESET SLAVE ALL;

-- 在主库执行
DROP USER 'repl_user'@'node6';

3.2 MGR集群架构

Group Replication对网络更敏感,需要:

  1. 确保quorum机制仍然有效
  2. 检查GTID集合完整性
  3. 验证自动故障转移能力
-- 检查投票成员数
SELECT @@group_replication_member_weight;

-- 验证GTID
SELECT @@gtid_executed;

四、避坑指南与最佳实践

4.1 常见问题处理

遇到过最棘手的问题包括:

  1. 节点状态卡在RECOVERING超过2小时
  2. 移除后剩余节点自动重启
  3. 应用程序长连接未关闭
-- 强制恢复卡住的节点(谨慎使用)
SET GLOBAL group_replication_member_expel_timeout=60;

4.2 推荐的维护窗口方案

建议采用这样的时间安排:

  1. 业务低峰期操作(如凌晨2点)
  2. 分阶段执行:
    • 第一阶段:标记节点为维护状态
    • 第二阶段:观察24小时
    • 第三阶段:实际下架
-- 维护模式标记(自定义表)
INSERT INTO cluster_maintenance_log 
VALUES (NOW(), 'node6', 'drain_start', CURRENT_USER());

五、后续监控与调优

节点移除不是终点,还需要:

  1. 调整连接池配置
  2. 监控剩余节点负载
  3. 优化查询性能
-- 查看当前连接数趋势
SELECT COUNT(*) FROM information_schema.processlist 
WHERE TIME > 60;

通过完整的缩容流程,我们既实现了成本节约,又保障了服务稳定性。记住,好的DBA不是不会出问题,而是把所有可能的问题都想在前面。