首页 > 解决方案 > postgresql对pageinspect b-tree函数结果的解释在哪里?

问题描述

我正在使用 postgresql页面检查器,我想知道,在哪里可以找到有关其函数输出的更详细文档(输入也很好)。我只对 b-tree 函数感兴趣。

例如,文档说:

bt_page_stats 返回有关单页 B 树索引的摘要信息。例如:

 test=# SELECT * FROM bt_page_stats('pg_cast_oid_index', 1);
-[ RECORD 1 ]-+-----
blkno         | 1
type          | l
live_items    | 224
dead_items    | 0
avg_item_size | 16
page_size     | 8192
free_size     | 3668
btpo_prev     | 0
btpo_next     | 0
btpo_level    | 0
btpo_flags    | 3

在这里,我想知道这些结果的实际含义——什么是类型、dead_items 等等。我在哪里可以找到它?

标签: postgresql

解决方案


要了解这些值,您必须了解 B 树索引的树结构。

从某种程度的细节来看,ocumentation 在源中,在本例中为src/include/access/nbtree.h

/*
 *  BTPageOpaqueData -- At the end of every page, we store a pointer
 *  to both siblings in the tree.  This is used to do forward/backward
 *  index scans.  The next-page link is also critical for recovery when
 *  a search has navigated to the wrong page due to concurrent page splits
 *  or deletions; see src/backend/access/nbtree/README for more info.
 *
 *  In addition, we store the page's btree level (counting upwards from
 *  zero at a leaf page) as well as some flag bits indicating the page type
 *  and status.  If the page is deleted, a BTDeletedPageData struct is stored
 *  in the page's tuple area, while a standard BTPageOpaqueData struct is
 *  stored in the page special area.
 *
 *  We also store a "vacuum cycle ID".  When a page is split while VACUUM is
 *  processing the index, a nonzero value associated with the VACUUM run is
 *  stored into both halves of the split page.  (If VACUUM is not running,
 *  both pages receive zero cycleids.)  This allows VACUUM to detect whether
 *  a page was split since it started, with a small probability of false match
 *  if the page was last split some exact multiple of MAX_BT_CYCLE_ID VACUUMs
 *  ago.  Also, during a split, the BTP_SPLIT_END flag is cleared in the left
 *  (original) page, and set in the right page, but only if the next page
 *  to its right has a different cycleid.
 *
 *  NOTE: the BTP_LEAF flag bit is redundant since level==0 could be tested
 *  instead.
 *
 *  NOTE: the btpo_level field used to be a union type in order to allow
 *  deleted pages to store a 32-bit safexid in the same field.  We now store
 *  64-bit/full safexid values using BTDeletedPageData instead.
 */

typedef struct BTPageOpaqueData
{
    BlockNumber btpo_prev;      /* left sibling, or P_NONE if leftmost */
    BlockNumber btpo_next;      /* right sibling, or P_NONE if rightmost */
    uint32      btpo_level;     /* tree level --- zero for leaf pages */
    uint16      btpo_flags;     /* flag bits, see below */
    BTCycleId   btpo_cycleid;   /* vacuum cycle ID of latest split */
} BTPageOpaqueData;

其他值是:

  • blkno: 8kB 块编号
  • type:页面的类型(l对于“叶子”,i对于“内部”,r对于“根”,e对于“忽略”,d对于“已删除叶子”,D对于“已删除内部”)
  • live_items: 实时索引条目的数量
  • dead_items: 被杀死的索引条目数
  • avg_item_size: 索引元组的平均大小
  • page_size: 页面大小(总是 8kB)
  • free_size: 页面中的可用空间

推荐阅读