SQL Server 故障转移群集(FCI)
你的服务器突然宕机了。
如果是硬件故障(电源、主板、内存),单靠软件层面的高可用无法解决。你需要 FCI——故障转移群集。
故障转移群集(Failover Cluster Instance)是 SQL Server 最基础的高可用方案,基于 Windows Server Failover Cluster(WSFC),实现硬件级别的故障保护。
这篇文章,带你深入理解 SQL Server FCI。
故障转移群集概述
什么是 FCI?
FCI = 多个 SQL Server 实例组成一个「虚拟服务器」,共享存储。
┌─────────────────────────────────────────────────────────────┐
│ SQL Server FCI 架构 │
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ WSFC 群集 │ │
│ │ │ │
│ │ ┌──────────────┐ ┌──────────────┐ │ │
│ │ │ 节点 1 │◄──────►│ 节点 2 │ │ │
│ │ │ (SQL Node1) │ │ (SQL Node2) │ │ │
│ │ │ │ │ │ │ │
│ │ │ 实例:MSSQLSERVER │ 实例:MSSQLSERVER │ │ │
│ │ │ 虚拟 IP:VIP1 │ │ 虚拟 IP:VIP1 │ │ │
│ │ └──────────────┘ └──────────────┘ │ │
│ │ │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │ │
│ │ 共享存储 │
│ ▼ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ SAN 存储 │ │
│ │ ┌──────────────┐ ┌──────────────┐ │ │
│ │ │ 数据文件 │ │ 日志文件 │ │ │
│ │ │ (mdf/ldf) │ │ (.ldf) │ │ │
│ │ └──────────────┘ └──────────────┘ │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │
│ 客户端通过虚拟网络名(VNN)连接 │
└─────────────────────────────────────────────────────────────┘FCI vs Always On
| 特性 | FCI | Always On AG |
|---|---|---|
| 保护级别 | 实例级 | 数据库级 |
| 存储 | 必须共享 SAN | 不需要共享存储 |
| 故障转移 | 实例重启 | 数据库快速切换 |
| 读写分离 | ✗ | ✓ |
| 多副本 | ✗ | ✓ |
| 跨子网灾备 | ✗ | ✓ |
| 成本 | 需要 SAN | 可用普通存储 |
适用场景
| FCI 适用 | Always On AG 适用 |
|---|---|
| 操作系统级保护 | 数据库级保护 |
| 硬件故障保护 | 硬件 + 软件故障保护 |
| 简单高可用需求 | 读写分离需求 |
| 有共享 SAN 存储 | 无共享存储或异地灾备 |
WSFC 核心概念
节点(Node)
节点 = 群集中的每台物理服务器。
┌─────────────────────────────────────────────────────────────┐
│ WSFC 节点 │
│ │
│ 物理服务器 │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ Windows Server + SQL Server 实例 │ │
│ │ 加入 WSFC 群集 │ │
│ │ 参与故障检测和转移 │ │
│ └─────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘仲裁(Quorum)
仲裁 = 确保群集正常运行的投票机制。
┌─────────────────────────────────────────────────────────────┐
│ 仲裁机制 │
│ │
│ 目的:确保即使部分节点故障,群集仍能正常运行 │
│ │
│ 投票权重: │
│ - 每个节点:1 票 │
│ - 磁盘见证:1 票 │
│ - 文件共享见证:1 票 │
│ │
│ 多数原则: │
│ - 总票数 N │
│ - 正常节点 > N/2 才能运行 │
│ - 否则:群集停止 │
└─────────────────────────────────────────────────────────────┘仲裁模式
| 模式 | 说明 | 适用场景 |
|---|---|---|
| 节点多数 | 节点投票,简单多数即可 | 奇数节点(3、5、7) |
| 节点和磁盘多数 | 节点 + 见证磁盘投票 | 双节点 + 共享存储 |
| 节点和文件共享多数 | 节点 + 见证文件共享投票 | 双节点,无共享存储 |
| 仅磁盘 | 仅见证磁盘投票 | 不推荐,无节点投票 |
| 无多数:仅磁盘 | 仅磁盘,不推荐 | 不推荐 |
配置示例
powershell
# 查看当前仲裁配置
Get-ClusterQuorum
# 修改为节点和文件共享多数
Set-ClusterQuorum -FileShareWitness \\FileServer\Witness -NodeAndFileShareMajority
# 查看投票权重
Get-ClusterNode | Select-Object Name, NodeWeight, StateFCI 工作原理
故障检测
┌─────────────────────────────────────────────────────────────┐
│ 故障检测机制 │
│ │
│ 1. 心跳检测 │
│ 节点间定期发送心跳(默认 1 秒) │
│ │
│ 2. 资源健康检查 │
│ WSFC 定期检查 SQL Server 服务状态 │
│ 检查端口可达性 │
│ 执行健康存储过程(sp_server_diagnostics) │
│ │
│ 3. 故障判定 │
│ 连续 N 次健康检查失败 = 故障 │
│ 节点不可达 = 可能故障 │
└─────────────────────────────────────────────────────────────┘故障转移过程
┌─────────────────────────────────────────────────────────────┐
│ 故障转移过程 │
│ │
│ 1. 故障检测 │
│ WSFC 检测到节点 1 不可用 │
│ │
│ 2. 仲裁确认 │
│ 节点 2 + 见证确认可以接管 │
│ │
│ 3. 资源停止 │
│ WSFC 停止节点 1 上的 SQL Server 服务 │
│ 卸载共享存储 │
│ │
│ 4. 资源启动 │
│ 在节点 2 上启动 SQL Server 服务 │
│ 加载共享存储 │
│ 执行恢复 │
│ │
│ 5. 重定向客户端 │
│ 客户端通过 VNN 重新连接 │
│ │
│ 总时间:通常 1-3 分钟 │
└─────────────────────────────────────────────────────────────┘故障转移类型
| 类型 | 触发方式 | 说明 |
|---|---|---|
| 自动故障转移 | 系统自动触发 | 需要双节点 + 仲裁 |
| 计划内故障转移 | 管理员手动执行 | 正常维护操作 |
| 手动故障转移 | 管理员强制执行 | 可能丢数据 |
安装与配置
前置条件
| 要求 | 说明 |
|---|---|
| Windows Server | Enterprise/Datacenter 版本 |
| WSFC | 需要配置 |
| 共享存储 | SAN 或 SOFS |
| 域账户 | 域环境 |
| 网络 | 心跳网络 + 公网网络 |
| SQL Server | 企业版 |
安装步骤
powershell
# 1. 安装故障转移群集功能(所有节点)
Install-WindowsFeature -Name Failover-Clustering -IncludeManagementTools
# 2. 验证群集配置
Test-Cluster -Node Node1, Node2
# 3. 创建群集
New-Cluster -Name SQLCluster -Node Node1, Node2 -StaticAddress 192.168.1.100
# 4. 配置仲裁
Set-ClusterQuorum -NodeAndFileShareMajority -FileShareWitness \\FileServer\Witness
# 5. 安装 SQL Server(选择故障转移群集)SQL Server 安装
powershell
# 在节点 1 上启动安装向导,选择「故障转移群集」
# 配置项:
# - 群集网络:公网 IP + 心跳 IP
# - 共享磁盘:选择 SAN 磁盘
# - 群集资源组:SQL Server
# - 客户端访问点:虚拟网络名(VNN)和虚拟 IP
# 在节点 2 上添加节点
Setup.exe /Action=AddNode /INSTANCENAME="MSSQLSERVER"客户端连接
虚拟网络名(VNN)
VNN = 客户端连接的虚拟服务器名称。
连接字符串:
Server=SQLCluster_VNN; -- 虚拟网络名
Database=SalesDB;
-- 故障转移后自动重定向连接重试
java
// Java 连接字符串
String connectionString =
"jdbc:sqlserver://SQLCluster_VNN:1433;" +
"databaseName=SalesDB;" +
"failoverPartner=SQLCluster_VNN;" + -- 故障转移伙伴
"ConnectRetryCount=3;" + // 连接重试次数
"ConnectRetryInterval=10;"; // 重试间隔(秒)
// 故障发生时:
// 1. 当前连接断开
// 2. JDBC 驱动自动重试连接
// 3. 连接到故障转移后的节点
// 4. 应用无感知监控与维护
群集监控
powershell
# 查看群集状态
Get-Cluster
# 查看节点状态
Get-ClusterNode
# 查看资源状态
Get-ClusterResource
# 查看故障转移历史
Get-ClusterLog -TimeSpan 1 | Select-String "Failover"
# 查看 SQL Server 资源
Get-ClusterResource | Where-Object {$_.ResourceType -eq "SQL Server"}DMV 监控
sql
-- 查看 FCI 相关信息
SELECT
@@SERVERNAME AS CurrentNode,
SERVERPROPERTY('ComputerNamePhysicalNetBIOS') AS PhysicalNode,
SERVERPROPERTY('IsClustered') AS IsClustered,
SERVERPROPERTY('ClusterName') AS ClusterName,
SERVERPROPERTY('ClusterNodeName') AS ClusterNode;
-- 查看实例状态
SELECT
session_id,
host_name,
program_name,
login_name,
status,
reads,
writes,
cpu_time
FROM sys.dm_exec_sessions
WHERE is_user_process = 1;健康检查
sql
-- 执行健康检查存储过程
EXEC sp_server_diagnostics;
-- 查看诊断结果
SELECT
CREATE_DATE,
component_type,
component_name,
state,
data
FROM sys.dm_server_registry;
-- 查看最近错误日志
EXEC xp_readerrorlog;常见问题
问题 1:「群集资源无法联机」
可能原因:
1. 共享存储不可访问
2. 磁盘权限问题
3. 服务账户问题
4. IP 地址冲突
解决方案:
1. 检查 SAN 连接
2. 验证磁盘权限(Everyone 完全控制)
3. 检查服务账户密码和权限
4. 检查 IP 配置问题 2:「自动故障转移失败」
可能原因:
1. 仲裁不足(无法达成多数)
2. 目标节点资源不足
3. 网络隔离
解决方案:
1. 检查仲裁配置
2. 确保目标节点有足够资源
3. 检查网络配置问题 3:「所有节点都显示 Down」
这是「脑裂」问题,仲裁不足导致群集停止。
解决方案:
1. 使用强制仲裁启动群集
2. 检查见证服务器状态
3. 修复网络问题后重新配置仲裁与 Always On 的结合
为什么需要两者结合?
┌─────────────────────────────────────────────────────────────┐
│ FCI + Always On 架构 │
│ │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ FCI 节点 1 │ │
│ │ ┌─────────────────────────────────────────────────┐ │ │
│ │ │ Always On AG │ │ │
│ │ │ ┌─────────────┐ ┌─────────────┐ │ │ │
│ │ │ │ 主副本 │◄──►│ 辅助副本 │ │ │ │
│ │ │ └─────────────┘ └─────────────┘ │ │ │
│ │ └─────────────────────────────────────────────────┘ │ │
│ └─────────────────────────────────────────────────────────┘ │
│ │ │
│ │ 共享存储 │
│ ┌─────────────────────────────────────────────────────────┐ │
│ │ FCI 节点 2 │ │
│ │ (类似节点 1 的配置) │ │
│ └─────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────┘优势:
- FCI 保护操作系统和硬件故障
- Always On 保护数据库故障并支持读写分离
- 两层保护,最大程度保障可用性
面试追问方向
- FCI 和 Always On 的核心区别是什么?
- 什么是 WSFC 仲裁?为什么需要仲裁?
- FCI 的故障转移过程是怎样的?
- FCI 需要什么样的存储?与 Always On 有什么不同?
- 什么是虚拟网络名(VNN)?客户端如何连接?
- FCI 和 Always On 可以同时使用吗?
下一步
理解了 FCI,我们来看 SQL Server 镜像(Database Mirroring),了解一种已过时的但仍有参考价值的高可用方案。
