summaryrefslogtreecommitdiff
path: root/doc/src/sgml/page.sgml
diff options
context:
space:
mode:
Diffstat (limited to 'doc/src/sgml/page.sgml')
-rw-r--r--doc/src/sgml/page.sgml354
1 files changed, 0 insertions, 354 deletions
diff --git a/doc/src/sgml/page.sgml b/doc/src/sgml/page.sgml
deleted file mode 100644
index 4db4cb4e05..0000000000
--- a/doc/src/sgml/page.sgml
+++ /dev/null
@@ -1,354 +0,0 @@
-<!--
-$PostgreSQL$
--->
-
-<chapter id="page">
-
-<title>Database Page Layout</title>
-
-<abstract>
-<para>
-A description of the database file page format.
-</para>
-</abstract>
-
-<para>
-This section provides an overview of the page format used by
-<productname>PostgreSQL</productname> tables and indexes.<footnote>
- <para>
- Actually, index access methods need not use this page format.
- All the existing index methods do use this basic format,
- but the data kept on index metapages usually doesn't follow
- the item layout rules.
- </para>
-</footnote>
-TOAST tables and sequences are formatted just like a regular table.
-</para>
-
-<para>
-In the following explanation, a
-<firstterm>byte</firstterm>
-is assumed to contain 8 bits. In addition, the term
-<firstterm>item</firstterm>
-refers to an individual data value that is stored on a page. In a table,
-an item is a row; in an index, an item is an index entry.
-</para>
-
-<para>
-Every table and index is stored as an array of <firstterm>pages</> of a
-fixed size (usually 8K, although a different page size can be selected
-when compiling the server). In a table, all the pages are logically
-equivalent, so a particular item (row) can be stored in any page. In
-indexes, the first page is generally reserved as a <firstterm>metapage</>
-holding control information, and there may be different types of pages
-within the index, depending on the index access method.
-</para>
-
-<para>
-<xref linkend="page-table"> shows the overall layout of a page.
-There are five parts to each page.
-</para>
-
-<table tocentry="1" id="page-table">
-<title>Overall Page Layout</title>
-<titleabbrev>Page Layout</titleabbrev>
-<tgroup cols="2">
-<thead>
-<row>
-<entry>
-Item
-</entry>
-<entry>Description</entry>
-</row>
-</thead>
-
-<tbody>
-
-<row>
- <entry>PageHeaderData</entry>
- <entry>20 bytes long. Contains general information about the page, including
-free space pointers.</entry>
-</row>
-
-<row>
-<entry>ItemPointerData</entry>
-<entry>Array of (offset,length) pairs pointing to the actual items.
-4 bytes per item.</entry>
-</row>
-
-<row>
-<entry>Free space</entry>
-<entry>The unallocated space. New item pointers are allocated from the start
-of this area, new items from the end.</entry>
-</row>
-
-<row>
-<entry>Items</entry>
-<entry>The actual items themselves.</entry>
-</row>
-
-<row>
-<entry>Special space</entry>
-<entry>Index access method specific data. Different methods store different
-data. Empty in ordinary tables.</entry>
-</row>
-
-</tbody>
-</tgroup>
-</table>
-
- <para>
-
- The first 20 bytes of each page consists of a page header
- (PageHeaderData). Its format is detailed in <xref
- linkend="pageheaderdata-table">. The first two fields track the most
- recent WAL entry related to this page. They are followed by three 2-byte
- integer fields
- (<structfield>pd_lower</structfield>, <structfield>pd_upper</structfield>,
- and <structfield>pd_special</structfield>). These contain byte offsets
- from the page start to the start
- of unallocated space, to the end of unallocated space, and to the start of
- the special space.
- The last 2 bytes of the page header,
- <structfield>pd_pagesize_version</structfield>, store both the page size
- and a version indicator. Beginning with
- <productname>PostgreSQL</productname> 8.0 the version number is 2;
- <productname>PostgreSQL</productname> 7.3 and 7.4 used version number 1;
- prior releases used version number 0.
- (The basic page layout and header format has not changed in these versions,
- but the layout of heap row headers has.) The page size
- is basically only present as a cross-check; there is no support for having
- more than one page size in an installation.
-
- </para>
-
- <table tocentry="1" id="pageheaderdata-table">
- <title>PageHeaderData Layout</title>
- <titleabbrev>PageHeaderData Layout</titleabbrev>
- <tgroup cols="4">
- <thead>
- <row>
- <entry>Field</entry>
- <entry>Type</entry>
- <entry>Length</entry>
- <entry>Description</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>pd_lsn</entry>
- <entry>XLogRecPtr</entry>
- <entry>8 bytes</entry>
- <entry>LSN: next byte after last byte of xlog record for last change
- to this page</entry>
- </row>
- <row>
- <entry>pd_tli</entry>
- <entry>TimeLineID</entry>
- <entry>4 bytes</entry>
- <entry>TLI of last change</entry>
- </row>
- <row>
- <entry>pd_lower</entry>
- <entry>LocationIndex</entry>
- <entry>2 bytes</entry>
- <entry>Offset to start of free space</entry>
- </row>
- <row>
- <entry>pd_upper</entry>
- <entry>LocationIndex</entry>
- <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>
- </tbody>
- </tgroup>
- </table>
-
- <para>
- All the details may 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</>, which is increased to allocate a new identifier.
- Because an item
- identifier is never moved until it is freed, its index may 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 may
- 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</> to equal the page size).
-
- </para>
-
- <para>
-
- All table rows are structured in the same way. There is a fixed-size
- header (occupying 27 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</>, 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, <structfield>t_natts</> bits altogether). 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</firstterm> bit
- is set in <structfield>t_infomask</structfield>. If present, it appears just
- before the <structfield>t_hoff</> boundary. Any padding needed to make
- <structfield>t_hoff</> a MAXALIGN multiple will appear between the null
- bitmap and the object ID. (This in turn ensures that the object ID is
- suitably aligned.)
-
- </para>
-
- <table tocentry="1" id="heaptupleheaderdata-table">
- <title>HeapTupleHeaderData Layout</title>
- <titleabbrev>HeapTupleHeaderData Layout</titleabbrev>
- <tgroup cols="4">
- <thead>
- <row>
- <entry>Field</entry>
- <entry>Type</entry>
- <entry>Length</entry>
- <entry>Description</entry>
- </row>
- </thead>
- <tbody>
- <row>
- <entry>t_xmin</entry>
- <entry>TransactionId</entry>
- <entry>4 bytes</entry>
- <entry>insert XID stamp</entry>
- </row>
- <row>
- <entry>t_cmin</entry>
- <entry>CommandId</entry>
- <entry>4 bytes</entry>
- <entry>insert CID stamp</entry>
- </row>
- <row>
- <entry>t_xmax</entry>
- <entry>TransactionId</entry>
- <entry>4 bytes</entry>
- <entry>delete XID stamp</entry>
- </row>
- <row>
- <entry>t_cmax</entry>
- <entry>CommandId</entry>
- <entry>4 bytes</entry>
- <entry>delete CID stamp (overlays with t_xvac)</entry>
- </row>
- <row>
- <entry>t_xvac</entry>
- <entry>TransactionId</entry>
- <entry>4 bytes</entry>
- <entry>XID for VACUUM operation moving a row version</entry>
- </row>
- <row>
- <entry>t_ctid</entry>
- <entry>ItemPointerData</entry>
- <entry>6 bytes</entry>
- <entry>current TID of this or newer row version</entry>
- </row>
- <row>
- <entry>t_natts</entry>
- <entry>int16</entry>
- <entry>2 bytes</entry>
- <entry>number of attributes</entry>
- </row>
- <row>
- <entry>t_infomask</entry>
- <entry>uint16</entry>
- <entry>2 bytes</entry>
- <entry>various flag bits</entry>
- </row>
- <row>
- <entry>t_hoff</entry>
- <entry>uint8</entry>
- <entry>1 byte</entry>
- <entry>offset to user data</entry>
- </row>
- </tbody>
- </tgroup>
- </table>
-
- <para>
- All the details may be found in
- <filename>src/include/access/htup.h</filename>.
- </para>
-
- <para>
-
- Interpreting the actual data can only be done with information obtained
- from other tables, mostly <structname>pg_attribute</structname>. The
- key values needed to identify field locations are
- <structfield>attlen</structfield> and <structfield>attalign</structfield>.
- There is no way to directly get a
- particular attribute, except when there are only fixed width fields and no
- NULLs. All this trickery is wrapped up in the functions
- <firstterm>heap_getattr</firstterm>, <firstterm>fastgetattr</firstterm>
- and <firstterm>heap_getsysattr</firstterm>.
-
- </para>
- <para>
-
- To read the data you need to examine each attribute in turn. First check
- whether the field is NULL according to the null bitmap. If it is, go to
- the next. Then make sure you have the right alignment. If the field is a
- fixed width field, then all the bytes are simply placed. If it's a
- variable length field (attlen = -1) then it's a bit more complicated.
- All variable-length datatypes share the common header structure
- <type>varattrib</type>, which includes the total length of the stored
- value and some flag bits. Depending on the flags, the data may be either
- inline or in another table (TOAST); it might be compressed, too.
-
- </para>
-</chapter>