SQL Server之所以记录事务日志,首要目的是为了把失败或取消的操作还原到最原始的状态,但是,并不是所有的操作都需要完全记录事务日志,比如,在一个空表上放置排他锁,把大量的数据插入到该空表中。即使插入操作在任意时刻失败,只需要把清空表,就可以把表还原,根本不需要记录插入的详细数据。在表上放置排他锁的目的,是为了阻止其他人更新该表,当插入失败时,只需要清空表就还原到最原始的状态。

最小化日志记录仅记录恢复事务所需的信息,而不支持任意时间点恢复,也就是说,在最小化日志记录操作时,SQL Server也会记录事务日志,但是仅记录回滚事务所需的有限信息。“有限信息”是指,仅把分配的页面记录在事务日志中,而没有记录这些页面包含的实际数据,因此保持了较小的事务日志文件的大小。

一,最小日志操作

在FULL还原模式下,所有的大容量操作都会完全记录事务日志,在进行大容量数据插入时,最小化日志记录更有效率,减少了事务日志空间在大容量操作时暴增的可能性,但是,如果在最小化日志记录生效时数据库已损坏或丢失,那么无法把数据库恢复到故障点。

在最小化日志记录期间执行大容量数据插入,虽然数据插入不会记录在事务日志中,但是,对于每次为表分配的区(8个物理地址连续的Page)都会记录在事务日志中。不是所有的操作都能实现最小化日志记录,最小化日志操作的类型:

  • 大容量导入操作(Bulk Import Operations)包括 BULK INSERT、BCP和 INSERT SELECT
  • SELECT INTO
  • 索引操作:CREATE INDEX、ALTER INDEX REBUILD、DROP INDEX

有意思的是,TRUNCATE 并不是最小化日志记录操作,在任何还原模式下,TRUNCATE 都完整记录事务日志的,并能够还原到任意时间点,不过TRUNCATE记录日志的效率更高,采用deferred-drop 机制来记录日志。

二,触发最小日志的条件

测试用例的环境是SQL Server 2017版本,在 SIMPLE或BULK_LOGGED还原模式下做测试。

实际上,要在执行大容量插入时实现最小化日志记录,必须满足五个条件:

  • 数据库处于SIMPLE或BULK_LOGGED还原模式
  • 表级锁定,推荐使用表 hint 显式上锁:with(tablock)
  • 不是复制表
  • 不是内存优化表
  • 在满足前四个条件的基础上,有如下结论:

一个表是否可以进行最小化日志记录还取决于该表是否已建立索引,如果是,则取决于该表是否为空。

结论1:表没有索引,Data Page执行最小化日志记录。

结论2:表没有聚集索引,但是有非聚集索引,Data Page执行最小化日志记录。

  • 当表是空的时,Index Page执行最小化日志记录
  • 当表有数据时,Index Page执行完整日志记录

对于使用分Batch插入的情况,当表是空的,对于第一个Batch插入,Data Page和Index Page都执行最小化日志记录;从第二个Batch开始,Data Page执行最小化日志记录,而Index Page执行完整日志记录。

结论3:表有聚集索引

  • 当表有聚集索引,并且是空表时,Data Page和Index Page都执行最小化日志记录。
  • 当表有聚集索引,并且有数据时,Data Page和Index Page都执行完整日志记录。

对于使用分Batch插入的情况,当表是空的,对于第一个Batch插入,Data Page和Index Page都执行最小化日志记录;从第二个Batch开始,Data Page执行最小化日志记录,而Index Page执行完整日志记录。

结论4,从表中可以看出:

  • 索引页的分配都是Fully Logged,
  • 堆表的数据页更新都是Min Logged,
  • 只有当表是聚集索引时,数据页的更新才是Fully Logged的,实际上,BTree表就是索引本身。

三,索引操作中的最小化日志

从上节中的结论4中知道,索引页的分配都是Fully Logged,索引页的回收(deallocation )也都是Fully Logged。在特定的情况下,执行CREATE INDEX、ALTER INDEX REBUILD 和 DROP INDEX能够激发数据页的最小化日志记录,索引的重建(REBUILD)相当于先删除索引,再创建索引。

比如,创建索引相当于向有数据的表中插入数据,索引页是Full Logged,数据表根据结论4来判断数据页是Full Logged或Min Logged。

四,延迟删除

TRUNCATE TABLE简单来说,是通过回收已分配的数据页来移除数据,并且只把回收的数据页记录在事务日志中。

DROP TABLE 和 TRUNCATE TABLE 都是完整记录日志的操作,不过日志不是立即创建,而是延迟记录,这是由延迟删除(deferred drop)的机制来实现的。当一个表被 drop 或 truncate 时,属于该表的所有数据页都会被系统标记为回收,并把标记为回收的数据页和区放置在延迟删除队列(deferred-drop queue)中,该数据页或区实际上并没有释放,只是标记为回收(deallocation )。延迟删除机制通过回收表的数据页,从而模拟drop 或 truncate操作立即完成后的效果,这个过程仅仅产生很少的日志记录。

但是延迟删除的后台处理程序(deferred-drop background task)每隔几秒钟就会执行一次,并以小批量的方式回收放置在延迟删除队列(deferred-drop queue)中的所有Page和Extent,从而确保操作不会耗尽内存。回收空间的操作是完全记录日志的,不过,释放一个充满数据或索引记录的页面,并不会记录个别数据行的删除。相反,整个页面只是在相关的PFS(Page Free Space)分配字节图中标记为已取消分配。

从SQL Server 2000 SP3开始,执行表的DROP或TRUNCATE时,只会看到一些正在生成的日志记录。如果等待一分钟左右,然后再次查看事务日志,您将看到deferred-drop操作已经生成了成千上万的日志记录,每个日志记录都表示回收一个Page或Extent。

 

参考文档:

Operations that can be minimally logged

Prerequisites for Minimal Logging in Bulk Import

SQL Server: Understanding Minimal Logging Under Bulk-Logged Recovery Model vs. Logging in Truncate Operation

SQL Server: An Examination of Logging in Truncate Table Statement and Its Comparison With Delete Statement

The Myth that DROP and TRUNCATE TABLE are Non-Logged

SQL Server 最小日志记录的更多相关文章

  1. 人人都是 DBA(VI)SQL Server 事务日志

    SQL Server 的数据库引擎通过事务服务(Transaction Services)提供事务的 ACID 属性支持.ACID 属性包括: 原子性(Atomicity) 一致性(Consisten ...

  2. SQL Server中日志

    再谈SQL Server中日志的的作用 简介 之前我已经写了一个关于SQL Server日志的简单系列文章.本篇文章会进一步挖掘日志背后的一些概念,原理以及作用.如果您没有看过我之前的文章,请参阅: ...

  3. SQL Server 错误日志过滤(ERRORLOG)

    一.背景 有一天我发现SQL Server服务器的错误日志中包括非常多关于sa用户的登陆错误信息:“Login failed for user 'sa'. 原因: 评估密码时出错.[客户端: XX.X ...

  4. [AlwaysOn Availability Groups]SQL Server错误日志(AG)

    SQL Server错误日志(AG) SQL Server错误日志会记录影响AG的时间,比如: 1.和Windows故障转移集群交互 2.可用副本的状态 3.可用数据的状态 4.AG endpoint ...

  5. SQL Server自动化运维系列——监控磁盘剩余空间及SQL Server错误日志(Power Shell)

    需求描述 在我们的生产环境中,大部分情况下需要有自己的运维体制,包括自己健康状态的检测等.如果发生异常,需要提前预警的,通知形式一般为发邮件告知. 在所有的自检流程中最基础的一个就是磁盘剩余空间检测. ...

  6. SQL Server 错误日志收缩(ERRORLOG)

    一.基础知识 默认情况下,错误日志位于 : C:\Program Files\Microsoft SQL Server\MSSQL.1\MSSQL\LOG\ERRORLOG 和ERRORLOG.n 文 ...

  7. SQL Server 使用日志传送

    参考文献: http://msdn.microsoft.com/en-us/library/ms187103.aspx 概述 SQL Server 使用日志传送,您可以自动将“主服务器”实例上“主数据 ...

  8. SQL Server自动化运维系列 - 监控磁盘剩余空间及SQL Server错误日志(Power Shell)

    需求描述 在我们的生产环境中,大部分情况下需要有自己的运维体制,包括自己健康状态的检测等.如果发生异常,需要提前预警的,通知形式一般为发邮件告知. 在所有的自检流程中最基础的一个就是磁盘剩余空间检测. ...

  9. sql server 错误日志errorlog

    一 .概述 SQL Server 将某些系统事件和用户定义事件记录到 SQL Server 错误日志和 Microsoft Windows 应用程序日志中. 这两种日志都会自动给所有记录事件加上时间戳 ...

随机推荐

  1. postgreSQL命令大全(更新中)

    1.PostgreSQL索引的建立https://blog.csdn.net/jubaoquan/article/details/78850899: 2.PostgreSQL9中索引的原理和效率查询h ...

  2. JavaScript之Date常用知识点

    1.new Date(dateStr) :把字符串转换为Date对象 参数: ①dateStr {string} :可转换为Date对象的字符串(可省略时间):字符串的格式主要有两种: 1) yyyy ...

  3. IMX6Q开发板Linux-QT挂载U盘及TF卡

    本文基于:迅为-iMX6开发板Linux-QT挂载U盘及TF卡 如下图所示,qt 启动之后,在超级终端中使用命令“mknod /dev/sda1 b 8 1”创建 U盘的设备节点,如下图所示. 插入 ...

  4. arduino驱动oled

    OLED一款小巧的显示屏,感觉可以做出很可爱的东西. 这次实验的这款是128X64的OLED屏幕 , 芯片是SSD1306,请确认自家模块芯片型号,不然对不上号啊 使用IIC的方法,简单实验显示示例程 ...

  5. Cow Routing(最短路spfa)

    题:https://www.luogu.org/problem/P3115 题意:给出起点A,终点B,N条路线,下面没俩行一个路线,第一行是俩个数,第一个为这条路线的花费,第二个为这条路线经过的点数n ...

  6. 花生壳的ddns 关键时刻又掉链子,准备迁到阿里万网

    https://www.oray.com/news/affiche/?aid=628 免费版花生壳服务故障 因免费版机房线路节点负荷突然暴增,导致花生壳免费版登录缓慢或异常,或出现域名指向到127.0 ...

  7. ambulance|severely|halt

    N-COUNT 救护车An ambulance is a vehicle for taking people to and from hospital. very seriously 严重地 Thei ...

  8. OpenCV 实现自己的线性滤波器

    #include "opencv2/imgproc/imgproc.hpp" #include "opencv2/highgui/highgui.hpp" #i ...

  9. JSP_EL的回顾

    在 JSP 页面中,使用标签库代替传统的 Java 片段语言来实现页面的显示逻辑已经不是新技术了,然而,由自定义标签很容易造成重复定义和非标准的实现.鉴于此,出现了 JSTL ( JSP Standa ...

  10. winform窗体中webbrowser如何屏蔽脚本错误弹窗

    在构造函数中加入: webBrowser.ScriptErrorsSuppressed = true;