本文目录导读:

在数据库升级失败后,切换备库(通常是主备切换,即 Failover 或 Switchover)是一个常见的灾难恢复操作,具体步骤会根据你使用的数据库类型(如 MySQL、PostgreSQL、Oracle、SQL Server 等)以及高可用架构(如主从复制、集群、Always On、Data Guard等)而有所不同。
下面以几种主流数据库为例,分别说明升级失败后切换备库的通用逻辑和关键步骤。
核心原则:
- 确保数据一致性: 切换前必须确认备库与主库的数据差距(延迟)在可接受范围内,或者能接受部分数据丢失(RPO - 恢复点目标)。
- 确保备库健康: 备库进程、存储、网络必须正常。
- 记录原主库状态: 切换后原主库通常需要降级为备库或进行修复,不要轻易覆盖数据。
- 更新应用连接: 应用连接必须指向新主库。
- 测试: 在非生产环境充分测试切换流程。
MySQL (主从复制架构)
场景: 主库升级脚本执行失败,导致服务不可用或数据损坏,需要将备库提升为新主库。
步骤:
-
确认备库状态:
-- 在备库执行 SHOW SLAVE STATUS\G
- 检查
Slave_IO_Running: Yes和Slave_SQL_Running: Yes。 - 检查
Seconds_Behind_Master数值,理想情况是 0 或很小。
- 检查
-
停止主库的写入(如果主库还活着但故障): 防止脑裂。
# 在主库执行 SET GLOBAL read_only = ON; # 设置只读 # 或者直接 kill 主库进程
-
在备库停止复制并提升为新主库:
STOP SLAVE; RESET SLAVE ALL; -- 清除旧的复制信息,防止恢复复制后回滚到老主库 SET GLOBAL read_only = OFF; -- 允许写入
-
更新应用连接: 修改应用配置文件或通过 DNS/负载均衡器将数据库连接指向这个新主库的 IP/域名。
-
处理原主库(降级或修复):
- 如果原主库只是升级失败但数据未损坏,可以将其作为新主库的从库重新建立复制。
- 步骤:在原主库上执行
CHANGE MASTER TO MASTER_HOST='新主库IP', ...;START SLAVE。
PostgreSQL (流复制架构)
场景: 主库升级失败(pg_upgrade 出错),需要触发备库提升。
步骤:
-
检查备库状态:
-- 在备库执行 SELECT * FROM pg_stat_replication; SELECT pg_is_in_recovery(); -- 返回 true 为备库
-
提升备库为主库(推荐使用 pg_ctl promote 或触发触发文件):
# 方法1:使用 pg_ctl (推荐) pg_ctl promote -D /path/to/data_directory # 方法2:创建触发文件(旧式方法) touch /path/to/data_directory/trigger_file
提升后,备库会停止流复制并开始接受写操作。
-
验证新主库:
SELECT pg_is_in_recovery(); -- 返回 false
-
更新应用连接: 指向新主库 IP/端口。
-
处理原主库:
- 原主库如果还活着,需要降级为新备库。
- 清除原主库的数据目录或重建集群,然后从新主库进行基础备份并配置流复制。
Oracle (Data Guard 架构)
场景: 主库升级失败(例如应用补丁后无法启动),需要执行 Failover (切换) 到备库。
步骤:
-
检查备库状态 (备库上执行):
SELECT DATABASE_ROLE, PROTECTION_MODE, OPEN_MODE FROM V$DATABASE; -- 期望: DATABASE_ROLE = PHYSICAL STANDBY, OPEN_MODE = READ ONLY SELECT THREAD#, SEQUENCE#, APPLIED FROM V$ARCHIVED_LOG WHERE APPLIED='NO'; -- 确保日志应用无积压
-
执行 Failover 切换 (在备库执行):
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE FINISH; -- 尝试应用所有日志 ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY WITH SESSION SHUTDOWN; ALTER DATABASE OPEN;
- 注意: 如果主库彻底损坏无法通信,使用
ACTIVATE STANDBY DATABASE会导致数据丢失(FORCE LOGGING 除外),慎用。
- 注意: 如果主库彻底损坏无法通信,使用
-
验证新主库:
SELECT DATABASE_ROLE, OPEN_MODE FROM V$DATABASE; -- 期望: PRIMARY, READ WRITE
-
更新应用连接(TNSNAMES.ORA 或连接池配置): 指向新主库。
-
处理原主库 (需重建 Data Guard): 原主库通常需要重建为备库,重新创建控制文件并配置复制。
SQL Server (Always On 可用性组)
场景: 主副本升级失败(例如安装 CU 更新失败),需要手动进行故障转移。
步骤:
-
检查可用性组状态 (SSMS 或 T-SQL):
SELECT * FROM sys.dm_hadr_availability_group_states; SELECT * FROM sys.dm_hadr_database_replica_states;
-
执行手动故障转移 (在目标备副本上执行):
- 使用 SSMS:右键可用性组 -> Failover... -> 选择目标备副本。
- 使用 T-SQL:
ALTER AVAILABILITY GROUP [YourAGName] FAILOVER;
- 备副本会自动转换为 PRIMARY_ROLE,并开始接受读写。
-
验证新主副本:
SELECT role_desc FROM sys.dm_hadr_availability_replica_states WHERE is_local = 1; -- 期望: PRIMARY
-
更新应用连接字符串: 指向新主副本的监听器名称(Always On 监听器会跟随主副本自动切换,所以通常无需修改),如果没使用监听器,需手动更新。
-
处理原主副本: 原主副本会自动进入 SECONDARY_ROLE 并试图重新连接可用性组,通常无需手动干预,只需检查其状态并修复导致升级失败的问题即可。
通用故障排除(如果切换失败)
如果上述标准步骤执行后切换失败(例如备库无法提升、数据不一致),可能的原因及对策:
-
备库延迟过大 (同步延迟):
- 表现:
Seconds_Behind_Master很大,或 Oracle 日志未应用。 - 措施: 等待同步追上,如果无法追上且业务急需恢复,需要接受一定数据丢失,对于 MySQL,可以设置
MASTER_AUTO_POSITION=0后手动补日志;对于 Oracle,要评估ACTIVATE的风险。
- 表现:
-
备库文件损坏/不完整:
- 表现: 数据库无法正常启动或 CRC 校验失败。
- 措施: 该备库不可用于切换,必须寻找其他备库或从最近的备份恢复。
-
主库未彻底停止 (脑裂风险):
- 表现: 主库仍对外提供写入,切换后出现双主。
- 措施: 必须先确保原主库完全停止(
SHUTDOWN ABORT或物理断开网络),切换后使用 STONITH 机制(如fail2ban、iptables封锁)防止原主库重新上线。
-
复制配置残留:
- 表现: MySQL 的
relay_log或 PostgreSQL 的recovery.conf(新版本为standby.signal)未清除。 - 措施: 在提升备库前,清理复制相关文件/配置(如
RESET SLAVE、删除standby.signal)。
- 表现: MySQL 的
-
网络/安全组拦截:
- 表现: 备库无法连接主库,或新主库无法被应用访问。
- 措施: 检查防火墙、VPN、数据库用户权限、
my.cnf/pg_hba.conf中的listen_addresses。
总结建议
| 数据库类型 | 关键命令/操作 | 提醒 |
|---|---|---|
| MySQL | STOP SLAVE; RESET SLAVE ALL; SET read_only=OFF; |
务必先确保主库只读或关闭,清除复制信息后,需手动重建新复制。 |
| PostgreSQL | pg_ctl promote 或 SELECT pg_promote() |
提升后,原主库可降级为备库,但需要重新进行基础备份。 |
| Oracle | ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY; |
优先使用 Switchover (正常切换),再考虑 Failover (强制切换,有数据丢失风险)。 |
| SQL Server | ALTER AVAILABILITY GROUP ... FAILOVER; |
通常最自动化,Always On 监听器可自动跟随主副本,应用改连接最方便。 |
最重要的预防措施: 在进行任何重大升级前,一定要备份原主库(物理备份/快照),并在一台测试备库上演练升级过程,这样即使升级失败,也能迅速回滚或使用备库恢复服务。