1.数据块的结构
块头:
行指针(32bit的数字)
行指针中表示行内容的偏移量是15bit,能表示的最大偏移量是 215=32768,因此在PostgreSQL中,块的最大大小是32768,即32KB。
2.tuple(行)的结构
·natts&infomask2:字段数,其中低11位表示这行有多少个列。其 他的位则是HOT(Heap Only Touples)技术及行可见性的标志位。
·infomask:用于标识行当前的状态,比如行是否具有OID,是否有空属性,共有16位,每位都代表不同的含义。
·hoff:表示行头的长度。
·bits:是一个数组,用于标识该行上哪些字段(列)为空。
行上的xmin、xmax、cmin、cmax和CLOG日志 一起用于控制行的可见性。
每个事务在clog中占2个bit。几年可能有上亿甚至二十亿事务,clog可能占用512M,在如此大clog中查事务状态效率太低。所以pg把一些可见性的信息记录在infomask字段上,该字段的t_infomask中有以下标志位:
·#define HEAP_XMIN_COMMITTED 0x0100 /* t_xmin committed*/。
·#define HEAP_XMIN_INVALID 0x0200 /* t_xmin invalid/aborted*/。
·#define HEAP_XMAX_COMMITTED 0x0400 /* t_xmax committed*/。
·#define HEAP_XMAX_INVALID 0x0800 /* t_xmax invalid/aborted*/。
·#define HEAP_XMAX_IS_MULTI 0x1000 /* t_xmax is a MultiXactId*/。
如果t_infomask中HEAP_XMIN_COMMITTED为真,而 HEAP_XMAX_INVALID为假,则说明该行是新插入的行,是可见的, 此时就不需要到CLOG中查询xmin和xmax的事务状态了。
如果未设置HEAP_XMIN_COMMITTED,并不表示该行没有提 交,而是说不知道xmin是否提交了,需要到CLOG中去判断xmin的状 态。HEAP_XMAX_COMMITTED也是如此。
第一次插入数据时,t_infomask中的HEAP_XMIN_COMMITTED和 HEAP_XMAX_INVALID并未设置,但当事务提交后,有用户再读取这 个数据块时会通过CLOG判断出这些行的事务已提交,会设置 t_infomask中的HEAP_XMIN_COMMITTED和HEAP_XMAX_INVALID 标志位。下次再查询该行时,直接使用t_infomask中的 HEAP_XMIN_COMMITTED和HEAP_XMAX_INVALID标志位就可以判 断出行的可见性了,不再需要到CLOG中查询事务的状态。