SQL Server 2000 数据结构剖析(1): 日志文件结构

原创 2011年03月27日 20:23:00

SQL Server 2000是一个可以自增长的可复写的循环文件,最小增长大小为248K(256K-8K),而一个数据库的多个日志文件,是被轮流选择写入日志的,也就是同时循环使用,所以日志文件如果要增长,也是轮流依次增长。

每一个事务日志文件都被分成若干个小的部分,称为虚拟日志文件(VLF),它是SQL Server日志的最小单元,当整个VLF中的所有记录不在包含活动事务(未提交事务)的信息的时候,比如存在这个VLF的事务刚好提交了,那么这个VLF就处于不活动的状态,能够被SQL Server所复用。

日志文件刚创建时,被分割成如干个相同大小的VLF文件(最少2个,最多16个),创建时,日志文件如果大于1MB,VLF的大小总是64K的倍数,下表提供了日志文件刚创建时的分配情况:

日志创建时大小 VLF数量 每个VLF的大小
小于1MB 2-4个 248KB-334KB
1MB-64MB 4个 256K-16MB
64MB-1GB 8个 8MB-128MB
1GB以上 16个 64MB或更大

日志文件的前8K用来存放日志头信息,后面依次存放VLF,所以,对于一个1MB大小的日志文件,先存放一个8K的日志头以后,显然是放不下4个256K的VLF的,其实SQL Server是存了3个256K的VLF和1个256K-8K=248K的VLF。

日志头信息

这8K的文件头也并非填满了信息,其实只有前42个字节是有用的信息,从42-8192这部分字节都是补0的。下面介绍着42个字节究竟存放了哪些信息。

数据类型 名称 大小 描述
UCHAR lfh_fixedValue 1 用于保护以下区域的重复映射.在SQL Server 2000中,被设为0xAB
UCHAR lfh_parity 1 在0x40和0x80之间切换,以防止这段VLF被重用.在做位填充操作时,在每512字节的小边界处会填充这个值,以便在恢复时判断日志的结尾
USHORT lfh_versionNo 2 日志文件的格式版本,SQL Server 7时,此值为1,SQL Server 2000时,此值为2
ULONG lfh_fSeqNo 4 VLF的序列号,如果是不活动的,则为0
ULONG lfh_status 4 活动的是0x02,否则为0
ULONG lfh_writeSeqNo 4 每次更新时的VLF序列号自增长计数器
ULONGLONG lfh_fileSize 8 VLF的大小
ULONGLONG lfh_startOffset 8 物理文件开始到这个头文件的位移
LSN lfh_createLSN 10 此时需要创建的LSN

日志块结构

每个VLF会包含若干个日志块(log block),而每个日志块依次存放以下信息:

日志块头信息,日志记录(用一个4字节的边界隔开),位置槽数组,一段空白区(用于伸缩填充,以确保后面剩余512个字节作为边界),512字节的边界

image

日志块总是512字节的倍数(NTFS的sector的大小),最大不会超过60K,一个日志块是一次日志I/O的基本单元. 通常情况下,VLF中的日志块是被填的满满的,但也有时候,VLF中的最后一个日志块是空的,如果VLF剩余的空间装不下这个记录的时候,会保留这个空日志块,而直接去填充下一个VLF。

日志块头信息

名称 大小 偏移量 描述
lbk_version 2 0x0 日志块的格式版本,SQL Server 7是1,SQL Server 2000是2
lbk_noOfRecords 2 0x2 日志块中日志记录的个数
lbk_offsetSlotArray 2 0x4 位置槽数组的偏移量
lbk_totalSize 2 0x6 日志块的总大小
lbk_status 2 0x8 被填充为0x01,非填充为0
lbk_prevBlkSize 2 0xA 上一个日志块的起始位置的偏移量,这样可以快速地定位前一个日志块的位置,因此SQL Server是可以反向扫描日志块的
lbk_startLSN 10 0xC 块中第一条记录的LSN
lbk_pad 2 0x16 用于补齐头信息为四字节的整数倍

位置槽数组

位置槽数组是一串2字节偏移量值的数组,反向记录每条记录的偏移量.如下图

image

字节填充

由于日志块是日志I/O的最小单元,所以日志块占用的磁盘段要么全部写入磁盘,要么全都不写。未能在读取日志块的时候能够检查这种状态,采用一种在这些sector的开头标识一个相同的小标记,这个标记在一个VLF中公用同一个,就是lfh_parity的值,每次重用的时候,在0x40和0x80之间切换,即上次使用了0x40这标记,这次就采用0x80(是不是日志块只有一部分被写到了磁盘中,因为日志块是512字节的倍数,它包换若干个sector,而磁盘的写入是以sector为单位的。)

当然,光这么标记也不行,更重要的是记录这个块的开头和结尾,于是在开头sector多加0X10,在结尾sector多加0x08。在NTFS中,读取一个被重映射的sector,可能会读到一段被0xFE填充的字节,但并不返回错误报告,虽然0xFE的0x40和0x80位都是1,并且0x10和0x08位也都是1,但是显然它是个有问题的,怎么办呢,我们通过0x20位来进行检验(我们之前无论怎么标记,0x20位一定是0,但是如果是0xFE是1,那就说明有问题了)

具体规则如下,假设sector开头的那个小标记叫B

if(B AND 0x02==1),说明这个字节很可能是0xFE,可能文件系统经历过磁盘硬件故障
if(B AND 0x10==1),日志段的第一个sector
if(B AND 0x08==1),日志段的最后一个sector
if(B AND lfh_parity == 0),旧的日志块

字节填充技术也用于在启动时检测日志的真实结尾,找到最后一个VLF的最后一个日志块,由于日志文件头并没有提供这个VLF中有多少个日志块,所以需要另外的表示方法来确定当前读取的日志块是否属于当前的VLF。

逻辑日志文件(LLF)

VLF以逻辑日志文件LLF的形式放在日志中,LLF是用于表示一个VLF或存放在备份设备中的临时对象,下表显示了LLF与VLF的关系

日志文件 日志备份
VLF 11 LLF1
VLF 12 LLF2
VLF 13 LLF3
VLF 14 LLF4
VLF 9 LLF5
VLF 10 LLF6
  LLF7
  LLF8

日志备份存放了原来的VLF1-VLF8,其实一个LLF就是一个VLF,他们的结构是相同的,只不过LLF会存放在日志备份中,而VLF只存放在日志文件中

sql server日志文件总结及日志满的处理办法[转]

交易日志(Transaction logs)是数据库结构中非常重要但又经常被忽略的部分。由于它并不像数据库中的schema那样活跃,因此很少有人关注交易日志。   交易日志是针对数据库改变所做的记录,...
  • cosio
  • cosio
  • 2006年08月08日 11:30
  • 836

SQL Server 安装日志文件路径及日志组成解释

Summary.txt Log File Location: %programfiles%\Microsoft SQL Server\100\Setup Bootstrap\Log\ (%prog...
  • jzt_designer
  • jzt_designer
  • 2012年10月13日 15:18
  • 845

SQL SERVER 2000 日志文件清理

查看方式执行SQL语句:DBCC log ( {dbiddbname}, [, type={01234}] )参数:Dbid or dbname - 任一数据库的ID或名字,一般都是用数据库名字了,比...
  • KitChan
  • KitChan
  • 2011年07月17日 16:48
  • 1851

sql server 2000收缩数据库【极简操作】

个人理解,数据库在平凡长期操作的过程中会数据的日志文件永远是按一定的比例在增加,数据文件在数据库删除大量的数据后不一定减小磁盘空间,反复操作会出现空间浪费,所以收缩数据库将会得以体现。 假设把数据库...
  • w200221626
  • w200221626
  • 2016年07月25日 15:26
  • 2653

记一次处理日志文件过大问题的解决过程(SQL Server)

问题描述: SQL2008R2的一个DB, 兼容等级=100, 恢复模式=full, 数据量约30GB. 之前一直正常运行, 最近日志文件暴涨(日志文件66G),  日志备份作业执行很久没完成, 手工...
  • ap0405140
  • ap0405140
  • 2015年12月09日 10:52
  • 1131

SQL日志文件查看工具(Log Explorer for SQL Server v4.0.2)

  • 2011年09月21日 10:41
  • 3.76MB
  • 下载

限制SQL Server2000日志文件大小

如果您没有存储空间的瓶颈,让数据库库日志文件任意增长是最好的,因为在发生数据库错误是,日志文件可以帮助您查找和分析错误的原因。如果您确实要限制日志文件的增长,这里提供了多种方法供您参考,必须提醒的是,...
  • lwj3025
  • lwj3025
  • 2007年05月11日 14:02
  • 1719

通过查看日志文件检查SQL Server2000的安装错误

安装过SQL Server2000的同学都深有感触,在安装的过程免不了出现这样或那样的错误。其实安装错误是可以通过查看日志文件检查错误的,下面介绍一下这种方法查看安装错误。要说通过查看日志文件检查错误...
  • huanjileaimeidan
  • huanjileaimeidan
  • 2012年08月01日 17:12
  • 4275

SQL Server 2000 数据结构剖析(1): 日志文件结构

SQL Server 2000是一个可以自增长的可复写的循环文件,最小增长大小为248K(256K-8K),而一个数据库的多个日志文件,是被轮流选择写入日志的,也就是同时循环使用,所以日志文件如果要增...
  • kedingboy12345
  • kedingboy12345
  • 2011年03月27日 20:23
  • 2054

SQL Server 存储(1/8):理解数据页结构

我们都很清楚SQL Server用8KB 的页来存储数据,并且在SQL Server里磁盘 I/O 操作在页级执行。也就是说,SQL Server 读取或写入所有数据页。页有不同的类型,像数据页,GA...
  • yangmeng518889
  • yangmeng518889
  • 2016年12月28日 17:30
  • 564
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:SQL Server 2000 数据结构剖析(1): 日志文件结构
举报原因:
原因补充:

(最多只允许输入30个字)