- 时间:2022-01-29 14:44 编辑: 来源: 阅读:
- 扫一扫,手机访问
摘要:SQL Server误区30日谈 第19天 Truncate表的操作不会被记录到日志
误区 #19:Truncate表的操作不会被记录到日志
错误
在用户表中的操作都会被记录到日志。在SQL Server中唯一不会被记录到日志的操作是TempDB中的行版本控制。
Truncate Table语句会将整个表中的所有数据删除。但删除的方式并不是一行一行的删除,而是将组成表的数据页释放,将组成表的相关页释放的操作交给一个后台的线程进行队列处理的过程被称为deferred-drop。使用后台线程处理deferred-drop的好处是这个操作不会使得其所在的事务需要执行很长时间,因此也就不需要大量的锁。在SQL Server 2000SP3之前的版本(这个版本引入了deferred-drop)在Truncate Table的时候出现过多的锁耗尽内存的事是家常便饭。
下面是测试代码:
[url=http://www.sqlskills.com/BLOGS/PAUL/post/Lock-logging-and-fast-recovery.aspx]Lock logging and fast recovery[/url]中了解更多)。
由上面日志看出,这个操作会对8个页加相关的锁,然后整个区一次性释放。释放过后会对相关的区加IX锁,也就是不能再被使用,当事务提交后才会进行deferred-drop,因此也就保证了Truncate table操作可以回滚。
另外,如果表上存在非聚集索引.那么操作方式也是类似,都是交给一个后台线程然后释放表和索引的页。释放的最小单位就是每个分配单元。按照上面步骤你自己尝试一下就应该能明白我的意思了。
PS:还有一个关于Truncate Table操作不能回滚的误区,我在:[url=http://www.sqlskills.com/BLOGS/PAUL/post/Search-Engine-QA-10-When-are-pages-from-a-truncated-table-reused.aspx]Search Engine Q&A #10: When are pages from a truncated table reused?[/url]这篇文章中进行了详细的解释。