截断 AG 中包含 170 亿行的表

yeg*_*sew 20 sql-server truncate transaction-log availability-groups

我需要截断一个包含 170 亿行的表,该表位于作为 AG 一部分的数据库中。

此操作对 AG 延迟和日志备份大小有什么影响?

有推荐的方法吗?

Jos*_*ell 58

记录范围

生成(从而通过网络发送到其他节点AG)日志的数据量取决于如何的行是在17十亿行的表是。 TRUNCATE肯定是比较做了一个微小的量DELETE。但它可能仍然很重要,具体取决于您的基础设施和期望。

考虑dbo.VotesStack Overflow 示例数据库中的表:

显示投票表中的列及其数据类型的 SSMS 屏幕截图

每行是 28 个字节。SQL Server 中的页面为 8 KB(8,192 字节),因此您可以在页面上容纳大约 292 行。这并不完全正确,因为页面和行都有开销,但对于此示例来说,这是一个不错的近似值。

这意味着大约需要 58,219,178 页来容纳所有 170 亿行。执行DROPor 时TRUNCATE,后台任务会解除分配范围(8 页为一组)。这些释放中的每一个都被记录下来。这意味着通过截断此表将创建大约 7,277,397 条日志记录。

测试 dbo.Votes

在将恢复模型设置为完整并进行完整备份和日志备份以初始化备份链之后,我在该示例数据库的副本上尝试了此方法。该dbo.Votes表有 10,146,802 行。根据我们之前的计算,这应该是大约 34,749 页,或 4,343 个盘区。

实际上,该表使用分配给它的 47,721 页(因为前面提到的开销),即 5,965.125 个区。

现在我要TRUNCATE表:

TRUNCATE TABLE dbo.Votes;
Run Code Online (Sandbox Code Playgroud)

这会立即完成,但我最终得到了 17,605 条日志记录。看起来每个区确实有 3 条日志记录(2 条用于更新 IAM 和 GAM 页面,一条用于更新 PFS 页面以解除分配数据页面)。

这些日志记录总共只使用了约 1.28 MB 的日志文件。但是你的真实表的行数是这个的 1,600 倍,你的行大小可能更大。这可能意味着生成超过 1 GB 的日志数据并通过网络发送到每个副本。

如果您在此表上有非聚集索引(以相同方式记录),则数据量会进一步增长。

行大小有很大的不同

另一个案例研究可能是dbo.Comments表格。它具有3907472点的行,但每一行是1424个字节长(最大-该Text列是nvarchar(700))。

尽管行数明显少于dbo.Votes,但该表分配了 176,722 页。 TRUNCATEingdbo.Comments在63792个日志记录和4.86 MB的日志数据的结果。

如果您的实际行大小在此范围内更大,则日志数据可能超过 7.5 GB。

该怎么办

也许您的基础设施和日志文件可以轻松处理几 GB 的数据——如果您有一个 17 B 行的表,它们似乎应该如此!但我认为值得一提的是,流量不一定微不足道,因为现有的答案没有提到这一点。

如果可以,请在非生产环境中进行测试。测量之前和之后的日志文件使用情况,并确保您的生产基础设施设置为处理该数量的数据。确保日志文件已预先调整大小以处理此截断 - 在此操作中间发生自动增长会大大减慢速度,并导致阻塞。

如果您无法测试,请尽最大努力估计会产生什么影响。使用查询这样一个让表中的页数。然后将其除以 8(以获得范围的数量)并乘以 3 以获得日志记录的近似数量。

我的测试有大约 70 字节的平均日志记录大小,但我不知道这是否是典型的。但是您可以尝试将近似日志记录乘以 70 以获得截断产生的潜在日志字节数。

混合使用 AG,您还可以尝试使用日志流压缩。我没有使用过这些跟踪标志,所以我只是提到它是另一个可以调整的旋钮。


如果您发现该TRUNCATE方法太不可预测,或者对您的系统来说太过分了,您总是可以DELETE批量使用法线。这总共使用了更多的日志,但您可以将其分散在您喜欢的任何时间段内。但是,如果您走那条路,请确保在编写批处理脚本时要小心

  • 这是一个很好的答案!DBA SE 是一个学习的好地方。现在编辑我自己的答案,我不想误导问题作者并让他认为 170 亿行截断不会导致任何流量:( 如果你们能从我的答案中删除反对票,我会很感激。不要有如果作者将答案转换为这个答案,则有任何异议 (7认同)

Ale*_*sko 19

Truncate table 命令立即截断行并且不会将删除的行写入事务日志文件

通常Truncate table立即执行,并且与您执行时相比,AG 中的副本之间没有明显的网络流量,因此不会有明显的日志备份等Delete from。但是,可以有明显的流量和明显的日志备份,因为 170 亿行是很多

PS 做truncate之前考虑备份数据库,把备份保存到archive中,这样以后有需要可以恢复170亿表

  • +100 为“备份优先”! (2认同)