一、数据库镜像的"双人舞"原理

在客户现场处理过上百次镜像故障后,我想用夫妻吵架的场景来形容数据库镜像的工作原理:主体数据库(老公)负责生产数据,镜像数据库(老婆)实时复制"谈话记录"。当主数据库突然宕机(丈夫说不出话),镜像数据库就要立即接管(妻子接话茬)——这就是所谓的自动故障转移。

但现实往往是这样的灾难场景:

-- 查看镜像会话状态(总出问题的查岗电话)
SELECT 
    database_id,
    mirroring_role_desc AS 当前角色,
    mirroring_state_desc AS 婚姻状态,
    mirroring_safety_level_desc AS 相处模式
FROM sys.database_mirroring
WHERE database_id = DB_ID('YourDatabase');

/* 返回结果解析:
   婚姻状态 = DISCONNECTED → 夫妻失联
   相处模式 = OFF → 开启撕逼模式 */

二、常见翻车现场与救火指南

2.1 场景一:网络闪断导致的"异地分居"

去年给某证券公司处理过一起典型案例:两地机房间的网络设备凌晨升级导致镜像中断。次日交易时段出现数据库响应延迟,交易系统显示"正在同步中..."却永远读不完进度条。

# 通过PowerShell检测网络链路(婚姻咨询师登场)
Import-Module SQLPS -DisableNameChecking

$primaryServer = "TCP:DBServer01,5022"
$mirrorServer = "TCP:DBServer02,5022"

Test-NetConnection -ComputerName $primaryServer.Split(':')[1].Trim('TCP:') -Port $primaryServer.Split(',')[1]
Test-NetConnection -ComputerName $mirrorServer.Split(':')[1].Trim('TCP:') -Port $mirrorServer.Split(',')[1]

# 预期输出应显示TcpTestSucceeded:True
# 若出现False建议检查:
# 1. Windows防火墙是否放行5022端口
# 2. 路由器的ACL列表是否包含对方IP
# 3. 网络设备的QoS策略是否限制流量

2.2 场景二:日志堆积引发"冷战危机"

某电商大促期间遇到过镜像延迟12小时的险情,事务日志文件暴涨到500GB,磁盘空间红色告警。此时不能直接删除日志文件,我们使用如下应急方案:

-- 三步急救法(婚姻调解三板斧)
-- 步骤1:检查发送队列(积压的未读消息)
SELECT 
    database_name,
    log_send_queue_size AS 待发送日志量_KB,
    (log_send_queue_size/1024.0) AS 待发送日志量_MB
FROM sys.dm_db_mirroring_transport_stats;

-- 步骤2:临时切换运行模式(从安全模式切到飙车模式)
ALTER DATABASE SalesDB 
SET PARTNER SAFETY OFF;  -- 相当于关闭吵架时的"情绪缓冲机制"

-- 步骤3:加速追赶(启动真心话大冒险)
EXEC sp_dbmmonitorupdate SalesDB;

三、数据同步的军规

3.1 绝对不能踩的雷区

在给某省级医保系统做容灾演练时,曾因忽略服务账户权限导致整个镜像会话崩溃。正确配置方式如下:

# 服务账户权限配置脚本(民政局登记流程)
$serviceAccount = "DOMAIN\SQLService"
$endpointName = "Mirroring_Endpoint"

# 创建端点
CREATE ENDPOINT [$endpointName]
STATE = STARTED
AS TCP (LISTENER_PORT = 5022)
FOR DATABASE_MIRRORING (ROLE = ALL)

# 授权语句(结婚证颁发)
GRANT CONNECT ON ENDPOINT::[$endpointName] TO [$serviceAccount]

3.2 性能优化的暗黑技巧

某视频网站的DBA曾跟我抱怨镜像导致CPU使用率飙升,后来发现是加密证书惹的祸。这是我们的优化方案:

-- 加密优化三步曲(给聊天记录上锁)
-- (1)检查当前加密状态
SELECT name, is_encrypted 
FROM sys.database_mirroring_endpoints;

-- (2)重建不加密的端点(拆除隔音墙)
DROP ENDPOINT Mirroring_Endpoint;

CREATE ENDPOINT Mirroring_Endpoint
STATE = STARTED
AS TCP (LISTENER_PORT = 5022)
FOR DATABASE_MIRRORING (
    ROLE = ALL,
    AUTHENTICATION = WINDOWS NEGOTIATE,
    ENCRYPTION = DISABLED  -- 关闭加密提高性能
);

-- (3)监控网络流量变化
SELECT * 
FROM sys.dm_db_mirroring_connections;

四、替代方案的华山论剑

当某物流公司的全球业务出现跨洲镜像延迟时,我们建议改用日志传送+手动故障转移的组合方案。配置对比如下:

指标 数据库镜像 日志传送
延迟 秒级 分钟级
自动切换 支持 不支持
网络要求 专线/高带宽 普通带宽
管理复杂度 中等

五、血泪教训总结

在经历了金融客户的交易数据丢失事故后,我们制定了一套标准操作规程:

  1. 预检查清单:每次维护前必须验证网络延迟(<5ms)、磁盘空间(>20%)、证书有效期(>30天)
  2. 监控四要素
    # 每日健康检查脚本(婚姻状况日报)
    check_disk_space.ps1
    check_mirroring_state.sql
    monitor_log_send_rate.sh
    alert_on_high_latency.py
    
  3. 故障演练手册:每季度模拟网络中断、主库宕机、日志损坏三种场景的应急演练