Die*_*roz 7 sql-server sql-server-2012 transaction-log recovery-model
我面临的情况有点难以解决。我需要帮助来了解正在发生的事情。
TL;DR:每次 SQL Server 中的事务日志已满时,它都需要关闭数据库以进入恢复模式并回滚有问题的事务吗?这总是由设计完成还是仅在发生不好的事情时才会发生?
场景:
我们大量使用的生产数据库之一,它运行多个 ETL 作业和长时间运行的表批处理,进入恢复模式并在一段时间内无法访问。这周发生了 3 次(这个服务器已经运行了大约 2 年,我们过去没有注意到这个问题)。
查看错误日志很清楚发生了什么:事务日志已满,数据库需要回滚事务,回滚失败,数据库关闭,并以恢复模式启动。
DBA 认为这是 SQL Server 的正常行为。也就是说,按照他的说法,每次事务日志满了,一个事务需要回滚,数据库就会因为日志空间不足而进入恢复模式。回滚后(根据他的说法只能在恢复模式下完成),数据库将再次可用。
我找不到此信息的参考。所以我强烈反对。如果有人让我相信我错了,我将不胜感激。
我的观点:
据我所知,DBMS 是用来管理/运行查询的。如果空间不足,查询将失败。就这么简单。我不是在谈论其他任何东西的性能,而只是在谈论可用性。
接受 DBMS在设计上需要关闭自身以回滚任何事务对我来说是没有意义的。根据我的理解,我是否正在运行大量查询或查询设计是否不当都无关紧要。错误的查询应该会失败,而生活仍在继续。不是吗?
我的猜测是其他原因导致它失败,我需要跟踪正在发生的事情。
我的理解是错误的还是这真的是 SQL Server 的设计方式?假设我没有错,我还能做些什么来追踪这个问题的来源?
一些附加信息
select @@version
:Microsoft SQL Server 2012 (SP1) - 11.0.3156.0 (X64) 2015 年 5 月 4 日 18:48:09 版权所有 (c) Windows NT 6.2(内部版本 9200:)微软公司标准版(64 位)日志转储(按发生顺序,删除重复项)
[02:58:37am ~ 04:47:42pm, 12 times]
错误:845。严重性:17。状态:1。等待页面的缓冲区锁存类型 3 时发生超时 (1:8728760)。数据库 ID 7. FlushCache:在 77540 毫秒内清理了 10460 个缓冲区,其中 6709 次写入(避免了 864 个新的脏缓冲区),数据库 7:0 平均吞吐量:1.05 MB/秒。I/O 饱和度:107。上下文切换 391 上一个未完成的目标:4800。avgWriteLatency 0 FlushCache:清理 95448 个 buf,在 85820 毫秒内进行了 37560 次写入(避免了 60465 个新的脏 buf),db 7:09 平均吞吐量:8 MB。I/O 饱和度:17026。上下文切换 20713 最后一个未完成的目标:446。avgWriteLatency 3。
[02:58:37am ~ 04:47:42pm, 13 times]
等待缓冲区锁存器时发生超时 - 类型 3。bp 000000109B9E69C0。第 1 页:73430228。状态 0x10b。数据库 ID:7. 分配单元 ID:72057594304790528. 任务 0x00000008BC0850C8:1. 等待时间 300 秒。标志 0x100000001a。拥有任务 0x0000000827B38188。没有继续等待。
[02:58:37am ~ 04:47:42pm, 12 times]
错误:5901。严重性:16。状态:1。属于数据库“XXXXXXXXXX”的一个或多个恢复单元未能生成检查点。这通常是由于缺乏系统资源(如磁盘或内存)或在某些情况下由于数据库损坏造成的。检查错误日志中以前的条目以获取有关此故障的更多详细信息。
[05:14:29pm ~ 05:14:53pm, 9 times]
错误:9002。严重性:17。状态:4。由于“ACTIVE_TRANSACTION”,数据库“XXXXXXXXXX”的事务日志已满。
[05:14:53pm, once]
错误:3314。严重性:21。状态:3。由于例程“XdesRMReadWrite::RollbackToLsn”中的错误 3314,数据库 XXXXXXXXXX 已关闭。在与数据库的所有连接都中止后,将尝试重新启动非快照数据库。
[05:14:53pm ~ 05:14:53pm, 16 times]
错误:3314。严重性:21。状态:3。在撤销数据库“XXXXXXXXXX”中记录的操作期间,日志记录 ID (8064074:20971:110) 发生错误。通常,特定故障之前在 Windows 事件日志服务中记录为错误。从备份还原数据库或文件或修复数据库。
[05:14:53pm ~ 05:14:53pm, 9 times]
错误:9001。严重性:21。状态:5。数据库“XXXXXXXXXX”的日志不可用。检查事件日志以获取相关错误消息。解决所有错误并重新启动数据库。
[05:14:58, once]
正在启动数据库“XXXXXXXXXX”。
[05:15:02, once]
数据库 'XXXXXXXXXX' (7) 的恢复已完成 0%(剩余大约 2931 秒)。第 1 阶段(共 3 个)。这只是一条信息性消息。无需用户操作。...
[05:51:01pm, once]
6 个事务在数据库 'XXXXXXXXXX' (7:0) 中回滚。这只是一条信息性消息。无需用户操作。
[05:51:01pm, once]
恢复正在数据库 'XXXXXXXXXX' (7) 中写入检查点。这只是一条信息性消息。无需用户操作。
[05:56:47pm, once]
数据库 XXXXXXXXXX(数据库 ID 7)的恢复在 2505 秒内完成(分析 1774 毫秒重做 406623 毫秒撤消 1749182 毫秒。)这只是一条信息性消息。无需用户操作。
我在错误日志或事件查看器中没有发现其他相关的日志条目。事件查看器中发生的最接近的错误是:
[04:56:45pm ~ 05:27:24pm, 13 times]
特定于应用程序的权限设置不会向具有 CLSID {FDC3723D-1588-4BA3-92D4-42C430735D7D} 和 APPID {83B33982-693D-4824-B42E-7196AE61BB05} 的 COM 服务器应用程序授予本地激活权限。 Personal.user SID (S-1-5-21-000000000-000000000-0000000000-00000) 来自地址 LocalHost (Using LRPC) 在应用程序容器中运行的 Unavailable SID (Unavailable)。可以使用组件服务管理工具修改此安全权限。
此错误发生在数据库开始恢复过程前约 18 分钟,并且有时在恢复开始期间重复发生。和DBA用户有点关系,但我真的不知道是什么(我还没有时间问DBA)。
首先,很少有家政规则。
以下两个链接可以帮助您更好地管理事务日志文件。
当事务日志文件已满且无法进一步增长时,您遇到的情况不是正常行为。
当事务日志已满时,SQL Server 数据库引擎将发出 9002 错误。当数据库联机或恢复时,日志可能会填满。如果数据库处于联机状态时日志已满,则数据库仍保持联机状态,但只能读取而不能更新。如果恢复期间日志已满,数据库引擎会将数据库标记为“RESOURCE PENDING”。无论哪种情况,都需要用户操作以使日志空间可用。
对完整事务日志的适当响应部分取决于导致日志填满的条件。要发现在给定情况下阻止日志截断的原因,请使用 sys.database 目录视图的 log_reuse_wait 和 log_reuse_wait_desc 列。
您看到的是事务回滚失败。有关更多详细信息,请阅读这篇文章。
根据 Paul Randal 的博客文章,您遇到了一个错误,该错误已在 SQL 2012 SP4 中修复。
有关错误 3314 的更多详细信息:
参考: