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如需转载请自行联系原作者


相关实践学习
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
【涂鸦即艺术】基于云应用开发平台CAP部署AI实时生图绘板
相关文章
|
6月前
|
SQL 存储 监控
SQL日志优化策略:提升数据库日志记录效率
通过以上方法结合起来运行调整方案, 可以显著地提升SQL环境下面向各种搜索引擎服务平台所需要满足标准条件下之数据库登记作业流程综合表现; 同时还能确保系统稳健运行并满越用户体验预期目标.
346 6
|
7月前
|
SQL 传感器 人工智能
生成更智能,调试更轻松,SLS SQL Copilot 焕新登场!
本文是阿里云日志服务(SLS)首次对外系统性地揭秘 SLS SQL Copilot 背后的产品理念、架构设计与核心技术积淀。我们将带你深入了解,这一智能分析助手如何从用户真实需求出发,融合前沿 AI 能力与 SLS 十余年日志分析最佳实践,打造出面向未来的智能化日志分析体验。
641 51
|
7月前
|
SQL 传感器 人工智能
生成更智能,调试更轻松,SLS SQL Copilot 焕新登场!
阿里云日志服务(SLS)推出智能分析助手 SLS SQL Copilot,融合 AI 技术与日志分析最佳实践,将自然语言转换为 SQL 查询,降低使用门槛,提升查询效率。其具备原生集成、智能语义理解与高效执行能力,助力用户快速洞察日志数据价值,实现智能化日志分析新体验。
475 1
|
SQL 存储 缓存
MySQL进阶突击系列(02)一条更新SQL执行过程 | 讲透undoLog、redoLog、binLog日志三宝
本文详细介绍了MySQL中update SQL执行过程涉及的undoLog、redoLog和binLog三种日志的作用及其工作原理,包括它们如何确保数据的一致性和完整性,以及在事务提交过程中各自的角色。同时,文章还探讨了这些日志在故障恢复中的重要性,强调了合理配置相关参数对于提高系统稳定性的必要性。
|
监控 安全 网络安全
使用EventLog Analyzer日志分析工具监测 Windows Server 安全威胁
Windows服务器面临多重威胁,包括勒索软件、DoS攻击、内部威胁、恶意软件感染、网络钓鱼、暴力破解、漏洞利用、Web应用攻击及配置错误等。这些威胁严重威胁服务器安全与业务连续性。EventLog Analyzer通过日志管理和威胁分析,有效检测并应对上述威胁,提升服务器安全性,确保服务稳定运行。
520 2
|
SQL 数据库
为什么 SQL 日志文件很大,我应该如何处理?
为什么 SQL 日志文件很大,我应该如何处理?
|
SQL 数据库
为什么SQL日志文件很大,该如何处理?
为什么SQL日志文件很大,该如何处理?
|
11月前
|
监控 容灾 算法
阿里云 SLS 多云日志接入最佳实践:链路、成本与高可用性优化
本文探讨了如何高效、经济且可靠地将海外应用与基础设施日志统一采集至阿里云日志服务(SLS),解决全球化业务扩展中的关键挑战。重点介绍了高性能日志采集Agent(iLogtail/LoongCollector)在海外场景的应用,推荐使用LoongCollector以获得更优的稳定性和网络容错能力。同时分析了多种网络接入方案,包括公网直连、全球加速优化、阿里云内网及专线/CEN/VPN接入等,并提供了成本优化策略和多目标发送配置指导,帮助企业构建稳定、低成本、高可用的全球日志系统。
1070 54
|
监控 Java 应用服务中间件
Tomcat log日志解析
理解和解析Tomcat日志文件对于诊断和解决Web应用中的问题至关重要。通过分析 `catalina.out`、`localhost.log`、`localhost_access_log.*.txt`、`manager.log`和 `host-manager.log`等日志文件,可以快速定位和解决问题,确保Tomcat服务器的稳定运行。掌握这些日志解析技巧,可以显著提高运维和开发效率。
1478 13