gooderp18绿色标准版
Du kannst nicht mehr als 25 Themen auswählen Themen müssen entweder mit einem Buchstaben oder einer Ziffer beginnen. Sie können Bindestriche („-“) enthalten und bis zu 35 Zeichen lang sein.

157 Zeilen
15KB

  1. <?xml version="1.0" encoding="UTF-8" standalone="no"?>
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /><title>68.6. Database Page Layout</title><link rel="stylesheet" type="text/css" href="stylesheet.css" /><link rev="made" href="pgsql-docs@lists.postgresql.org" /><meta name="generator" content="DocBook XSL Stylesheets V1.79.1" /><link rel="prev" href="storage-init.html" title="68.5. The Initialization Fork" /><link rel="next" href="bki.html" title="Chapter 69. System Catalog Declarations and Initial Contents" /></head><body><div xmlns="http://www.w3.org/TR/xhtml1/transitional" class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="5" align="center">68.6. Database Page Layout</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="storage-init.html" title="68.5. The Initialization Fork">Prev</a> </td><td width="10%" align="left"><a accesskey="u" href="storage.html" title="Chapter 68. Database Physical Storage">Up</a></td><th width="60%" align="center">Chapter 68. Database Physical Storage</th><td width="10%" align="right"><a accesskey="h" href="index.html" title="PostgreSQL 12.4 Documentation">Home</a></td><td width="10%" align="right"> <a accesskey="n" href="bki.html" title="Chapter 69. System Catalog Declarations and Initial Contents">Next</a></td></tr></table><hr></hr></div><div class="sect1" id="STORAGE-PAGE-LAYOUT"><div class="titlepage"><div><div><h2 class="title" style="clear: both">68.6. Database Page Layout</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="storage-page-layout.html#STORAGE-TUPLE-LAYOUT">68.6.1. Table Row Layout</a></span></dt></dl></div><p>
  3. This section provides an overview of the page format used within
  4. <span class="productname">PostgreSQL</span> tables and indexes.<a href="#ftn.id-1.10.21.8.2.2" class="footnote"><sup class="footnote" id="id-1.10.21.8.2.2">[15]</sup></a>
  5. Sequences and <acronym class="acronym">TOAST</acronym> tables are formatted just like a regular table.
  6. </p><p>
  7. In the following explanation, a
  8. <em class="firstterm">byte</em>
  9. is assumed to contain 8 bits. In addition, the term
  10. <em class="firstterm">item</em>
  11. refers to an individual data value that is stored on a page. In a table,
  12. an item is a row; in an index, an item is an index entry.
  13. </p><p>
  14. Every table and index is stored as an array of <em class="firstterm">pages</em> of a
  15. fixed size (usually 8 kB, although a different page size can be selected
  16. when compiling the server). In a table, all the pages are logically
  17. equivalent, so a particular item (row) can be stored in any page. In
  18. indexes, the first page is generally reserved as a <em class="firstterm">metapage</em>
  19. holding control information, and there can be different types of pages
  20. within the index, depending on the index access method.
  21. </p><p>
  22. <a class="xref" href="storage-page-layout.html#PAGE-TABLE" title="Table 68.2. Overall Page Layout">Table 68.2</a> shows the overall layout of a page.
  23. There are five parts to each page.
  24. </p><div class="table" id="PAGE-TABLE"><p class="title"><strong>Table 68.2. Overall Page Layout</strong></p><div class="table-contents"><table class="table" summary="Overall Page Layout" border="1"><colgroup><col /><col /></colgroup><thead><tr><th>
  25. Item
  26. </th><th>Description</th></tr></thead><tbody><tr><td>PageHeaderData</td><td>24 bytes long. Contains general information about the page, including
  27. free space pointers.</td></tr><tr><td>ItemIdData</td><td>Array of item identifiers pointing to the actual items. Each
  28. entry is an (offset,length) pair. 4 bytes per item.</td></tr><tr><td>Free space</td><td>The unallocated space. New item identifiers are allocated from
  29. the start of this area, new items from the end.</td></tr><tr><td>Items</td><td>The actual items themselves.</td></tr><tr><td>Special space</td><td>Index access method specific data. Different methods store different
  30. data. Empty in ordinary tables.</td></tr></tbody></table></div></div><br class="table-break" /><p>
  31. The first 24 bytes of each page consists of a page header
  32. (<code class="structname">PageHeaderData</code>). Its format is detailed in <a class="xref" href="storage-page-layout.html#PAGEHEADERDATA-TABLE" title="Table 68.3. PageHeaderData Layout">Table 68.3</a>. The first field tracks the most
  33. recent WAL entry related to this page. The second field contains
  34. the page checksum if <a class="xref" href="app-initdb.html#APP-INITDB-DATA-CHECKSUMS">data checksums</a> are
  35. enabled. Next is a 2-byte field containing flag bits. This is followed
  36. by three 2-byte integer fields (<code class="structfield">pd_lower</code>,
  37. <code class="structfield">pd_upper</code>, and
  38. <code class="structfield">pd_special</code>). These contain byte offsets
  39. from the page start to the start of unallocated space, to the end of
  40. unallocated space, and to the start of the special space. The next 2
  41. bytes of the page header, <code class="structfield">pd_pagesize_version</code>,
  42. store both the page size and a version indicator. Beginning with
  43. <span class="productname">PostgreSQL</span> 8.3 the version number is 4;
  44. <span class="productname">PostgreSQL</span> 8.1 and 8.2 used version number 3;
  45. <span class="productname">PostgreSQL</span> 8.0 used version number 2;
  46. <span class="productname">PostgreSQL</span> 7.3 and 7.4 used version number 1;
  47. prior releases used version number 0.
  48. (The basic page layout and header format has not changed in most of these
  49. versions, but the layout of heap row headers has.) The page size
  50. is basically only present as a cross-check; there is no support for having
  51. more than one page size in an installation.
  52. The last field is a hint that shows whether pruning the page is likely
  53. to be profitable: it tracks the oldest un-pruned XMAX on the page.
  54. </p><div class="table" id="PAGEHEADERDATA-TABLE"><p class="title"><strong>Table 68.3. PageHeaderData Layout</strong></p><div class="table-contents"><table class="table" summary="PageHeaderData Layout" border="1"><colgroup><col /><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Type</th><th>Length</th><th>Description</th></tr></thead><tbody><tr><td>pd_lsn</td><td>PageXLogRecPtr</td><td>8 bytes</td><td>LSN: next byte after last byte of WAL record for last change
  55. to this page</td></tr><tr><td>pd_checksum</td><td>uint16</td><td>2 bytes</td><td>Page checksum</td></tr><tr><td>pd_flags</td><td>uint16</td><td>2 bytes</td><td>Flag bits</td></tr><tr><td>pd_lower</td><td>LocationIndex</td><td>2 bytes</td><td>Offset to start of free space</td></tr><tr><td>pd_upper</td><td>LocationIndex</td><td>2 bytes</td><td>Offset to end of free space</td></tr><tr><td>pd_special</td><td>LocationIndex</td><td>2 bytes</td><td>Offset to start of special space</td></tr><tr><td>pd_pagesize_version</td><td>uint16</td><td>2 bytes</td><td>Page size and layout version number information</td></tr><tr><td>pd_prune_xid</td><td>TransactionId</td><td>4 bytes</td><td>Oldest unpruned XMAX on page, or zero if none</td></tr></tbody></table></div></div><br class="table-break" /><p>
  56. All the details can be found in
  57. <code class="filename">src/include/storage/bufpage.h</code>.
  58. </p><p>
  59. Following the page header are item identifiers
  60. (<code class="type">ItemIdData</code>), each requiring four bytes.
  61. An item identifier contains a byte-offset to
  62. the start of an item, its length in bytes, and a few attribute bits
  63. which affect its interpretation.
  64. New item identifiers are allocated
  65. as needed from the beginning of the unallocated space.
  66. The number of item identifiers present can be determined by looking at
  67. <code class="structfield">pd_lower</code>, which is increased to allocate a new identifier.
  68. Because an item
  69. identifier is never moved until it is freed, its index can be used on a
  70. long-term basis to reference an item, even when the item itself is moved
  71. around on the page to compact free space. In fact, every pointer to an
  72. item (<code class="type">ItemPointer</code>, also known as
  73. <code class="type">CTID</code>) created by
  74. <span class="productname">PostgreSQL</span> consists of a page number and the
  75. index of an item identifier.
  76. </p><p>
  77. The items themselves are stored in space allocated backwards from the end
  78. of unallocated space. The exact structure varies depending on what the
  79. table is to contain. Tables and sequences both use a structure named
  80. <code class="type">HeapTupleHeaderData</code>, described below.
  81. </p><p>
  82. The final section is the <span class="quote">“<span class="quote">special section</span>”</span> which can
  83. contain anything the access method wishes to store. For example,
  84. b-tree indexes store links to the page's left and right siblings,
  85. as well as some other data relevant to the index structure.
  86. Ordinary tables do not use a special section at all (indicated by setting
  87. <code class="structfield">pd_special</code> to equal the page size).
  88. </p><p>
  89. <a class="xref" href="storage-page-layout.html#STORAGE-PAGE-LAYOUT-FIGURE" title="Figure 68.1. Page Layout">Figure 68.1</a> illustrates how these parts are
  90. laid out in a page.
  91. </p><div class="figure" id="STORAGE-PAGE-LAYOUT-FIGURE"><p class="title"><strong>Figure 68.1. Page Layout</strong></p><div class="figure-contents"><div class="mediaobject"><object type="image/svg+xml" data="pagelayout.svg" width="100%"></object></div></div></div><br class="figure-break" /><div class="sect2" id="STORAGE-TUPLE-LAYOUT"><div class="titlepage"><div><div><h3 class="title">68.6.1. Table Row Layout</h3></div></div></div><p>
  92. All table rows are structured in the same way. There is a fixed-size
  93. header (occupying 23 bytes on most machines), followed by an optional null
  94. bitmap, an optional object ID field, and the user data. The header is
  95. detailed
  96. in <a class="xref" href="storage-page-layout.html#HEAPTUPLEHEADERDATA-TABLE" title="Table 68.4. HeapTupleHeaderData Layout">Table 68.4</a>. The actual user data
  97. (columns of the row) begins at the offset indicated by
  98. <code class="structfield">t_hoff</code>, which must always be a multiple of the MAXALIGN
  99. distance for the platform.
  100. The null bitmap is
  101. only present if the <em class="firstterm">HEAP_HASNULL</em> bit is set in
  102. <code class="structfield">t_infomask</code>. If it is present it begins just after
  103. the fixed header and occupies enough bytes to have one bit per data column
  104. (that is, the number of bits that equals the attribute count in
  105. <code class="structfield">t_infomask2</code>). In this list of bits, a
  106. 1 bit indicates not-null, a 0 bit is a null. When the bitmap is not
  107. present, all columns are assumed not-null.
  108. The object ID is only present if the <em class="firstterm">HEAP_HASOID_OLD</em> bit
  109. is set in <code class="structfield">t_infomask</code>. If present, it appears just
  110. before the <code class="structfield">t_hoff</code> boundary. Any padding needed to make
  111. <code class="structfield">t_hoff</code> a MAXALIGN multiple will appear between the null
  112. bitmap and the object ID. (This in turn ensures that the object ID is
  113. suitably aligned.)
  114. </p><div class="table" id="HEAPTUPLEHEADERDATA-TABLE"><p class="title"><strong>Table 68.4. HeapTupleHeaderData Layout</strong></p><div class="table-contents"><table class="table" summary="HeapTupleHeaderData Layout" border="1"><colgroup><col /><col /><col /><col /></colgroup><thead><tr><th>Field</th><th>Type</th><th>Length</th><th>Description</th></tr></thead><tbody><tr><td>t_xmin</td><td>TransactionId</td><td>4 bytes</td><td>insert XID stamp</td></tr><tr><td>t_xmax</td><td>TransactionId</td><td>4 bytes</td><td>delete XID stamp</td></tr><tr><td>t_cid</td><td>CommandId</td><td>4 bytes</td><td>insert and/or delete CID stamp (overlays with t_xvac)</td></tr><tr><td>t_xvac</td><td>TransactionId</td><td>4 bytes</td><td>XID for VACUUM operation moving a row version</td></tr><tr><td>t_ctid</td><td>ItemPointerData</td><td>6 bytes</td><td>current TID of this or newer row version</td></tr><tr><td>t_infomask2</td><td>uint16</td><td>2 bytes</td><td>number of attributes, plus various flag bits</td></tr><tr><td>t_infomask</td><td>uint16</td><td>2 bytes</td><td>various flag bits</td></tr><tr><td>t_hoff</td><td>uint8</td><td>1 byte</td><td>offset to user data</td></tr></tbody></table></div></div><br class="table-break" /><p>
  115. All the details can be found in
  116. <code class="filename">src/include/access/htup_details.h</code>.
  117. </p><p>
  118. Interpreting the actual data can only be done with information obtained
  119. from other tables, mostly <code class="structname">pg_attribute</code>. The
  120. key values needed to identify field locations are
  121. <code class="structfield">attlen</code> and <code class="structfield">attalign</code>.
  122. There is no way to directly get a
  123. particular attribute, except when there are only fixed width fields and no
  124. null values. All this trickery is wrapped up in the functions
  125. <em class="firstterm">heap_getattr</em>, <em class="firstterm">fastgetattr</em>
  126. and <em class="firstterm">heap_getsysattr</em>.
  127. </p><p>
  128. To read the data you need to examine each attribute in turn. First check
  129. whether the field is NULL according to the null bitmap. If it is, go to
  130. the next. Then make sure you have the right alignment. If the field is a
  131. fixed width field, then all the bytes are simply placed. If it's a
  132. variable length field (attlen = -1) then it's a bit more complicated.
  133. All variable-length data types share the common header structure
  134. <code class="type">struct varlena</code>, which includes the total length of the stored
  135. value and some flag bits. Depending on the flags, the data can be either
  136. inline or in a <acronym class="acronym">TOAST</acronym> table;
  137. it might be compressed, too (see <a class="xref" href="storage-toast.html" title="68.2. TOAST">Section 68.2</a>).
  138. </p></div><div class="footnotes"><br /><hr style="width:100; text-align:left;margin-left: 0" /><div id="ftn.id-1.10.21.8.2.2" class="footnote"><p><a href="#id-1.10.21.8.2.2" class="para"><sup class="para">[15] </sup></a>
  139. Actually, use of this page format is not required for either table or
  140. index access methods. The <code class="literal">heap</code> table access method
  141. always uses this format. All the existing index methods also use the
  142. basic format, but the data kept on index metapages usually doesn't follow
  143. the item layout rules.
  144. </p></div></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="storage-init.html">Prev</a> </td><td width="20%" align="center"><a accesskey="u" href="storage.html">Up</a></td><td width="40%" align="right"> <a accesskey="n" href="bki.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">68.5. The Initialization Fork </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> Chapter 69. System Catalog Declarations and Initial Contents</td></tr></table></div></body></html>
上海开阖软件有限公司 沪ICP备12045867号-1