在简单的恢复模式下,为什么日志会持续增长.docVIP

在简单的恢复模式下,为什么日志会持续增长.doc

  1. 1、原创力文档(book118)网站文档一经付费(服务费),不意味着购买了该文档的版权,仅供个人/单位学习、研究之用,不得用于商业用途,未经授权,严禁复制、发行、汇编、翻译或者网络传播等,侵权必究。。
  2. 2、本站所有内容均由合作方或网友上传,本站不对文档的完整性、权威性及其观点立场正确性做任何保证或承诺!文档内容仅供研究参考,付费前请自行鉴别。如您付费,意味着您自己接受本站规则且自行承担风险,本站不退款、不进行额外附加服务;查看《如何避免下载的几个坑》。如果您已付费下载过本站文档,您可以点击 这里二次下载
  3. 3、如文档侵犯商业秘密、侵犯著作权、侵犯人身权等,请点击“版权申诉”(推荐),也可以打举报电话:400-050-0827(电话支持时间:9:00-18:30)。
  4. 4、该文档为VIP文档,如果想要下载,成为VIP会员后,下载免费。
  5. 5、成为VIP后,下载本文档将扣除1次下载权益。下载后,不支持退款、换文档。如有疑问请联系我们
  6. 6、成为VIP后,您将拥有八大权益,权益包括:VIP文档下载权益、阅读免打扰、文档格式转换、高级专利检索、专属身份标志、高级客服、多端互通、版权登记。
  7. 7、VIP文档为合作方或网友上传,每下载1次, 网站将根据用户上传文档的质量评分、类型等,对文档贡献者给予高额补贴、流量扶持。如果你也想贡献VIP文档。上传文档
查看更多
在简单的恢复模式下,为什么日志会持续增长

在简单的恢复模式下,为什么日志会持续增长 说明:这篇BLOG的原文标题为:A Race Condition in the Simple Recovery Mode: Why is my log autogrowing。其中,Race Condition 的字面意思为“竞态条件”,感觉不怎么通。但是,文中确确实实是在讲由于SQL SERVER 的其它线程比较繁忙而导致CHECKPOINT线程不能被及时的唤醒和完成工作而导致了日志的增长。翻译水平有限,大家多指教,谢谢。 译文: “我的数据库工作在简单的恢复模式。不,我没有任何巨大的、长时间运行后者用于复制的事务日志,并且,我有足够数量的VLFs循环使用,准确的说有250个VLFs。为什么我的事务日志会保持持续增长呢?” 正如SQL SERVER 联机丛书所记载的一样,当数据库工作在简单恢复模式的时候,在SQL SEVER唤醒检查点线程并运行的时候,它的事务日志被截断(即:所有的没有包含任何活动事务记录的虚拟日志被标记为可重用),而检查点线程在以下三种情况下会被唤醒,1.恢复的时间间隔阈值被足够多的日志记录超过。2.你手工运行了CHECKPOINT命令。3.事物日志已经达到了70%满。 即使没有任何大型的,长时间运行或者用于复制的事物,对于一个运行在简单恢复模式的数据库来说,当CHECKPOINT进程不能被足够快的唤醒而及时的截断日志,填满日志空间或者在自动增长被启用的情况下导致日志的增长是非常可能发生的事情。 例如:即使更改没有达到恢复间隔的阈值,但是,如果更改在日志70%空间被使用以后非常快,SQL SERVER 在日志空间被用尽以前没有足够的时间来运行CHECKPOINT以完成日志的截断。从某种意义上来说,日志空间是否会被用完(或自动增长)取决于下面两个条件之间的竞争状态: 1. 如果SQL SERVER能够首先截断日志,日志空间将被释放且标记为可重用,那么,将不会自动增长或失败事物。 2. 但是,由于数据改变的足够快以至于在日志被截断以前而用尽了日志的空间,这种情况也是可能发生的。 让我们用一个脚本来实际的阐明这种行为。首先在一个测试数据库中运行一下脚本创建一个测试表并填充一些数据。测试数据库1.已经设置为简单的恢复模式。2.日志的大小固定为100M.3.日志文件的自动增长被禁用(因为观察日志空间被用完的错误比检查自动增长要容易) set nocount on go drop table test go create table test i int, c char 1000 go declare @i int set @i 1 while @i 10000 begin insert test values @i, abc set @i @i + 1 end 为了观察这种资源竞争,运行一下脚本 set nocount on go declare @change_size int set @change_size 100 -- adjust this value declare @i int set @i 1 while @i 100 begin if @i % 2 0 update test set c replicate a, @change_size else update test set c replicate b, @change_size select @i @i + 1 end 你可能需要多次调整变量@change_size的值,首先使用一个比较小的值(比如40)使脚本能够运行至结束,然后挑一个比较大的值(比如400)使该脚本运行失败。请尽量使该脚本在运行中途失败。在我的几次测试中,当@change_size 100时,成功运行了上面的脚本并且在运行过程中日志的空间没有被填满。但是当我将@change_size改为120时,我得到了9002的错误信息非常准确的告诉我数据库的事务日志已满。 当我将变量@change_size设置为116时,有时候脚本会成功结束,而有时候会失败。但这只是一个大致的阈值,在一个不稳定的测试及此测试环境下它是不精确的。实际上,在我的其它一些测试中,这个阈值低至50。这中情况说明,SQL SERVER 在有些时候能够足够快的截断日志,而有时候却不能。 值得注意的是,尽管上面的两个UPDATE语句的每一个都更新了9999行,由修改而占用的日志空间控制的比较好,大约在2-3M或者总日志空间2%-3%.这并不是一个很小的事务,尽管它也不是一个大的,长时间运行的事务。 对于一个工作在简单恢复模式的数据库来说,对我们有什么启示呢? 首先,在事务日志中预留足够的空间。这可能意味着你必须让SQL SERV

文档评论(0)

hf916589 + 关注
实名认证
文档贡献者

该用户很懒,什么也没介绍

1亿VIP精品文档

相关文档