1. 为什么要做缩容操作?

在我们公司去年的一次服务器资源优化项目中,我亲历了某核心业务系统从6节点Always On集群缩减到3节点的完整过程。主数据库管理员在半夜的维护窗口手抖误删副本,导致业务系统出现半小时的查询超时,这充分说明了规范操作流程的重要性。

2. 基础环境准备

演示环境配置(适用于SQL Server 2019+)

# 查看当前可用性组状态(需在任意副本执行)
SELECT 
    ag.name AS AG_Name,
    ar.replica_server_name AS Replica,
    drs.database_name AS DB,
    drs.synchronization_state_desc AS Sync_State
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 ar.group_id = ag.group_id
WHERE
    ag.name = 'OrderSystem_AG'

/* 输出示例
AG_Name        Replica        DB        Sync_State
OrderSystem_AG SQLNODE01       OrderDB   SYNCHRONIZED
OrderSystem_AG SQLNODE02       OrderDB   SYNCHRONIZED
OrderSystem_AG SQLNODE03       OrderDB   SYNCHRONIZING
*/

3. 节点缩容六步操作法

3.1 选择撤离的节点

通过WSFC管理器优先处理状态为"Non-Active"的节点:

-- 识别最低优先级的同步副本
SELECT 
    replica_server_name,
    availability_mode_desc,
    failover_mode_desc,
    primary_role_allow_connections_desc
FROM 
    sys.availability_replicas
WHERE 
    group_id = (SELECT group_id FROM sys.availability_groups WHERE name = 'OrderSystem_AG')
ORDER BY 
    priority DESC

3.2 停止数据同步(关键步骤)

使用PowerShell进行优雅离线:

# 安全断开副本连接(需在要移除的节点执行)
$instanceName = "SQLNODE03\PROD"
$agName = "OrderSystem_AG"

Set-Location SQLSERVER:\SQL\$instanceName\AvailabilityGroups\$agName
Suspend-SqlAvailabilityDatabase -Path ".\Databases\*"
Set-SqlAvailabilityReplica -Path ".\AvailabilityReplicas\$($env:COMPUTERNAME)" -AvailabilityMode Offline -FailoverMode Manual

3.3 配置更新原子操作

通过TSQL进行事务性修改:

-- 从可用性组移除副本(在主副本执行)
ALTER AVAILABILITY GROUP OrderSystem_AG
REMOVE REPLICA ON N'SQLNODE03';

-- 验证副本状态更新
SELECT 
    replica_server_name,
    join_state_desc,
    connected_state_desc
FROM 
    sys.dm_hadr_availability_replica_states
WHERE 
    replica_server_name = 'SQLNODE03'

4. 深水区注意事项

4.1 仲裁权重重新分配

在Windows故障转移集群中调整投票数:

# 检查当前投票配置
Get-ClusterNode -Name "SQLNODE03" | Format-List *

# 修改节点投票权重
(Get-ClusterNode -Name "SQLNODE03").NodeWeight = 0

# 验证剩余节点投票总数是否为奇数
$totalVotes = (Get-ClusterNode | Where-Object {$_.State -eq 'Up'}).Count
if ($totalVotes % 2 -eq 0) {
    Write-Warning "当前投票节点数量为偶数,建议至少保留一个见证磁盘!"
}

4.2 性能基线重建

使用Query Store重建查询优化器统计:

-- 清除旧性能基线
ALTER DATABASE OrderDB SET QUERY_STORE CLEAR ALL;

-- 创建新基线
DECLARE @baseline_name VARCHAR(128) = N'Post_ScaleIn_Baseline_' + CONVERT(VARCHAR(8), GETDATE(), 112)
EXEC sp_query_store_create_baseline @baseline_name;

5. 经验与教训

在某证券交易系统的缩容操作中,我们忽视了日志传送延迟的问题。当主副本的日志生成速率达到500MB/分钟时,直接移除处于异步提交模式的副本会导致未同步事务丢失。最终通过提前设置日志保留策略避免了该问题:

-- 配置日志保留策略
ALTER AVAILABILITY GROUP OrderSystem_AG 
MODIFY REPLICA ON N'SQLNODE03' 
WITH (SEEDING_MODE = AUTOMATIC, BACKUP_PRIORITY = 10);

-- 查询待提交事务
SELECT 
    transaction_id,
    database_transaction_log_bytes_used
FROM 
    sys.dm_tran_database_transactions
WHERE 
    database_id = DB_ID('OrderDB')

6. 关联技术解析

**Windows故障转移集群(WSFC)**的节点状态维护直接影响可用性组的健康检查机制。通过事件查看器过滤下列ID可获取关键信息:

  • 1135:可用性组角色更改
  • 1141:副本状态变更
  • 1177:仲裁丢失警告

7. 操作总结与建议

  • 最佳窗口期:选择业务低峰期的周二/周四凌晨执行
  • 回退方案:提前备份MSDB和Master系统数据库
  • 监控指标:重点关注hadr_synchronized_databasecluster_quorum性能计数器