耗时超过 15 秒的 I/O 请求

Mar*_*sen 31 backup sql-server-2008-r2 network san

通常我们每周的完整备份在大约 35 分钟内完成,每日差异备份在大约 5 分钟内完成。从星期二开始,每天的日常工作需要将近 4 个小时才能完成,远远超出了应有的要求。巧合的是,这在我们获得新的 SAN/磁盘配置后立即开始发生。

请注意,服务器正在生产中运行,我们没有整体问题,它运行平稳 - 除了主要表现在备份性能中的 IO 问题。

在备份期间查看 dm_exec_requests,备份一直在等待 ASYNC_IO_COMPLETION。啊哈,所以我们有磁盘争用!

但是,MDF(日志存储在本地磁盘上)和备份驱动器都没有任何活动(IOPS ~= 0 - 我们有足够的内存)。磁盘队列长度 ~= 0 也是如此。CPU 徘徊在 2-3% 左右,也没有问题。

SAN 是 Dell MD3220i,LUN 由 6x10k SAS 驱动器组成。服务器通过两条物理路径连接到 SAN,每条路径都通过一个单独的交换机与 SAN 的冗余连接 - 总共有四个路径,其中两个随时处于活动状态。我可以通过任务管理器验证两个连接是否都处于活动状态 - 完美均匀地分配负载。两个连接都运行 1G 全双工。

我们曾经使用巨型帧,但我已禁用它们以排除此处的任何问题 - 没有变化。我们有另一台服务器(相同的操作系统 + 配置,2008 R2)连接到其他 LUN,它没有显示任何问题。然而,它没有运行 SQL Server,而只是在它们之上共享 CIFS。但是,它的 LUN 首选路径之一与麻烦的 LUN 位于同一 SAN 控制器上 - 所以我也排除了这一点。

尽管存在以下问题,但运行几个 SQLIO 测试(10G 测试文件)似乎表明 IO 是不错的:

sqlio -kR -t8 -o8 -s30 -frandom -b8 -BN -LS -Fparam.txt
IOs/sec:  3582.20
MBs/sec:    27.98
Min_Latency(ms): 0
Avg_Latency(ms): 3
Max_Latency(ms): 98
histogram:
ms: 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24+
%: 45  9  5  4  4  4  4  4  4  3  2  2  1  1  1  1  1  1  1  0  0  0  0  0  2

sqlio -kW -t8 -o8 -s30 -frandom -b8 -BN -LS -Fparam.txt
IOs/sec:  4742.16
MBs/sec:    37.04
Min_Latency(ms): 0
Avg_Latency(ms): 2
Max_Latency(ms): 880
histogram:
ms: 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24+
%: 46 33  2  2  2  2  2  2  2  1  1  1  1  0  0  0  0  0  0  0  0  0  0  0  1

sqlio -kR -t8 -o8 -s30 -fsequential -b64 -BN -LS -Fparam.txt
IOs/sec:  1824.60
MBs/sec:   114.03
Min_Latency(ms): 0
Avg_Latency(ms): 8
Max_Latency(ms): 421
histogram:
ms: 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24+
%:  1  3 14  4 14 43  4  2  1  1  1  1  1  1  0  0  0  0  0  0  0  0  0  0  6

sqlio -kW -t8 -o8 -s30 -fsequential -b64 -BN -LS -Fparam.txt
IOs/sec:  3238.88
MBs/sec:   202.43
Min_Latency(ms): 1
Avg_Latency(ms): 4
Max_Latency(ms): 62
histogram:
ms: 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24+
%:  0  0  0  9 51 31  6  1  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0  0
Run Code Online (Sandbox Code Playgroud)

我意识到这些在任何方面都不是详尽的测试,但它们确实让我很舒服地知道它不是完全垃圾。请注意,较高的写入性能是由两条活动的 MPIO 路径引起的,而读取只会使用其中的一条。

检查应用程序事件日志会发现像这些分散的事件:

SQL Server has encountered 2 occurrence(s) of I/O requests taking longer than 15 seconds to complete on file [J:\XXX.mdf] in database [XXX] (150).  The OS file handle is 0x0000000000003294.  The offset of the latest long I/O is: 0x00000033da0000
Run Code Online (Sandbox Code Playgroud)

它们不是恒定的,但确实会定期发生(每小时几次,备份期间更多)。除了该事件,系统事件日志将发布以下内容:

Initiator sent a task management command to reset the target. The target name is given in the dump data.
Target did not respond in time for a SCSI request. The CDB is given in the dump data.
Run Code Online (Sandbox Code Playgroud)

这些也发生在运行在同一个 SAN/控制器上的没有问题的 CIFS 服务器上,从我的谷歌搜索来看,它们似乎并不重要。

请注意,所有服务器都使用相同的 NIC - Broadcom 5709C 以及最新的驱动程序。服务器本身是戴尔 R610。

我不确定接下来要检查什么。有什么建议?

更新 - 运行 perfmon
我尝试记录 Avg. 执行备份时的磁盘秒/读写性能计数器。备份开始时非常火爆,然后基本上在 50% 时停止,缓慢地爬向 100%,但花费的时间是应该的 20 倍。

备份开始期间的任务监视器 显示正在使用的两个 SAN 路径,然后下降。

在同一期间执行备份在 15:38:50 左右开始 - 注意一切看起来都不错,然后出现了一系列峰值。我不关心写入,只有读取似乎挂起。

备份结束期间的任务监视器 注意很少有开/关动作,尽管最后表现非常出色。

同一时期的表现 请注意最长 12 秒,但总体来说平均值不错。

更新 - 备份到 NUL 设备
为了隔离读取问题并简化事情,我运行了以下命令:

BACKUP DATABASE XXX TO DISK = 'NUL'
Run Code Online (Sandbox Code Playgroud)

结果完全相同 - 从突发读取开始,然后停顿,不时恢复操作:

结果

更新 - IO 停顿
我按照 Shawn 的建议运行了 Jonathan Kehayias 和 Ted Kruegers一书(第 29 页)中的 dm_io_virtual_file_stats 查询。查看前 25 个文件(每个文件一个数据文件 - 所有结果都是数据文件),似乎读取比写入更糟糕 - 可能是因为写入直接进入 SAN 缓存,而冷读取需要命中磁盘 - 只是猜测.

IO 档

更新 - 等待统计
我做了三个测试来收集一些等待统计。使用 Glenn Berry / Paul Randals脚本查询等待统计信息。只是为了确认 - 备份不是对磁带进行的,而是对 iSCSI LUN 进行的。如果对本地磁盘执行,结果类似,结果类似于 NUL 备份。

清除统计。跑了10分钟,正常负载: 没有备份

清除统计。跑了10分钟,正常负载+正常备份运行(没有完成): 正常备份

清除统计。跑了10分钟,正常加载+NUL备份运行(没有完成): 空备份

更新 - Wtf,博通?
根据 Mark Storey-Smiths 的建议和 Kyle Brandts 以前使用 Broadcom NIC 的经验,我决定做一些实验。由于我们有多个活动路径,我可以相对轻松地逐个更改 NIC 的配置,而不会造成任何中断。

禁用 TOE 和大发送卸载产生了近乎完美的运行: 在此处输入图片说明

Processed 1064672 pages for database 'XXX', file 'XXX' on file 1.
Processed 21 pages for database 'XXX', file 'XXX' on file 1.
BACKUP DATABASE successfully processed 1064693 pages in 58.533 seconds (142.106 MB/sec).
Run Code Online (Sandbox Code Playgroud)

那么罪魁祸首是TOE 还是LSO?启用 TOE,禁用 LSO: 在此处输入图片说明

Didn't finish the backup as it took forever - just as the original problem!
Run Code Online (Sandbox Code Playgroud)

禁用 TOE,启用 LSO - 看起来不错: 在此处输入图片说明

Processed 1064680 pages for database 'XXX', file 'XXX' on file 1.
Processed 29 pages for database 'XXX', file 'XXX' on file 1.
BACKUP DATABASE successfully processed 1064709 pages in 59.073 seconds (140.809 MB/sec).
Run Code Online (Sandbox Code Playgroud)

作为控制,我禁用了 TOE 和 LSO 以确认问题已经消失: 在此处输入图片说明

Processed 1064720 pages for database 'XXX', file 'XXX' on file 1.
Processed 13 pages for database 'XXX', file 'XXX' on file 1.
BACKUP DATABASE successfully processed 1064733 pages in 60.675 seconds (137.094 MB/sec).
Run Code Online (Sandbox Code Playgroud)

总之,似乎启用了 Broadcom NICs TCP Offload Engine 导致了问题。一旦 TOE 被禁用,一切都像魅力一样。猜猜我以后不会再订购任何 Broadcom NIC。

更新 - CIFS 服务器关闭
今天,相同且正常运行的 CIFS 服务器开始表现出 IO 请求挂起。这台服务器没有运行 SQL Server,只是简单的 Windows Web Server 2008 R2 通过 CIFS 服务共享。一旦我也禁用了 TOE,一切又恢复了顺畅。

只是确认我不会再在 Broadcom NIC 上使用 TOE,如果我根本无法避免使用 Broadcom NIC,那就是。

Mar*_*ith 14

请注意,所有服务器都使用相同的 NIC - Broadcom 5709C 以及最新的驱动程序。服务器本身是戴尔 R610。

凯尔·布​​兰特 (Kyle Brandt) 对博通网卡的看法与我自己的(重复)经验相呼应。

博通,Die Mutha

我的问题一直与TCP 卸载功能有关,并且在 99% 的情况下禁用或切换到其他网卡已解决了这些症状。一个客户端(如您的情况)使用戴尔服务器,总是订购单独的英特尔 NIC 并在构建时禁用板载 Broadcom 卡。

正如这篇MSDN 博客文章中所述,我将从在操作系统中禁用以下内容开始:

netsh int ip set chimney DISABLED
Run Code Online (Sandbox Code Playgroud)

IIRC 在某些情况下可能需要在卡驱动程序级别禁用这些功能,这样做当然不会有什么坏处。