【问题标题】:Why SQL Server seems to be so attached to transaction logs为什么 SQL Server 似乎如此依附于事务日志
【发布时间】:2009-10-12 20:03:11
【问题描述】:

好的,到此为止。我不是数据库专家或管理员。事实上,除了偶尔的索引/查询调优之外,我并没有经常在数据库中闲逛。我经常忽略的一件事是 SQL Server 事务日志。我知道它的用途、它包含什么以及它是如何工作的(至少在概念上),但我想我不明白为什么 SQL Server 似乎如此依附于事务日志

这是第一个问题。如果我错了,请纠正我,但在我看来,默认情况下事务日志将只包含数据库中所有更改的整个历史记录。有两个迹象表明情况可能确实如此。当我创建一个新数据库时,其日志的最大大小设置为“无限制增长”。第二个原因是我经常处理带有大量事务日志的小型数据库,无论我做什么都无法缩小。这似乎很奇怪,我不敢相信这是真的。为什么我会默认想要整个历史记录?我只关心处于一致状态的最新版本数据。好吧,我怀疑在某些情况下可能有正当理由,但我会认为这是一个额外的选择。

我的第二个问题是为什么要摆脱转换日志如此复杂?只是我,还是真的没有直接的方法可以做到这一点?就在最近,我试图摆脱 5MB 数据库的 100MB+ 日志,我发现最简单的方法是分离数据库,删除日志并重新附加它(甚至 SQL Serve 也抱怨了一点)。我用我能找到的所有可能的选项尝试了缩小命令,但我只能缩小到大约 50%。数据库没有使用(没有活动连接),老实说,我根本不关心过去的任何转换。我注意到可能还有其他一些“方法”可以做到这一点;一些涉及备份和恢复。

我努力尝试阅读 MSDN 文档并了解更多关于转换的知识,但在大约 15 分钟后,感觉就像在泥泞中转圈一样,我放弃了。我知道对于数据库管理员和专家来说,我的问题听起来很愚蠢。感谢您提供任何反馈。

编辑:在第一个答案之后,我意识到我可能不够清楚。我知道事务日志在事务期间是如何工作的,为什么它很重要,并且它可以用于备份目的。我想我想从开发人员的角度提出更多问题。大多数时候,我处理暂存/测试临时数据库,这些临时数据库不需要任何备份,除了我之外没有人使用,我经常发现自己需要传输它,并且在这种情况下拥有巨大的过渡日志是不必要的不​​便.

【问题讨论】:

    标签: sql-server transaction-log


    【解决方案1】:

    数据库日志不是一些事后的历史记录,就像一个 IIS 日志。在具有Write-Ahead Logging 的数据库中,日志是主要的恢复、重做和撤消源,并且在所有方面都是权威的数据源。删除或替换日志是管理数据库的人可以做的最糟糕的决定之一。您的数据库此时可能已损坏。

    截断日志的正确方法是执行完整的数据库备份,然后是数据库日志备份,然后是定期日志备份。这将释放日志中的空间并允许其重用。它不会缩小物理 LDF 文件。

    另一个途径是将恢复模式更改为SIMPLE,这将允许服务器在它认为合适的时候自动回收日志文件。将恢复模式更改为 SIMPLE 会影响数据库的可恢复性,因为您将无法应用某些灾难恢复方案(例如时间点恢复),也无法恢复自上次备份以来的任何数据更改。

    Understanding Logging and Recovery in SQL Server
    Misconceptions around the log and log backups: how to convince yourself
    Inside the Storage Engine: More on the circular nature of the log

    【讨论】:

    • 感谢您提供非常详细的答复。只是为了确认一下:如果我不对事务日志做任何事情并将所有选项保留为默认值,它是否会永远增长并最终包含数据库中所有更改的完整历史记录(以某种形式)?
    • 不,不是真的。新数据库将具有 SIMPLE 恢复模式,并将回收日志。已更改恢复模式但从未进行备份的数据库仍将处于“伪简单”模式并且仍不会增长日志。只有在更改恢复模式并进行备份后,日志才会开始增长。
    • 您能否详细说明“伪简单”模式或指向一些链接?我以为我在某处看到了一些关于它的东西,但我再也找不到了。
    • 简单模式下100MB+的日志怎么可能缩水不超过50%?有问题的数据库被其他任何人使用了很长时间,然后我和我主要使用它或只读操作。
    【解决方案2】:

    交易日志的存在主要有两个原因

    1 - 允许数据库“回滚”当前事务 2 - 允许崩溃的数据库将其状态恢复到崩溃前最后提交的事务

    1 是暂时的,如果您没有活动事务,那么它将消耗很少的空间。 2 但是,正如您推测的那样,随着时间的推移会继续增长,可能没有限制。

    这个想法是您经常将事务日志备份到转储文件中。转储文件是数据库的完整状态快照,您可以在某个时间点从中恢复整个数据库。当您执行此操作时,事务日志将被截断并从空重新开始。

    如果数据库随后崩溃,您从转储文件加载数据库快照,然后应用事务日志,其中包含自上次快照以来的增量更改,以恢复状态。因此,事务日志需要保存在高弹性存储上,否则您无法恢复数据库。

    因此,通过定期进行数据库转储,您的事务日志会被反复清除。

    还有另一个我不推荐的选项,即禁用数据库上的事务日志。这基本上消除了上面的 2,因此事务日志不会随着时间的推移而增长。当然,如果您的数据库崩溃,您只能从上次完整备份/转储中恢复,因此如果您正在运行任何甚至是半重要的事情,此选项会带来相当大的风险。

    HTH。

    【讨论】:

      【解决方案3】:

      您对日志中包含或不包含的内容有几个错误的想法,根据您的恢复模式,日志可能仅包含当前未提交的事务,因此它们可能会回滚(简单模式)或可能仅包含最低限度记录操作,但生成的事务日志备份会更大,因为它们将包含在日志备份之间更改的范围(批量记录模式),或者可能包含自上次日志备份以来每个已提交事务的所有日志信息。

      不受限制的增长只是一个默认值,让日志随意增长并不是最佳实践,因为这会通过增加实际日志文件中 vlf 虚拟日志文件的数量而导致日志碎片。如果您获得太多这些,某些操作(例如复制)的性能会受到影响。

      如果日志文件大于数据库并且在备份后无法收缩,则可能在持有 VLF activem 的系统上存在一个打开的事务,这会阻止它重新使用空间。

      分离数据库并在杀死日志后重新附加它对您的数据库来说是一件非常糟糕的事情,它不能处于事务一致的状态,您真的想在这样做之后运行 dbcc checkdb。是的,您没有活动连接,但这是一件有风险的事情,而且当您遇到日志损坏时,这几乎是最后的手段,而不是列表中的第一件事。

      这被认为是糟糕的,在 2005 年甚至有一个你不能改变的标志表明你已经做到了。 MS 支持人员可以检查您是否在寻求他们的帮助以解决 SQL 中的潜在错误。

      就摆脱日志而言,正是日志使 DBA 能够提供一种恢复策略,该策略可以将数据库恢复到硬件故障/损坏破坏数据库的近乎精确的时间点。如果没有事务日志,您将只能恢复到上次的完整备份。使用日志,您可以像快进录像机一样重播交易。

      这个话题非常庞大,正如您所看到的那样复杂,但值得学习。

      【讨论】:

        【解决方案4】:

        (这是 MS-SQL,对吗?)

        是的,我敢打赌,当您手动分离并删除日志时,服务器确实会抱怨。

        如果您不想保留 T 日志,请将目录的恢复模式更改为“简单”(在目录的属性中),这将在事务成功提交时截断日志。

        如果您确实想要日志(大多数人都想要,拥有它们非常方便!)备份时日志将被截断。

        (交易日志,FTW!)

        【讨论】:

          【解决方案5】:

          大多数关系数据库服务器都维护一个事务日志,记录对数据库所做的所有更改。这个想法是,如果数据库服务器出现故障,您可以“重播”上次数据库备份对数据库所做的所有更改,这应该是一个已知状态。

          自从我使用 SQL Server 以来已经有一段时间了,所以我无法回答为什么要摆脱事务日志如此困难。在 SQL Server 7 中,SQL Server 2000 天,对数据库进行完整备份会默认截断事务日志。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2010-09-23
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-04-08
            • 2012-09-11
            • 2010-09-08
            • 1970-01-01
            相关资源
            最近更新 更多