chinaab 发表于 2016-11-20 11:37:53

PostgreSQL的数据存储(八)---数据存储

4.2数据的内部格式
4.2.1 页的存储数据结构
  在操作系统层面,数据存储,只是一些二进制信息,这个层次,是不知道文件内容的含义的。文件的逻辑含义,取决于应用层面。
  数据库系统的文件组织,也如此。在外存存储,以二进制格式存放,读写文件,以块(8k)为单位,读入的数据,存放与数据缓冲区,所以,数据的逻辑含义,始于数据缓冲区。
  在bufpage.h文件中,有如下定义:
  typedef struct PageHeaderData
  {
  /* XXX LSN is member of *any* block, not only page-organized ones */
  XLogRecPtr pd_lsn; /* LSN: next byte after last byte of xlog
  * record for last change to this page */
  uint16 pd_tli;/* least significant bits of the TimeLineID
  * containing the LSN */
  uint16 pd_flags; /* flag bits, see below */
  LocationIndex pd_lower; /* offset to start of free space */
  LocationIndex pd_upper; /* offset to end of free space */
  LocationIndex pd_special; /* offset to start of special space */
  uint16 pd_pagesize_version;
  TransactionId pd_prune_xid; /* oldest prunable XID, or zero if none */
  ItemIdData pd_linp; /* beginning of line pointer array */
  } PageHeaderData;
  这个结构,描述了数据页的页头信息。一个数据页,是一个块大小,即8k。这个页的初始部分,完全由PageHeaderData这个结构定义。
  结构成员名称
  类型
  功能
  pd_lsn
  XLogRecPtr
  写到redo日志中的记录的结束位置的位置标识,用以把数据页和redo日志关联,用于恢复数据时校验日志文件和数据文件的一致性
  pd_tli
  uint16
  与redo日志相关,上一个记录了redo日志的文件id和偏移,本标志记载了redo日志的“timeline”时间线。在redo日志中,完整标识一个日志文件,是靠时间线和日志id;完整标识一个日志位置,是靠时间线和日志id和日志文件中的偏移值
  pd_flags
  uint16
  标识本页面的数据存储情况,是半满页、满页、、还是有冗余数据(数据对于一些用户是否可见,与事务相关,与PG实现的MVCC相关)
  pd_lower
  LocationIndex
  指向空闲空间的开始位置
  pd_upper
  LocationIndex
  指向空闲空间的结束位置
  pd_special
  LocationIndex
  指向页面尾部的一个特殊块的位置处,通过PageInit函数可以了解不同调用函数通常有不同的特殊块存在。如gin索引对应的页面、hash页面、BTree索引页面都有特殊的块标识特别的信息
  pd_pagesize_version
  uint16
  标识数据页的页面版本,不同PG的版本,数据页格式可能发生变化,用以标识变化的。这样,就存在根据页面版本号读取不同信息的可能
  pd_prune_xid
  TransactionId
  记载本页面上最老的事务ID值,在做vacuum操作时使用
  pd_linp
  ItemIdData
  指向页面上存在的tuple(记录)的指针
  相关代码:
  src/include/storage/itemid.h
页: [1]
查看完整版本: PostgreSQL的数据存储(八)---数据存储