如何调试导致我的数据库备份维护计划运行突然变得极其缓慢的原因?

如何调试导致我的数据库备份维护计划运行突然变得极其缓慢的原因?

(最初发布在 DBA.StackExchange.com 上但已关闭,希望与此处更具相关性。)

亚历山大和可怕的、可怕的、不好的、非常糟糕的……备份。

设置:

我有一个本地SQL Server 2016 标准版实例运行于虚拟机来自 VMWare。

@@版本:

Microsoft SQL Server 2016 (SP2-CU17) (KB5001092) - 13.0.5888.11 (X64) 2021 年 3 月 19 日 19:41:38 版权所有 (c) Microsoft Corporation Windows Server 2016 Datacenter 10.0 (Build 14393:) 上的标准版 (64 位) (虚拟机管理程序)

服务器本身目前已分配8 个虚拟处理器, 有32 GB 内存,以及所有的磁盘是 NVMe传播1 GB/秒的 I/O。数据库本身位于 G: 驱动器上,备份单独存储在 P: 驱动器上。所有数据库的总大小约为 500 GB(在压缩到备份文件本身之前)。

维护计划每晚运行一次(大约晚上 10:30),对服务器上的每个数据库进行完整备份。服务器上没有运行任何其他异常程序,也没有任何其他程序在特定时间运行。服务器的电源计划设置为“平衡”(“关闭硬盘时间”设置为 0 分钟,即永不关闭)。

发生了什么:

在过去一年左右的时间里,维护计划作业的总运行时间约为 15分钟总共需要 15 分钟才能完成。自上周以来,它已经飙升到大约 40 倍的时间,大约 15小时去完成。

在维护计划放缓的同一天,我所知道的唯一变化是在维护计划运行之前在机器上安装了以下 Windows 更新:

Windows 更新

  1. KB890830
  2. KB5004752
  3. KB5005043
  4. VMWare-SCSI适配器-1.3.17.0
  5. VMWare - 显示 - 8.17.2.14

我们还在另一台虚拟机上配置了另一个类似的 SQL Server 实例,该实例经历了相同的 Windows 更新,随后也经历了较慢的备份。我们认为 Windows 更新是直接原因,因此我们将其完全回滚,但备份维护计划仍然运行得非常慢。奇怪的是,还原给定数据库的备份非常快,并且几乎占用了 NVMe 上的全部 1 GB/秒的 I/O。

我尝试过的事情:

使用 Adam Mechanic 的 sp_whoisactive 时,我发现备份过程的最后等待类型始终表明存在磁盘性能问题。我总是看到BACKUPBUFFERBACKUPIO等待类型,此外还有ASYNC_IO_COMPLETION

sp_whoisactive

在备份期间查看服务器本身的资源监视器时,磁盘 I/O 部分显示正在利用的总 I/O 仅为约 14 MB/秒(自此问题发生以来我见过的最高值为 30 MB/秒):

资源监控

在偶然发现这个有用的Brent Ozar 撰写了有关使用 DiskSpd 的文章,我尝试在类似的参数下自己运行它(仅将线程数降低到 8,因为我的服务器上有 8 个虚拟处理器,并将写入设置为 50%)。这是确切的命令diskspd.exe -b2M -d60 -o32 -h -L -t8 -W -w50 "C:\Users\...\Desktop\Microsoft DiskSpd\Test\LargeFile.txt"。我使用了一个手动生成的文本文件,大小略小于 1 GB。我相信它测量的 I/O 似乎没问题,但磁盘延迟显示了一些荒谬的数字:

DiskSpd 结果 1

DiskSpd 结果 2

DiskSpd 的结果看起来简直令人难以置信。经过进一步阅读,我偶然发现了 Paul Randall 的查询,该查询返回每个数据库的磁盘延迟指标。结果如下:

Paul Randal - 磁盘延迟指标

最差的写入延迟为 63 毫秒,最差的读取延迟为 6 毫秒,因此这似乎与 DiskSpd 有很大差异,但似乎还不足以成为我的问题的根本原因。为了进一步交叉检查,我在服务器本身上运行了一些 PerfMon 计数器,每个这篇微软文章,结果如下:

PerfMon 结果

这里没有什么特别的,我测量的所有计数器的最大值是 0.007(我相信是毫秒?)。最后,我让我的基础设施团队检查 VMWare 在备份作业期间记录的磁盘延迟指标,结果如下:

VMWare 磁盘延迟和 I/O 日志

似乎最糟糕的情况是,午夜时分出现了大约 200 毫秒的延迟峰值,最高 I/O 为 600 KB/秒(我不太明白,因为资源监视器显示备份至少使用大约 14 MB/秒的 I/O)。

我尝试过的其他方法:

我刚刚尝试恢复一个较大的数据库(大约 250 GB),总共只花了大约 8 分钟就恢复了。然后我尝试运行DBCC CHECKDB它,总共花了 16 分钟(不确定这是否正常),但资源监视器显示了类似的 I/O 问题(它曾经使用的最大 I/O 是 100 MB/s),没有其他运行:

DBCC CHECKDB 资源监视器

这是我第一次运行 sp_whoisactive 时的结果,DBCC CHECKDB在它完成 5% 后,请注意,即使已经完成 5%,预计剩余时间也增加了大约 5 分钟。

开始: sp_whoisactive DBCC CHECKDB 启动

已完成 5%: sp_whoisactive DBCC CHECKDB 5%完成

我猜这只是一个估计值,很正常。对于一个 250 GB 的数据库来说,16 分钟似乎并不算太​​糟糕(虽然我不确定这是否正常),但 I/O 最多只达到了驱动器容量的 10%,服务器或 SQL 实例上没有其他任何运行。

这些是结果DBCC CHECKDB,没有报告错误。

我也遇到了命令执行缓慢的问题SHRINK。我刚刚尝试了SHRINK数据库,其中有 5% 的空间需要释放(大约 14 GB)。它只花了大约 1 分钟就完成了 90% 的操作SHRINK

迅速收缩至 90%

大约 5 分钟后,它仍然停留在相同的完成百分比,并且我的事务日志备份(通常在 1-2 秒内完成)已经处于争用状态约 30 秒:

收缩停留在 90%

15 分钟后,SHRINK刚刚完成,而事务日志备份仍然处于争用状态约 6 分钟,只完成了 50%。我相信他们在那之后就立即完成了,因为完成了SHRINK。整个过程中,资源监视器显示 I/O 仍然很糟糕:

收缩完成

Shrink 的资源监视器

SHRINK然后当命令完成时我收到一个错误:

收缩误差

SHRINK再次重试,结果与上述完全相同。

然后,我尝试手动编写 T-SQL 备份脚本到 P: 驱动器上的文件,但运行速度很慢,就像维护计划备份作业一样:

T-SQL 手动备份

大约 3 分钟后我最终取消了它,然后它立即回滚了。

概括:

巧合的是,在安装 Windows 更新后,备份维护计划作业每晚都会变慢约 40 倍(从 15 分钟到 15 小时)。回滚这些 Windows 更新并不能解决问题。SQL Server 等待类型、资源监视器和 Microsoft DiskSpd 指示磁盘问题(特别是 I/O),但 Paul Randall 的查询、PerfMon 和 VMWare 日志中的所有其他测量均未报告磁盘存在任何问题。恢复特定数据库的备份很快,并且几乎使用了完整的 1 GB/秒 I/O。我挠头了……

答案1

在这种情况下,我们确实遇到了磁盘问题,但对于这个特定的虚拟机来说,这不是 SQL Server 内部的问题。实际上,这是我们在使用 Veeam 和 VMWare 时遇到的一个错误案例。

总结一下我对所发生事情的理解,显然我们的 Veeam 备份没有被 VMWare 确认为已完成。因此,每天当需要备份服务器时,VMWare 都会指示 Veeam 重新备份前一天的内容,这在两周内变成了一个累积的问题。(我确信我的解释很糟糕,但这几乎是我所知道的全部。)

Veeam / VMWare 必须删除每个快照文件,而每天的文件都比前一个大,因此他们的 3 级支持人员花了大约 26 小时才完成。之后,虚拟机又可以正常运行了。根据他们的技术支持,这显然不是一个罕见的问题。

抱歉,这是一个非常具体的问题,可能不会对其他人有帮助,但希望如此。

相关内容