透过pageinspect了解PostgreSQl中的page

透过pageinspect了解PostgreSQl中的page,第1张

概述        博客 PostgreSQL的Page分析记录 有过对page的 大体介绍,可以参看之前的blog,下面主要通过插件 pageinspect 向大家进行介绍。         在此之前需要了解的名词:         page,物理文件的单位,默认大小为8K。         tuple,PG中物理行。         xid,事务号,执行 *** 作时的顺序id。         page 博客 PostgreSQL的Page分析记录 有过对page的 大体介绍,可以参看之前的blog,下面主要通过插件 pageinspect 向大家进行介绍。

在此之前需要了解的名词:
page,物理文件的单位,默认大小为8K。
tuple,PG中物理行。
xID,事务号,执行 *** 作时的顺序ID。

pageinspect里边有三个函数是本文用到的,他们分别是:
a.get_raw_page,根据参数表明、数据文件类型(main、fsm、vm)以及page位置,将当前表文件中的page内容返回。还有一个函数于此同名,只有两个参数,是将第二个参数省略,直接使用'main'。
b.page_header,参数是函数get_raw_page的返回值,返回值是将本page结构中的PageheaderData详细信息
c.heap_page_items,参数是函数get_raw_page的返回值,返回值是将page内的项指针(ItemIDdata)以及HeapTupleheaderData的详细信息。

下面通过例子来对page的PageheaderDataItemIDdata和HeapTupleheaderData进行说明
a.建表mvcc

[postgres@localhost bin]$ ./psql psql (9.4.5)Type "help" for help.postgres=# create table mvcc(ID int);CREATE tablepostgres=# insert into mvcc values (1),(2);INSERT 0 2

b.PageheaderData

postgres=# select * from page_header(get_raw_page('mvcc','main',0));    lsn    | checksum | flags | lower | upper | special | pagesize | version | prune_xID -----------+----------+-------+-------+-------+---------+----------+---------+----------- 0/300F4D8 |        0 |     0 |    32 |  8128 |    8192 |     8192 |       4 |         0(1 row)
这是表mvcc的PageheaderData信息,现在比对源码对各个字段进行解释:
typedef struct PageheaderData{	/* XXX LSN is member of *any* block,not only page-organized ones */	PageXLogRecPtr pd_lsn;		/* LSN: next byte after last byte of xlog								 * record for last change to this page */	uint16		pd_checksum;	/* checksum */	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[1];		/* beginning of line pointer array */} PageheaderData;
pg_lsn:记录最后一次对page修改的xlog记录ID。
pg_checksum:页面的校验和,主要是通过函数pg_checksum_block函数生成的,0也是有效地,参数为PageheaderData和BLCKSZ(page's size)。当校验和验证失败,即认为当前页面无效。
pg_flags:page的flags,具体值为,可以叠加:
#define PD_HAS_FREE_lines	0x0001		/* are there any unused line pointers? */#define PD_PAGE_FulL		0x0002		/* not enough free space for new										 * tuple? */#define PD_ALL_VISIBLE		0x0004		/* all tuples on page are visible to										 * everyone */#define PD_VALID_FLAG_BITS	0x0007		/* OR of all valID pd_flags bits */
pg_lower和pg_upper:最后一个项指针的位置和最新的tuple位置。主要进行查找空闲位置,进行插入工作。
pg_special:page预留的位置,可以存储索引等信息。
pg_pagesize_version:page大小以及当前版本。page大小可以通过configure进行设置。version的意思是
/* * Page layout version number 0 is for pre-7.3 Postgres releases. * Releases 7.3 and 7.4 use 1,denoting a new HeapTupleheader layout. * Release 8.0 uses 2; it changed the HeapTupleheader layout again. * Release 8.1 uses 3; it redefined HeapTupleheader infomask bits. * Release 8.3 uses 4; it changed the HeapTupleheader layout again,and *		added the pd_flags fIEld (by stealing some bits from pd_tli),*		as well as adding the pd_prune_xID fIEld (which enlarges the header). * * As of Release 9.3,the checksum version must also be consIDered when * handling pages. */
pg_prune_xID:一般是最后一次删除或者更新的xID。

pg_linp:项指针。
c.ItemIDdata

postgres=# select lp,lp_off,lp_flags,lp_len from heap_page_items(get_raw_page('mvcc',0)); lp | lp_off | lp_flags | lp_len ----+--------+----------+--------  1 |   8160 |        1 |     28  2 |   8128 |        1 |     28(2 rows)
这是表mvcc的项指针的信息,一样通过结合源码进行介绍:
typedef struct ItemIDData{	unsigned	lp_off:15,/* offset to tuple (from start of page) */				lp_flags:2,/* state of item pointer,see below */				lp_len:15;		/* byte length of tuple */} ItemIDData;
lp:这是插件自己定义的列,在源码中其实没有,这个是项指针的顺序。
lp_off:tuple在page中的位置。
lp_flags:tuple的flags,具体为
#define LP_UNUSED		0		/* unused (should always have lp_len=0) */#define LP_norMAL		1		/* used (should always have lp_len>0) */#define LP_REDIRECT		2		/* HOT redirect (should have lp_len=0) */#define LP_DEAD			3		/* dead,may or may not have storage */
lp_len: HeapTupleheaderData 的长度+OID的长度(8,因为要数据对齐,所以在这里会比原来预计的多4)。

d.HeapTupleheaderData

postgres=# select * from heap_page_items(get_raw_page('mvcc',0)); lp | lp_off | lp_flags | lp_len | t_xmin | t_xmax | t_fIEld3 | t_ctID | t_infomask2 | t_infomask | t_hoff | t_bits | t_oID ----+--------+----------+--------+--------+--------+----------+--------+-------------+------------+--------+--------+-------  1 |   8160 |        1 |     28 |   1831 |      0 |        0 | (0,1)  |           1 |       2048 |     24 |        |        2 |   8128 |        1 |     28 |   1831 |      0 |        0 | (0,2)  |           1 |       2048 |     24 |        |      (2 rows)
同样结合源码进行介绍:
typedef struct HeapTupleFIElds{	TransactionID t_xmin;		/* inserting xact ID */	TransactionID t_xmax;		/* deleting or locking xact ID */	union	{		CommandID	t_cID;		/* inserting or deleting command ID,or both */		TransactionID t_xvac;	/* old-style VACUUM FulL xact ID */	}			t_fIEld3;} HeapTupleFIElds;typedef struct DatumTupleFIElds{ int32		datum_len_;		/* varlena header (do not touch directly!) */ int32		datum_typmod;	/* -1,or IDentifIEr of a record type */ OID			datum_typeID;	/* composite type OID,or RECORDOID */ /* * Note: fIEld ordering is chosen with thought that OID might someday * wIDen to 64 bits. */} DatumTupleFIElds;struct HeapTupleheaderData{	union	{		HeapTupleFIElds t_heap;		DatumTupleFIElds t_datum;	}			t_choice;	ItemPointerData t_ctID;		/* current TID of this or newer tuple */	/* FIElds below here must match MinimalTupleData! */	uint16		t_infomask2;	/* number of attributes + varIoUs flags */	uint16		t_infomask;		/* varIoUs flag bits,see below */	uint8		t_hoff;			/* sizeof header incl. bitmap,padding */	/* ^ - 23 bytes - ^ */	bits8		t_bits[1];		/* bitmap of NulLs -- VARIABLE LENGTH */	/* MORE DATA FolLOWS AT END OF STRUCT */};
xmin和xmax是插入、删除和更新时的事务ID,插入时会在xmin内写入当前事务ID,当删除时就会在xmax写入当前事务ID。更新是进行删除后再插入。
t_cID:这个是指一个事务内的命令ID,每个事务都是从0开始。
t_ctID:这个是指物理ID,结构如下:
typedef struct ItemPointerData{	BlockIDData ip_blkID;	OffsetNumber ip_posID;}typedef struct BlockIDData{	uint16		bi_hi;	uint16		bi_lo;} BlockIDData;
存储的为bi_hi(文件号) << 16 | bi_lo(page号),来获取磁盘顺序,ip_posID是在page的中序号。以此来准确定位数据。
t_infomask2:表字段的个数以及一些flags,flags如下:
#define HEAP_NATTS_MASK			0x07FF	/* 11 bits for number of attributes *//* bits 0x1800 are available */#define HEAP_KEYS_UPDATED		0x2000	/* tuple was updated and key cols										 * modifIEd,or tuple deleted */#define HEAP_HOT_UPDATED		0x4000	/* tuple was HOT-updated */#define HEAP_ONLY_TUPLE			0x8000	/* this is heap-only tuple */#define HEAP2_XACT_MASK			0xE000	/* visibility-related bits */
t_infomask:tuple的flags,如下:
#define HEAP_HASNulL			0x0001	/* has null attribute(s) */#define HEAP_HASVARWIDTH		0x0002	/* has variable-wIDth attribute(s) */#define HEAP_HASEXTERNAL		0x0004	/* has external stored attribute(s) */#define HEAP_HASOID				0x0008	/* has an object-ID fIEld */#define HEAP_XMAX_KEYSHR_LOCK	0x0010	/* xmax is a key-shared locker */#define HEAP_COMBOCID			0x0020	/* t_cID is a combo cID */#define HEAP_XMAX_EXCL_LOCK		0x0040	/* xmax is exclusive locker */#define HEAP_XMAX_LOCK_ONLY		0x0080	/* xmax,if valID,is only a locker */ /* xmax is a shared locker */#define HEAP_XMAX_SHR_LOCK	(HEAP_XMAX_EXCL_LOCK | HEAP_XMAX_KEYSHR_LOCK)#define HEAP_LOCK_MASK	(HEAP_XMAX_SHR_LOCK | HEAP_XMAX_EXCL_LOCK | \						 HEAP_XMAX_KEYSHR_LOCK)#define HEAP_XMIN_COMMITTED		0x0100	/* t_xmin committed */#define HEAP_XMIN_INVALID		0x0200	/* t_xmin invalID/aborted */#define HEAP_XMIN_FROZen		(HEAP_XMIN_COMMITTED|HEAP_XMIN_INVALID)#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 */#define HEAP_UPDATED			0x2000	/* this is UPDATEd version of row */#define HEAP_MOVED_OFF			0x4000	/* moved to another place by pre-9.0
t_hoff: HeapTupleheaderData长度,如果有OID会增加4,但由于受到对齐的影响,会增加8。
t_bits:具体数据,可以参照 PostgreSQL的基础数据类型分析记录。 总结

以上是内存溢出为你收集整理的透过pageinspect了解PostgreSQl中的page全部内容,希望文章能够帮你解决透过pageinspect了解PostgreSQl中的page所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/sjk/1174899.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-02
下一篇 2022-06-02

发表评论

登录后才能评论

评论列表(0条)

保存