Home Explore Blog CI



postgresql

13th chunk of `doc/src/sgml/storage.sgml`
1de9e8ed97217d1a77efc1665d6129e83cb2b5c9deab3f8c0000000100000fa6
 <entry>2 bytes</entry>
   <entry>Offset to end of free space</entry>
  </row>
  <row>
   <entry>pd_special</entry>
   <entry>LocationIndex</entry>
   <entry>2 bytes</entry>
   <entry>Offset to start of special space</entry>
  </row>
  <row>
   <entry>pd_pagesize_version</entry>
   <entry>uint16</entry>
   <entry>2 bytes</entry>
   <entry>Page size and layout version number information</entry>
  </row>
  <row>
   <entry>pd_prune_xid</entry>
   <entry>TransactionId</entry>
   <entry>4 bytes</entry>
   <entry>Oldest unpruned XMAX on page, or zero if none</entry>
  </row>
 </tbody>
 </tgroup>
 </table>

 <para>
  All the details can be found in
  <filename>src/include/storage/bufpage.h</filename>.
 </para>

 <para>
  Following the page header are item identifiers
  (<type>ItemIdData</type>), each requiring four bytes.
  An item identifier contains a byte-offset to
  the start of an item, its length in bytes, and a few attribute bits
  which affect its interpretation.
  New item identifiers are allocated
  as needed from the beginning of the unallocated space.
  The number of item identifiers present can be determined by looking at
  <structfield>pd_lower</structfield>, which is increased to allocate a new identifier.
  Because an item
  identifier is never moved until it is freed, its index can be used on a
  long-term basis to reference an item, even when the item itself is moved
  around on the page to compact free space.  In fact, every pointer to an
  item (<type>ItemPointer</type>, also known as
  <type>CTID</type>) created by
  <productname>PostgreSQL</productname> consists of a page number and the
  index of an item identifier.

 </para>

 <para>

  The items themselves are stored in space allocated backwards from the end
  of unallocated space.  The exact structure varies depending on what the
  table is to contain. Tables and sequences both use a structure named
  <type>HeapTupleHeaderData</type>, described below.

 </para>

 <para>

  The final section is the <quote>special section</quote> which can
  contain anything the access method wishes to store.  For example,
  b-tree indexes store links to the page's left and right siblings,
  as well as some other data relevant to the index structure.
  Ordinary tables do not use a special section at all (indicated by setting
  <structfield>pd_special</structfield> to equal the page size).

 </para>

 <para>
  <xref linkend="storage-page-layout-figure"/> illustrates how these parts are
  laid out in a page.
 </para>

 <figure id="storage-page-layout-figure">
  <title>Page Layout</title>
  <mediaobject>
   <imageobject>
    <imagedata fileref="images/pagelayout.svg" format="SVG" width="100%"/>
   </imageobject>
  </mediaobject>
 </figure>

 <sect2 id="storage-tuple-layout">

 <title>Table Row Layout</title>

 <para>

  All table rows are structured in the same way. There is a fixed-size
  header (occupying 23 bytes on most machines), followed by an optional null
  bitmap, an optional object ID field, and the user data. The header is
  detailed
  in <xref linkend="heaptupleheaderdata-table"/>.  The actual user data
  (columns of the row) begins at the offset indicated by
  <structfield>t_hoff</structfield>, which must always be a multiple of the MAXALIGN
  distance for the platform.
  The null bitmap is
  only present if the <firstterm>HEAP_HASNULL</firstterm> bit is set in
  <structfield>t_infomask</structfield>. If it is present it begins just after
  the fixed header and occupies enough bytes to have one bit per data column
  (that is, the number of bits that equals the attribute count in
  <structfield>t_infomask2</structfield>). In this list of bits, a
  1 bit indicates not-null, a 0 bit is a null.  When the bitmap is not
  present, all columns are assumed not-null.
  The object ID is only present if the <firstterm>HEAP_HASOID_OLD</firstterm> bit
  is set in <structfield>t_infomask</structfield>.  If present, it appears just
  before the <structfield>t_hoff</structfield> boundary.

Title: Item Identifiers, Page Structure, and Table Row Layout
Summary
This section describes the layout of data pages in PostgreSQL, including item identifiers (ItemIdData), the arrangement of items themselves, and the special section for access method-specific data. It also details the structure of table rows, comprising a fixed-size header (HeapTupleHeaderData), an optional null bitmap, an optional object ID field, and user data. The location of user data is determined by the t_hoff field, and the presence of the null bitmap and object ID depends on specific bits in the t_infomask.