(最初发布在 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 更新:
我们还在另一台虚拟机上配置了另一个类似的 SQL Server 实例,该实例经历了相同的 Windows 更新,随后也经历了较慢的备份。我们认为 Windows 更新是直接原因,因此我们将其完全回滚,但备份维护计划仍然运行得非常慢。奇怪的是,还原给定数据库的备份非常快,并且几乎占用了 NVMe 上的全部 1 GB/秒的 I/O。
我尝试过的事情:
使用 Adam Mechanic 的 sp_whoisactive 时,我发现备份过程的最后等待类型始终表明存在磁盘性能问题。我总是看到BACKUPBUFFER
和BACKUPIO
等待类型,此外还有ASYNC_IO_COMPLETION
:
在备份期间查看服务器本身的资源监视器时,磁盘 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 的结果看起来简直令人难以置信。经过进一步阅读,我偶然发现了 Paul Randall 的查询,该查询返回每个数据库的磁盘延迟指标。结果如下:
最差的写入延迟为 63 毫秒,最差的读取延迟为 6 毫秒,因此这似乎与 DiskSpd 有很大差异,但似乎还不足以成为我的问题的根本原因。为了进一步交叉检查,我在服务器本身上运行了一些 PerfMon 计数器,每个这篇微软文章,结果如下:
这里没有什么特别的,我测量的所有计数器的最大值是 0.007(我相信是毫秒?)。最后,我让我的基础设施团队检查 VMWare 在备份作业期间记录的磁盘延迟指标,结果如下:
似乎最糟糕的情况是,午夜时分出现了大约 200 毫秒的延迟峰值,最高 I/O 为 600 KB/秒(我不太明白,因为资源监视器显示备份至少使用大约 14 MB/秒的 I/O)。
我尝试过的其他方法:
我刚刚尝试恢复一个较大的数据库(大约 250 GB),总共只花了大约 8 分钟就恢复了。然后我尝试运行DBCC CHECKDB
它,总共花了 16 分钟(不确定这是否正常),但资源监视器显示了类似的 I/O 问题(它曾经使用的最大 I/O 是 100 MB/s),没有其他运行:
这是我第一次运行 sp_whoisactive 时的结果,DBCC CHECKDB
在它完成 5% 后,请注意,即使已经完成 5%,预计剩余时间也增加了大约 5 分钟。
我猜这只是一个估计值,很正常。对于一个 250 GB 的数据库来说,16 分钟似乎并不算太糟糕(虽然我不确定这是否正常),但 I/O 最多只达到了驱动器容量的 10%,服务器或 SQL 实例上没有其他任何运行。
这些是结果的DBCC CHECKDB
,没有报告错误。
我也遇到了命令执行缓慢的问题SHRINK
。我刚刚尝试了SHRINK
数据库,其中有 5% 的空间需要释放(大约 14 GB)。它只花了大约 1 分钟就完成了 90% 的操作SHRINK
:
大约 5 分钟后,它仍然停留在相同的完成百分比,并且我的事务日志备份(通常在 1-2 秒内完成)已经处于争用状态约 30 秒:
15 分钟后,SHRINK
刚刚完成,而事务日志备份仍然处于争用状态约 6 分钟,只完成了 50%。我相信他们在那之后就立即完成了,因为完成了SHRINK
。整个过程中,资源监视器显示 I/O 仍然很糟糕:
SHRINK
然后当命令完成时我收到一个错误:
我SHRINK
再次重试,结果与上述完全相同。
然后,我尝试手动编写 T-SQL 备份脚本到 P: 驱动器上的文件,但运行速度很慢,就像维护计划备份作业一样:
大约 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 小时才完成。之后,虚拟机又可以正常运行了。根据他们的技术支持,这显然不是一个罕见的问题。
抱歉,这是一个非常具体的问题,可能不会对其他人有帮助,但希望如此。