Han*_*non 23 sql-server-2005 sql-server mirroring troubleshooting
我们有两个生产 SQL Server 运行 SQL Server 2005 SP4 和累积更新 3。两台服务器都在相同的物理机器上运行。DELL PowerEdge R815 配备 4 个 12 核 CPU 和 512GB(是 GB)内存,以及用于所有 SQL 数据库和日志的 10GB iSCSI SAN 连接驱动器。操作系统是带有所有 SP 和 Windows 更新的 Microsoft Windows Server 2008 R2 企业版。操作系统驱动器是一个 RAID 5 阵列,包含 3 个 72GB 2.5" 15k SAS 驱动器。SAN 是一个 Dell EqualLogic 6510,带有 48 个 10K SAS 3.5" 驱动器,配置为 RAID 50,为 2 个 SQL Server 划分为各种 LUN,并且还共享带有一台 Exchange 机器和几台 VMWare 服务器。
我们有 20 多个数据库,其中 11 个使用见证服务器以高可用性镜像。见证服务器是一台运行 SQL Server 实例的低功耗机器,它除了提供见证服务外别无其他用途。最大的镜像数据库是 450GB,产生大约 100-300 iops。数据库镜像监视器报告的当前发送速率约为每秒 100kb 到 10mb,镜像提交开销(通常)为 0 毫秒。镜像服务器跟上主体没有问题。
我们一直在经历镜像故障转移。有时单个数据库会进行故障转移,有时几乎所有数据库都会同时进行故障转移。例如,昨晚,我们对 11 个数据库中的 10 个进行了故障转移,其余数据库保持可访问状态,直到我手动对其进行故障转移。
我已经执行了几个故障排除步骤来尝试确定问题,但到目前为止还没有解决问题:
1) 该机器配备了 Broadcom BCM5709C NetXtreme II 4 端口千兆网络适配器,我们最初将其用作主要网络连接。此后,我们在两台机器上都安装了 Intel(R) PRO/1000 PT 双端口服务器适配器,以消除 NIC 问题。
2) 所有数据库每晚都有一个自动完整备份以及镜像所涉及数据库的日志备份。日志文件的使用受到监控,很少超过 15%。主数据库的日志文件为 125GB,由 159 个虚拟日志文件组成,大小从 511MB 到 1GB。TempDB 位于它自己的 LUN 上,由 24 x 2GB 文件组成。
3) 见证服务器上的 SQL Server 日志显示除以下错误之外没有任何错误: 30 秒后,数据库“Data”的镜像连接到“TCP://SQL02.DOMAIN.INET:5022”已超时,但没有响应。检查服务和网络连接。
主服务器和辅助服务器上的 SQL Server 日志显示与镜像相关的消息:
到“TCP://SQL01.DOMAIN.INET:5022”的镜像连接已超时,数据库“Data”在 30 秒后没有响应。检查服务和网络连接。
由于角色同步,镜像数据库“Data”正在将角色从“PRINCIPAL”更改为“MIRROR”。 (这里故意拼错了同步,因为这正是实际消息的显示方式。)
由于故障转移,镜像数据库“Data”正在将角色从“PRINCIPAL”更改为“MIRROR”。
由于来自合作伙伴的故障转移,镜像数据库“Data”正在将角色从“MIRROR”更改为“PRINCIPAL”。
SQL Server 服务继续运行,网络连接似乎保持正常。我们始终有 500 到 2500 个会话连接到每个服务器(主要是连接到单个数据库上的服务代理队列的机器人应用程序)。
4) 使用 NET SH 语法禁用 TCP Chimney 和 RSS 等。
5) 我在两台机器上运行了 SQL Server 2005 最佳实践分析器,除了非常偶然的应用程序事件日志错误 833 之外,没有发现其他任何东西,其中没有一个与故障转移事件重合:
SQL Server 在数据库 [Data] (9) 中的文件 [F:\Data.MDF] 上遇到 1 次 I/O 请求需要超过 15 秒才能完成。操作系统文件句柄是 0x00000000000010A0。最近一次 long I/O 的偏移量为:0x000007d4b10000)。
6) 有时我们会看到“客户端无法重用带有 SPID XXX 的会话,该会话已为连接池重置。此错误可能是由较早的操作失败引起的。在此错误消息之前检查失败操作的错误日志.” 由两台服务器生成。似乎没有表明任何问题的“较早”消息。
7) 数据库邮件偶尔会向应用程序事件日志写入错误:
异常类型:Microsoft.SqlServer.Management.SqlIMail.Server.Common.BaseException 消息:连接出错。原因:超时已过期。操作完成前超时时间已过或服务器未响应。连接参数:服务器名称:MGSQL02,数据库名称:msdb 数据:System.Collections.ListDictionaryInternal TargetSite:Void OpenConnection(Microsoft.SqlServer.Management.Common. SqlConnectionInfo) 帮助链接:NULL 来源:DatabaseMailEngine
Microsoft.SqlServer.Management.SqlIMail.Server.DataAccess.ConnectionManager.OpenConnection(SqlConnectionInfo ci) 的堆栈跟踪信息 Microsoft.SqlServer.Management.SqlIMail.Server.DataAccess.DataAccessAdapter.OpenConnection(String dbServerName, String dbName, String userName, String password ) 在 Microsoft.SqlServer.Management.SqlIMail.IMailProcess.QueueItemProcesser.ProcessQueueItems(String dbName, String dbServerName, Int32 lifeMinimumSec, LogLevel loggingLevel)
我相信超时导致故障转移;什么可能导致这些超时?显然,如果存在实际的网络问题,例如电缆损坏或交换机损坏,可能会导致数据包丢失并因此超时,但是还有哪些其他事情会导致超时?阻塞?如果 MSDB 或其他一些系统数据库有 I/O 超时,是否会导致镜像故障转移?
感谢您的任何建议!
MSDN 有以下关于超时机制本身的说法:
镜像超时机制
由于服务器实例无法直接检测软错误,因此软错误可能会导致服务器实例无限期等待。为了防止这种情况,数据库镜像实现了自己的超时机制,基于镜像会话中的每个服务器实例以固定的时间间隔在每个打开的连接上发送一个 ping。
要保持连接打开,服务器实例必须在定义的超时期限内接收该连接上的 ping,加上再发送一个 ping 所需的时间。在超时期间收到 ping 表示连接仍然打开并且服务器实例正在通过它进行通信。收到 ping 后,服务器实例会重置该连接上的超时计数器。
如果在超时期间未在连接上收到 ping,则服务器实例认为该连接已超时。服务器实例关闭超时连接并根据会话的状态和操作模式处理超时事件。
netsh interface tcp show global 显示:
Receive-Side Scaling State : disabled
Chimney Offload State : disabled
NetDMA State : enabled
Direct Cache Acess (DCA) : disabled
Receive Window Auto-Tuning Level : disabled
Add-On Congestion Control Provider : ctcp
ECN Capability : disabled
RFC 1323 Timestamps : disabled
Run Code Online (Sandbox Code Playgroud)
netsh interface ipv4 show dynamicportrange tcp
Protocol tcp Dynamic Port Range
Start Port : 1025
Number of Ports : 64510
Run Code Online (Sandbox Code Playgroud)
SELECT name, value_in_use FROM sys.configurations
临时分布式查询 0
亲和 I/O 掩码 0
亲和掩码 0
Affinity64 I/O 掩码 0
亲和性 64 掩码 0
特工 XP 1
允许更新 0
敬畏启用 0
阻塞进程阈值 5
c2 审计模式 0
clr 启用 1
启用通用标准合规性 0
并行性的成本阈值 4
跨数据库所有权链接 0
光标阈值 -1
数据库邮件 XP 1
默认全文语言 1033
默认语言 0
默认跟踪启用 1
禁止来自触发器的结果 0
填充因子 (%) 0
ft 爬行带宽(最大) 100
ft 爬行带宽 (min) 0
ft 通知带宽(最大) 100
ft 通知带宽 (min) 0
索引创建内存 (KB) 0
有疑问的 xact 分辨率 0
轻量级池化 0
锁 0
最大并行度 6
最大全文抓取范围 4
最大服务器内存 (MB) 393216
最大文本复制大小 (B) 65536
最大工作线程数 0
媒体留存率 0
每个查询的最小内存 (KB) 2048
最小服务器内存 (MB) 52427
嵌套触发器 1
网络数据包大小 (B) 1400
Ole 自动化程序 1
打开对象 0
PH 超时 (s) 60
预计算等级 0
优先级提升 0
查询调控器成本限制 0
查询等待 (s) -1
恢复间隔(分钟) 0
远程访问 1
远程管理连接 0
远程登录超时(s) 20
远程 proc trans 0
远程查询超时 (s) 600
复制 XP 0
扫描启动过程 0
服务器触发器递归 1
设置工作集大小 0
显示高级选项 1
SMO 和 DMO XP 1
SQL 邮件 XP 0
变换噪声词 0
两位数年份截止 2049
用户连接 0
用户选项 4216
网络助手程序 0
xp_cmdshell 1
前段时间,我手动将mirroring_connection_timeout所有镜像数据库的值修改为30秒,试图修复问题;这只是增加了故障转移事件之间的时间量。随着mirroring_connection_timeout设定集在10秒的默认,我们看到了很多更多的故障切换。
一条评论要求我确保禁用 IPSec,因此我发布了几个netsh显示操作系统 IPSec 配置的命令的内容:
C:\>netsh ipsec 动态显示全部 当前没有分配的策略 主模式策略不可用。 快速模式策略不可用。 通用主模式过滤器不可用。 特定的主模式过滤器不可用。 通用快速模式过滤器不可用。 特定的快速模式过滤器不可用。 IPsec MainMode 安全关联不可用。 IPsec QuickMode 安全关联不可用。 IPsec 配置参数 ------------------------------ 强CRL检查:1 IPsecexempt : 3 IPsec统计 ---------------- 活跃协会 : 0 卸载 SA:0 待定密钥:0 关键添加:0 键删除:0 重新密钥:0 活动隧道:0 坏 SPI Pkts : 0 未解密的 Pkts : 0 未经身份验证的 Pkts : 0 带重放检测的包:0 发送的机密字节数:0 收到的机密字节数:0 发送的经过身份验证的字节数:0 接收到的经过身份验证的字节数:0 发送的传输字节数:0 接收的传输字节数:0 在隧道中发送的字节数:0 在隧道中接收的字节数:0 发送的卸载字节数:0 接收到的卸载字节数:0 C:\>netsh ipsec 静态显示全部 ERR IPsec[05072]:策略存储中没有策略
更新:2012-12-20
我们现在已经将我们的生产系统转移到 SQL Server 2012。我们从 12 月 17 日早上开始运行它 - 到目前为止没有故障转移。然而,几天是我们在基于 2005 的系统中看到的。
为了记录我们新系统的性能,我一直在sys.dm_os_wait_stats更仔细地查看;并注意到DBMIRROR_DBM_EVENT,这是一种未记录的等待类型。微软的 Graham Kent 有一篇关于排除意外故障转移和这种等待类型的有趣文章。我将在这里回顾他的发现:
客户正在体验建立在高容量 OLTP 数据库上的巨大阻塞链,其中所有头部阻塞器都在等待 DBMIRROR_DBM_EVENT。以下是我经历的一系列事件:
查看阻塞链本身 - 在这里有帮助,因为我们可以看到我们正在等待 DBMIRROR_DBM_EVENT
查看未记录的等待类型的来源。显然你不能在 MS 之外做这件事,但我可以说在撰写本文时,这种等待类型表示主体等待镜像强化 LSN 时使用的等待,这意味着它所属的事务无法提交. 这立即非常明确地指出了主体在等待镜像时无法提交事务的问题。现在我们需要调查为什么镜像没有提交事务或者为什么主体不知道它是否提交。
查看 msdb 系统表
(a) 查看 [backupset] 表,看看问题发生时产生的日志大小是否明显高于正常值。如果它们特别大,可能是镜像被事务淹没,根本跟不上交易量。这就是为什么在线书籍有时会告诉您,如果您需要执行非常大的日志操作(例如索引重建),请禁用镜像。(参考为什么这是在http://technet.microsoft.com/en-us/library/cc917681.aspx)。在这里我使用了以下 TSQL
SELECT backup_set_id,backup_start_date,database_name,has_bulk_logged_data,backup_size / 1000
FROM [backupset]
where backup_start_date between '2011-01-05 14:00:00' and '2011-01-05 19:30:00'
go
select round((AVG(backup_size)/1000),0)
FROM [backupset]
where database_name = 'mydatabase'
Run Code Online (Sandbox Code Playgroud)
(b) 其次,我查看了表 [dbm_monitor_data] 中的数据。这里的关键是找到我们遇到问题的时间范围,然后查看我们是否在以下任何方面发生了重大变化:
log_flush_rate
send_queue_size
send_rate
redo_queue_size
redo_rate
Run Code Online (Sandbox Code Playgroud)
这些都是与 (a) 部分相似的指标,因为它们可能显示没有响应的组件或架构。例如,如果 send_queue 突然开始增长但 re_do 队列没有增长,那么这意味着主体无法将日志记录发送到镜像,因此您可能想要查看连接性,或者服务代理队列处理实际传输。
在这个特定场景中,我们注意到所有计数器似乎都有奇怪的值,因为有正常大小的日志备份正在进行,但没有状态变化,0 发送队列,0 重做队列,一个固定的发送速率和一个固定的重做率。这很奇怪,因为这意味着 DBM 监视器无法在问题期间从任何地方记录任何值。
查看 SQL Server 错误日志。在这种情况下,没有任何错误或信息消息,但在其他情况下,例如,报告 1400 范围内的错误是很常见的,您可以在我的其他镜像博客的其他地方找到示例,例如此错误 1413 示例
查看默认跟踪文件 - 在这种情况下,我没有提供默认跟踪,但是它们是 DBM 问题信息的绝佳来源,因为它们记录了所有合作伙伴的状态更改事件。 此处记录:
这通常可以让您很好地了解场景,例如当一个或所有合作伙伴之间的网络连接出现故障时,以及之后合作伙伴关系的状态如何。
结论:
在这种特殊情况下,我目前缺少 2 个关键数据点,但除此之外,我仍然可以对上述信息做出合理的假设。我们当然可以说阻塞是由于 DBM 已启用,因为所有阻塞程序都在等待 DBMIRROR_DBM_EVENT 等待类型。由于我们知道我们没有用大型日志操作淹没镜像,并且此部署在这种模式下正常运行,我们可以排除不寻常的大型操作。这意味着我们在这个阶段有 2 个潜在的候选人:
部分或所有合作伙伴之间的连接硬件问题。
镜像服务器上的 CPU 耗尽 - 根本无法跟上重做 - CPU 耗尽本身可能来自 SQL Server 之外的进程或此镜像伙伴关系之外。
镜像代码本身存在问题(不过我们确实需要一些内存转储来确认这一点)。
根据经验,我怀疑是 1 或 2,但我也始终对 3 持开放态度,我们现在正在尝试收集更多数据以更详细地研究此问题。
听起来您可能用完了 SQL Server 上的 TCP 端口。您一次看到多少个与服务器的连接?
像这样的超时肯定会导致问题。
| 归档时间: |
|
| 查看次数: |
23365 次 |
| 最近记录: |