引言

数据库镜像是SQL Server高可用性解决方案中的重要角色(但也是最容易被忽视的元老)。当故障切换发生时,DBA们常常以为主备切换就万事大吉,殊不知此时真正的挑战才刚开始。本文将以SQL Server 2019为技术栈,通过真实案例解析故障切换后那些必须做的配置调整。


一、故障切换后的典型问题

1.1 连接字符串引发的血案

当镜像会话从Principal切换到Mirror后,应用程序连接字符串若未配置Failover Partner参数,会导致长达30秒的连接超时。这是最常见的生产事故触发点。

-- 错误示例:缺少故障转移伙伴配置
Server=PrimaryServer;Database=OrderDB;Integrated Security=True;

-- 正确配置(ADO.NET连接字符串示例)
"Server=PrimaryServer;Failover Partner=MirrorServer;Database=OrderDB;Integrated Security=True;"

1.2 端点配置的幽灵残留

镜像端点(Endpoint)的加密配置在切换后可能失效。通过系统视图可验证当前状态:

-- 查看所有端点状态(需在master库执行)
SELECT 
    name AS EndpointName,
    state_desc AS Status,
    encryption_algorithm_desc AS EncryptionType
FROM 
    sys.database_mirroring_endpoints;

当发现状态为STOPPED或加密算法显示NO_ENCRYPTION时,需要重建端点:

-- 删除原有端点(先备份配置!)
DROP ENDPOINT Mirroring_Endpoint;

-- 创建AES加密的端点
CREATE ENDPOINT Mirroring_Endpoint
STATE = STARTED
AS TCP (LISTENER_PORT = 5022)
FOR DATABASE_MIRRORING (
    AUTHENTICATION = WINDOWS NEGOTIATE,
    ENCRYPTION = REQUIRED ALGORITHM AES
);

二、配置调整实战四步曲

2.1 镜像会话状态验证(必须做!)

通过动态管理视图获取关键指标:

-- 查看所有数据库镜像状态(需在master库执行)
SELECT 
    database_id,
    mirroring_role_desc AS CurrentRole,
    mirroring_state_desc AS SyncStatus,
    mirroring_safety_level_desc AS SafetyLevel
FROM 
    sys.database_mirroring
WHERE 
    mirroring_guid IS NOT NULL;

重点关注SyncStatus字段,当显示SYNCHRONIZED时才允许执行回切操作。

2.2 孤立用户处理方案

故障切换后经常出现用户SID不匹配问题,通过以下脚本批量修复:

-- 生成用户映射修复脚本
SELECT 
    'ALTER USER [' + name + '] WITH LOGIN = [' + name + '];' AS FixCommand
FROM 
    sys.database_principals
WHERE 
    type_desc = 'SQL_USER'
    AND sid IS NOT NULL 
    AND sid NOT IN (SELECT sid FROM sys.server_principals);

2.3 日志传送链重建

当镜像与日志传送共存时,必须重新初始化日志传送:

-- 步骤1:在新主体执行日志备份
BACKUP LOG [SalesDB] TO DISK = N'\\BackupSrv\Logs\SalesDB_Log.trn' WITH INIT;

-- 步骤2:在镜像服务器还原(需带NORECOVERY)
RESTORE LOG [SalesDB] FROM DISK = N'\\BackupSrv\Logs\SalesDB_Log.trn' WITH NORECOVERY;

2.4 性能计数器迁移

镜像切换后需要重建性能基线,推荐使用扩展事件捕获关键指标:

-- 创建镜像监控事件会话
CREATE EVENT SESSION [Mirror_Monitor] ON SERVER 
ADD EVENT sqlserver.database_mirroring_state_change,
ADD EVENT sqlserver.database_mirroring_send_queue 
ADD TARGET package0.event_file(SET filename=N'D:\Monitor\Mirror_Monitor.xel')
WITH (STARTUP_STATE=ON);

三、关联技术对比分析

3.1 镜像 vs AlwaysOn可用性组

维度 数据库镜像 AlwaysOn AG
故障检测 基于TCP心跳(秒级) 集群仲裁+健康检测(亚秒级)
存储架构 单副本 多副本共享存储
回切复杂度 需要手动重新同步 自动页修复

3.2 混合部署的陷阱

某电商系统同时使用镜像和日志传送,在故障切换后出现日志链断裂。解决方案:

-- 在镜像服务器执行(需NORECOVERY模式)
EXEC master.dbo.sp_add_log_shipping_secondary_database 
    @secondary_database = N'SalesDB',
    @primary_server = N'NewPrincipal',
    @backup_source_directory = N'\\BackupSrv\Logs\',
    @copy_dest = N'D:\LS_Copy\';

四、应用场景深度解析

4.1 计划内维护的最佳实践

执行滚动升级时,建议按以下顺序操作:

  1. 暂停日志传送作业
  2. 手动故障切换到镜像
  3. 在旧主体执行补丁安装
  4. 验证后执行回切操作

4.2 跨机房容灾的特殊处理

当镜像服务器位于不同地域时,需要调整连接超时设置:

-- 设置镜像超时为60秒(默认10秒)
ALTER DATABASE SalesDB 
SET PARTNER TIMEOUT 60;

五、技术优缺点全景评估

优势:

  • 零存储成本:无需共享存储
  • 快速部署:相比集群更轻量
  • 细粒度控制:支持异步提交模式

劣势:

  • 单点写入:镜像数据库不可读
  • 回切复杂:需要完整日志同步
  • 功能局限:不支持FILESTREAM

六、九条保命注意事项

  1. 网络隔离测试:定期断开主备网络模拟故障
  2. 加密验证:每月检查端点证书有效期
  3. 日志磁盘监控:确保镜像服务器有足够空间存放重做日志
  4. 版本一致性:禁止混合版本镜像(如2019主库配2017镜像)
  5. 作业同步:定期同步SQL Server Agent作业
  6. 快照隔离:切换后检查快照数据库状态
  7. Filestream处理:需要额外手动同步
  8. 内存优化表:需检查持久化状态
  9. 统计信息维护:镜像库统计信息不会自动更新

七、总结

数据库镜像的故障切换不是终点,而是新运维周期的起点。通过本文的配置调整方案,读者可系统性地掌握从状态验证到性能优化的完整闭环。记住:稳定的系统不是配置出来的,而是持续调整出来的。