Skip to content

MariaDB 手动切换

手动切换概述

手动切换是指在主库需要维护或出现故障时,通过手动操作将从库提升为主库,并将其他从库重新指向新主库的过程。手动切换是数据库运维中的重要技能,需要谨慎操作以确保数据一致性和服务可用性。

手动切换的适用场景

  1. 计划内维护:主库需要停机维护(如硬件升级、软件升级、参数调整等)
  2. 主库性能问题:主库出现性能瓶颈,需要将负载转移到性能更好的从库
  3. 主库故障:主库不可用,需要将从库提升为主库以恢复服务
  4. 灾难恢复:数据中心故障,需要将服务切换到备用数据中心的从库

手动切换的准备工作

1. 监控复制状态

在执行手动切换前,需要确保所有从库的复制状态正常:

sql
-- 在所有从库上执行
SHOW SLAVE STATUS\G

-- 检查关键指标
-- Slave_IO_Running: Yes
-- Slave_SQL_Running: Yes
-- Seconds_Behind_Master: 0

2. 选择合适的从库

选择从库时需要考虑以下因素:

  • 复制延迟最小(Seconds_Behind_Master 接近 0)
  • 硬件配置与主库相当或更好
  • 网络连接稳定
  • 数据一致性验证通过

3. 准备切换脚本和工具

  • 准备切换步骤的脚本,包括:

    • 停止应用写操作
    • 等待从库追上主库
    • 将从库提升为主库
    • 重新配置其他从库
    • 恢复应用写操作
  • 准备验证工具:

    • mariadb-check:验证数据一致性
    • pt-table-checksum:检查主从数据差异
    • 监控工具:监控切换过程中的性能和状态

4. 通知相关团队

  • 通知应用团队切换时间和可能的影响
  • 通知运维团队准备应急方案
  • 通知业务团队可能的服务中断

手动切换步骤

场景 1:计划内切换

1. 停止应用写操作

  • 暂停应用服务器的写操作
  • 或使用中间件禁止写操作
  • 确保所有未提交的事务完成

2. 确认主库二进制日志位置

sql
-- 在主库上执行
FLUSH TABLES WITH READ LOCK;
SHOW MASTER STATUS;
-- 记录 File 和 Position 值,例如:
-- File: mariadb-bin.000010
-- Position: 12345

3. 等待从库追上主库

sql
-- 在待提升的从库上执行
SHOW SLAVE STATUS\G
-- 检查 Relay_Master_Log_File 和 Exec_Master_Log_Pos 是否与主库的 File 和 Position 一致
-- 检查 Seconds_Behind_Master 是否为 0

4. 将从库提升为主库

sql
-- 在待提升的从库上执行
STOP SLAVE;
RESET SLAVE ALL;
-- 如果使用 GTID,执行:
-- RESET MASTER;

-- 解除只读模式
SET GLOBAL read_only = OFF;
SET GLOBAL super_read_only = OFF;

-- 记录新主库的二进制日志位置
SHOW MASTER STATUS;

5. 释放主库的读锁

sql
-- 在原主库上执行
UNLOCK TABLES;

6. 重新配置其他从库

sql
-- 在其他从库上执行
STOP SLAVE;
RESET SLAVE ALL;

-- 指向新主库
CHANGE MASTER TO
  MASTER_HOST='new_master_ip',
  MASTER_USER='repl',
  MASTER_PASSWORD='repl_password',
  MASTER_LOG_FILE='new_master_binlog_file',
  MASTER_LOG_POS=new_master_binlog_pos;

-- 如果使用 GTID,执行:
-- CHANGE MASTER TO
--   MASTER_HOST='new_master_ip',
--   MASTER_USER='repl',
--   MASTER_PASSWORD='repl_password',
--   MASTER_USE_GTID=slave_pos;

-- 启动复制
START SLAVE;

-- 验证复制状态
SHOW SLAVE STATUS\G

7. 恢复应用写操作

  • 恢复应用服务器的写操作
  • 或使用中间件允许写操作
  • 监控应用访问情况

场景 2:主库故障切换

当主库不可用时,需要执行故障切换:

1. 确认主库故障

  • 尝试连接主库,确认不可用
  • 检查主库服务器状态(网络、硬件、进程等)
  • 评估故障恢复时间,如果恢复时间过长,执行故障切换

2. 选择最新的从库

sql
-- 在所有从库上执行
SHOW SLAVE STATUS\G

-- 选择 Relay_Master_Log_File 最新且 Exec_Master_Log_Pos 最大的从库
-- 或选择 GTID 集合最完整的从库

3. 将从库提升为主库

sql
-- 在待提升的从库上执行
STOP SLAVE;
RESET SLAVE ALL;

-- 如果使用 GTID,执行:
-- RESET MASTER;

-- 解除只读模式
SET GLOBAL read_only = OFF;
SET GLOBAL super_read_only = OFF;

-- 记录新主库的二进制日志位置
SHOW MASTER STATUS;

4. 重新配置其他从库

sql
-- 在其他从库上执行
STOP SLAVE;
RESET SLAVE ALL;

-- 指向新主库
CHANGE MASTER TO
  MASTER_HOST='new_master_ip',
  MASTER_USER='repl',
  MASTER_PASSWORD='repl_password',
  MASTER_LOG_FILE='new_master_binlog_file',
  MASTER_LOG_POS=new_master_binlog_pos;

-- 如果使用 GTID,执行:
-- CHANGE MASTER TO
--   MASTER_HOST='new_master_ip',
--   MASTER_USER='repl',
--   MASTER_PASSWORD='repl_password',
--   MASTER_USE_GTID=slave_pos;

-- 启动复制
START SLAVE;

-- 验证复制状态
SHOW SLAVE STATUS\G

5. 恢复应用写操作

  • 将应用写操作指向新主库
  • 监控应用访问情况

手动切换的验证

1. 验证新主库状态

sql
-- 检查新主库状态
SHOW GLOBAL STATUS LIKE 'Uptime';
SHOW GLOBAL VARIABLES LIKE 'read_only';
SHOW MASTER STATUS;

-- 检查连接数
SHOW GLOBAL STATUS LIKE 'Threads_connected';

-- 检查错误日志
SELECT * FROM mysql.error_log ORDER BY event_time DESC LIMIT 10;

2. 验证复制状态

sql
-- 在所有从库上执行
SHOW SLAVE STATUS\G

-- 检查关键指标
-- Slave_IO_Running: Yes
-- Slave_SQL_Running: Yes
-- Seconds_Behind_Master: 0

3. 验证数据一致性

sql
-- 使用 mariadb-check 验证数据一致性
mariadb-check -u root -p --all-databases --check-upgrade

-- 或使用 pt-table-checksum 检查主从数据差异
pt-table-checksum h=new_master_ip,u=root,p=password

4. 验证应用访问

  • 检查应用日志,确认没有连接错误
  • 执行简单的读写操作,验证服务正常
  • 监控应用响应时间,确认性能正常

手动切换的回滚方案

1. 回滚条件

  • 新主库出现问题
  • 数据一致性验证失败
  • 应用无法正常访问新主库

2. 回滚步骤

场景 1:原主库可恢复

  1. 停止应用写操作
  2. 恢复原主库:修复原主库的问题,确保可以正常运行
  3. 将原主库作为从库指向新主库
    sql
    CHANGE MASTER TO
      MASTER_HOST='new_master_ip',
      MASTER_USER='repl',
      MASTER_PASSWORD='repl_password',
      MASTER_LOG_FILE='new_master_binlog_file',
      MASTER_LOG_POS=new_master_binlog_pos;
    START SLAVE;
  4. 等待原主库追上新主库
  5. 将原主库提升回主库:按照计划内切换的步骤执行
  6. 恢复应用写操作

场景 2:原主库不可恢复

  1. 停止应用写操作
  2. 选择另一个从库:选择复制状态正常的从库
  3. 将该从库提升为主库:按照故障切换的步骤执行
  4. 重新配置其他从库:指向新选择的主库
  5. 恢复应用写操作

手动切换的最佳实践

1. 制定详细的切换计划

  • 编写详细的切换步骤脚本
  • 明确每个步骤的责任人
  • 设定切换时间窗口
  • 准备回滚方案

2. 提前测试切换流程

  • 在测试环境中多次演练切换流程
  • 记录切换时间和可能的问题
  • 优化切换步骤,减少切换时间

3. 确保数据一致性

  • 在切换前验证主从数据一致性
  • 切换过程中避免数据丢失
  • 切换后再次验证数据一致性

4. 最小化服务中断时间

  • 优化切换步骤,减少每个步骤的执行时间
  • 考虑使用并行操作,同时配置多个从库
  • 准备好应用切换的脚本,快速将应用指向新主库

5. 监控切换过程

  • 监控切换过程中的数据库状态
  • 监控应用访问情况
  • 及时发现并处理切换过程中的问题

6. 文档记录

  • 记录切换的原因、时间、步骤和结果
  • 记录切换过程中遇到的问题和解决方案
  • 更新架构文档,记录新的主从关系

手动切换的常见问题及解决方案

问题 1:从库复制延迟过大

现象:执行 SHOW SLAVE STATUS\G 时,Seconds_Behind_Master 数值较大 解决方案

  • 等待从库追上主库,再执行切换
  • 或选择复制延迟较小的从库
  • 优化从库性能,加快复制速度

问题 2:主库无法执行 FLUSH TABLES WITH READ LOCK

现象:主库上执行 FLUSH TABLES WITH READ LOCK 超时或失败 解决方案

  • 检查是否存在长时间运行的事务
  • 执行 KILL 命令终止长时间运行的事务
  • 或使用 SET GLOBAL read_only = ON 替代

问题 3:从库提升为主库后无法写入

现象:新主库上执行写操作失败,提示只读模式 解决方案

  • 检查 read_onlysuper_read_only 参数:
    sql
    SET GLOBAL read_only = OFF;
    SET GLOBAL super_read_only = OFF;

问题 4:其他从库无法连接新主库

现象:其他从库执行 START SLAVE 后,Slave_IO_RunningNo解决方案

  • 检查新主库的防火墙设置,确保复制端口(默认 3306)开放
  • 验证复制用户的权限:
    sql
    SHOW GRANTS FOR 'repl'@'%';
  • 检查复制连接参数是否正确

问题 5:数据一致性验证失败

现象:使用 mariadb-checkpt-table-checksum 发现数据不一致 解决方案

  • 使用 pt-table-sync 修复数据差异
  • 或重新初始化有问题的从库
  • 分析数据不一致的原因,避免再次发生

常见问题 (FAQ)

Q1:手动切换需要多长时间?

A:手动切换的时间取决于多个因素,包括:

  • 从库的复制延迟
  • 从库的数量
  • 切换脚本的效率
  • 运维人员的操作熟练程度

一般来说,计划内切换需要几分钟到十几分钟,故障切换可能需要更长时间。

Q2:如何选择合适的从库进行提升?

A:选择从库时需要考虑以下因素:

  • 复制延迟最小
  • 硬件配置与主库相当或更好
  • 网络连接稳定
  • 数据一致性验证通过

Q3:手动切换会导致数据丢失吗?

A:在计划内切换中,通过执行 FLUSH TABLES WITH READ LOCK 并等待从库追上主库,可以确保数据不丢失。在故障切换中,如果主库不可用,可能会丢失主库上未同步到从库的数据。

Q4:如何减少手动切换的风险?

A:可以通过以下方式减少手动切换的风险:

  • 制定详细的切换计划
  • 提前在测试环境中演练
  • 确保数据一致性
  • 准备回滚方案
  • 监控切换过程

Q5:使用 GTID 复制会简化手动切换吗?

A:是的,使用 GTID 复制可以简化手动切换,因为不需要手动记录和指定二进制日志位置,只需要使用 MASTER_USE_GTID=slave_pos 即可。

Q6:手动切换后需要更新哪些配置?

A:手动切换后需要更新以下配置:

  • 应用程序的数据库连接配置
  • 中间件(如 MaxScale、ProxySQL)的配置
  • 监控系统的配置
  • 备份系统的配置

Q7:如何验证手动切换的成功?

A:可以通过以下方式验证手动切换的成功:

  • 检查新主库的状态正常
  • 检查所有从库的复制状态正常
  • 验证数据一致性
  • 验证应用可以正常访问

Q8:手动切换和自动切换有什么区别?

A:手动切换需要运维人员手动执行切换步骤,适用于计划内维护或复杂的故障场景;自动切换通过中间件或脚本自动执行切换步骤,适用于简单的故障场景,可以快速恢复服务。