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

本文涉及的产品
云数据库 RDS SQL Server,基础系列 2核4GB
RDS SQL Server Serverless,2-4RCU 50GB 3个月
推荐场景:
日志服务 SLS,月写入数据量 50GB 1个月
简介:
    本系列文章是我在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如需转载请自行联系原作者


相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
目录
打赏
0
0
0
0
49
分享
相关文章
MySQL进阶突击系列(02)一条更新SQL执行过程 | 讲透undoLog、redoLog、binLog日志三宝
本文详细介绍了MySQL中update SQL执行过程涉及的undoLog、redoLog和binLog三种日志的作用及其工作原理,包括它们如何确保数据的一致性和完整性,以及在事务提交过程中各自的角色。同时,文章还探讨了这些日志在故障恢复中的重要性,强调了合理配置相关参数对于提高系统稳定性的必要性。
使用EventLog Analyzer日志分析工具监测 Windows Server 安全威胁
Windows服务器面临多重威胁,包括勒索软件、DoS攻击、内部威胁、恶意软件感染、网络钓鱼、暴力破解、漏洞利用、Web应用攻击及配置错误等。这些威胁严重威胁服务器安全与业务连续性。EventLog Analyzer通过日志管理和威胁分析,有效检测并应对上述威胁,提升服务器安全性,确保服务稳定运行。
108 2
高基数 GroupBy 在 SLS SQL 中的查询加速
本文详细介绍了SLS中的高基数GroupBy查询加速技术。
172 24
为什么 SQL 日志文件很大,我应该如何处理?
为什么 SQL 日志文件很大,我应该如何处理?
为什么SQL日志文件很大,该如何处理?
为什么SQL日志文件很大,该如何处理?
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
5-10Can't connect to MySQL server on 'sh-cynosl-grp-fcs50xoa.sql.tencentcdb.com' (110)")
基于SQL Server事务日志的数据库恢复技术及实战代码详解
基于事务日志的数据库恢复技术是SQL Server中一个非常强大的功能,它能够帮助数据库管理员在数据丢失或损坏的情况下,有效地恢复数据。通过定期备份数据库和事务日志,并在需要时按照正确的步骤恢复,可以最大限度地减少数据丢失的风险。需要注意的是,恢复数据是一个需要谨慎操作的过程,建议在执行恢复操作之前,详细了解相关的操作步骤和注意事项,以确保数据的安全和完整。
307 0
Struts 2 日志管理化身神秘魔法师,洞察应用运行乾坤,演绎奇幻篇章!
【8月更文挑战第31天】在软件开发中,了解应用运行状况至关重要。日志管理作为 Struts 2 应用的关键组件,记录着每个动作和决策,如同监控摄像头,帮助我们迅速定位问题、分析性能和使用情况,为优化提供依据。Struts 2 支持多种日志框架(如 Log4j、Logback),便于配置日志级别、格式和输出位置。通过在 Action 类中添加日志记录,我们能在开发过程中获取详细信息,及时发现并解决问题。合理配置日志不仅有助于调试,还能分析用户行为,提升应用性能和稳定性。
86 0
图解MySQL【日志】——Redo Log
Redo Log(重做日志)是数据库中用于记录数据页修改的物理日志,确保事务的持久性和一致性。其主要作用包括崩溃恢复、提高性能和保证事务一致性。Redo Log 通过先写日志的方式,在内存中缓存修改操作,并在适当时候刷入磁盘,减少随机写入带来的性能损耗。WAL(Write-Ahead Logging)技术的核心思想是先将修改操作记录到日志文件中,再择机写入磁盘,从而实现高效且安全的数据持久化。Redo Log 的持久化过程涉及 Redo Log Buffer 和不同刷盘时机的控制参数(如 `innodb_flush_log_at_trx_commit`),以平衡性能与数据安全性。
26 5
图解MySQL【日志】——Redo Log
【日志框架整合】Slf4j、Log4j、Log4j2、Logback配置模板
本文介绍了Java日志框架的基本概念和使用方法,重点讨论了SLF4J、Log4j、Logback和Log4j2之间的关系及其性能对比。SLF4J作为一个日志抽象层,允许开发者使用统一的日志接口,而Log4j、Logback和Log4j2则是具体的日志实现框架。Log4j2在性能上优于Logback,推荐在新项目中使用。文章还详细说明了如何在Spring Boot项目中配置Log4j2和Logback,以及如何使用Lombok简化日志记录。最后,提供了一些日志配置的最佳实践,包括滚动日志、统一日志格式和提高日志性能的方法。
1068 31
【日志框架整合】Slf4j、Log4j、Log4j2、Logback配置模板
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等