SQL Serve 日志体系结构
SQL Server 事务日志记录着 undo 及 redo 日志,为了保证数据库在崩溃后恢复,或者在正常数据库操作期间进行回滚,保证数据库事务完整性和持久化。如果没有事务日志记录,数据库在事务上将不一致,并且在数据库崩溃后可能导致结构上损坏。
SQL Server 日志记录最初在内存中处理,可能在事务提交之前写入磁盘,单必须在事务完成提交之前写入磁盘,否则事务不会持久化(延迟事务特性例外)。
事务日志的内部结果是什么样子呢?
结构层次
事务日志在内部使用三层结构进行组织,如下图所示。

事务日志包含虚拟日志文件,虚拟日志文件包含存储实际日志记录的日志块。
事务日志分为多个虚拟日志文件(virtual log files),通常称为VLF。这样做是为了让 SQL Server 中的日志管理器更轻松地管理事务日志中的操作。你无法指定 SQL Server 在首次创建数据库或日志文件自动增长时创建了多少 VLF,但你可以影响它。创建多少个 VLF 的算法如下:
-
日志文件大小小于 64MB:创建 4 个 VLF,每个大小约为 16 MB
-
日志文件大小从 64MB 至 1GB:创建 8 个 VLF,每个大约是总大小的 1/8
-
日志文件大小大于 1GB:创建 16 个 VLF,每个大约是总大小的 1/16
在 SQL Server 2014 之前,当日志文件自动增长时,添加到日志文件末尾的新 VLF 数量由上述算法根据自动增长大小确定。但是,使用这种算法,如果自动增长的大小很小,并且日志文件经历了许多自动增长,它可能会导致大量的小 VLF(称为VLF 碎片),这可能是一个很大的性能问题。
由于这个问题,在 SQL Server 2014 中,日志文件的自动增长算法发生了变化。如果自动增长的大小小于总日志文件大小的 1/8,则只创建一个新的 VLF,否则使用旧算法。这大大减少了由日志文件频繁自动增长的 VLF 数量。
每个 VLF 都有一个唯一标识它的序列号,并用于各种地方,你可能认为全新数据库的序列号将从 1 开始,但事实并非如此。
在 SQL Server 2019 实例上,我创建了一个新数据库,但未指定任何文件大小,然后使用以下代码检查 VLF:
CREATE DATABASE NewDB;GO--MSSQL 2016 SP2开始可用SELECT[file_id],[vlf_begin_offset],[vlf_size_mb],[vlf_sequence_number]FROM sys.dm_db_log_info (DB_ID (N'NewDB'));GO--MSSQL 任意版本可用DBCC LOGINFO('NewDB');GO
请注意,sys.dm_db_log_info 是在 SQL Server 2016 SP2 中添加的。你也可以使用 DBCC LOGINFO 命令查看,FSeqNo为 VLF 序列号。

请注意,第一个 VLF 从日志文件的偏移量 8192 字节开始。这是因为包括事务日志在内的所有数据库文件都有一个文件头页,该页占用了前 8KB,并存储了有关该文件的各种元数据。
那么为什么 SQL Server 选择 36 而不是 1 作为第一个 VLF 序列号呢?这是因为数据库的创建都是以 model 作为参考,model 中的最大 VLF 序列号加上1,即为新数据库的 VLF 序列号。该算法从 SQL Server 7.0 开始就已使用。
为了证明这一点,我运行了以下代码:
SELECT MAX ([vlf_sequence_number]) AS [Max_VLF_SeqNo]FROM sys.dm_db_log_info (DB_ID (N'model'));GODBCC LOGINFO('model');GO

现在只要知道每个 VLF 都有一个序列号就足够了,每个 VLF 序列号增量为1。
日志块
每个 VLF 包含一个小的元数据标头,其余空间由日志块填充。每个日志块从 512 字节开始,以 512 字节为增量增长到最大 60KB,此时必须将其写入磁盘。如果发生以下情况之一,日志块可能会在达到其最大大小之前写入磁盘:
-
事务提交,并且延迟持久性未作用于该事务,因此必须将日志块写入磁盘以使事务持久;
-
使用延迟持久化,后台“flush the current log block to disk”每1ms定时触发;
-
检查点或惰性写入器正在将数据文件页面写入磁盘,并且当前日志块中有日志记录影响要写入的页面(预写日志);
你可以将日志块看作是大小可变的页面,它按照事务更改数据库创建的顺序存储日志记录。每个事务没有专门的日志块,多个并发事务的日志记录可以混合在一个日志块中。你可能认为,当去寻找单个事务的所有日志记录时会带来困难,但事实并非如此。此外,当一个日志块被写入磁盘时,它完全有可能包含来自未提交事务的日志记录。
日志序列号(LSN)
日志块在 VLF 中有一个 ID,从 1 开始,对于 VLF 中的每个新日志块增量为 1。日志记录在日志块中也有一个 ID,从 1 开始,对于日志块中的每个新日志记录增加 1。因此,事务日志的结构层次结构中的所有三个元素都有一个 ID,它们合并为一个称为日志序列号的三方标识符中,通常简称为LSN。
一条 LSN 定义为 <VLF sequence number>:<log block ID>:<log record ID>(4 字节:4 字节:2 字节),唯一标识一条日志记录。这是一个不断增加的标识符,因为 VLF 序列号永远增加。
你也可以使用 fn_dblog 查看当前数据库的事务日志:
--sys.fn_dblog(Start LSN nvarchar(25), End LSN nvarchar(25))SELECT [Current LSN] FROM sys.fn_dblog(NULL, NULL)
相关文章:
SQL Serve 日志体系结构
SQL Server 事务日志记录着 undo 及 redo 日志,为了保证数据库在崩溃后恢复,或者在正常数据库操作期间进行回滚,保证数据库事务完整性和持久化。如果没有事务日志记录,数据库在事务上将不一致,并且在数据库崩溃后可能导…...
【C++1】函数重载,类和对象,引用,string类,vector容器,类继承和多态,/socket,进程信号,public,ooci
文章目录1.函数重载:writetofile(),Ctrue和false,C0和非02.类和对象:vprintf2.1 构造函数:对成员变量初始化2.2 析构函数:一个类只有一个,不允许被重载3.引用:C中&取地址&#x…...
asio网络编程 tcp、udp、rpc
轻量级的tcp/udp/rpc库,简化socket程序编写。 同时,RPC部分也提供了方便易用的功能。 仓库地址 https://github.com/shuai132/asio_net asio_net a Tiny Async TCP/UDP/RPC library based on ASIO and RpcCore Features 简化TCP、UDP相关程序的编写…...
双目测距------双目相机V1.0,将双目相机采集到任意一点的深度数据进行串口传输(带源码)
Depth2Uart 双目测距------双目相机V1.0,将双目相机采集到任意一点的深度数据进行串口传输 一、项目说明/Overview 所实现的功能:基于Intel Realsense官方提供的SDK,双目深度相机能获取到相机任何一个像素点距离前方障碍物的距离࿰…...
jetson nano(ubuntu)安装Cmake
文章目录安装环境一.命令行安装二.Cmake源码编译安装安装环境 jetson nano 系统:4.6.1 一.命令行安装 sudo apt install cmake这种直接安装cmake的方式,其实安装的版本都太老了,这种方式不推荐 二.Cmake源码编译安装 更新一下系统软件 su…...
图的基本介绍和表示方式
图的基本介绍 为什么要有图这个基本数据结构? 我们还学习过线性表(数组、队列、链表和栈)和树,但是我们可以发现,线性表局限于一个直接前驱(就是只能有唯一一个前面的结点)和一个直接后继的(…...
本周大新闻|传微软解散工业元宇宙团队,MIT研发垂直堆叠全彩Micro LED
本周大新闻,AR方面,消息称微软解散工业元宇宙团队;德国AR公司Gixel GmbH亮相;Brilliant推出单片式附加形态AR眼镜;MIT研发垂直堆叠全彩Micro LED;谷歌XR串流正式上线。VR方面,索尼发布了PS VR2的…...
SpringMVC:拦截器(12)
拦截器1. 拦截器概念2. 拦截器入门案例2.1 环境准备2.2 拦截器开发步骤1: 创建拦截器类步骤2: 配置拦截器类步骤3: SpringMVC添加SpringMvcSupport包扫描和interceptor包扫描步骤4: 简化SpringMvcSupport的编写5 测试3. 拦截器参数解析(了解)3.1 前置处理…...
计算机网络3:HTTP1.0和HTTP1.1的区别
目录1. HTTP是什么2.HTTP1.0和HTTP1.1的区别3.名词解释(1)If-Modified-Since(IMS)、Expires(2)If-None-Match,Etag(3)If-Unmodified-Since1. HTTP是什么 超文本传输协议…...
Urho3D 编辑器说明
Urho3D编辑器是一个脚本应用程序,可以与Urho3D播放器应用程序一起运行。要开始,请执行以下任意命令:(在bin目录中)Editor.bat、Editor.sh或Urho3DPlayer Scripts/Editor.as Urho3D播放器应用程序支持的所有命令行选项…...
C++类基础(十一)
运算符重载(二) ● 对称运算符通常定义为非成员函数以支持首个操作数的类型转换 struct Str {int val 0;Str(int input): val(input){}auto operator(Str x){std::cout << "auto operator(Str x)\n";return Str(val x.val);} }; int …...
Windows安装系列:SVN Server服务
一、下载与安装 1、下载VisualSVN-Server-5.1.1-x64.msi 地址:Download | VisualSVN Server 2、找到最新版本SVN 5.1.1,直接双击它,弹出如下安装界面 3、点击Next 4、勾选我接受, 点击"Next" 5、默认选项,…...
快速傅里叶算法(FFT)快在哪里?
目录 前言 1、DFT算法 2、FFT算法 2.1 分类 2.2 以基2 DIT(时间抽取) FFT 算法为例 2.2.1 一次分解 2.2.2 多次分解 参考 前言 对信号分析的过程中,为了能换一个角度观察问题,很多时候需要把时域信号波形变换到频域进行分…...
利用Markdown写学术论文资料汇总贴
1是最详细的,重点看! Markdown 写作,Pandoc 转换:我的纯文本学术写作流程 2补充一些细节,也可以看看。 用Markdown写作学术论文 3写得和上面差不多,如果上面两篇有什么问题还没解决,可以看看…...
MySQL 高级查询
目录1.左关联2.右关联3.子查询4.联合查询5.分组查询1.左关联 MySQL中的左关联(Left Join)是一种基于共同列的连接操作, 它将左侧表中的所有行与右侧表中匹配的行结合在一起, 如果右侧表中没有匹配的行,则结果集中右侧…...
JavaSE学习day4_01 循环for,while,do...while
1. 循环高级 1.1 无限循环 for、while、do...while都有无限循环的写法。 最为常用的是while格式的。 因为无限循环是不知道循环次数的,所以用while格式的 代码示例: while(true){} 1.2 跳转控制语句(掌握) 跳转控制语句&…...
C/C++中的static关键字
概述在C/C中都有static关键字的使用,可以分别修饰变量和函数,分为静态变量【静态成员】、静态成员函数。2. static用法概况静态变量的作用范围在一个文件内,程序开始时分配空间,结束时释放空间,默认初始化为0ÿ…...
67 自注意力【动手学深度学习v2】
67 自注意力【动手学深度学习v2】 深度学习学习笔记 学习视频:https://www.bilibili.com/video/BV19o4y1m7mo/?spm_id_fromautoNext&vd_source75dce036dc8244310435eaf03de4e330 给定长为n 的序列,每个xi为长为d的向量,自注意力将xi 既当…...
电子学会2022年12月青少年软件编程(图形化)等级考试试卷(二级)答案解析
青少年软件编程(图形化)等级考试试卷(二级) 一、单选题(共25题,共50分) 1. 一个骰子,从3个不同角度看过去的点数如图所示,请问5的对面是什么点数?( ) …...
关于链表中插入结点的操作……
服了,好久没敲链表了,这都忘了 newnode->next cur->next; cur->next newnode; newnode->next cur->next; cur->next newnode; newnode->next cur->next; cur->next newnode; newnode->next cur->next; cur-…...
微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...
如何在看板中体现优先级变化
在看板中有效体现优先级变化的关键措施包括:采用颜色或标签标识优先级、设置任务排序规则、使用独立的优先级列或泳道、结合自动化规则同步优先级变化、建立定期的优先级审查流程。其中,设置任务排序规则尤其重要,因为它让看板视觉上直观地体…...
【第二十一章 SDIO接口(SDIO)】
第二十一章 SDIO接口 目录 第二十一章 SDIO接口(SDIO) 1 SDIO 主要功能 2 SDIO 总线拓扑 3 SDIO 功能描述 3.1 SDIO 适配器 3.2 SDIOAHB 接口 4 卡功能描述 4.1 卡识别模式 4.2 卡复位 4.3 操作电压范围确认 4.4 卡识别过程 4.5 写数据块 4.6 读数据块 4.7 数据流…...
STM32F4基本定时器使用和原理详解
STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...
全球首个30米分辨率湿地数据集(2000—2022)
数据简介 今天我们分享的数据是全球30米分辨率湿地数据集,包含8种湿地亚类,该数据以0.5X0.5的瓦片存储,我们整理了所有属于中国的瓦片名称与其对应省份,方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...
STM32标准库-DMA直接存储器存取
文章目录 一、DMA1.1简介1.2存储器映像1.3DMA框图1.4DMA基本结构1.5DMA请求1.6数据宽度与对齐1.7数据转运DMA1.8ADC扫描模式DMA 二、数据转运DMA2.1接线图2.2代码2.3相关API 一、DMA 1.1简介 DMA(Direct Memory Access)直接存储器存取 DMA可以提供外设…...
【HTTP三个基础问题】
面试官您好!HTTP是超文本传输协议,是互联网上客户端和服务器之间传输超文本数据(比如文字、图片、音频、视频等)的核心协议,当前互联网应用最广泛的版本是HTTP1.1,它基于经典的C/S模型,也就是客…...
C# 求圆面积的程序(Program to find area of a circle)
给定半径r,求圆的面积。圆的面积应精确到小数点后5位。 例子: 输入:r 5 输出:78.53982 解释:由于面积 PI * r * r 3.14159265358979323846 * 5 * 5 78.53982,因为我们只保留小数点后 5 位数字。 输…...
深度学习之模型压缩三驾马车:模型剪枝、模型量化、知识蒸馏
一、引言 在深度学习中,我们训练出的神经网络往往非常庞大(比如像 ResNet、YOLOv8、Vision Transformer),虽然精度很高,但“太重”了,运行起来很慢,占用内存大,不适合部署到手机、摄…...
32单片机——基本定时器
STM32F103有众多的定时器,其中包括2个基本定时器(TIM6和TIM7)、4个通用定时器(TIM2~TIM5)、2个高级控制定时器(TIM1和TIM8),这些定时器彼此完全独立,不共享任何资源 1、定…...
