SQL Server误区30日谈-Day19-Truncate表的操作不会被记录到日志

    本系列文章是我在sqlskill.com的PAUL的博客看到的,很多误区都比较具有典型性和代表性,原文来自T-SQL Tuesday #11: Misconceptions about.... EVERYTHING!!,经过我们团队的翻译和整理发布在AgileSharp上。希望对大家有所帮助。

 

    这个误区也同样流传已久,我想是时候通过一些Demo进行揭穿了。

 

误区 #19:Truncate表的操作不会被记录到日志

错误

 

    在用户表中的操作都会被记录到日志。在SQL Server中唯一不会被记录到日志的操作是TempDB中的行版本控制。

    Truncate Table语句会将整个表中的所有数据删除。但删除的方式并不是一行一行的删除,而是将组成表的数据页释放,将组成表的相关页释放的操作交给一个后台的线程进行队列处理的过程被称为deferred-drop。使用后台线程处理deferred-drop的好处是这个操作不会使得其所在的事务需要执行很长时间,因此也就不需要大量的锁。在SQL Server 2000SP3之前的版本(这个版本引入了deferred-drop)在Truncate Table的时候出现过多的锁耗尽内存的事是家常便饭。

    下面是测试代码:

CREATE DATABASE TruncateTest; 
GO 
USE TruncateTest; 
GO 
ALTER DATABASE TruncateTest SET RECOVERY SIMPLE; 
GO 
CREATE TABLE t1 (c1 INT IDENTITY, c2 CHAR (8000) DEFAULT 'a'); 
CREATE CLUSTERED INDEX t1c1 on t1 (c1); 
GO

SET NOCOUNT ON; 
GO

INSERT INTO t1 DEFAULT VALUES; 
GO 1280

CHECKPOINT; 
GO

 

    上面的测试数据库恢复模式是简单,所以每个Checkpoint都会截断日志(仅仅是为了简单,哈哈)。

    一分钟后让我们来看看日志中有多少条记录。

 

SELECT COUNT (*) FROM fn_dblog (NULL, NULL); 
GO

 

    可以看到,现在的日志条目数字为2。

    如果你得到的数字不是2,那么再做一次Checkpoint直到数据是2为止。

    现在已有的日志已经知道了,那么日志的增长就是由于后面的操作所导致。下面我们执行如下代码:

TRUNCATE TABLE t1; 
GO

SELECT COUNT (*) FROM fn_dblog (NULL, NULL); 
GO

 

    可以看到现在已经有了541条日志记录。很明显Truncate操作是需要记录到日志中的。但也可以看出Truncate并不会逐行删除,因为这541条日志记录删除的是1280条数据。

    执行下面语句来查看日志:

SELECT 
  [Current LSN], [Operation], [Context], 
  [Transaction ID], [AllocUnitName], [Transaction Name] 
FROM fn_dblog (NULL, NULL);

 

    下面是结果:

    2012-10-18_135444

    图1.查看Truncate后的日志(部分)

 

    通过日志可以看出第一条显式开始Truncate Table事务,最后一条开始DeferredAlloc。正如你所见,Truncate操作仅仅是释放了构成表的页和区。

    下面这个代码可以查看日志具体所做操作的描述:

SELECT 
[Current LSN], [Operation], [Lock Information], [Description] 
FROM fn_dblog (NULL, NULL); 
GO

 

    结果如图2:

    2

    图2.日志操作描述(节选)

   

    你可以看出为了快速恢复的目的而加的相关锁(你可以在我的博文:Lock logging and fast recovery中了解更多)。

    由上面日志看出,这个操作会对8个页加相关的锁,然后整个区一次性释放。释放过后会对相关的区加IX锁,也就是不能再被使用,当事务提交后才会进行deferred-drop,因此也就保证了Truncate table操作可以回滚。

    另外,如果表上存在非聚集索引.那么操作方式也是类似,都是交给一个后台线程然后释放表和索引的页。释放的最小单位就是每个分配单元。按照上面步骤你自己尝试一下就应该能明白我的意思了。

   

 

PS:还有一个关于Truncate Table操作不能回滚的误区,我在:Search Engine Q&A #10: When are pages from a truncated table reused?这篇文章中进行了详细的解释。

分类: SQL Server DBA误区



本文转自CareySon博客园博客,原文链接:http://www.cnblogs.com/CareySon/archive/2012/12/25/2831880.html如需转载请自行联系原作者


优秀的个人博客,低调大师

微信关注我们

原文链接:https://yq.aliyun.com/articles/343702

转载内容版权归作者及来源网站所有!

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。

相关文章

发表评论

资源下载

更多资源
Mario,低调大师唯一一个Java游戏作品

Mario,低调大师唯一一个Java游戏作品

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Apache Tomcat7、8、9(Java Web服务器)

Apache Tomcat7、8、9(Java Web服务器)

Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache、Sun 和其他一些公司及个人共同开发而成。因为Tomcat 技术先进、性能稳定,而且免费,因而深受Java 爱好者的喜爱并得到了部分软件开发商的认可,成为目前比较流行的Web 应用服务器。

Java Development Kit(Java开发工具)

Java Development Kit(Java开发工具)

JDK是 Java 语言的软件开发工具包,主要用于移动设备、嵌入式设备上的java应用程序。JDK是整个java开发的核心,它包含了JAVA的运行环境(JVM+Java系统类库)和JAVA工具。

Sublime Text 一个代码编辑器

Sublime Text 一个代码编辑器

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。