SQLSERVER事务日志的LSN到底是什么?
一:背景1。讲故事
大家都知道数据库应用程序它天生需要围绕着数据文件打转,诸如包含数据的。mdf,事务日志的。ldf,很多时候深入了解这两类文件的合成原理,差不多对数据库就能理解一半了,关于。mdf的合成前面的文章已经有所介绍,这篇我们来聊一下。ldf的一些内部知识,比如LSN。二:对LSN的理解1。什么是LSN
如果大家玩过SQLSERVER的发布订阅或者AlwaysOn或多或少都见过LSN,比如下面的格式:00000030:00018090:0002,这一串编号到底是什么意思呢?本质上指示的是。ldf文件的某一个物理位置上的偏移,画个图大概如下:
从图中可以看到其实是由虚拟文件号:日志段起始扇区编号:槽号编号三部分组成,要了解这三部分就需要明白。ldf文件是如何进行逻辑划分的,画个简图如下:
通过上面的图很容易就能明白其中的逻辑关系,事务日志文件被划分成了多个虚拟文件,虚拟文件又划分成了多个日志段,日志段又划分成了多个扇区,日志段中日志记录位置存储在槽号中,有了这些理论基础,接下来用一个案例来加深大家的理解吧。2。一个案例演示
新建一个MyLSN数据库,再创建一个test表,插入3w条记录,sql如下:CREATEDATABASEMyLSNGOUSEMyLSNGOCREATETABLEtest(aINTIDENTITY,bCHAR(10)DEFAULTaaaaaaaaaa)SETNOCOUNTONINSERTINTOtest(b)DEFAULTVALUESGO30000SETNOCOUNTOFF
接下来通过fndblog来查询和dbo。test表相关的事务日志记录。SELECT〔CurrentLSN〕,Operation,Context,AllocUnitName,〔RowLogContents0〕,〔LogRecord〕,〔LogRecordLength〕FROMfndblog(NULL,NULL)WHEREAllocUnitNameLIKEtest;
从图中可以看到这是一个INSERT的事务日志记录,这里就拿编号00000030:00000db0:0002去定位。ldf中的物理偏移位置吧,要想获取物理偏移就要知道下面偏移值才可以。0x30虚拟文件号的偏移值是多少?
要想知道这个信息,可以用DBCCloginfo命令,查看FSeqNo下的StartOffset偏移值即可,即0n48对应的4071424,截图如下:
0xdb0扇区号的偏移是多少?
大家都知道磁盘的扇区是512byte,sqlserver为了更好的写入磁盘,也用了512byte这个粒度,所以偏移值就是5120xdb0。
综合上面就能定位到日志段的物理偏移值为:lkd?0n4071424(0n35040n512)Evaluateexpression:58654720000000000598000
接下来用WinHex来定位MyLSNlog。ldf文件偏移00598000的位置,定位之前先将数据库离线。ALTERDATABASEMyLSNSETOFFLINE
前面的0x0003表示该日志段只有3条记录,后面的0x019E表示该日志段的大小为414byte,接下来就是槽号了,槽号位置的物理偏移计算规则如下:lkd?00598000019E1Evaluateexpression:5865885000000000059819d
从图中可以看到,slot2的偏移值为00C8,即物理偏移值为005980c8。lkd?0059800000C8Evaluateexpression:586567200000000005980c8
从上面框出的内容可以轻松的看到,事务日志中记录了Insert的aaaaaaaaaa值,太棒了,起始就是fndblog查出来的LogRecord值。
三:总结
对LSN有一个深度的理解,对各种数据库事务日志暴涨的故障分析都会有一个很好的理论基础,后面我们再聊这些话题。