我有许多 SQL 2008 实例,它们都在运行 Microsoft SQL Server 2008 (SP4)(已select @@VERSION
在相关服务器上确认)。它们在 Windows Server 2008 或 Windows Server 2008 R2 上运行。
其中两个仅用于与 Red Gate SQL Backup 7.4.0.23 一起登录,我遇到了其中一个问题。(它是 2008 R2 服务器之一,如果有区别的话。)我正在使用一个 t-sql 作业,它滚动浏览一个很长的数据库列表(从其他服务器动态提取)并恢复它们。
以前,这项工作只需不到 10 分钟。现在需要一个半小时到两个半小时。没有代码更改,也没有大幅增加要恢复的数据库数量。它的同级服务器具有几乎相同的代码,可以在 4 分钟内运行此作业。(兄弟服务器是非 R2 服务器之一,如果这有所不同的话。)
事件日志和 SQL 错误日志显示以下错误:
操作系统错误 0x80770006(未能检索此错误的文本。原因:317)。
我不知道这是否是问题的原因;Google 建议当不同版本的 SQL Server 共存或 Red Gate SQL Backup 6.x 需要特殊补丁时会发生这种情况。我认为这些都不是问题,因为错误是间歇性的,SQL Server 版本相同,并且我正在运行 Red Gate SQL Backup 7.x,但我肯定是错的。Red Gate 论坛建议运行查询以查看 VAS 内存是否不足,因为这可能会导致类似问题。
VAS Total avail mem, KB Max free size, KB
8320072080 8314974784
我尝试解决的其他问题包括:
- 清理“C:\ProgramData\Red Gate\SQL Backup\Log[instancename]”中的旧日志文件,因为上次作业变慢是因为该目录中的日志文件太多。
- 检查并解决服务器上的任何内存问题。
- 确保防病毒软件排除了 .sqb 文件(SQL 备份)。
CHKDSK
在涉及的卷上 运行。- 看着作业运行
sp_WhoIsActive
。 - 检查 msdb 以确保清除作业正常运行。最早的条目是四个星期大,但它似乎仍然过大。
DBCC CheckDB
在 msdb 上运行。- 要求那些对存储实用程序有可见性的人检查那里的任何故障。他们说我的存储是“最佳的”。
我打算做的事情:
- 将 msdb 的历史清除为仅一周。这是一个阻塞查询,所以我想等到几个小时后,即使客户没有主动查询这个实例。
看着作业运行sp_whoisactive
似乎在 msdb 上显示了很多PAGEIOLATCH
(SH
和EX
),但等待通常不到一秒。(查询是更新备份集的过程。)
我能找到的唯一错误是(来自 SQL 错误日志)的间歇性变体:
2016-05-25 14:12:39.18 Backup Error: 3201, Severity: 16, State: 7.
2016-05-25 14:12:39.18 Backup Cannot open backup device 'SQLBACKUP_D99ABDE1-42E6-4617-B1EB-BDA30BF8113B'. Operating system error 0x80770006(failed to retrieve text for this error. Reason: 317).
(紧随其后的是“日志已恢复。”)和(来自事件查看器应用程序日志):
SQLVDI: Loc=SVDS::Open. Desc=Bad State. ErrorCode=(-1). Process=8056. Thread=10512. Server. Instance=DR. VD=Global\SQLBACKUP_D99ABDE1-42E6-4617-B1EB-BDA30BF8113B_SQLVDIMemoryName_0.
Cannot open backup device 'SQLBACKUP_D99ABDE1-42E6-4617-B1EB-BDA30BF8113B'. Operating system error 0x80770006(failed to retrieve text for this error. Reason: 317).
我错过了什么?我还能在哪里看?
我下班后做的事情:
- 将 msdb 清除到一周。
- 为 Red Gate SQL 备份的 VDI 超时添加注册表项。(我之前更改了这个值,然后删除了该键。默认值为 30 秒,我认为一个数据库似乎挂起的时间比 30 秒长得多,所以我输入了一个具有默认值的键来确定。)
没有区别,但我确实找到了这个查询,它似乎给了我一个线索。特别是一个数据库,我认为我sp_WhoIsActive
花了很长时间才注意到它。这不是我的想象。大约恢复时间包括 5068100、4252443、4408026、2184080、2786363(除了 330、373 等之外)。(那是毫秒。)我检查了这个数据库中 VLF 的数量,只有 46 个,所以还有其他问题。
我将加载完整的日志传送数据库列表并再次运行它。
辅助数据库处于恢复状态,而不是待机状态。我们使用 Red Gate 进行日志传送以进行压缩,因为我们已经将加密备份的副本写入该服务器上的共享,并且担心主服务器上可能存在开销。有很多数据库正在发货。该服务器上超过 800 个。我尝试将其作为减少 msdb 争用的一个过程。
这些机器是裸机,而不是虚拟机。据我所知,它只是落后了,争论要么是恢复,要么是写入有关恢复到 MSDB 的信息(或两者兼而有之)。最近的恢复是在最后一分钟内。
这比评论要大,但要先测试然后再实施:
您正在对 800 多个数据库进行日志传送。那就是您每 15 分钟登录一次的大量数据库。
您应该将一些数据库卸载到另一台服务器。恕我直言,单个服务器上的 800 个数据库很多!
当我们将 200 多个数据库从 NY 发送到 LD 地区时,我们遇到了类似的日志发送问题。
我们所做的如下:
有阻塞写入
msdb.dbo.sysjobhistory with (TABLOCKX)
。TABLOCK
提示意味着对 sysjobhistory 的访问始终是序列化的。而且由于您每 15 分钟运行大量作业,因此会出现争用(阻塞)。我们实现了跟踪标志 TF – 1236。它将引入数据库锁分区。对 DATABASE 锁进行分区可以使锁列表的深度在每个本地分区中都易于管理。这显着优化了用于获取 DATABASE 锁的访问路径。
sysjobhistory
在和log_shipping_monitor_history_detail
表上创建索引,如下所示:我将所有正在运送的数据库加载到此查询中:
(但我编辑它给我开始时间,就像一个健全的检查。)这给了我一系列的结果,比如:
在我看来,数据库恢复得很好,而减速是将此信息写入 msdb。
sp_WhoIsActive
这与显示出很多缓慢的事实相结合:让我觉得是的,msdb 是我的问题。
截至今天早上,它只有一周的历史记录,但每 15 分钟有 800 多个数据库被恢复,所以 MDF 仍然是 5 GB。我禁用了这些工作并将这个数字减少到 3 天并添加了一些索引。这项工作现在需要 4 或 5 分钟。
我仍然不确定为什么一个运行了两年多的系统,令人高兴的是,有四个星期的历史现在只运行了三天,但我怀疑我的存储团队错了,我的存储不是最佳的。我已经让他们对此进行评估。
同时,如果此实例的其中一台服务器正在保护蓝屏,我不会过时两个半小时!
托管服务提供商现在说这
C:
是碎片化的。无论如何,我已经将 msdb 移动到更快的存储空间,因为它是系统上最难工作的数据库。