F.B*_*ate 5 sql-server sql-server-2012
这个问题一直困扰着我一段时间,但我实际上修复了导致问题的查询(在我最终找到它们之后)但我很好奇它是否是一个 SQL 进程,这是我们的raidcontrollers是狗屎的潜在问题还是什么问题真的是。所以这就是一直困扰我们的场景。
@ 11:10~ 和 01:10~ 服务器会给出这些 IO 错误,即使通过远程桌面服务器也会失败,管理工作室会超时,一切都将指向集群即将失败。
(服务器是相同的,我们运行 Windows Server 2012 标准,群集在运行 SQL Server 2012 企业版的 AlwaysOn 中)。
大约 5-15 分钟后,服务器将恢复运行(除了事件 ID 833 是“众所周知的”:SQL Server 已遇到 16870 次 I/O 请求花费的时间更长,事件日志中没有任何内容15 秒内完成数据库 [XXXXX] 中的文件 [E:\XXXXXXXX.mdf] (10). OS 文件句柄为 0x0000000000001284。最新的 long I/O 的偏移量为:0x0000041fb3c000。
现在我正在运行分析器以找出正在运行的查询,并尽我所能找出导致服务器冻结并拒绝正常服务的原因。事件日志针对特定的数据库,我朝那个方向搜索,昨天我发现了一张对我来说看起来很奇怪的表。
特定的表有 11 演出大,有价值 23 演出的索引(还没有研究这些,但对我来说这似乎是错误的)并且有 8000 万条记录。考虑到该表应该容纳大约 200 万个并且增长相对缓慢,这激发了我的兴趣,我发现了三个填充该表的存储过程。
所有三个存储过程都有缺陷,这使得它们每次运行时插入的记录不是几百条而是超过 500.000。(这些现在已修复,因此问题不会出现,但我觉得这里存在潜在问题)。
这些存储过程将在 09:00 和 23:00 运行(恰好在问题发生前 2 小时)。程序本身大约需要 5 分钟才能完成。
现在我想知道为什么在有问题的实际存储过程已经完成后,服务器需要两个小时才能开始死在我身上。那时我没有运行任何索引维护,或者其他任何事情(这是我检查的第一件事)。据我所知,在特定时间没有运行@。可能是 SQL Server 做了一些“自我维护”,并注意到一些索引需要进行碎片整理或其他什么,即使我没有要求任何这样的事情?
是不是我们的raidcontrollers(或者甚至是连接到它们的SSD)有缺陷并且在很多活动决定在2小时后显示降级迹象?
我根本无法解释这种行为,我担心我们的生产服务器可能不可靠(这会很糟糕,因为它们大约有 4 个月大)。现在我昨晚已经解决了这个问题,24 小时以来我们都没有遇到过这个问题(除非它稳定了多天,否则我不会称它为“已解决”)但我仍然很好奇我的到底是什么服务器正在做。
此问题可能是由系统性能问题、硬件错误、固件错误、设备驱动程序问题或过滤驱动程序干预 IO 过程引起的。
这意味着什么
以下是我将遵循的方法:
使用等待统计信息进行故障排除- DMV
WITH [Waits] AS
(SELECT
[wait_type],
[wait_time_ms] / 1000.0 AS [WaitS],
([wait_time_ms] - [signal_wait_time_ms]) / 1000.0 AS [ResourceS],
[signal_wait_time_ms] / 1000.0 AS [SignalS],
[waiting_tasks_count] AS [WaitCount],
100.0 * [wait_time_ms] / SUM ([wait_time_ms]) OVER() AS [Percentage],
ROW_NUMBER() OVER(ORDER BY [wait_time_ms] DESC) AS [RowNum]
FROM sys.dm_os_wait_stats
WHERE [wait_type] NOT IN (
N'CLR_SEMAPHORE', N'LAZYWRITER_SLEEP',
N'RESOURCE_QUEUE', N'SQLTRACE_BUFFER_FLUSH',
N'SLEEP_TASK', N'SLEEP_SYSTEMTASK',
N'WAITFOR', N'HADR_FILESTREAM_IOMGR_IOCOMPLETION',
N'CHECKPOINT_QUEUE', N'REQUEST_FOR_DEADLOCK_SEARCH',
N'XE_TIMER_EVENT', N'XE_DISPATCHER_JOIN',
N'LOGMGR_QUEUE', N'FT_IFTS_SCHEDULER_IDLE_WAIT',
N'BROKER_TASK_STOP', N'CLR_MANUAL_EVENT',
N'CLR_AUTO_EVENT', N'DISPATCHER_QUEUE_SEMAPHORE',
N'TRACEWRITE', N'XE_DISPATCHER_WAIT',
N'BROKER_TO_FLUSH', N'BROKER_EVENTHANDLER',
N'FT_IFTSHC_MUTEX', N'SQLTRACE_INCREMENTAL_FLUSH_SLEEP',
N'DIRTY_PAGE_POLL', N'SP_SERVER_DIAGNOSTICS_SLEEP')
)
SELECT
[W1].[wait_type] AS [WaitType],
CAST ([W1].[WaitS] AS DECIMAL(14, 2)) AS [Wait_S],
CAST ([W1].[ResourceS] AS DECIMAL(14, 2)) AS [Resource_S],
CAST ([W1].[SignalS] AS DECIMAL(14, 2)) AS [Signal_S],
[W1].[WaitCount] AS [WaitCount],
CAST ([W1].[Percentage] AS DECIMAL(4, 2)) AS [Percentage],
CAST (([W1].[WaitS] / [W1].[WaitCount]) AS DECIMAL (14, 4)) AS [AvgWait_S],
CAST (([W1].[ResourceS] / [W1].[WaitCount]) AS DECIMAL (14, 4)) AS [AvgRes_S],
CAST (([W1].[SignalS] / [W1].[WaitCount]) AS DECIMAL (14, 4)) AS [AvgSig_S]
FROM [Waits] AS [W1]
INNER JOIN [Waits] AS [W2]
ON [W2].[RowNum] <= [W1].[RowNum]
GROUP BY [W1].[RowNum], [W1].[wait_type], [W1].[WaitS],
[W1].[ResourceS], [W1].[SignalS], [W1].[WaitCount], [W1].[Percentage]
HAVING SUM ([W2].[Percentage]) - [W1].[Percentage] < 95; -- percentage threshold
GO
Run Code Online (Sandbox Code Playgroud)
查看待处理的 I/O
SELECT database_id
,file_id
,io_stall
,io_pending_ms_ticks
,scheduler_address
FROM sys.dm_io_virtual_file_stats(NULL, NULL) t1
,sys.dm_io_pending_io_requests AS t2
WHERE t1.file_handle = t2.io_handle
Run Code Online (Sandbox Code Playgroud)
以下是可以帮助您的 PERFMON 计数器:
此外,有时为服务器选择不同的电源管理方案时也会出现此类错误。因此,最好检查您的 Windows 电源计划设置,并确保您使用的是高性能电源计划。
所有三个存储过程都存在缺陷,导致它们每次运行时插入的记录不是几百条而是超过 500,000 条。(这些现已修复,因此问题不会出现,但我觉得这里存在潜在的问题)。
如果您要插入大量数据,那么您需要参考《数据加载性能指南》来满足您的服务器的此类操作,例如启用跟踪标志 610。
注意:其他人提到可能是自动更新统计造成的,这也值得一看,但我主要集中精力找出导致大量磁盘 I/O 的恶意进程,并检查存储子系统以查看是否所有divers 等是最新的并且配置正确。
好的阅读链接: