您好,欢迎访问三七文档
当前位置:首页 > 机械/制造/汽车 > 第11章多版本数据原理
第11章多版本数据原理除了readuncommitted隔离级别,在SQLServer2000版本的其他隔离级别都会发生读写操作相互等待的情况,使数据库运行效率大幅降低。为了解决这种问题,从SQLServer2005版本开始,引入了多版本数据技术,在一个事务中修改表中的数据时(主要指对表执行update或delete操作),会把旧版本的数据临时存入tempdb数据库,此事务结束之前,其他连接的读操作可以由tempdb数据库读取这些临时数据,而不是从原数据库读取,从而使得读写操作不再相互等待。本章内容主要包括:数据库开启read_committed_snapshot参数后产生的多版本数据数据库开启allow_snapshot_isolation参数后产生的多版本数据11.1开启read_committed_snapshot参数后产生的多版本数据开启read_committed_snapshot参数后,新添加到表中的记录都会在行数据最后附加14字节的版本信息数据,用于指向记录更新后产生的旧版本数据,这些旧版本数据存储于tempdb数据库,开启read_committed_snapshot参数之前已存在的记录会在其被执行update操作时附加14字节的版本信息。11.1.1参数开启前后行数据存储方式的变化创建测试数据库testRowVersion,并在其中创建测试表t,数据库的read_committed_snapshot参数默认未开启。1createdatabasetestRowVersion2go在testRowVersion数据库中创建测试表t,并添加一行测试记录。1usetestRowVersion2createtablet(aintidentity,bchar(5)default'xxxxx')3go在数据库的read_committed_snapshot参数开启前后,对t表各添加一行记录。1insertintotdefaultvalues2alterdatabasetestRowVersionsetread_committed_snapshoton3insertintotdefaultvalues4go为了查看t表的两行记录在数据页中的存储形式,先查看表t分配到的数据页。1dbccind(testRowVersion,t,-1)2goPageFIDPagePIDIAMFIDIAMPIDObjectIDIndexID---------------------------------------------------------177NULLNULL2105058535015517721050585350先使用参数2执行dbccpage命令,导出55号数据页内容,以下导出内容中的粗体部分即是表t的两行记录对应的十六进制数据。1dbcctraceon(3604)2dbccpage(testRowVersion,1,55,2)3go……3C16C050:00000000000000000000000000000000?................3C16C060:10000d00010000007878787878020000?........xxxxx...3C16C070:50000d00020000007878787878020000?P.......xxxxx...3C16C080:00000000000000005101000000000000?........Q.......……3C16DFF0:e00f2e010e01e4000010b80070006000?............p.`.OFFSETTABLE:Row-Offset1(0x1)-112(0x70)0(0x0)-96(0x60)再使用参数3执行dbccpage命令导出55号数据页内容,可以更清楚地看出两行记录的差别。1dbccpage(testRowVersion,1,55,3)2go……Slot0Offset0x60Length16RecordType=PRIMARY_RECORDRecordAttributes=NULL_BITMAPRecordSize=16MemoryDump@0x3D4EC06000000000:10000d00010000007878787878020000?........xxxxx...Slot0Column1Offset0x4Length4Length(physical)4a=1Slot0Column2Offset0x8Length5Length(physical)5b=xxxxxSlot1Offset0x70Length30RecordType=PRIMARY_RECORDRecordAttributes=NULL_BITMAPVERSIONING_INFORecordSize=30MemoryDump@0x3D4EC07000000000:50000d00020000007878787878020000?P.......xxxxx...00000010:0000000000000000510100000000??????........Q.....VersionInformation=TransactionTimestamp:337VersionPointer:NullSlot1Column1Offset0x4Length4Length(physical)4a=2Slot1Column2Offset0x8Length5Length(physical)5b=xxxxx由以上导出数据可以看出两行记录存储方式的差异:第1行记录的行头数据第1个字节为0x10,其二进制数据为:00010000。第2行记录的行头数据第1个字节为0x50,其二进制数据为:01010000。第2行记录附加了14字节的版本信息。版本信息前8个字节表示对应的旧版本数据在tempdb数据库中的RowID,后6个字节表示修改记录操作所在事务的序号。因为当前还未产生旧版本数据,前8个字节都为0。版本信息各部分的含义请参考11.1.2节内容。11.1.2update产生的旧版本数据及版本信息为了观察到update产生的版本信息数据,下面开始一个事务,并在其中更新t表的第1行记录。1begintran2updatetsetb='aaaaa'wherea=13go重新导出55号数据页,查看其第1行记录存储形式的变化。1dbccpage(testRowVersion,1,55,2)2go……3C16C050:00000000000000000000000000000000?................3C16C060:10000d00010000007878787878020000?........xxxxx...3C16C070:50000d00020000007878787878020000?P.......xxxxx...3C16C080:00000000000000005101000000005000?........Q.....P.3C16C090:0d00010000006161616161020000c000?......aaaaa.....3C16C0A0:00000100000087010000000000005f00?.............._.……3C16DFF0:e00f2e010e01e4000010b80070008e00?............p...OFFSETTABLE:Row-Offset1(0x1)-112(0x70)0(0x0)-142(0x8e)可以看到,更新后的记录数据被重新添加到数据页的空闲区域,同时修改了slot0的偏移量数值,即第1行记录的偏移量数据指向更新后的数据所存储的位置,而不是在原数据基础上修改。再使用参数3导出55号数据页,可以更清楚地看到第1行记录被更新后,其存储格式的变化。1dbccpage(testRowVersion,1,55,3)2go……Slot0Offset0x8eLength30RecordType=PRIMARY_RECORDRecordAttributes=NULL_BITMAPVERSIONING_INFORecordSize=30MemoryDump@0x3D4EC08E00000000:50000d00010000006161616161020000?P.......aaaaa...00000010:c000000001000000870100000000??????..............VersionInformation=TransactionTimestamp:391VersionPointer:(file1page192currentSlotId0)由上面导出数据的最后部分可以得知,旧版本数据在tempdb数据库的地址为(1:192:0)。14字节版本数据的前8个字节表示旧版本记录在tempdb数据库中的RowID,后面4个字节表示修改记录所在的事务的序号,其各部分含义可以分解如下。表11-1版本数据的各部分含义原十六进制数据转换前后顺序十进制数据长度表示意义c00000000xc01924B旧版本记录所在数据页01000x112B旧版本记录所在文件号00000x002B旧版本记录slot序号8701000000000x1873916B修改操作所在事务序号导出tempdb数据库的192号数据页,查看其中的旧版本数据。1dbccpage(tempdb,1,192,2)2go……3D64C050:00000000000000000000000000000000?................3D64C060:26010055000019763d702d5d01870100?&..U...v=p-]....3D64C070:00000000000100000000000000050000?................3D64C080:050000000000000d00000000010d0000?................3D64C090:00000000009419763dfe2c5d01000000?.......v=.,]....3D64C0A0:000000000010000d0001000000787878?.............xxx3D64C0B0:78780200000000000000000000000000?xx..............3D64C0C0:00000000000000000000000000000000?................……3D64DFF0:01000000a80f00004050100500006000?........@P....`.OFFSETTABLE:Row-Offset0(0x0)-96(0x60)可以发现,上面粗体部分是表t第1行记录在修改之前在(1:55)号数据页中存储的数据,从偏移量3D64C060至3D64C0A4为此旧版本数据的行头系统信息。也可以查询动态系统视图sys.dm_tran_version_store得到tempdb数据库中的当前多版本数据信息。1selecttransaction_sequence_num,database_id,record_image_first_part2fromsys.dm_tran_version_store3gotransaction_sequence_numdatabase_idrecord_image_first_part------------------------------------------------------------------------39150x10000D00010000007878787878020
本文标题:第11章多版本数据原理
链接地址:https://www.777doc.com/doc-2242223 .html