如何防止索引重组期间事务日志变满?

20 sql-server-2008 sql-server transaction-log index-maintenance

我们有多台机器,我们已将事务日志的大小预先分配为 50GB。我试图重组的表的大小是 55 - 60 GB,但会不断增加。我想重组的主要原因是回收空间和任何性能优势,因为这是一个额外的好处。

表的碎片级别为 30 - 35%。在其中一些机器上,我收到“事务日志已满”错误并且重组失败。事务日志大小高达 48GB。有什么好的方法可以解决这个问题?我们没有打开自动增量,我不愿意这样做。

我可以将日志大小增加到更大的值,但是随着将来表大小的增加,该值可能不够。如果我要同等地增加日志大小,它也会破坏进行重组以回收空间的目的。关于如何有效应对这种情况的任何想法?使用批量模式不是一种选择,因为数据丢失是不可接受的。

gbn*_*gbn 8

最佳实践REORGANIZE低于大约 30% 的碎片和REBUILD高于此。简单地说,REBUILD制作一个干净的副本,REORGANIZE就地做。

检查您实际在做什么:您没有维护计划两者都做,是吗?

在较大的表上(50GB 表正在到达那里),REORGANIZE如果您遵循此规则,我已经看到消耗所有事务日志空间。不经常:只有一个具有特定负载模式的系统。在REORGANIZE刚跑,直到日志扩大和消费的所有磁盘空间。

我们改用REBUILD没有更多问题,但忽略了低于 25% 的碎片。这对我们更有效:你必须看看它是否适合你。

REBUILD对性能的影响可能比REORGANIZE在生产中更大,但有时可以通过ONLINE选项(需要企业版)来减轻这种影响。


Rem*_*anu 7

REORGANIZE(如在 ALTER INDEX ... REORGANIZE 中)是一个非常快的操作(好吧,主要是...),它需要少量日志,可以随时中断并稍后恢复,并且在小批量事务中在内部工作:

碎片整理作为一系列短事务执行,因此如果频繁进行日志备份或恢复模型设置为 SIMPLE,则不需要大日志。

你确定你不是在谈论重建?索引 REBUILD 速度慢、成本高、消耗大量日志(如果未离线且无法进行最少日志记录,则在线重建无法进行最少日志记录),是一个巨大的事务,并且无法在不丢失所有工作的情况下中断。

在我看来,您正在重建,这是一个非常特殊的操作,除非您有非常深思熟虑的理由,否则您不应该这样做。你想要什么样的空间回收?有什么DBCC CLEANTABLE不能处理的?您是否检查过表物理结构,它是否偏离了逻辑结构(有关详细信息,请参阅引擎盖下的 SQL Server 表列)?

如果您真的必须重建表,那么恐怕您别无选择,只能硬着头皮分配必要的日志。不要让它自动增长,它只会减慢进程。将其预长到桌子大小的 2.5 倍。

如果表已分区,那么您可以一次离线重建(并重新组织)一个分区。在线重建只能在整个表级别完成。

  • 我正在重组。恢复模型已满,我确实看到了很大的事务日志大小。失败的原因是两个 1. 镜像之一。需要将日志推送到次要空间才能回收空间 2. 日志备份。即使我们每 15 分钟进行一次备份,它有时也会由于这个原因而失败。 (2认同)

Cod*_*ior 6

我以前有过这个问题。

  • 您有一个大数据库和一个小日志驱动器。您想重组(出于各种原因)。
  • 当您在大型碎片表上尝试此操作时,日志会填满,直到日志驱动器已满,然后命令中止。
  • 如果它处于简单模式,其他事务可能会失败,直到在下一个检查点清除日志,如果它处于完整模式,其他事务可能会失败,直到下一次日志备份。停电!
  • 如果您处于完整模式,您会增加日志备份频率,但这无助于避免该问题,因为重组是在隐式事务中完成的,在该事务完成或中止或停止之前,日志不会清除。
  • 而且您真的希望重新组织能够完成。

这有点违反直觉,因为你知道如果你中止重组,它可以从它停止的地方继续,只是中止提交事务而不是回滚。

这就是你要做的。它有点长但很简单。

  • 将您的日志文件预增长到相对较大的大小,但不是最大值。基本上你想留出足够的空间来做有用的工作,加上一些小的增长,如果它们发生的话,这样正常的操作就不会停止。
  • 创建一个作业来运行您的索引重组 ('Reorganize')。
  • 在性能条件下创建代理 WMI 警报(“重组安全阀”)。

    • 对象:SQLServer:数据库
    • 计数器:使用的日志百分比
    • 实例:(你的大数据库名称)
    • 计数器上升到以上时发出警报:80
    • 响应:执行作业(“重新组织检查”)
  • 创建作业(“重新组织检查”)

    • 在作业中检查 msdb.dbo.sysjobactivity 以查看“重组”作业是否正在运行。如果是...
    • 停止作业并轮询直到它停止。这可能需要几秒钟。
    • (如果您处于完整模式)触发您的日志备份作业并在完成时确认。
    • 仔细检查 sys.dm_os_performance_counters,您的日志可用空间计数器已减少到阈值以下。
    • 开始“重组”工作。
  • 在某个地方测试这一切,甚至是开发沙箱,以确保它在将其粘贴到生产服务器之前正常运行。

您将看到的是“重组”作业开始并开始填充日志。当日志达到百分比满时,它会触发 WMI 警报(大约 30 秒内),该警报会运行您的其他作业,该作业会看到“重组”作业正在运行,因此很可能出现故障。然后它停止“重组”,进行备份,确认日志可用空间恢复到合理的值,然后再次启动“重组”工作,这将在停止的地方继续。

因此,在这种情况下,您将日志预先调整为合理数字的原因是减少增长/触发器/作业/停止/重新启动的次数,从而提高效率,并为日志保留足够的空间没有及时发现的偶然增长。

这是一种奇怪的场景。我很确定几年前我会对此犹豫不决,显然这里有一些根本的潜在问题。但是,如果您处理数百台服务器,则会出现一些像这样的边缘情况,无论出于何种商业原因,这些边缘情况都无法以任何方式处理,除非 MacGyvering 是一个完成工作的临时解决方案。

只要它是安全的、合乎逻辑的、经过测试并且有据可查的,就应该没有问题。


小智 0

我假设您正在运行以下内容:

重组时更改索引

不幸的是,没有办法运行部分组织(例如,可以部分收缩日志文件的方式)。我可以思考解决这个问题的方法是:

1)在运行重组时将数据库设置为简单恢复模式,但你说这是不可接受的

2)对索引进行分区 - 如果可以想出一种方法对索引进行分区以获得大约相同大小的分区,那么您将能够独立地重新组织(或使用在线选项重建)每个分区,从而限制日志文件的增长

我确信您正在这样做,但如果您没有这样做,您可能需要在进行任何索引优化之前和之后启动日志文件备份,这将允许它回收已使用的空间。