如何管理大型、大量使用的数据库中的日志文件大小

UnL*_*uys 5 sql-server sql-server-2012

我们是一个数学家团队(即,没有 DBA 经验)。

我们在 SQL Server 2012 中有一个大型数据库。它有超过 2 TB 的数据(数百个表,每个表有数百万行和数百列宽)。每个月,我们都会收到一系列数据的添加和修订,这要求我们通过删除、替换或更新大部分或所有表来对数据库进行大量更新。

我们的工作主要集中在制定 SQL 逻辑来计算我们需要的结果。我们没有运行实时呼叫中心。我们根据需要应用了一些索引,我们对性能非常满意。

问题是日志文件。自然地,日志文件随着如此多的数据操作而增长和增长。我们的日志文件目前大约为 1 TB。我们有大量的磁盘空间,但不是无限的。

根据我们在 Internet 上的阅读,我们了解到日志文件对于事务完整性、回滚和恢复是必需的。但就我们的特定目的而言,我们并不关心这些。我们可能永远不会执行回滚,也永远不会尝试恢复。更糟糕的是,我们只需再次下载数据文件并从头开始创建一个新数据库。

我们真的只是希望日志文件消失并且永远不会回来。

我们将数据库恢复模式设置为简单,天真地认为这意味着“无恢复模式”,但我们很快就消除了这些幻想。

我们也明白有很多错误的事情不能做(分离、收缩等)。我们只是不知道正确的做法。

也许有人会建议我们设置日志文件增长的限制。但是,这留下了两个问题:(1) 我们如何摆脱已经存在的 1 TB?(2) 我们之前尝试过,当我们接近指定的限制时,我们开始在这里、那里和任何地方收到错误 9002(日志文件已满)。所以现在我们害怕应用大小限制。

我们如何在没有任何伤害的情况下告诉数据库“没有日志文件,请”?

Bra*_*adC 12

如果您从没想过要进行时间点恢复,那么您只需要做两件事:

  1. 将数据库更改为SIMPLE恢复模式
  2. 小批量做大改动。

在 SIMPLE 恢复模式下,日志文件仅用于处理中的事务。当事务完成时,tran 日志中的空间将被标记为可重用,而下一个事务只会重新使用该空间*。

(* 这并不完全正确,偶尔运行的“检查点”实际上清除了重用空间,但在大多数情况下,它无需干预即可工作;只有挑剔的 DBA 可能会关心这里的内部细节。)

所以保持你的交易一口大小:

  • 如果您需要删除表的所有行,请不要执行DELETE100m 行(这会炸毁日志),TRUNCATE而是执行 a ,或者仅删除DROP表并重新创建它。
  • 如果您不能这样做(您只需要删除一些行),请分批进行
  • 在进行大数据导入时,了解批量导入快速加载数据并每隔一段时间提交数据的SSIS 快速加载
  • 更新也是一样,不要更新大表的每一行,使用更具选择性的WHERE子句将更新限制为一次约 10 万行。了解如何在 SQL 中使用游标

当然,确切的详细信息将取决于您的实际数据库和实际活动,但是具有 1TB 数据的数据库不应具有大于 100Gb 的 tran 日志文件,具体取决于您的批次有多大。

关于缩小现有文件,您可以使用以下脚本查看数据和日志文件中的可用/已用空间:

SELECT DB_NAME() as dbname, type_desc, name as logical_name, 
    CONVERT(decimal(12,1),size/128.0) as TotalMB,
    CONVERT(decimal(12,1),FILEPROPERTY(name,'SpaceUsed')/128.0) as UsedMB,
    CONVERT(decimal(12,1),(size - FILEPROPERTY(name,'SpaceUsed'))/128.0) as FreeMB,
    physical_name
 FROM sys.database_files WITH (NOLOCK)
 ORDER BY type, file_id;
Run Code Online (Sandbox Code Playgroud)

如果日志中的已用空间很高,那么您可能仍有打开的事务。寻找第 3 方工具sp_WhoIsActive来深入了解您当前的活动/开放交易。

当您准备好收缩时,选择一个合理的目标大小,然后执行 SHRINKFILE:

DBCC SHRINKFILE (NAME = 'mylogfile', SIZE = 100000)
Run Code Online (Sandbox Code Playgroud)

(该大小以 MB 为单位)。

如果您的日志文件仍然在增长,请返回sp_WhoIsActive查看哪些事务运行了这么长时间,并弄清楚如何分批执行它们。