关键词:事务日志不能收缩,事务日志不能截断,收缩日志,截断日志
一、日志截断的目的
日志截断后,数据库引擎将MinLSN之前的虚拟日志文件(VLF)标记为“可复用”。“可复用”的VLF可以成为日志回绕后重复利用的空间,也可以在收缩日志文件时释放其占用的磁盘空间。详情已经在第五章讨论过。
如果日志文件不能被截断,为了能写入后续的事务日志,数据库引擎将为日志文件(ldf)申请更多的磁盘空间。因此,将导致日志文件持续增长。
二、阻碍日志截断的常见原因
1. 未提交的事务
如果不发出显式 COMMIT 或 ROLLBACK 命令,显式事务将不提交。这种情况最常发生在应用程序发出了 CANCEL 或 T-SQL 的 KILL 命令但未发出对应的 ROLLBACK 命令时。这时会发生事务取消,但不回退;这样,SQL Server 将不能截断此后发生的每一个事务,因为中止的事务仍处于打开状态。
可以使用 DBCC OPENTRAN 来检查在某一特定时间数据库中是否有一个活动的事务。
2. 非常大的事务
事务日志文件中的日志记录的截断是逐个事务进行的。如果事务的范围较大,此事务和任何在其后开始的事务只有在此事务完成后才能从事务日志中被删除。这可能会导致较大的日志文件。如果事务大到一定程度,日志文件就可能会用尽可用磁盘空间并导致“transaction log full”之类的错误消息(如 Error 9002)。
3. 需要日志备份
完整恢复模式或大容量日志恢复模式时,需要执行一次事务日志备份才能截断日志。
4. 尚未出现检查点
简单恢复模式时,等待一个CHECKPOINT。
5. 未复制的事务
完整恢复模式时,如果数据库处于镜像、事务复制状态,如果事务日志同步发生的延迟,那么可能会导致源数据库的日志不能被截断。
三、查看不能截断日志的原因
运行以下语句,查看日志不能截断的原因。
SELECT log_reuse_wait , log_reuse_wait_desc FROM sys.databases WHERE name='db01'
下表对这些列的值进行了说明。
log_reuse_wait 值 | log_reuse_wait_desc 值 | 说明 |
0 | NOTHING | 当前有一个或多个可重复使用的虚拟日志文件。 |
1 | CHECKPOINT | 自上次日志截断之后,尚未生成检查点,或者日志头尚未跨一个虚拟日志文件移动。这是日志截断延迟的常见原因。 |
2 | LOG_BACKUP | 在截断事务日志前,需要进行日志备份。(仅限完整恢复模式或大容量日志恢复模式) 完成下一个日志备份后,一些日志空间可能变为可重复使用。 |
3 | ACTIVE_BACKUP_OR_RESTORE | 数据备份或还原正在进行。如果数据备份阻止了日志截断,则取消备份操作可能有助于解决备份直接导致的此问题。 |
4 | ACTIVE_TRANSACTION | 事务处于活动状态。请用 DBCC OPENTRAN 检查最旧的活动事务。 |
5 | DATABASE_MIRRORING | 数据库镜像暂停,或者在高性能模式下,镜像数据库明显滞后于主体数据库。 |
6 | REPLICATION | 在事务复制过程中,与发布相关的事务仍未传递到分发数据库。 |
7 | DATABASE_SNAPSHOT_CREATION | 正在创建数据库快照。 |
8 | LOG_SCAN | 发生日志扫描。 |
9 | AVAILABILITY_REPLICA | 可用性组的辅助副本正将此数据库的事务日志记录应用到相应的辅助数据库。 |
13 | OLDEST_PAGE | 如果将数据库配置为使用间接检查点,数据库中最早的页可能比检查点 LSN 早。在这种情况下,最早的页可以延迟日志截断。 |
根据返回的 log_reuse_wait 值和 log_reuse_wait_desc 描述,可以发现日志不能截断的原因。更多的说明,请参考《可能延迟日志截断的因素》
http://technet.microsoft.com/zh-cn/library/ms345414(v=sql.105).aspx
收缩日志文件
一、收缩日志的前提条件
1. 确保日志已被截断
只有日志被截断之后,日志文件中的VLF被标记为“可复用”,这部分空间才可以被释放,从而达到收缩日志文件的目的。
2. 查看日志文件的空间
3.收缩日志文件的必要
一般情况下没有收缩日志文件的必要。通常仅在以下场景中需要收缩日志文件:
(1)完整恢复模式时,由于日志未能截断(例如,长时间未执行事务日志备份),导致日志文件过度增长,即使在日志被截断后日志文件也不会自动收缩(释放磁盘空间),因此需要手动收缩日志文件。
(2)执行大批量操作时(插入大量数据),日志文件迅速增长,大批量操作结束后,日志文件不会自动释放空间,因此需要先截断事务日志然后再收缩日志文件。
二、收缩日志文件的方法
1. T-SQL
例如:
DBCC SHRINKFILE (N'db01_log' , 0, TRUNCATEONLY)
注意:T-SQL语句中需要使用日志文件的逻辑名称。逻辑名称可以在数据库属性中查找。
2. 图形界面