页面是数据库的存储管理的基本单位,也是和磁盘交互的最小单位。页面在数据库中有承上启下的作用,页面支撑着数据库的各种管理功能,包括表管理、索引管理、集群管理以及缓冲区管理等。在页面上也保存着数据库中最重要的信息——用户数据,所以页面的管理非常重要,今天接着讨论Oracle页面管理更详细的内容,主要包括页公共头、事务层、表目录、项目录以及数据区域。
PageCommonHeader
Oracle数据库的页公共头是所有的页面都有的一个结构,其大小为20个字节,内容主要包括:
页面的类型,占用1Byte:表页面、索引页面、回滚段页面或者临时表页面等
页面的版本信息,占用1Byte:目前数据页面是A2
保留空间,占用2Byte,一般都被填充成0x
数据页面的物理地址,占用4Byte,也被称为RDBA信息(RelativeDataBlockAddress):包括文件号和文件内的偏移等
SCN(systemchangenumber)Base信息,占用4个字节
SCNWrap信息,占用2字节
SEQ(Sequencenumber)信息,占用1Byte
FLG(Flags)信息,占用1Byte
校验信息,占用2个字节:保存页面校验值,用于检查页面的完整性,如果是0x表示没打开校验功能,只有将DB_BLOCK_CHECKSUM设置为TRUE时才会进行校验。
保留空间,占用2Byte,一般都被填充成0x
TransactionLayer
Oracle数据库页面的事务层主要包括两个部分的信息。
固定部分:
1、页面类型,占用1Byte,0x01表示数据页面
2、对象编号,占用4Byte,这个数值在前面的ROWID中可以找到
3、页面最后一次刷出的时间,简称为:CSC(CleanoutSCN),占用4Byte。
4、ITL(InterestedTransactionList)项数目,简称为:ITC(InterestedTransactionCount),占用1Byte
5、BDBA(Blockrelativedatablockaddress)信息,占用4Byte
除此之外,还有下面信息,但这几个信息的值都是0,再没有仔细确认他们都保存的位置:
a.标志信息,如果页面在空闲列表中,此标志将被标记成大写字母O
b.空闲空间锁,简称为:FSL(FreeSpaceLock)
c.下一个空闲页面指针,简称为:FNX(FreeNeXtblock)
变化部分:主要是ITLs信息
默认情况下只包含表数据的页面只有一个ITL,但对于包含索引数据的页面,会有两个ITL信息。
在创建索引和表时,通过INITRANS子句可以修改默认的ITL的数量,对于并发要求高的应用,最好将此值设置的大一点。ITL的数量的取值范围是1~,设置的越大,事务层占用的空间就越多,页面能保存的数据就越少,但并发性越好。建议不要走两个极端,设置的符合真实的应用即可,用4、8、16几个值。
每一个ITL大小为24字节,但这个结构大小与不同的版本相关,我参考的是Oracle12C文档中的值。
ITL结构体主要包括下面信息:
1、事务号,简称为:XID(TransactionID),占用8Byte
2、回滚页面地址,简称为:UBA(UndoBlockAddress),占用8Byte
3、事务状态标识,占用1Byte
4、事务在当前页面持有的锁总数,占用1Byte
5、一个SCN或者一个FSC(FreeSpaceCredit),占用6Byte
Tabledirectory
因为Oracle有些页面上会保存多个表的数据,主要是使用了聚集的情况下同一个页面会保存多个表数据。下面是表目录的详细内容:
1、表目录个数,占用1Byte
2、表数据在项目录上的索引偏移,简称为:PTI(PositionTableIndicates),每个表项占用2Byte,第一个表一般都是0x。
需要注意的是,表目录个数和表目录这两部分内容并没有保存在一起,这个相关的内容,下次会继续说明。
RowDirectory
项目录是一个复杂的结构体,其中记录了数据行和页面空间相关的重要信息,具体如下:
1、页面上的数据项个数,简称为:NROW,占用2Byte
2、第一个空闲项的位置,简称为:FRRE(FirstfReeRowEntry),如果没有就用0xFFFF填充。
3、空闲空间起始位置,简称为:FSBO(FreeSpaceBeginOffset),占用2Byte。
4、空闲空间结束位置,简称为:FSEO(FreeSpaceEndOffset),占用2Byte。
5、页面可用空间大小,简称为:AVSP(AVailableSPace),占用2Byte
6、页面总的空间,简称为:TOSP(TOtalSPace),占用2Byte
7、项目录数,后面的有效的项目录个数,占用2Byte。
8、每一行起始位置在页面上的偏移,简称为:PRI(PositionRowIndicates),项目录中的每一项占用2Byte。
旧的版本中,项目录中除了保存项的偏移之外,还保存了项的一些简单状态信息,例如:删除项,链接项,迁移项等状态信息。后来支持的页面大小有所扩展,目前已经将这些信息都保存到了行数据头上。
RowData
行数据部分主要包含这个页面上的用户数据,每一行是一块连续的空间,前几个是行头信息,其后紧跟行的所有数据。
行数据上面保存的内容主要有:行状态标识、行上的锁类型、列偏移数组、聚集键的位置和所有的列数据。以后介绍行结构的时候会涉及到这部分内容,到时候再详细的介绍。
Tail
每个页面的最后四个字节用于检查页面块是否是同一次写入磁盘的页面,以避免写磁盘到一半的时候突然断电引起的页面不一致的情况。
Oracle的页面结构先介绍这么多,下一次会实际的演示一下,如何看Oracle的页面结构。
参考资料: