首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >邮政和表格内部组织

邮政和表格内部组织
EN

Stack Overflow用户
提问于 2020-01-22 14:13:10
回答 1查看 490关注 0票数 3

我找到了一个解释,解释了postgresql的内部工作原理。以下是一幅图片:

以及以下解释:

标题之后的

项是一个数组标识符,它由指向实际项的(偏移量、长度)对组成。

因为一个项目标识符在被释放之前是不会移动的,所以它的索引可以长期使用来引用一个项目,甚至当项目本身在页面上移动以压缩空闲空间时也是如此。指向项的指针称为CTID (ItemPointer),由PostgreSQL创建,它由一个页码和项目标识符的索引组成。

你能帮我把这几件事弄清楚吗?

我说得对吗?页面标题附近的项目是CTID本身或项,而CTID是不同的东西吗? rows?

  • Depending

  • 做CTID从来不移动,或者在答案上使用CTID,也许我会理解以下的确切含义:“因为一个项目标识符在被释放之前永远不会移动,它的索引可以长期地用于引用一个项,即使当项目本身在页面上移动以压缩空闲空间时。”然而,更详细的解释会更好。
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2020-01-22 16:34:10

在图片中被称为“项目”的是PostgreSQL术语中的“行指针”。它在src/include/storage/itemid.h中定义。

代码语言:javascript
运行
复制
/*
 * A line pointer on a buffer page.  See buffer page definitions and comments
 * for an explanation of how line pointers are used.
 *
 * In some cases a line pointer is "in use" but does not have any associated
 * storage on the page.  By convention, lp_len == 0 in every line pointer
 * that does not have storage, independently of its lp_flags state.
 */
typedef struct ItemIdData
{
    unsigned    lp_off:15,      /* offset to tuple (from start of page) */
                lp_flags:2,     /* state of line pointer, see below */
                lp_len:15;      /* byte length of tuple */
} ItemIdData;

typedef ItemIdData *ItemId;

这些行指针就存储在页面标题之后的数组中。

参见src/include/storage/bufpage.h中的优秀文档

代码语言:javascript
运行
复制
/*
 * A postgres disk page is an abstraction layered on top of a postgres
 * disk block (which is simply a unit of i/o, see block.h).
 *
 * specifically, while a disk block can be unformatted, a postgres
 * disk page is always a slotted page of the form:
 *
 * +----------------+---------------------------------+
 * | PageHeaderData | linp1 linp2 linp3 ...           |
 * +-----------+----+---------------------------------+
 * | ... linpN |                                      |
 * +-----------+--------------------------------------+
 * |           ^ pd_lower                             |
 * |                                                  |
 * |             v pd_upper                           |
 * +-------------+------------------------------------+
 * |             | tupleN ...                         |
 * +-------------+------------------+-----------------+
 * |       ... tuple3 tuple2 tuple1 | "special space" |
 * +--------------------------------+-----------------+
 *                                  ^ pd_special
 *
 * NOTES:
 *
 * linp1..N form an ItemId (line pointer) array.  ItemPointers point
 * to a physical block number and a logical offset (line pointer
 * number) within that block/page.  Note that OffsetNumbers
 * conventionally start at 1, not 0.
 *
 * tuple1..N are added "backwards" on the page.  Since an ItemPointer
 * offset is used to access an ItemId entry rather than an actual
 * byte-offset position, tuples can be physically shuffled on a page
 * whenever the need arises.  This indirection also keeps crash recovery
 * relatively simple, because the low-level details of page space
 * management can be controlled by standard buffer page code during
 * logging, and during recovery.

回答您的问题:

  1. 元组的ctid是物理地址,由块号(从0开始)和行指针(从1开始)组成。您可以从表行的ctid中识别行指针:这是第二个数字。例如,(321,5)将是第322页上的第5行指针。
  2. 块中实际元组的位置不是固定的:它存储在lp_off中。这允许PostgreSQL在块中移动数据,而不更改元组的物理地址(tid)。正如上面所解释的那样,实际的数据可以在块中移动,但是行指针不会改变。元组的ctid是存储在索引中的内容。语句现在应该清楚了。
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/59861645

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档