一、为什么要搞自动故障转移?
某天夜里2点,我刚躺下就被生产环境的告警震醒。主数据库所在的物理机突然宕机,业务系统瞬间瘫痪。当时还没配置自动故障转移,等到运维手动切换时已经流失了上百万订单——这惨痛教训让我彻底明白Always On的价值。
就像足球比赛的替补队员机制,Always On自动故障转移让数据库服务拥有随时待命的"替补选手"。当主库(Principal)出现故障时,秒级切换备用库(Secondary)接棒,整个过程无需人工干预。
二、手把手搭建高可用集群
(本章技术栈:Windows Server 2022 + SQL Server 2022 Enterprise)
- 先决条件检查清单
- 三台域控环境服务器(主节点、辅助节点、见证服务器)
- 共享存储或每节点独立存储
- 相同版本的SQL Server实例
- 开放5022端口用于端点通信
- 见证服务器配置示例
Install-WindowsFeature -Name Failover-Clustering -IncludeManagementTools
# 创建集群(注意替换实际IP)
New-Cluster -Name AGCluster -Node "NodeA","NodeB" -StaticAddress 192.168.1.100 -NoStorage
- 数据库镜像端点配置
-- 在所有节点执行
CREATE ENDPOINT AG_Endpoint
STATE = STARTED
AS TCP (LISTENER_PORT = 5022)
FOR DATABASE_MIRRORING (ROLE = ALL)
三、完整可用性组创建实录
- 创建可用性组
-- 主节点执行
CREATE AVAILABILITY GROUP Sales_AG
WITH (AUTOMATED_BACKUP_PREFERENCE = PRIMARY)
FOR DATABASE SalesDB
REPLICA ON
'NODEA\SQL2022' WITH (
ENDPOINT_URL = 'TCP://nodeA:5022',
AVAILABILITY_MODE = SYNCHRONOUS_COMMIT,
FAILOVER_MODE = AUTOMATIC,
SEEDING_MODE = AUTOMATIC
),
'NODEB\SQL2022' WITH (
ENDPOINT_URL = 'TCP://nodeB:5022',
AVAILABILITY_MODE = SYNCHRONOUS_COMMIT,
FAILOVER_MODE = AUTOMATIC,
SEEDING_MODE = AUTOMATIC
)
- 辅助节点接入
-- 在辅助节点执行
ALTER AVAILABILITY GROUP Sales_AG JOIN
ALTER AVAILABILITY GROUP Sales_AG GRANT CREATE ANY DATABASE
四、故障转移验证大全
- 模拟主库宕机
# 突然关闭主库服务
Stop-Service -Name MSSQLSERVER -Force
# 验证日志输出(关键指标)
Get-ClusterLog -Node NodeB -UseLocalTime | Select-String "failover"
- 应用重连测试代码(C#示例)
var connectionString = "Server=AGListener;Database=SalesDB;MultiSubnetFailover=True";
using (var conn = new SqlConnection(connectionString))
{
try
{
conn.Open();
// 断线重试逻辑
var retryPolicy = Policy
.Handle<SqlException>()
.WaitAndRetry(3, retryAttempt =>
TimeSpan.FromSeconds(Math.Pow(2, retryAttempt)));
retryPolicy.Execute(() =>
{
using (var cmd = new SqlCommand("SELECT @@SERVERNAME", conn))
{
Console.WriteLine($"当前连接服务器: {cmd.ExecuteScalar()}");
}
});
}
catch (Exception ex)
{
Console.WriteLine($"连接异常: {ex.Message}");
}
}
五、技术选择的利弊权衡
🟢 核心优势:
- 秒级故障切换(实测平均1.8秒)
- 支持最多8个同步副本
- 允许读取扩展
- 集成Windows故障转移集群
🔴 已知限制:
- 需要企业版授权
- 跨子网延迟可能触发误切换
- 日志传输带宽消耗较高
- 无法自动重建损坏副本
六、前辈的避坑指南
- 存储层级同步问题: 某次存储阵列延迟导致日志积压,同步延迟达到6小时。解决方案是:
-- 监控同步状态
SELECT
ag.name AS AG_Name,
ar.replica_server_name,
drs.database_name,
drs.synchronization_state_desc,
drs.log_send_queue_size
FROM sys.dm_hadr_database_replica_states drs
JOIN sys.availability_replicas ar ON drs.replica_id = ar.replica_id
JOIN sys.availability_groups ag ON ag.group_id = ar.group_id
- 网络隔离假死现象: 建议设置更精准的检测阈值
(Get-Cluster).SameSubnetThreshold = 20
(Get-Cluster).CrossSubnetThreshold = 40
七、适用场景推荐
✅ 推荐使用场景:
- 金融交易系统
- 电商大促期间
- 医疗HIS系统
- 物联网实时数据处理
❌ 不推荐场景:
- 开发测试环境
- 低于50GB的小型数据库
- 跨地域多活部署
- 非Windows平台
八、行业最佳实践
某证券公司真实架构:
- 主库:DL580 Gen10物理机
- 辅助库:VMware虚拟化集群
- 见证服务器:Azure云托管实例
- 网络延迟:内网<2ms,异地灾备<50ms 实现了全年99.999%的可用性指标
九、结语
经历了那次生产事故后,我为所有核心系统都部署了Always On。最近三年处理了17次硬件故障、5次网络中断,但业务系统始终保持零感知。自动故障转移就像给数据库上了双保险,让它具备"断臂求生"的能力——这是DBA能给业务最坚实的承诺。
评论