SQL Server 为什么事务日志自动增长会降低你的性能
原文地址:点击打开链接
在这篇文章里,我想详细谈下为什么你要避免事务日志(Transaction Log)上的自动增长操作(Auto Growth operations)。很多运行的数据库服务器,对于事务日志,用的都是默认的日志文件大小和自动增长设置。人们有时会很依赖自动增长机制,因为它们刚好能正常工作。当然,如果它正常工作的话,你不必太关注它,但很快你会发现会有问题出现。
只依赖于事务日志的自动增长机制总不是个好主意。首先它会导致严重的日志碎片(Log Fragmentation),在SQL Server启动期间,在你数据库上执行崩溃恢复(Crash Recovery)时会有很大的负面影响。另外,在你数据库里写入事务需要等待,只要事务日志触发了自动增长机制。
当事务日志的自动增长机制发生时,SQL Server总要零初始化新块,这个会在文件末尾加上。这和你的SQL Server实例是否用即时文件初始化(Instant File Initialization)特权——事务日志总会零初始化。这上面的原因非常明显:当SQL Server在过去已经完成事务日志的环绕式处理(wrap-around ),崩溃恢复(Crash Recovery)需要知道在哪里停。
零初始化的问题是会占用更多的时间(取决与你的自动增长率,还有你的存储速度)。在此期间没有别的事务可以写事务日志记录到事务日志。在事务日志管理器上会有闩锁造成的阻塞。因此你的写入事务会进入挂起状态(直到它们获得需要的闩锁),它们就等啊,等啊,等啊,直到你的事务日志自动增长完成。让我们用一个简单的例子演示下。
首先我为这个演示创建一个新的数据库。对于这个数据库,这里我不用默认的设置,对于事务日志,我指定了10GB的自动增长系数。这个的确是个不好的做法,但我只是用它来展示这个设置的副作用。请不要在你的生产数据库里使用这个错误配置!!!
1 -- Create a new database with 10 GB Auto Growth for the Transaction Log 2 CREATE DATABASE AutoGrowthTransactionLog ON PRIMARY 3 ( 4 NAME = N'AutoGrowthTransactionLog', 5 FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\DATA\AutoGrowthTransactionLog.mdf', 6 SIZE = 5120KB, 7 FILEGROWTH = 1024KB 8 ) 9 LOG ON 10 ( 11 NAME = N'AutoGrowthTransactionLog_log', 12 FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL10.MSSQLSERVER\MSSQL\DATA\AutoGrowthTransactionLog_log.ldf', 13 SIZE = 1024KB, 14 FILEGROWTH = 10240000KB -- 10 GB Auto Growth! 15 ) 16 GO
下一步里我在数据库里创建2个表。第1个表我通过插入一些日志来快速填充我的事务日志。在事务日志自动增长阶段,我们在第2个表里插入新的记录来证明这个事务会被自动增长机制阻塞。
1 -- Create a new table, every records needs a page of 8kb 2 CREATE TABLE Chunk 3 ( 4 Col1 INT IDENTITY PRIMARY KEY, 5 Col2 CHAR(8000) 6 ) 7 GO 8 9 -- Another simple table 10 CREATE TABLE Foo 11 ( 12 Bar INT NOT NULL 13 ) 14 GO
现在我们已经创建了必须的数据库对象,因次我可以通过新的没有立即提交的事务来填充事务日志:
1 -- Begin a new transaction, that blocks the 1st VLF in the Transaction Log 2 BEGIN TRANSACTION 3 INSERT INTO Chunk VALUES (REPLICATE('x', 8000)) 4 GO
因为我们现在有了进行中,没提交的事务,SQL Server不能重用那部分事务日志,即这个事务存储的事务日志。它们有需要回滚的可能。因此现在我通过不同的会话插入66条其他记录来填充事务日志:
1 INSERT INTO AutoGrowthTransactionLog.dbo.Chunk VALUES (REPLICATE('x', 8000)) 2 GO 66
最后在第一个会话里提交我们的事务:
1 COMMIT
这意味着在我们面前有一个几乎满的的事务日志,我们可以通过DBCC LOGINFO来验证:
1 DBCC LOGINFO
现在当我们往表里插入兮的记录时,事务日志已经没有可用空间了,SQL Server进入事务日志的自动增长。
1 -- This statement will trigger the Auto Growth mechanism! 2 INSERT INTO Chunk VALUES (REPLICATE('x', 8000)) 3 GO
在自动增长期间的同时,为了监控发生了什么,我们可以在SSMS里打开新的一个会话窗口,尝试在第2个表插入另外的记录——表Foo:
1 -- This statement is now blocked by the Auto Growth mechanism. 2 INSERT INTO Foo VALUES (1) 3 GO
这个SQL 语句会阻塞,因为事务要写入事务日志记录的事务日志,当前不可用。为了进一步分析这个阻塞情形,你可以打开第3个会话窗口,执行下列2个SQL语句:
1 -- Analyze the blocking situation 2 SELECT wait_type, * FROM sys.dm_exec_requests 3 WHERE session_id IN (54, 55) 4 5 SELECT wait_type, * FROM sys.dm_os_waiting_tasks 6 WHERE session_id IN (54, 55) 7 GO
(额,俺本机测试失败………………)
从代码里可以看到,我用2个DMV sys.dm_exec_requests 和 sys.dm_os_waiting_tasks对2个会话都进行了跟踪——触发自动增长的会话,和被自动增长机制阻塞的会话。在这里,触发自动增长的会话里有所谓的抢占等待类型(Preemptive Wait Type)——PREEMPTIVE_OS_WRITEFILEGATHER。抢占等待类型是由SQL Server返回的等待类型,当SQL Server 执行一个WIN32 API函数在调度机制之外时。这里自动增长是通过WriteFileGather的WIN32 API函数完成的。
INSERT语句尝试在Foo表里插入新的记录出现LATCH_EX等待类型。如你从DMV sys.dm_os_waiting_tasks 里的resource_description列所见,在SQL Server的日志管理器上需要获得闩锁。你可以通过查询DMV sys.dm_os_latch_stats 限制lactch class为LOG_MANAGER再次确认。在那个特定闩锁上你会看到一些等待。那个闩锁是事务获取的,由事务日志的自动增长触发,只要这个闩锁要获得,每个其他写事务都会被阻塞。因此在系统上有大量等待时间时,这暗示这在事务日志里当前有自动增长问题需要处理。
希望我已经用这个日志说服你,依赖于事务日志的自动增长机制并不是最好的解决方案。用这个简单的例子可以看到,在你数据库里每个被自动增长操作阻塞的写入事务会发生阻塞,这肯定会伤及你数据库的吞吐量和扩展性。为了保证你有很好的事务日志性能,你可以最佳想实践下这个文章。
感谢关注!
注:此文章为WoodyTu学习MS SQL技术,收集整理相关文档撰写,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出此文链接!
SQL Server 为什么事务日志自动增长会降低你的性能相关推荐
- SQL Server中事务日志自动增长对性能的影响
SQL Server中事务日志自动增长对性能的影响 SQL Server中事务日志自动增长对性能的影响(上) SQL Server中事务日志自动增长对性能的影响(下) posted on 2011-0 ...
- 为什么事务日志自动增长会降低你的性能
在这篇文章里,我想详细谈下为什么你要避免事务日志(Transaction Log)上的自动增长操作(Auto Growth operations).很多运行的数据库服务器,对于事务日志,用的都是默认的 ...
- XenDesktop 5 SQL Server Mirror事务日志比较大的原因分析
在实施XenDesktop5项目过程中,发现XenDesktop5版本的数据库镜像事务日志很大,在XenDesktop4和XenApp版本中不存在该问题:于是我根据该现象探究XenDesktop5及以 ...
- 如何读懂SQL Server的事务日志
本文将介绍SQL Server的事务日志中记录了哪一些信息,如何来读懂这些事务日志中信息.首先介绍一个微软没有公开的函数fn_dblog,在文章的接下来的部分主要用到这个函数来读取事务日志. fn_d ...
- [ZT]SQL Server 的事务日志意外增大或充满的处理方法
http://support.microsoft.com/kb/317375 事务日志文件Transaction Log File是用来记录数据库更新情况的文件,扩展名为ldf. 在 SQL Serv ...
- 如何利用SQL Server的事务日志?
介绍 (Introduction) SQL Server keeps track of all database modifications and every database transactio ...
- SQL Server中事务日志已满的原因以及解决办法
错误描述:数据库的事务日志已满.若要查明无法重用日志中的空间的原因 ,请参阅sys.databases 中的 log_reuse_wait_desc 列 . 首先引入一下事务日志的概念(来自百度百科) ...
- sql server数据库事务日志已满请参阅log_reuse_wait_desc怎么解决?
数据库使用时,莫名其妙出现关于事务日志已满的报错.具体报错如下: 数据库中的事务日志已满.若要查明无法重用日志中的空间的原因,请参阅sys.databases中的log_reuse_wait_desc ...
- SQL Server 数据库清除日志的方法
方法一: 1.打开查询分析器,输入命令 BACKUP LOG database_name WITH NO_LOG 2.再打开企业管理器--右键要压缩的数据库--所有任务--收缩数据库--收缩文件- ...
最新文章
- 企业如何利用新闻类软文营销策划
- 自定义控件学习,优秀网站推荐
- linux python源码目录结构,TensorFlow0.8源码阅读 -- 代码目录结构讲解
- [No0000D7]img生成器.bat合并所有图片到html网页中
- php 通讯协议,通讯协议作用
- SQL Server中的报表–结合T-SQL和DAX查询以生成有效的报表
- 如何查看sqlserver数据库文件位置
- 传奇开服架设之地图索引编辑器以及安装问题排查教程
- 计算机毕业设计源码—SpringBoot+Vue宿舍管理系统
- OpenGL基础48:高度贴图(上)
- java毕设答辩准备
- 奥城大学计算机专业,美国提供研究生双录取的大学
- IT职业教育(7) 从《大国崛起》(德国)看中国IT教育
- OC面向对象的三大特征(封装 继承 多态)习题2 复合
- 什么软件去视频水印 拍抖音技巧视频教程
- sql 数据库前两列值乘_SQL注入原理和方法汇总
- MarchingCubes算法提取等值面的基本原理
- QQ2013 协议分析
- 鱼c论坛 python课后题pdf,我与python的第一次亲密接触_课后测试题及答案.pdf
- 04 Softmax分类器