一、SQL Server Always On 可用性组到底是个啥玩意儿?
兄弟们,今天咱们来聊聊SQL Server里这个听起来高大上的"Always On可用性组"。说白了,这就是微软给我们准备的一套数据库高可用性解决方案,让咱们的数据库能够像打不死的小强一样顽强生存。
想象一下这样的场景:你正在美滋滋地喝着咖啡,突然主数据库服务器宕机了。要是没有Always On,这会儿你可能就要被老板叫去喝茶了。但有了它,系统会自动切换到备用服务器上,用户甚至都感觉不到异常,你的咖啡时间也不会被打扰。
这个技术其实是在SQL Server 2012版本中首次亮相的,它建立在Windows Server故障转移集群(WSFC)的基础上。简单来说,就是把一组数据库打包成一个"可用性组",然后这个组可以在多个SQL Server实例之间来回切换。
二、可用性组的工作原理剖析
让我们深入扒一扒它的工作原理。可用性组的核心思想其实很简单:主副本负责处理所有读写请求,同时把这些操作记录发送到辅助副本。
这里有个关键点要记住:辅助副本可以配置成三种模式:
- 同步提交模式 - 主副本必须等辅助副本确认收到数据后才会提交事务
- 异步提交模式 - 主副本不需要等待辅助副本确认
- 仅配置模式 - 特殊用途,不存储数据
举个生活中的例子,同步提交就像你发重要邮件必须等对方回复"收到"才放心;异步提交则像发普通消息,发出去就完事了。
下面我们来看个配置示例(技术栈:SQL Server 2019):
-- 创建可用性组
CREATE AVAILABILITY GROUP [AG_Demo]
WITH (
AUTOMATED_BACKUP_PREFERENCE = PRIMARY,
DB_FAILOVER = ON,
DTC_SUPPORT = NONE,
REQUIRED_SYNCHRONIZED_SECONDARIES_TO_COMMIT = 0
)
FOR DATABASE [YourDatabase]
REPLICA ON
'PrimaryServer' WITH (
ENDPOINT_URL = 'TCP://PrimaryServer:5022',
AVAILABILITY_MODE = SYNCHRONOUS_COMMIT,
FAILOVER_MODE = AUTOMATIC,
BACKUP_PRIORITY = 50,
SECONDARY_ROLE(ALLOW_CONNECTIONS = READ_ONLY)
),
'SecondaryServer' WITH (
ENDPOINT_URL = 'TCP://SecondaryServer:5022',
AVAILABILITY_MODE = SYNCHRONOUS_COMMIT,
FAILOVER_MODE = AUTOMATIC,
BACKUP_PRIORITY = 50,
SECONDARY_ROLE(ALLOW_CONNECTIONS = READ_ONLY)
);
这段代码创建了一个名为AG_Demo的可用性组,包含主副本和辅助副本,都配置为同步提交和自动故障转移模式。
三、实战部署步骤详解
现在咱们来手把手教你部署一个Always On可用性组。整个过程可以分为以下几个步骤:
- 准备Windows Server故障转移集群
- 在所有节点上安装SQL Server
- 启用Always On功能
- 创建可用性组
- 添加数据库到可用性组
让我们重点看看PowerShell脚本部分(技术栈:Windows Server 2019 + SQL Server 2019):
# 启用Always On功能
Import-Module SQLPS -DisableNameChecking
# 在所有节点上启用Always On
$nodes = "Server1", "Server2", "Server3"
foreach ($node in $nodes) {
Enable-SqlAlwaysOn -ServerInstance $node -Force
}
# 创建端点
$endpointName = "Hadr_endpoint"
$port = 5022
$sql = @"
CREATE ENDPOINT [$endpointName]
STATE = STARTED
AS TCP (LISTENER_PORT = $port)
FOR DATA_MIRRORING (
ROLE = ALL,
AUTHENTICATION = CERTIFICATE dbm_certificate,
ENCRYPTION = REQUIRED ALGORITHM AES
)
"@
Invoke-Sqlcmd -Query $sql -ServerInstance "Server1"
Invoke-Sqlcmd -Query $sql -ServerInstance "Server2"
这个脚本首先在所有节点上启用Always On功能,然后为每个实例创建镜像端点。注意要提前准备好证书。
四、故障转移的艺术
故障转移是Always On最核心的功能,但这里面门道可不少。咱们得搞清楚几种不同的故障转移方式:
- 自动故障转移 - 当主副本挂了,系统自动切换到同步副本
- 手动故障转移 - DBA主动发起的切换
- 强制故障转移 - 紧急情况下使用,可能丢失数据
来看个手动故障转移的T-SQL示例:
-- 检查当前副本角色
SELECT ag.name AS [AG Name], ar.replica_server_name, ars.connected_state_desc, ars.synchronization_health_desc
FROM sys.availability_groups ag
JOIN sys.availability_replicas ar ON ag.group_id = ar.group_id
JOIN sys.dm_hadr_availability_replica_states ars ON ar.replica_id = ars.replica_id
-- 执行故障转移
ALTER AVAILABILITY GROUP [AG_Demo] FAILOVER;
执行故障转移前一定要先检查副本状态,确保目标副本是健康的。强制故障转移要慎用,因为它可能导致数据丢失。
五、性能调优技巧大公开
配置好了不代表就完事了,调优才是重头戏。下面这些技巧能让你的可用性组飞起来:
- 网络优化:确保节点间有专用网络通道
- 日志文件优化:放在高性能磁盘上
- 并行重做线程:提高辅助副本应用日志的速度
来看个设置并行重做的示例:
-- 在辅助副本上设置并行重做
ALTER DATABASE [YourDatabase] SET HADR RESUME WITH (MAX_DOP = 4);
-- 查看当前重做设置
SELECT
db_name(database_id) as DatabaseName,
redo_queue_size,
redo_rate,
log_send_queue_size
FROM sys.dm_hadr_database_replica_states
WHERE is_local = 1;
这个设置可以让辅助副本使用最多4个线程来并行应用日志,显著提高数据同步速度。
六、常见坑爹问题及解决方案
在实际使用中,我们经常会遇到一些让人抓狂的问题。下面列举几个最常见的:
- 同步延迟高:通常是网络或磁盘I/O瓶颈
- 故障转移失败:可能因为仲裁配置不当
- 连接字符串问题:应用连接不到新主副本
对于连接字符串问题,正确的写法应该是这样的(技术栈:.NET Core):
// 正确的连接字符串示例
string connectionString = "Server=tcp:AGListener,1433;Database=YourDB;Integrated Security=SSPI;MultiSubnetFailover=True";
// 错误示例(直接连接单个节点)
string badConnectionString = "Server=tcp:PrimaryServer,1433;Database=YourDB;Integrated Security=SSPI";
注意要使用监听器名称而不是具体服务器名,并且要加上MultiSubnetFailover参数。
七、应用场景与选型建议
Always On可用性组最适合以下场景:
- 需要高可用性的关键业务数据库
- 需要读写分离的OLTP系统
- 需要灾难恢复解决方案
但它也不是万能的,以下情况可能要考虑其他方案:
- 超大规模数据库(考虑分片)
- 跨平台需求(考虑第三方工具)
- 预算有限的小型应用(考虑日志传送)
八、总结与最佳实践
经过上面的探讨,我们可以总结出以下最佳实践:
- 至少配置两个同步副本实现自动故障转移
- 为可用性组配置专用监听器
- 定期测试故障转移流程
- 监控同步延迟和系统健康状况
- 为应用程序配置正确的连接字符串
记住,高可用性不是配置好了就一劳永逸的,需要持续的监控和维护。希望这篇文章能帮助你在SQL Server高可用性之路上少踩坑!
评论