Windows Server SQL Server 2019 Always On高可用集群实战指南
在企业级数据库部署中,高可用性是最核心的需求之一。SQL Server Always On可用性组技术为关键业务数据提供了自动故障转移的保障机制,确保服务连续性。本文将手把手带你完成从零开始的全套部署流程,特别针对实际环境中常见的权限配置、网络设置等"坑点"提供详细解决方案。
1. 环境准备与先决条件检查
部署Always On高可用集群前,必须确保基础环境满足所有技术要求。我们建议使用三台相同配置的服务器组成集群,避免因硬件差异导致性能瓶颈。
1.1 硬件与系统要求
- 服务器配置:每节点至少16GB内存,4核CPU,100GB可用存储空间(根据数据库规模调整)
- 操作系统:Windows Server 2016/2019/2022 Datacenter Edition
- 域环境:所有节点必须加入同一个Active Directory域
- 存储:建议使用高性能SSD存储数据库文件
注意:生产环境强烈建议使用企业级存储解决方案,如SAN或高性能NAS,避免使用本地磁盘作为唯一存储。
1.2 软件安装清单
在主节点和所有辅助节点上需要安装以下组件:
- SQL Server 2019 Enterprise Edition(Always On功能需要企业版支持)
- SQL Server Management Studio 18.0或更高版本
- Windows故障转移集群功能
安装SQL Server时,必须勾选以下功能组件:
# 通过PowerShell检查已安装的SQL功能 Get-WindowsFeature -ComputerName $env:COMPUTERNAME | Where-Object {$_.Installed -eq $true -and $_.Name -like "*SQL*"}1.3 网络配置要点
集群节点间需要开通以下关键端口:
| 端口号 | 协议 | 用途 | 方向 |
|---|---|---|---|
| 1433 | TCP | SQL Server默认实例 | 双向 |
| 5022 | TCP | 可用性组端点通信 | 节点间双向 |
| 135 | TCP | WMI和集群通信 | 节点间双向 |
| 445 | TCP | SMB文件共享 | 节点间双向 |
| 3343 | UDP | 集群心跳检测 | 节点间双向 |
配置防火墙规则的PowerShell命令:
New-NetFirewallRule -DisplayName "SQL Server Always On" -Direction Inbound -LocalPort 1433,5022 -Protocol TCP -Action Allow New-NetFirewallRule -DisplayName "Cluster Communication" -Direction Inbound -LocalPort 135,445,3343 -Protocol TCP -Action Allow2. 故障转移集群配置
Always On可用性组依赖于Windows故障转移集群服务,这是整个高可用架构的基础。
2.1 创建故障转移集群
- 在所有节点上安装故障转移集群功能:
Install-WindowsFeature -Name Failover-Clustering -IncludeManagementTools- 验证集群配置(任一节点执行):
Test-Cluster -Node Node1,Node2,Node3- 创建新集群:
New-Cluster -Name SQLCluster -Node Node1,Node2,Node3 -StaticAddress 192.168.1.100 -NoStorage提示:生产环境建议为集群配置专用静态IP,避免使用DHCP分配的地址。
2.2 配置集群仲裁
合理的仲裁配置可以防止"脑裂"情况发生。对于三节点集群,推荐使用节点多数仲裁:
Set-ClusterQuorum -NodeMajority关键集群参数检查命令:
Get-Cluster | Select-Object Name, DynamicQuorum, QuorumType Get-ClusterNode | Select-Object Name, State, Weight3. SQL Server Always On配置
基础集群就绪后,需要在SQL Server层面启用和配置Always On功能。
3.1 启用Always On功能
- 在每个节点的SQL Server配置管理器中:
- 右键SQL Server服务 → 属性
- 切换到"Always On可用性组"选项卡
- 勾选"启用Always On可用性组"
- 重启SQL Server服务
验证功能是否启用:
-- 在每台服务器上执行 SELECT @@SERVERNAME AS [ServerName], SERVERPROPERTY('IsHadrEnabled') AS [IsHadrEnabled]3.2 创建可用性组
- 在主节点上准备示范数据库:
CREATE DATABASE HATestDB; GO USE HATestDB; GO CREATE TABLE TestData (ID INT PRIMARY KEY, DataValue NVARCHAR(100)); GO INSERT INTO TestData VALUES (1, 'Initial Test Data'); GO -- 执行完整备份 BACKUP DATABASE HATestDB TO DISK = 'C:\Backup\HATestDB.bak' WITH COMPRESSION;- 在辅助节点上还原数据库:
RESTORE DATABASE HATestDB FROM DISK = '\\PrimaryNode\Backup\HATestDB.bak' WITH NORECOVERY, REPLACE, MOVE 'HATestDB' TO 'E:\SQLData\HATestDB.mdf', MOVE 'HATestDB_log' TO 'F:\SQLLogs\HATestDB_log.ldf';- 在主节点创建可用性组:
CREATE AVAILABILITY GROUP [SQLAG] WITH (AUTOMATED_BACKUP_PREFERENCE = PRIMARY, DB_FAILOVER = ON, DTC_SUPPORT = NONE) FOR DATABASE [HATestDB] REPLICA ON 'NODE1' WITH ( ENDPOINT_URL = 'TCP://node1.domain.com:5022', AVAILABILITY_MODE = SYNCHRONOUS_COMMIT, FAILOVER_MODE = AUTOMATIC, BACKUP_PRIORITY = 50, SECONDARY_ROLE(ALLOW_CONNECTIONS = READ_ONLY) ), 'NODE2' WITH ( ENDPOINT_URL = 'TCP://node2.domain.com:5022', AVAILABILITY_MODE = SYNCHRONOUS_COMMIT, FAILOVER_MODE = AUTOMATIC, BACKUP_PRIORITY = 30, SECONDARY_ROLE(ALLOW_CONNECTIONS = READ_ONLY) ), 'NODE3' WITH ( ENDPOINT_URL = 'TCP://node3.domain.com:5022', AVAILABILITY_MODE = ASYNCHRONOUS_COMMIT, FAILOVER_MODE = MANUAL, BACKUP_PRIORITY = 20, SECONDARY_ROLE(ALLOW_CONNECTIONS = NO) );3.3 配置可用性组监听器
监听器为应用提供统一的连接入口,自动路由到当前主副本。
-- 在可用性组上添加监听器 ALTER AVAILABILITY GROUP [SQLAG] ADD LISTENER 'SQLAG-Listener' ( WITH IP ((N'192.168.1.150', N'255.255.255.0')), PORT = 1433 );验证监听器状态:
Get-ClusterResource | Where-Object {$_.ResourceType -eq "SQL Server Availability Group"} | Format-Table -AutoSize4. 运维与故障排查
部署完成后,需要掌握日常监控和常见问题的处理方法。
4.1 关键监控指标
建议定期检查以下性能计数器:
| 计数器路径 | 正常值范围 | 说明 |
|---|---|---|
| SQLServer:Availability Replica\Flow Control | < 1000 ms | 数据流动控制延迟 |
| SQLServer:Database Replica\Log Send Queue | 接近0 KB | 待发送日志量 |
| SQLServer:Database Replica\Redo Queue | < 1000 KB | 待重做日志量 |
| SQLServer:Wait Statistics\Hadr_sync_commit | < 100 ms (P99) | 同步提交等待时间 |
监控查询示例:
SELECT ar.replica_server_name, db_name(ds.database_id) as [Database], ds.synchronization_state_desc, ds.synchronization_health_desc, ds.log_send_queue_size, ds.log_send_rate, ds.redo_queue_size, ds.redo_rate FROM sys.dm_hadr_database_replica_states ds JOIN sys.availability_replicas ar ON ds.replica_id = ar.replica_id ORDER BY ar.replica_server_name, ds.database_id;4.2 常见问题解决方案
问题1:无法创建可用性组,提示"先决条件不满足"
排查步骤:
- 确认所有节点已启用Always On功能
- 检查SQL Server服务账户是否具有集群权限
- 验证端点是否可访问(telnet node1 5022)
- 检查防火墙规则是否允许相关端口通信
问题2:故障转移失败
典型原因:
- 集群见证配置不当
- 网络分区导致仲裁丢失
- 同步副本日志不同步
恢复命令:
# 强制转移(仅限紧急情况) Move-ClusterGroup -Name "SQLAG" -Node Node2 -IgnoreDependencies问题3:辅助副本无法连接
检查清单:
- 辅助副本是否配置为允许只读连接
- 只读路由列表是否配置正确
- 应用程序连接字符串是否指定了ApplicationIntent=ReadOnly
4.3 备份策略优化
利用可用性组特性实现备份负载分担:
-- 设置备份优先级 ALTER AVAILABILITY GROUP [SQLAG] MODIFY REPLICA ON 'NODE2' WITH (BACKUP_PRIORITY = 80); -- 查看当前备份偏好 SELECT ag.name AS [AG Name], ar.replica_server_name, ar.backup_priority, ar.secondary_role_allow_connections_desc FROM sys.availability_groups ag JOIN sys.availability_replicas ar ON ag.group_id = ar.group_id;备份脚本示例(在计划任务中运行):
$primaryReplica = (Get-SqlAvailabilityGroup -Path "SQLSERVER:\SQL\Node1\DEFAULT" -Name "SQLAG").PrimaryReplicaServerName if ($env:COMPUTERNAME -eq $primaryReplica) { # 在主副本上执行完整备份 Invoke-Sqlcmd -Query "BACKUP DATABASE [HATestDB] TO DISK = 'E:\Backups\HATestDB_Full_$(Get-Date -Format 'yyyyMMdd').bak' WITH COMPRESSION, CHECKSUM" } else { # 在辅助副本上执行差异备份 Invoke-Sqlcmd -Query "BACKUP DATABASE [HATestDB] TO DISK = 'E:\Backups\HATestDB_Diff_$(Get-Date -Format 'yyyyMMdd').bak' WITH DIFFERENTIAL, COMPRESSION, CHECKSUM" }