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只存放在日志文件中

相关文章推荐

导致日志截断延迟的因素(sys.databases 目录视图的 log_reuse_wait 列和 log_reuse_wait_desc 列)

转载:http://technet.microsoft.com/zh-cn/library/ms345414%28zh-tw,SQL.90%29.aspx 日志截断可释放日志文件中的空间,以...

新一代Hive客户端工具:Beeline

Hive客户端工具后续将使用Beeline 替代HiveCLI ,并且后续版本也会废弃掉HiveCLI 客户端工具。 Beeline是Hive新的命令行客户端工具。Beeline是从 Hive 0.1...

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

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

sql server 2000 日志文件丢失,附加数据库失败的解决办法

/* 我在中国万网的虚拟主机在9月份停掉了,当时没有备份数据库,数据库是sqlserver2000的。这两天,几经周折后,万网给我提供了一个数据库文件。 但是,没有日志文件。这让我在附加数据库时出...
  • gzyes
  • gzyes
  • 2011年10月29日 23:07
  • 2463

SQL SERVER 2000 日志文件清理

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

SQL Server 更改数据/日志文件位置

由于建数据库的时候没有考虑周全,放在了C盘上,导致C盘满了。现在的任务就是将SQLServer的数据文件移动到其他盘去。 1、记录原Logical Name和原来数据库文件位置。 对着数据...

SQL Server管理页和区的数据结构(对设计和开发高效执行的数据库有帮助)

1、全局分配映射表 (GAM) GAM 页记录已分配的区。每个 GAM 包含 64,000 个区,相当于近 4 GB 的数据。GAM 用一个位来表示所涵盖区间内的每个区的状态。如果位为 1,则区可...

sql server数据库 日志文件过大的清理

sql server数据库使用时间长了,日志文件会很大,占用过多系统资源,数据库可能会报 log full 的错误,甚至磁盘空间占满让数据库处于不可用状态,这个时候我们需要清理数据库,以前有人开发了数...
  • educast
  • educast
  • 2012年09月03日 09:52
  • 726

SQL Server 2005无日志文件附加数据库

公司网站运营两年多了,日志文件超级大,在重装系统的时候,为了省事,就没有备份日志文件,而且是没有分离就把日志文件给删掉了(下次一定要记得先分离再删日志文件)。结果造成数据库怎么都附加不上。出现错误。 ...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:SQL Server 2000 数据结构剖析(1): 日志文件结构
举报原因:
原因补充:

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