简体   繁体   English

如何重复运行SQL Delete语句并缩小事务日志?

[英]How Do I Repeatedly Run SQL Delete Statements and Shrink Transaction Log?

I have a customer who is running out of space on their drive, and it's entirely taken up by the SQL DB and transaction log. 我有一个客户的驱动器空间不足,这完全由SQL DB和事务日志处理。 Unfortunately, moving the DB and log are not an option available to us at the current time, so I need to figure out how to delete lines from 2 massive tables. 不幸的是,移动数据库和日志目前尚不可用,因此我需要弄清楚如何从2个大型表中删除行。 So far a coworker has spent 4 days trying to do this and has not been able to put a dent in it. 到目前为止,一位同事已经花了4天的时间尝试执行此操作,但未能对此有所帮助。 There are only 13GB available for the transaction log, and deleting large quantities from these tables wipes that 13GB out really quick. 事务日志只有13GB的可用空间,从这些表中删除大量数据会很快擦除13GB的空间。 Obviously the quickest thing to do would be to move what we want to keep to a temporary table, truncate the existing tables, then move them back. 显然,最快的方法是将我们想要保留的内容移到临时表,截断现有表,然后再将它们移回。 Unfortunately, this is an extremely busy environment within a hospital, and there are tens of thousands of lines being written to these tables every hour. 不幸的是,这是医院中非常繁忙的环境,每小时有成千上万的行写入这些表。 So, unfortunately, we can't temporarily stop writing to this table to be able to truncate. 因此,不幸的是,我们无法暂时停止写入该表以进行截断。

So we've been deleting a month of data at a time from each of these tables, then shrinking the transaction log to do it again. 因此,我们已经一次从每个表中删除了一个月的数据,然后缩小事务日志以再次执行。 I feel like there's got to be a way to just get this to repeat, but I'm not entirely sure what I'm doing... I tried: 我觉得有一种方法可以重复执行此操作,但是我不确定自己在做什么...我尝试过:

delete top (10000)
from Table 1_
where CreationDate_ < '2017-06-01' 

Go

delete top (10000)
from Table2_
where CreationDate_ < '2017-06-01' 

Go

dbcc shrinkfile (SQL_Log,4)

Go 2

Go 2

This appears to remove 10,000 lines from each table, then runs the shrinkfile for the log twice (for some reason it doesn't fully shrink down to the 4224kb size when we only run it twice), but it does not seem to repeat. 这似乎从每个表中删除了10,000行,然后为日志运行了收缩文件两次(由于某些原因,当我们只运行两次时,它没有完全缩小到4224kb的大小),但是似乎没有重复。 I've also tried adding () starting at the first delete statement and ending after the first "Go 2" line. 我还尝试了从第一个delete语句开始到第一个“ Go 2”行之后结束的add()。 When I do that it just says: 当我这样做时,它只是说:

Incorrect syntax near "Go"

Anybody have any clue how to do this? 有人知道如何执行此操作吗? If we can get this to work, I plan on increasing the delete statements to a number much larger than 10,000, and increasing the repeat on the script to something much larger than 2, but I need to get it to work before I can actually do that... 如果我们可以正常工作,我计划将delete语句增加到大于10,000的数量,并将脚本上的重复语句增加到大于2的数量,但是我需要先使其生效,然后才能实际执行那...

You don't need to shrink the log file repeatedly. 您无需重复缩小日志文件。 If the database is in simple recovery mode the log file will not continue to grow, so long as you don't delete too many rows in a single transaction. 如果数据库处于简单恢复模式,则只要您在单个事务中不删除太多行,日志文件就不会继续增长。 Once all the rows have been purged you can shrink the log file down to something reasonable for the environment. 清除所有行后,您可以将日志文件缩小到适合环境的大小。

You can use a WHILE loop and control the number of iterations using a COUNT of records. 您可以使用WHILE循环并使用COUNT条记录来控制迭代次数。

DECLARE @Chunk INT = 10000
DECLARE @Date DATE = '2017-06-01'
DECLARE @Cnt INT = SELECT COUNT(*) FROM Table 1_ WHERE CreationDate_ < @Date
WHILE @Cnt > 0
  BEGIN
    delete top (@Chunk)
    from Table 1_
    where CreationDate_ < @Date
    SET @Cnt = @Cnt - @Chunk
  END
//Move on to the next group
SET @Date = '2017-07-01'
SET @Cnt = SELECT COUNT(*) FROM Table 1_ WHERE CreationDate_ < @Date

WHILE @Cnt > 0
   BEGIN
   // Your delete query
   SET @Cnt = @Cnt - @Chunk
END
//and so on

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM