如何清除SQL Server事务日志?

发布于 2024-07-05 04:47:00 字数 87 浏览 8 评论 0原文

我不是 SQL 专家,每次我需要做一些超出基础知识的事情时,我都会想起这一事实。 我有一个测试数据库,其大小并不大,但事务日志绝对很大。 如何清除交易记录?

I'm not a SQL expert, and I'm reminded of the fact every time I need to do something beyond the basics. I have a test database that is not large in size, but the transaction log definitely is. How do I clear out the transaction log?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(21

素染倾城色 2024-07-12 04:47:00

缩小日志文件实际上应该保留用于遇到意外增长且您不希望再次发生的情况。 如果日志文件将再次增长到相同的大小,那么暂时缩小它并没有多大作用。 现在,根据数据库的恢复目标,您应该采取以下操作。

首先,进行完整备份

切勿对数据库进行任何更改,除非确保出现问题时可以恢复数据库。

如果您关心时间点恢复

(所谓时间点恢复,我的意思是您关心能够恢复到除完整备份或差异备份之外的任何内容。)

大概您的数据库处于 FULL< /code> 恢复模式。 如果没有,请确保:

ALTER DATABASE testdb SET RECOVERY FULL;

-- and take another full backup here
-- so log backups are possible

即使您定期进行完整备份,日志文件也会不断增大,直到您执行日志备份 - 这是为了保护您,而不是不必要地消耗资源在你的磁盘空间。 根据您的恢复目标,您应该经常执行这些日志备份。 例如,如果您的业务规则规定在发生灾难时您可以承受不超过 15 分钟的数据丢失,那么您应该有一个每 15 分钟备份一次日志的作业。 这是一个脚本,它将根据当前时间生成带时间戳的文件名(但您也可以通过维护计划等来执行此操作,只是不要选择维护计划中的任何收缩选项,它们很糟糕)。

DECLARE @path nvarchar(4000) = CONCAT(
  N'\\backup_share\log\testdb_',  
  CONVERT(char(8), GETDATE(), 112), N'_',
  REPLACE(CONVERT(char(8), GETDATE(), 108),':',''),
  N'.trn');

BACKUP LOG foo TO DISK = @path WITH INIT, COMPRESSION;

WAITFOR DELAY '00:00:01';
GO 2 -- run twice to ensure file wrap-around

请注意,\\backup_share\ 应该位于代表不同底层存储设备的不同计算机上。 将它们备份到同一台机器(或使用相同底层磁盘的不同机器,或同一物理主机上的不同虚拟机)并不能真正帮助您,因为如果机器崩溃,您就会丢失数据库及其备份。 根据您的网络基础设施,在本地备份然后将它们传输到幕后的不同位置可能更有意义; 无论哪种情况,您都希望尽快将它们从主数据库计算机上删除。

现在,一旦您定期运行日志备份,就应该合理地将日志文件缩小到比目前所扩展的文件更合理的程度。 这并不意味着一遍又一遍地运行 SHRINKFILE 直到日志文件达到 1 MB - 即使您经常备份日志,它仍然需要容纳任何可能发生的并发事务。 日志文件自动增长事件的代价很高,因为 SQL Server 必须将文件归零(与启用即时文件初始化时的数据文件不同),并且用户事务必须等待这种情况发生。 您希望尽可能少地执行这种增长-收缩-增长-收缩例程,并且您当然不想让您的用户为此付费。

请注意,您可能需要备份日志两次才能进行收缩(感谢 Robert)。

因此,您需要为日志文件确定一个实用的大小。 如果不了解更多有关系统的信息,这里没有人可以告诉您那是什么,但是如果您经常缩小日志文件并且它又再次增长,那么一个好的水印可能比最大的水印高 10-50% 。 假设达到 200 MB,并且您希望任何后续自动增长事件为 50 MB,那么您可以通过这种方式调整日志文件大小(其中 'yourdb_log'逻辑 数据库日志文件的名称,您可以在 sys.database_files):

USE [master];
GO
ALTER DATABASE Test1 
  MODIFY FILE
  (NAME = N'yourdb_log', SIZE = 200MB, FILEGROWTH = 50MB);
GO

请注意,如果日志文件当前> 200 MB,您可能需要先运行以下命令:

USE yourdb;
GO
DBCC SHRINKFILE(N'yourdb_log', 200); -- unit is MB
GO

如果您不关心时间点恢复

如果这是一个测试数据库,并且您不关心时间点恢复,那么您应该确保您的数据库处于 SIMPLE 恢复模式。

ALTER DATABASE testdb SET RECOVERY SIMPLE;

将数据库置于SIMPLE 恢复模式将确保 SQL Server 重新使用日志文件的部分内容(实质上是逐步淘汰不活动的事务),而不是不断增长以保留全部记录。 > 事务(就像 FULL 恢复一样,直到您备份日志)。 CHECKPOINT 事件将有助于控制日志并确保日志不需要增长,除非您在 CHECKPOINT 之间生成大量 t-log 活动。

接下来,您应该绝对确保此日志增长确实是由于异常事件(例如,年度春季大扫除或重建最大索引)造成的,而不是由于正常的日常使用造成的。 如果你将日志文件缩小到小得离谱,而 SQL Server 只需要再次增大它来适应你的正常活动,你会得到什么? 您是否能够利用暂时释放的磁盘空间? 如果您需要立即修复,则可以运行以下命令:

USE yourdb;
GO
CHECKPOINT;
CHECKPOINT; -- run twice to ensure file wrap-around
GO
DBCC SHRINKFILE(N'yourdb_log', 200); -- unit is MB
GO

否则,设置适当的大小和增长率。 根据时间点恢复案例中的示例,您可以使用相同的代码和逻辑来确定合适的文件大小并设置合理的自动增长参数。

有些您不想做的事情

  • 使用TRUNCATE_ONLY选项备份日志,然后使用SHRINKFILE。 其一,此 TRUNCATE_ONLY 选项已被弃用,并且在当前版本的 SQL Server 中不再可用。 其次,如果您处于FULL恢复模式,这将破坏您的日志链并需要新的完整备份。

  • 分离数据库,删除日志文件,然后重新附加。 我无法强调这有多危险。 您的数据库可能无法恢复,它可能会被怀疑,您可能必须恢复到备份(如果有的话),等等。

  • 使用“收缩数据库”选项。 DBCC SHRINKDATABASE 和执行相同操作的维护计划选项都是坏主意,特别是如果您确实只需要解决日志问题的话。 使用DBCC SHRINKFILEALTER DATABASE ... MODIFY FILE(上面的示例)定位要调整的文件并独立调整它。

  • 将日志文件缩小至 1 MB。 这看起来很诱人,因为,嘿,SQL Server 会让我在某些情况下执行此操作,并查看它释放的所有空间! 除非您的数据库是只读的(确实如此,您应该使用ALTER DATABASE将其标记为只读),否则这绝对会导致许多不必要的增长事件,因为日志必须容纳当前事务,无论恢复模型。 暂时释放该空间,让 SQL Server 缓慢而痛苦地收回它,有什么意义呢?

  • 创建第二个日志文件。 这将为已填充磁盘的驱动器提供暂时的缓解,但这就像尝试用创可贴修复刺破的肺部一样。 您应该直接处理有问题的日志文件,而不是仅仅添加另一个潜在问题。 除了将某些事务日志活动重定向到不同的驱动器之外,第二个日志文件实际上对您没有任何作用(与第二个数据文件不同),因为一次只能使用其中一个文件。 Paul Randal 还解释了为什么多个日志文件会相互影响稍后你

积极主动

与其将日志文件缩小到较小的数量并让它以较小的速度不断自动增长,不如将其设置为相当大的大小(能够容纳最大并发事务集总和的大小)并设置一个合理的自动增长设置作为后备,这样它就不必多次增长来满足单个事务,并且在正常业务运营期间它需要增长的情况相对较少。

这里最糟糕的可能设置是 1 MB 增长或 10% 增长。 有趣的是,这些是 SQL Server 的默认设置(我对此有所抱怨,要求更改无济于事) - 1 MB 用于数据文件,10% 用于日志文件。 在当今时代,前者太小了,而后者每次都会导致越来越长的事件(例如,您的日志文件是 500 MB,第一次增长是 50 MB,下一次增长是 55 MB,下一次增长是 60.5 MB)等等 - 在缓慢的 I/O 上,相信我,你真的会注意到这条曲线)。

进一步阅读

请不要停在这里; 虽然您看到的许多关于缩小日志文件的建议本质上都是不好的,甚至可能是灾难性的,但有些人更关心数据完整性而不是释放磁盘空间。

Making a log file smaller should really be reserved for scenarios where it encountered unexpected growth which you do not expect to happen again. If the log file will grow to the same size again, not very much is accomplished by shrinking it temporarily. Now, depending on the recovery goals of your database, these are the actions you should take.

First, take a full backup

Never make any changes to your database without ensuring you can restore it should something go wrong.

If you care about point-in-time recovery

(And by point-in-time recovery, I mean you care about being able to restore to anything other than a full or differential backup.)

Presumably your database is in FULL recovery mode. If not, then make sure it is:

ALTER DATABASE testdb SET RECOVERY FULL;

-- and take another full backup here
-- so log backups are possible

Even if you are taking regular full backups, the log file will grow and grow until you perform a log backup - this is for your protection, not to needlessly eat away at your disk space. You should be performing these log backups quite frequently, according to your recovery objectives. For example, if you have a business rule that states you can afford to lose no more than 15 minutes of data in the event of a disaster, you should have a job that backs up the log every 15 minutes. Here is a script that will generate timestamped file names based on the current time (but you can also do this with maintenance plans etc., just don't choose any of the shrink options in maintenance plans, they're awful).

DECLARE @path nvarchar(4000) = CONCAT(
  N'\\backup_share\log\testdb_',  
  CONVERT(char(8), GETDATE(), 112), N'_',
  REPLACE(CONVERT(char(8), GETDATE(), 108),':',''),
  N'.trn');

BACKUP LOG foo TO DISK = @path WITH INIT, COMPRESSION;

WAITFOR DELAY '00:00:01';
GO 2 -- run twice to ensure file wrap-around

Note that \\backup_share\ should be on a different machine that represents a different underlying storage device. Backing these up to the same machine (or to a different machine that uses the same underlying disks, or a different VM that's on the same physical host) does not really help you, since if the machine blows up, you've lost your database and its backups. Depending on your network infrastructure it may make more sense to backup locally and then transfer them to a different location behind the scenes; in either case, you want to get them off the primary database machine as quickly as possible.

Now, once you have regular log backups running, it should be reasonable to shrink the log file to something more reasonable than whatever it's blown up to now. This does not mean running SHRINKFILE over and over again until the log file is 1 MB - even if you are backing up the log frequently, it still needs to accommodate the sum of any concurrent transactions that can occur. Log file autogrow events are expensive, since SQL Server has to zero out the files (unlike data files when instant file initialization is enabled), and user transactions have to wait while this happens. You want to do this grow-shrink-grow-shrink routine as little as possible, and you certainly don't want to make your users pay for it.

Note that you may need to back up the log twice before a shrink is possible (thanks Robert).

So, you need to come up with a practical size for your log file. Nobody here can tell you what that is without knowing a lot more about your system, but if you've been frequently shrinking the log file and it has been growing again, a good watermark is probably 10-50% higher than the largest it's been. Let's say that comes to 200 MB, and you want any subsequent autogrowth events to be 50 MB, then you can adjust the log file size this way (where 'yourdb_log' is the logical name of your database's log file, which you can find in sys.database_files):

USE [master];
GO
ALTER DATABASE Test1 
  MODIFY FILE
  (NAME = N'yourdb_log', SIZE = 200MB, FILEGROWTH = 50MB);
GO

Note that if the log file is currently > 200 MB, you may need to run this first:

USE yourdb;
GO
DBCC SHRINKFILE(N'yourdb_log', 200); -- unit is MB
GO

If you don't care about point-in-time recovery

If this is a test database, and you don't care about point-in-time recovery, then you should make sure that your database is in SIMPLE recovery mode.

ALTER DATABASE testdb SET RECOVERY SIMPLE;

Putting the database in SIMPLE recovery mode will make sure that SQL Server re-uses portions of the log file (essentially phasing out inactive transactions) instead of growing to keep a record of all transactions (like FULL recovery does until you back up the log). CHECKPOINT events will help control the log and make sure that it doesn't need to grow unless you generate a lot of t-log activity between CHECKPOINTs.

Next, you should make absolute sure that this log growth was truly due to an abnormal event (say, an annual spring cleaning or rebuilding your biggest indexes), and not due to normal, everyday usage. If you shrink the log file to a ridiculously small size, and SQL Server just has to grow it again to accommodate your normal activity, what did you gain? Were you able to make use of that disk space you freed up only temporarily? If you need an immediate fix, then you can run the following:

USE yourdb;
GO
CHECKPOINT;
CHECKPOINT; -- run twice to ensure file wrap-around
GO
DBCC SHRINKFILE(N'yourdb_log', 200); -- unit is MB
GO

Otherwise, set an appropriate size and growth rate. As per the example in the point-in-time recovery case, you can use the same code and logic to determine what file size is appropriate and set reasonable autogrowth parameters.

Some things you don't want to do

  • Back up the log with TRUNCATE_ONLY option and then SHRINKFILE. For one, this TRUNCATE_ONLY option has been deprecated and is no longer available in current versions of SQL Server. Second, if you are in FULL recovery model, this will destroy your log chain and require a new, full backup.

  • Detach the database, delete the log file, and re-attach. I can't emphasize how dangerous this can be. Your database may not come back up, it may come up as suspect, you may have to revert to a backup (if you have one), etc. etc.

  • Use the "shrink database" option. DBCC SHRINKDATABASE and the maintenance plan option to do the same are bad ideas, especially if you really only need to resolve a log problem issue. Target the file you want to adjust and adjust it independently, using DBCC SHRINKFILE or ALTER DATABASE ... MODIFY FILE (examples above).

  • Shrink the log file to 1 MB. This looks tempting because, hey, SQL Server will let me do it in certain scenarios, and look at all the space it frees! Unless your database is read only (and it is, you should mark it as such using ALTER DATABASE), this will absolutely just lead to many unnecessary growth events, as the log has to accommodate current transactions regardless of the recovery model. What is the point of freeing up that space temporarily, just so SQL Server can take it back slowly and painfully?

  • Create a second log file. This will provide temporarily relief for the drive that has filled your disk, but this is like trying to fix a punctured lung with a band-aid. You should deal with the problematic log file directly instead of just adding another potential problem. Other than redirecting some transaction log activity to a different drive, a second log file really does nothing for you (unlike a second data file), since only one of the files can ever be used at a time. Paul Randal also explains why multiple log files can bite you later.

Be proactive

Instead of shrinking your log file to some small amount and letting it constantly autogrow at a small rate on its own, set it to some reasonably large size (one that will accommodate the sum of your largest set of concurrent transactions) and set a reasonable autogrow setting as a fallback, so that it doesn't have to grow multiple times to satisfy single transactions and so that it will be relatively rare for it to ever have to grow during normal business operations.

The worst possible settings here are 1 MB growth or 10% growth. Funny enough, these are the defaults for SQL Server (which I've complained about and asked for changes to no avail) - 1 MB for data files, and 10% for log files. The former is much too small in this day and age, and the latter leads to longer and longer events every time (say, your log file is 500 MB, first growth is 50 MB, next growth is 55 MB, next growth is 60.5 MB, etc. etc. - and on slow I/O, believe me, you will really notice this curve).

Further reading

Please don't stop here; while much of the advice you see out there about shrinking log files is inherently bad and even potentially disastrous, there are some people who care more about data integrity than freeing up disk space.

薯片软お妹 2024-07-12 04:47:00

首先检查数据库恢复模型。 默认情况下,SQL Server Express Edition 会创建一个用于简单恢复的数据库
模型(如果我没记错的话)。

备份日志 DatabaseName With Truncate_Only:

DBCC ShrinkFile(yourLogical_LogFileName, 50)

SP_helpfile 将为您提供逻辑日志文件名。

请参阅:

从 SQL Server 数据库中的完整事务日志中恢复

如果您的数据库处于完整恢复模式并且您没有进行 TL 备份,则将其更改为 SIMPLE。

First check the database recovery model. By default, SQL Server Express Edition creates a database for the simple recovery
model (if I am not mistaken).

Backup log DatabaseName With Truncate_Only:

DBCC ShrinkFile(yourLogical_LogFileName, 50)

SP_helpfile will give you the logical log file name.

Refer to:

Recover from a full transaction log in a SQL Server database

If your database is in Full Recovery Model and if you are not taking TL backup, then change it to SIMPLE.

故人如初 2024-07-12 04:47:00

不建议使用 John 推荐的这种技术,因为不能保证数据库会在没有日志文件的情况下附加。 将数据库从完整更改为简单,强制检查点并等待几分钟。 SQL Server 将清除日志,然后您可以使用 DBCC SHRINKFILE 缩小该日志。

This technique that John recommends is not recommended as there is no guarantee that the database will attach without the log file. Change the database from full to simple, force a checkpoint and wait a few minutes. The SQL Server will clear the log, which you can then shrink using DBCC SHRINKFILE.

旧竹 2024-07-12 04:47:00

到目前为止,这里的大多数答案都假设您实际上不需要事务日志文件,但是如果您的数据库使用FULL恢复模型,并且您希望保留备份以备需要恢复数据库时使用,然后不要按照许多答案建议的方式截断或删除日志文件。

消除日志文件(通过截断、丢弃、擦除等)会破坏您的备份链,并且会阻止您恢复到自上次完整备份、差异备份或事务日志备份以来的任何时间点,直到下一次完整备份为止。或者进行差异备份。

来自 关于备份的 Microsoft 文章

我们建议您永远不要使用 NO_LOG 或 TRUNCATE_ONLY 手动
截断事务日志,因为这会破坏日志链。 直到
下一次完整或差异数据库备份时,该数据库不会
防止介质故障。 仅在非常情况下使用手动日志截断
特殊情况,请立即做好数据备份。

为了避免这种情况,请在收缩之前将日志文件备份到磁盘。 语法看起来像这样:

BACKUP LOG MyDatabaseName 
TO DISK='C:\DatabaseBackups\MyDatabaseName_backup_2013_01_31_095212_8797154.trn'

DBCC SHRINKFILE (N'MyDatabaseName_Log', 200)

Most answers here so far are assuming you do not actually need the Transaction Log file, however if your database is using the FULL recovery model, and you want to keep your backups in case you need to restore the database, then do not truncate or delete the log file the way many of these answers suggest.

Eliminating the log file (through truncating it, discarding it, erasing it, etc) will break your backup chain, and will prevent you from restoring to any point in time since your last full, differential, or transaction log backup, until the next full or differential backup is made.

From the Microsoft article onBACKUP

We recommend that you never use NO_LOG or TRUNCATE_ONLY to manually
truncate the transaction log, because this breaks the log chain. Until
the next full or differential database backup, the database is not
protected from media failure. Use manual log truncation in only very
special circumstances, and create backups of the data immediately.

To avoid that, backup your log file to disk before shrinking it. The syntax would look something like this:

BACKUP LOG MyDatabaseName 
TO DISK='C:\DatabaseBackups\MyDatabaseName_backup_2013_01_31_095212_8797154.trn'

DBCC SHRINKFILE (N'MyDatabaseName_Log', 200)
手长情犹 2024-07-12 04:47:00

需要正确维护 SQL Server 事务日志,以防止其不必要的增长。 这意味着足够频繁地运行事务日志备份。 如果不这样做,您将面临事务日志变满并开始增长的风险。

除了这个问题的答案之外,我建议阅读并理解事务日志的常见误区。 这些读数可能有助于理解事务日志并决定使用什么技术来“清除”它:

来自 10 个最重要的 SQL Server 事务日志神话

谣言:我的 SQL Server 太忙了。 我不想进行 SQL Server 事务日志备份

SQL Server 中最大的性能密集型操作之一是联机事务日志文件的自动增长事件。 如果不经常进行事务日志备份,则联机事务日志将变满并且必须增长。 默认增长大小为 10%。 如果不创建事务日志备份,数据库越繁忙,在线事务日志增长得越快
创建 SQL Server 事务日志备份不会阻止联机事务日志,但自动增长事件会阻止。 它可以阻止在线事务日志中的所有活动

事务日志神话< /em>:

<块引用>

神话:定期收缩日志是一种很好的维护实践

错误。 日志增长非常昂贵,因为新块必须清零。 该数据库上的所有写入活动都会停止,直到清零完成,如果您的磁盘写入速度很慢或自动增长大小很大,那么暂停可能会很大,用户会注意到。 这就是你想要避免增长的原因之一。 如果你收缩日志,它会再次增长,你只是在不必要的收缩和增长游戏上浪费磁盘操作

The SQL Server transaction log needs to be properly maintained in order to prevent its unwanted growth. This means running transaction log backups often enough. By not doing that, you risk the transaction log to become full and start to grow.

Besides the answers for this question I recommend reading and understanding the transaction log common myths. These readings may help understanding the transaction log and deciding what techniques to use to "clear" it:

From 10 most important SQL Server transaction log myths:

Myth: My SQL Server is too busy. I don’t want to make SQL Server transaction log backups

One of the biggest performance intensive operations in SQL Server is an auto-grow event of the online transaction log file. By not making transaction log backups often enough, the online transaction log will become full and will have to grow. The default growth size is 10%. The busier the database is, the quicker the online transaction log will grow if transaction log backups are not created
Creating a SQL Server transaction log backup doesn’t block the online transaction log, but an auto-growth event does. It can block all activity in the online transaction log

From Transaction log myths:

Myth: Regular log shrinking is a good maintenance practice

FALSE. Log growth is very expensive because the new chunk must be zeroed-out. All write activity stops on that database until zeroing is finished, and if your disk write is slow or autogrowth size is big, that pause can be huge and users will notice. That’s one reason why you want to avoid growth. If you shrink the log, it will grow again and you are just wasting disk operation on needless shrink-and-grow-again game

谜兔 2024-07-12 04:47:00

如果您不使用事务日志进行恢复(即您只进行完整备份),您可以将恢复模式设置为“简单”,事务日志将很快缩小并且永远不会再次填满。

如果您使用的是 SQL 7 或 2000,则可以在数据库选项选项卡中启用“在检查点截断日志”。 这具有相同的效果。

显然,在生产环境中不建议这样做,因为您将无法恢复到某个时间点。

If you do not use the transaction logs for restores (i.e. You only ever do full backups), you can set Recovery Mode to "Simple", and the transaction log will very shortly shrink and never fill up again.

If you are using SQL 7 or 2000, you can enable "truncate log on checkpoint" in the database options tab. This has the same effect.

This is not recomended in production environments obviously, since you will not be able to restore to a point in time.

姜生凉生 2024-07-12 04:47:00

这是一个简单且非常不优雅的& 潜在危险方式。

  1. 备份数据库
  2. 分离数据库
  3. 重命名日志文件
  4. 附加数据库
  5. 将重新创建新的日志文件
  6. 删除重命名的日志文件。

我猜你没有进行日志备份。 (这会截断日志)。 我的建议是将恢复模式从 完整 更改为 简单。 这将防止日志膨胀。

Here is a simple and very inelegant & potentially dangerous way.

  1. Backup DB
  2. Detach DB
  3. Rename Log file
  4. Attach DB
  5. New log file will be recreated
  6. Delete Renamed Log file.

I'm guessing that you are not doing log backups. (Which truncate the log). My advice is to change recovery model from full to simple. This will prevent log bloat.

凶凌 2024-07-12 04:47:00

使用DBCC ShrinkFile ({逻辑LogName}, TRUNCATEONLY) 命令。 如果这是一个测试数据库并且您正在尝试节省/回收空间,这将会有所帮助。

请记住,TX 日志确实有一种它们将增长到的最小/稳态大小。 根据您的恢复模型,您可能无法缩小日志 - 如果处于 FULL 并且您没有发出 TX 日志备份,则日志无法缩小 - 它将永远增长。 如果您不需要 TX 日志备份,请将恢复模式切换为“简单”。

请记住,在任何情况下都不要删除日志 (LDF) 文件! 您几乎会立即遇到数据库损坏。 煮熟了! 完毕! 数据丢失! 如果“不修复”,主 MDF 文件可能会永久损坏。

切勿删除事务日志 - 您将丢失数据! 您的部分数据位于 TX 日志中(无论恢复模式如何)...如果您分离并“重命名”TX 日志文件,则会有效删除数据库的一部分。

对于那些已删除 TX 日志的用户,您可能需要运行一些 checkdb 命令并在丢失更多数据之前修复损坏的情况。

查看 Paul Randal 关于这个主题的博客文章,不好的建议< /a>

另外,一般不要对 MDF 文件使用 Shrinkfile,因为它会严重碎片化您的数据。 查看他的“坏建议”部分以获取更多信息(“为什么您不应该缩小数据文件”)

查看 Paul 的网站 - 他涵盖了这些问题。 上个月,他在《Myth A Day》系列中探讨了许多此类问题。

Use the DBCC ShrinkFile ({logicalLogName}, TRUNCATEONLY) command. If this is a test database and you are trying to save/reclaim space, this will help.

Remember though that TX logs do have a sort of minimum/steady state size that they will grow up to. Depending upon your recovery model you may not be able to shrink the log - if in FULL and you aren't issuing TX log backups the log can't be shrunk - it will grow forever. If you don't need TX log backups, switch your recovery model to Simple.

And remember, never ever under any circumstances delete the log (LDF) file! You will pretty much have instant database corruption. Cooked! Done! Lost data! If left "unrepaired" the main MDF file could become corrupt permanently.

Never ever delete the transaction log - you will lose data! Part of your data is in the TX Log (regardless of recovery model)... if you detach and "rename" the TX log file that effectively deletes part of your database.

For those that have deleted the TX Log you may want to run a few checkdb commands and fix the corruption before you lose more data.

Check out Paul Randal's blog posts on this very topic, bad advice.

Also in general do not use shrinkfile on the MDF files as it can severely fragment your data. Check out his Bad Advice section for more info ("Why you should not shrink your data files")

Check out Paul's website - he covers these very questions. Last month he walked through many of these issues in his Myth A Day series.

小帐篷 2024-07-12 04:47:00

下面是一个用于收缩事务日志的脚本,但我绝对建议在收缩之前备份事务日志。

如果您只是缩小文件,您将丢失大量数据,而这些数据在发生灾难时可能会成为救星。 事务日志包含许多有用的数据,可以使用第三方事务日志读取器读取这些数据(可以手动读取,但需要付出极大的努力)。

当涉及到时间点恢复时,事务日志也是必须的,所以不要直接扔掉它,而要确保事先备份它。

以下是人们使用事务日志中存储的数据来完成恢复的几篇文章:

USE DATABASE_NAME;
GO

ALTER DATABASE DATABASE_NAME
SET RECOVERY SIMPLE;
GO
--First parameter is log file name and second is size in MB
DBCC SHRINKFILE (DATABASE_NAME_Log, 1);

ALTER DATABASE DATABASE_NAME
SET RECOVERY FULL;
GO

执行上面的命令时,您可能会收到类似这样的错误

“无法收缩日志文件(日志文件名),因为逻辑
位于文件末尾的日志文件正在使用“

这意味着 TLOG 正在使用中。 在这种情况下,请尝试连续执行多次或找到减少数据库活动的方法。

Below is a script to shrink the transaction log, but I’d definitely recommend backing up the transaction log before shrinking it.

If you just shrink the file you are going to lose a ton of data that may come as a life saver in case of disaster. The transaction log contains a lot of useful data that can be read using a third-party transaction log reader (it can be read manually but with extreme effort though).

The transaction log is also a must when it comes to point in time recovery, so don’t just throw it away, but make sure you back it up beforehand.

Here are several posts where people used data stored in the transaction log to accomplish recovery:

 

USE DATABASE_NAME;
GO

ALTER DATABASE DATABASE_NAME
SET RECOVERY SIMPLE;
GO
--First parameter is log file name and second is size in MB
DBCC SHRINKFILE (DATABASE_NAME_Log, 1);

ALTER DATABASE DATABASE_NAME
SET RECOVERY FULL;
GO

You may get an error that looks like this when the executing commands above

“Cannot shrink log file (log file name) because the logical
log file located at the end of the file is in use“

This means that TLOG is in use. In this case try executing this several times in a row or find a way to reduce database activities.

瀞厅☆埖开 2024-07-12 04:47:00

免责声明:请在尝试之前仔细阅读此答案下面的评论,并务必检查已接受的答案。 正如我大约 5 年前所说:

如果有人对这不是一个情况的情况有任何评论要添加
足够或最佳的解决方案,请在下面评论

结果是:-)


原始答案:

  • 右键单击数据库名称。

  • 选择任务→收缩→数据库

  • 然后单击确定

我通常打开包含数据库文件的Windows资源管理器目录,这样我就可以立即看到效果。

我真的很惊讶这竟然有效! 10 秒内释放了 17GB

通常我以前使用过 DBCC,但我只是尝试过,它没有缩小任何内容,所以我尝试了 GUI (2005),它工作得很好 -在完全恢复模式下, 这可能不起作用,因此您必须先备份日志,或者更改为简单恢复,然后收缩文件。 [感谢@onupdatecascade]

-

PS:我很欣赏一些人对这种危险的评论,但在我的环境中,我自己这样做没有任何问题,特别是因为我总是先进行完整备份。 因此,在继续之前,请考虑您的环境是什么,以及这如何影响您的备份策略和工作安全。 我所做的只是向人们介绍 Microsoft 提供的功能!

DISCLAIMER: Please read comments below this answer carefully before attempting it, and be sure to check the accepted answer. As I said nearly 5 years ago:

if anyone has any comments to add for situations when this is NOT an
adequate or optimal solution then please comment below

Turns out there were :-)


Original Answer:

  • Right click on the database name.

  • Select Tasks → Shrink → Database

  • Then click OK!

I usually open the Windows Explorer directory containing the database files, so I can immediately see the effect.

I was actually quite surprised this worked! Normally I've used DBCC before, but I just tried that and it didn't shrink anything, so I tried the GUI (2005) and it worked great - freeing up 17 GB in 10 seconds

In Full recovery mode this might not work, so you have to either back up the log first, or change to Simple recovery, then shrink the file. [thanks @onupdatecascade for this]

--

PS: I appreciate what some have commented regarding the dangers of this, but in my environment I didn't have any issues doing this myself especially since I always do a full backup first. So please take into consideration what your environment is, and how this affects your backup strategy and job security before continuing. All I was doing was pointing people to a feature provided by Microsoft!

青春如此纠结 2024-07-12 04:47:00
-- DON'T FORGET TO BACKUP THE DB :D (Check [here][1]) 


USE AdventureWorks2008R2;
GO
-- Truncate the log by changing the database recovery model to SIMPLE.
ALTER DATABASE AdventureWorks2008R2
SET RECOVERY SIMPLE;
GO
-- Shrink the truncated log file to 1 MB.
DBCC SHRINKFILE (AdventureWorks2008R2_Log, 1);
GO
-- Reset the database recovery model.
ALTER DATABASE AdventureWorks2008R2
SET RECOVERY FULL;
GO

来自:DBCC SHRINKFILE (Transact-SQL)

您可能需要先备份。

-- DON'T FORGET TO BACKUP THE DB :D (Check [here][1]) 


USE AdventureWorks2008R2;
GO
-- Truncate the log by changing the database recovery model to SIMPLE.
ALTER DATABASE AdventureWorks2008R2
SET RECOVERY SIMPLE;
GO
-- Shrink the truncated log file to 1 MB.
DBCC SHRINKFILE (AdventureWorks2008R2_Log, 1);
GO
-- Reset the database recovery model.
ALTER DATABASE AdventureWorks2008R2
SET RECOVERY FULL;
GO

From: DBCC SHRINKFILE (Transact-SQL)

You may want to backup first.

阳光下的泡沫是彩色的 2024-07-12 04:47:00

数据库事务日志收缩到最小大小

  1. 备份:事务日志
  2. 收缩文件:事务日志
  3. 备份:事务日志
  4. 收缩文件:事务日志

我对多个数据库进行了测试:此序列有效。

它通常缩小到2MB

或者通过脚本:

DECLARE @DB_Name nvarchar(255);
DECLARE @DB_LogFileName nvarchar(255);
SET @DB_Name = '<Database Name>';               --Input Variable
SET @DB_LogFileName = '<LogFileEntryName>';         --Input Variable
EXEC 
(
'USE ['+@DB_Name+']; '+
'BACKUP LOG ['+@DB_Name+'] WITH TRUNCATE_ONLY ' +
'DBCC SHRINKFILE( '''+@DB_LogFileName+''', 2) ' +
'BACKUP LOG ['+@DB_Name+'] WITH TRUNCATE_ONLY ' +
'DBCC SHRINKFILE( '''+@DB_LogFileName+''', 2)'
)
GO

DB Transaction Log Shrink to min size:

  1. Backup: Transaction log
  2. Shrink files: Transaction log
  3. Backup: Transaction log
  4. Shrink files: Transaction log

I made tests on several number of DBs: this sequence works.

It usually shrinks to 2MB.

OR by a script:

DECLARE @DB_Name nvarchar(255);
DECLARE @DB_LogFileName nvarchar(255);
SET @DB_Name = '<Database Name>';               --Input Variable
SET @DB_LogFileName = '<LogFileEntryName>';         --Input Variable
EXEC 
(
'USE ['+@DB_Name+']; '+
'BACKUP LOG ['+@DB_Name+'] WITH TRUNCATE_ONLY ' +
'DBCC SHRINKFILE( '''+@DB_LogFileName+''', 2) ' +
'BACKUP LOG ['+@DB_Name+'] WITH TRUNCATE_ONLY ' +
'DBCC SHRINKFILE( '''+@DB_LogFileName+''', 2)'
)
GO
合约呢 2024-07-12 04:47:00

针对 MSSQL 2017 并使用 SQL Server Management Studio 稍微更新了答案。
我主要参考这些说明 https:/ /www.sqlshack.com/sql-server-transaction-log-backup-truncate-and-shrink-operations/

我最近进行了数据库备份,因此我备份了事务日志。 然后我再次备份它以进行良好的测量。
最后我缩小了日志文件,从 20G 缩小到 7MB,更符合我的数据大小。
我认为自从两年前安装以来,事务日志就没有被备份过……所以把这个任务放在家政日历上。

Slightly updated answer, for MSSQL 2017, and using the SQL server management studio.
I went mostly from these instructions https://www.sqlshack.com/sql-server-transaction-log-backup-truncate-and-shrink-operations/

I had a recent db backup, so I backed up the transaction log. Then I backed it up again for good measure.
Finally I shrank the log file, and went from 20G to 7MB, much more in line with the size of my data.
I don't think the transaction logs had ever been backed up since this was installed 2 years ago.. so putting that task on the housekeeping calendar.

雨轻弹 2024-07-12 04:47:00
  1. 备份数据库
  2. 分离数据库
  3. 重命名日志文件
  4. 附加数据库(附加时删除重命名的 .ldf(日志文件)。选择它并按删除按钮删除)
  5. 将重新创建新日志文件
  6. 删除重命名的日志文件。

这可行,但建议先备份数据库。

  1. Backup DB
  2. Detach DB
  3. Rename Log file
  4. Attach DB (while attaching remove renamed .ldf (log file).Select it and remove by pressing Remove button)
  5. New log file will be recreated
  6. Delete Renamed Log file.

This will work but it is suggested to take backup of your database first.

谁人与我共长歌 2024-07-12 04:47:00

其他一些答案对我不起作用:当数据库在线时不可能创建检查点,因为事务日志已满(多么讽刺)。 但是,将数据库设置为紧急模式后,我能够缩小日志文件:

alter database <database_name> set emergency;
use <database_name>;
checkpoint;
checkpoint;
alter database <database_name> set online;
dbcc shrinkfile(<database_name>_log, 200);

Some of the other answers did not work for me: It was not possible to create the checkpoint while the db was online, because the transaction log was full (how ironic). However, after setting the database to emergency mode, I was able to shrink the log file:

alter database <database_name> set emergency;
use <database_name>;
checkpoint;
checkpoint;
alter database <database_name> set online;
dbcc shrinkfile(<database_name>_log, 200);
完美的未来在梦里 2024-07-12 04:47:00

尝试这个:

USE DatabaseName

GO

DBCC SHRINKFILE( TransactionLogName, 1)

BACKUP LOG DatabaseName WITH TRUNCATE_ONLY

DBCC SHRINKFILE( TransactionLogName, 1)

GO 

Try this:

USE DatabaseName

GO

DBCC SHRINKFILE( TransactionLogName, 1)

BACKUP LOG DatabaseName WITH TRUNCATE_ONLY

DBCC SHRINKFILE( TransactionLogName, 1)

GO 
别挽留 2024-07-12 04:47:00

数据库→右键单击属性→文件→添加另一个具有不同名称的日志文件,并将路径设置为与旧日志文件相同但文件名不同。

数据库自动选取新创建的日志文件。

Database → right click Properties → file → add another log file with a different name and set the path the same as the old log file with a different file name.

The database automatically picks up the newly created log file.

遗忘曾经 2024-07-12 04:47:00

根据我在大多数 SQL Server 上的经验,没有事务日志的备份。
完整备份或差异备份是常见做法,但事务日志备份却很少。
因此事务日志文件会永远增长(直到磁盘已满)。
在这种情况下,恢复模型应设置为“简单”。
不要忘记也修改系统数据库“model”和“tempdb”。

数据库“tempdb”的备份没有任何意义,因此该数据库的恢复模型应该始终是“简单”的。

To my experience on most SQL Servers there is no backup of the transaction log.
Full backups or differential backups are common practice, but transaction log backups are really seldom.
So the transaction log file grows forever (until the disk is full).
In this case the recovery model should be set to "simple".
Don't forget to modify the system databases "model" and "tempdb", too.

A backup of the database "tempdb" makes no sense, so the recovery model of this db should always be "simple".

轮廓§ 2024-07-12 04:47:00
  1. 备份 MDB 文件。
  2. 停止SQL服务
  3. 重命名日志文件
  4. 启动服务

(系统将创建新的日志文件。)

删除或移动重命名的日志文件。

  1. Take a backup of the MDB file.
  2. Stop SQL services
  3. Rename the log file
  4. Start the service

(The system will create a new log file.)

Delete or move the renamed log file.

始终不够 2024-07-12 04:47:00

截断日志文件:

  • 备份数据库
  • 通过使用企业管理器或执行以下命令分离数据库:Sp_DetachDB [DBName]
  • 删除事务日志文件。 (或重命名该文件,以防万一)
  • 使用以下命令再次重新附加数据库: Sp_AttachDB [DBName]
  • 附加数据库时,将创建一个新的事务日志文件。

要缩小日志文件:

  • 使用 No_Log 备份日志 [DBName]
  • 通过以下任一方式缩小数据库:

    使用企业管理器:-
    右键单击数据库,所有任务,收缩数据库,文件,选择日志文件,确定。

    使用 T-SQL :-
    Dbcc Shrinkfile ([Log_Logical_Name])

您可以通过运行 sp_helpdb 或在企业管理器中查看数据库属性来查找日志文件的逻辑名称。

To Truncate the log file:

  • Backup the database
  • Detach the database, either by using Enterprise Manager or by executing : Sp_DetachDB [DBName]
  • Delete the transaction log file. (or rename the file, just in case)
  • Re-attach the database again using: Sp_AttachDB [DBName]
  • When the database is attached, a new transaction log file is created.

To Shrink the log file:

  • Backup log [DBName] with No_Log
  • Shrink the database by either:

    Using Enterprise manager :-
    Right click on the database, All tasks, Shrink database, Files, Select log file, OK.

    Using T-SQL :-
    Dbcc Shrinkfile ([Log_Logical_Name])

You can find the logical name of the log file by running sp_helpdb or by looking in the properties of the database in Enterprise Manager.

蝶舞 2024-07-12 04:47:00

我的数据库日志文件大小为 28 GB。

你可以做什么来减少这种情况?
实际上,日志文件是 SQL Server 在事务发生时保留的文件数据。 对于要处理的事务,SQL Server 会为其分配页面。 但交易完成后,这些不会突然释放,希望可能有一笔类似的交易到来。 这样就撑住了空间。

步骤1:
首先在探索的数据库查询中运行此命令
检查点

步骤2:
右键单击数据库
任务> 备份
选择备份类型作为事务日志
添加目标地址和文件名以保留备份数据(.bak)

再次重复此步骤,此时指定另一个文件名

在此处输入图像描述

步骤 3:
现在进入数据库
右键单击数据库

任务> 收缩> 文件
选择文件类型为日志
收缩操作作为释放未使用的空间

在此处输入图像描述

第 4 步:

检查日志文件
中找到,

通常在 SQL 2014 中,可以在C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQL2014EXPRESS\MSSQL\DATA

在我的情况下,它从 28 GB 减少到 1 MB

It happened with me where the database log file was of 28 GBs.

What can you do to reduce this?
Actually, log files are those file data which the SQL server keeps when an transaction has taken place. For a transaction to process SQL server allocates pages for the same. But after the completion of the transaction, these are not released suddenly hoping that there may be a transaction coming like the same one. This holds up the space.

Step 1:
First Run this command in the database query explored
checkpoint

Step 2:
Right click on the database
Task> Back up
Select back up type as Transaction Log
Add a destination address and file name to keep the backup data (.bak)

Repeat this step again and at this time give another file name

enter image description here

Step 3:
Now go to the database
Right-click on the database

Tasks> Shrinks> Files
Choose File type as Log
Shrink action as release unused space

enter image description here

Step 4:

Check your log file
normally in SQL 2014 this can be found at

C:\Program Files\Microsoft SQL Server\MSSQL12.MSSQL2014EXPRESS\MSSQL\DATA

In my case, its reduced from 28 GB to 1 MB

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文