SQLServer误解30天第十九天截断表操作将不会被记录到日志中。
误解的# 19操作:截断表将不会被记录到日志错误
在用户表的操作记录到日志中。唯一的操作不会被记录在SQL Server是TempDB行版本控制。
截断表语句将删除整个表中的所有数据,但删除的方式不是一行一行删除。相反,它释放组合表的数据页,并将从组合表释放的相关页的操作提供给后台线程。队列处理的过程称为deferred-drop.the利用后台线程处理递延下降是这个操作不会使其交易需要很长时间执行的,因此不需要大量的锁。在SQL Server 2000sp3版本(此版本中引入了递延滴),太多的锁和耗尽内存是常见的表。
下面是测试代码:
复制代码代码如下所示:
创建数据库truncatetest;
去
使用truncatetest;
去
修改数据库truncatetest集回收简单;
去
创建表T1(C1国际身份,C2 char(8000)default'a);
创建聚集索引t1c1 T1(C1);
去
SET NOCOUNT ON;
去
插入到T1默认值;
去1280
检查点;
去
上面的测试数据库恢复模式很简单,所以每个检查点都会截断日志(只是为了简单起见,哈哈)。
一分钟后,让我们看看日志中有多少记录。
复制代码代码如下所示:
select count(*)从fn_dblog(null,null);
去
如您所见,当前的日志条目号是2。
如果您得到的数字不是2,那么在数据为2之前再做一个检查点。
现在日志已经被知道了,日志的增长是由于它背后的操作:
复制代码代码如下所示:
截断表t1;
去
select count(*)从fn_dblog(null,null);
去
您可以看到现在有541条日志记录,很明显,需要在日志中记录截断操作,但也可以看到截断操作没有一个一个地删除,因为541个日志记录是1280个数据段。
执行以下语句以查看日志:
复制代码代码如下所示:
选择
{ } { }当前LSN,手术,{背景},
{ } {事务ID,allocunitname } {姓名}交易,
从fn_dblog(null,null);
结果如下:图1。截断后查看日志(部分)
通过日志,你可以看到,第一次明确地开始TRUNCATETABLE交易,和最后一个开始deferredalloc。你可以看到,截断操作只是网页和地区构成表的释放。
下面的代码可以查看日志特定操作的描述:
复制代码代码如下所示:
选择
{ } { }当前LSN,操作信息},{锁,{说明}
从fn_dblog(null,null);
去
结果是图2:
图2。日志操作说明(节选)
为了快速恢复,您可以看到相关的锁(您可以在我的博客中了解更多信息:锁定日志记录和快速恢复)。
从上面的日志中可以看到,这个操作将把相关的锁添加到8个页面,然后整个区域被释放一次,释放后,IX锁将被添加到相关区域,也就是说,它不能再使用了。提交事务时,将执行延迟降,以便可以回滚截断表操作。
此外,如果表上有一个非聚合索引,那么操作类似,所有这些都被赋予后台线程,然后释放页面和索引。最小的释放单元是每个分配单元。
ps:还有一个误解,就是不能回滚的表操作。我详细解释了搜索引擎的质量# 10:当页面从页面。