【版本特性】sql server2014新特性 Delayed durability(lazy commit)延迟事务
【0】前置概念参考
预写式日志(Write-Ahead Logging (WAL))
【1】事务的持久化概念
ACID 是数据库的基本属性。其中的D是指"持久性":只要事务已经提交,对应的数据修改就会被保存下来,即使出现断电等情况,当系统重启后之前已经提交的数据依然能够反映到数据库中。
那么D特性是如何在SQL Server中实现的呢?SQL Server使用write-ahead logging的方式,保证日志记录会先于数据记录固化到磁盘中。
当事务提交后,只有当日志记录固化到磁盘时,才会向客户端返回提交成功的消息,至于相应的数据记录,会通过异步的方式后续写入到磁盘中。
如果在此期间发生断电等故障,那么就会出现以下两种情况:
-
日志已经写入到磁盘(committed),但数据没有写入:
系统重启后进行redo操作,通过读取日志,来将没有固化到数据文件的信息写入到数据文件。
-
部分日志已经写入到磁盘(uncommitted),数据部分写入或没有写入
系统重启后执行undo操作,将没有提交的事务对应的数据从数据文件中清除。
这样就保证了已经提交的事务不会丢失。
【2】Delayed durability 延迟日志写入
SQL Server 2014中引入了一个新的特性,叫做Delayed durability(也称作lazy commit),颠覆了之前提到的概念。通过Delayed durability。
可以让日志记录按照一定规律异步地写入到日志文件中,避免日志磁盘写入过于频繁。这样就以牺牲Durability来换取性能。
【2.1】应用场景
使用该特性的前提是您的应用可以容忍一定程度的数据丢失。
日志磁盘出现系统瓶颈。
由于日志磁盘性能问题,导致事务无法提交,导致相应的资源(memory,lock等)无法释放引发的资源竞争
【2.2】Delayed Durability 主要特性
- 一旦事务提交,事务中的数据变更对其他事务(包含full durable transaction和delayed durability transaction)可见。具体请参考isolation level http://msdn.microsoft.com/en-us/library/dn133175.aspx
- 事务的持久性(durability)依赖于日志记录是否固化到磁盘。
-
内存中的日志记录只有在任意以下情况发生时才会固化到磁盘:
- )Full durable transaction进行了数据变更,并且commit.
- )执行了sp_flush_log存储过程.
- )Log buffer满了,日志记录也会固化到磁盘.
如果1)或2)出现两次,那么SQLSERVER会保证第一次之前的Delayed durability transaction的数据变更已经被固化到了磁盘。
【3】如何使用Delayed durability
【3.1】一般形式和模式 ALTER DATABASE [DDtest] SET DELAYED_DURABILITY = FORCED|Allowed|Disabled
Delayed durability是一个数据库级别的特性,默认是禁用的,我们首先要开启这个选项。
ALTER DATABASE [DDtest] SET DELAYED_DURABILITY = FORCED|Allowed|Disabled
如果是forced,那么该数据库内所有的事务都强制使用delayed durability;
如果是allowed,那么delayed durability和full durable transaction可以同时存在;
如果是disabled,那么无法使用delayed durability.
当该属性发生变化后,errorlog中也会有相应的记录
Setting database option delayed_durability to forced for database 'DDtest'. Setting database option delayed_durability to allowed for database 'DDtest'. Setting database option delayed_durability to disabled for database 'DDtest'.
【3.2】语句级别的 delayed_durability commit tran with(delayed_durability=on)
如果数据库的DELAYED_DURABILITY为Allowed,我们可以在语句级别进行控制,否则就要遵循数据库的设定了(如果语句的设定和数据库级别设定冲突,那么SQL Server会使用数据库级别的设定)。
将数据的 DELAYED_DURABILITY设置为Allowed ALTER DATABASE [DDtest] SET DELAYED_DURABILITY = Allowed
创建一张表,并循环插入1000行数据,每次插入都是一个单独的事务
create table ta(col int) declare @N int=0 while @n<1000 begin begin tran insert ta values(1) commit tran with(delayed_durability=off) set @N+=1 print cast(@N as varchar(1000)) end
开启Process Monitor,监控对数据库日志文件的操作。
一共对日志文件进行了1012次的写入操作,也就是每次commit都会立刻固化到日志文件
下面比较一下使用delayed durability的情况
declare @N int=0 while @n<1000 begin begin tran insert ta values(1) commit tran with(delayed_durability=on) set @N+=1 print cast(@N as varchar(1000)) end
1000个事务只触发了32次写入,大大地减少了对日志文件的写入操作。
【4】日志持久化与数据丢失
- 当系统不忙时,也会主动将delayed durability的日志记录固化到磁盘。但目前不知道如何判断"不忙"这个标准。
- checkpoint不会将delayed durability的日志记录固化到磁盘。
- SQL Server正常关闭不会将delayed durability的日志记录固化到磁盘,也就说正常关闭也可能会导致数据丢失,建议之前先执行sp_flush_log。
- 很明显,如果断电等操作,直接内存中的未提交事务日志就丢失了,意味着已提交但脏页未持久化的事务也会丢失。
【5】开启该选项对其他操作的影响
更改跟踪和更改数据捕获
具有更改跟踪属性的所有事务都是完全持久事务。 如果一个事务对支持更改跟踪的表执行了任何写入操作,则该事务具有更改跟踪属性。 使用变更数据捕获 (CDC) 的数据库不支持使用延迟的持续性。
崩溃恢复
一致性可得到保证,但已提交的延迟持久事务的一些更改可能会丢失。
跨数据库和 DTC
如果事务跨数据库或是分布式事务,则无论数据库或事务提交设置如何,它都是完全持久事务。
AlwaysOn 可用性组和镜像
延迟持久事务并不能保证主数据库或任何辅助数据库的持续性。 此外,它们也不保证了解辅助数据库的事务。 提交后,在从同步辅助数据接收到任何确认之前,控制权就会归还客户端。 当主副本上的磁盘刷新时,会继续复制辅助副本。
故障转移群集
某些延迟持久事务写入可能会丢失。
事务复制
事务复制不支持延迟持久事务。
日志传送
传送的日志中仅包含已成为持久事务的事务。
日志备份
备份中仅包含已成为持久事务的事务。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
2019-04-25 yum源配置、epel源配置