gooderp18绿色标准版
Nelze vybrat více než 25 témat Téma musí začínat písmenem nebo číslem, může obsahovat pomlčky („-“) a může být dlouhé až 35 znaků.

221 lines
19KB

  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.2. TOAST</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-file-layout.html" title="68.1. Database File Layout" /><link rel="next" href="storage-fsm.html" title="68.3. Free Space Map" /></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.2. TOAST</th></tr><tr><td width="10%" align="left"><a accesskey="p" href="storage-file-layout.html" title="68.1. Database File Layout">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="storage-fsm.html" title="68.3. Free Space Map">Next</a></td></tr></table><hr></hr></div><div class="sect1" id="STORAGE-TOAST"><div class="titlepage"><div><div><h2 class="title" style="clear: both">68.2. TOAST</h2></div></div></div><div class="toc"><dl class="toc"><dt><span class="sect2"><a href="storage-toast.html#STORAGE-TOAST-ONDISK">68.2.1. Out-of-Line, On-Disk TOAST Storage</a></span></dt><dt><span class="sect2"><a href="storage-toast.html#STORAGE-TOAST-INMEMORY">68.2.2. Out-of-Line, In-Memory TOAST Storage</a></span></dt></dl></div><a id="id-1.10.21.4.2" class="indexterm"></a><a id="id-1.10.21.4.3" class="indexterm"></a><p>
  3. This section provides an overview of <acronym class="acronym">TOAST</acronym> (The
  4. Oversized-Attribute Storage Technique).
  5. </p><p>
  6. <span class="productname">PostgreSQL</span> uses a fixed page size (commonly
  7. 8 kB), and does not allow tuples to span multiple pages. Therefore, it is
  8. not possible to store very large field values directly. To overcome
  9. this limitation, large field values are compressed and/or broken up into
  10. multiple physical rows. This happens transparently to the user, with only
  11. small impact on most of the backend code. The technique is affectionately
  12. known as <acronym class="acronym">TOAST</acronym> (or <span class="quote">“<span class="quote">the best thing since sliced bread</span>”</span>).
  13. The <acronym class="acronym">TOAST</acronym> infrastructure is also used to improve handling of
  14. large data values in-memory.
  15. </p><p>
  16. Only certain data types support <acronym class="acronym">TOAST</acronym> — there is no need to
  17. impose the overhead on data types that cannot produce large field values.
  18. To support <acronym class="acronym">TOAST</acronym>, a data type must have a variable-length
  19. (<em class="firstterm">varlena</em>) representation, in which, ordinarily, the first
  20. four-byte word of any stored value contains the total length of the value in
  21. bytes (including itself). <acronym class="acronym">TOAST</acronym> does not constrain the rest
  22. of the data type's representation. The special representations collectively
  23. called <em class="firstterm"><acronym class="acronym">TOAST</acronym>ed values</em> work by modifying or
  24. reinterpreting this initial length word. Therefore, the C-level functions
  25. supporting a <acronym class="acronym">TOAST</acronym>-able data type must be careful about how they
  26. handle potentially <acronym class="acronym">TOAST</acronym>ed input values: an input might not
  27. actually consist of a four-byte length word and contents until after it's
  28. been <em class="firstterm">detoasted</em>. (This is normally done by invoking
  29. <code class="function">PG_DETOAST_DATUM</code> before doing anything with an input value,
  30. but in some cases more efficient approaches are possible.
  31. See <a class="xref" href="xtypes.html#XTYPES-TOAST" title="37.13.1. TOAST Considerations">Section 37.13.1</a> for more detail.)
  32. </p><p>
  33. <acronym class="acronym">TOAST</acronym> usurps two bits of the varlena length word (the high-order
  34. bits on big-endian machines, the low-order bits on little-endian machines),
  35. thereby limiting the logical size of any value of a <acronym class="acronym">TOAST</acronym>-able
  36. data type to 1 GB (2<sup>30</sup> - 1 bytes). When both bits are zero,
  37. the value is an ordinary un-<acronym class="acronym">TOAST</acronym>ed value of the data type, and
  38. the remaining bits of the length word give the total datum size (including
  39. length word) in bytes. When the highest-order or lowest-order bit is set,
  40. the value has only a single-byte header instead of the normal four-byte
  41. header, and the remaining bits of that byte give the total datum size
  42. (including length byte) in bytes. This alternative supports space-efficient
  43. storage of values shorter than 127 bytes, while still allowing the data type
  44. to grow to 1 GB at need. Values with single-byte headers aren't aligned on
  45. any particular boundary, whereas values with four-byte headers are aligned on
  46. at least a four-byte boundary; this omission of alignment padding provides
  47. additional space savings that is significant compared to short values.
  48. As a special case, if the remaining bits of a single-byte header are all
  49. zero (which would be impossible for a self-inclusive length), the value is
  50. a pointer to out-of-line data, with several possible alternatives as
  51. described below. The type and size of such a <em class="firstterm">TOAST pointer</em>
  52. are determined by a code stored in the second byte of the datum.
  53. Lastly, when the highest-order or lowest-order bit is clear but the adjacent
  54. bit is set, the content of the datum has been compressed and must be
  55. decompressed before use. In this case the remaining bits of the four-byte
  56. length word give the total size of the compressed datum, not the
  57. original data. Note that compression is also possible for out-of-line data
  58. but the varlena header does not tell whether it has occurred —
  59. the content of the <acronym class="acronym">TOAST</acronym> pointer tells that, instead.
  60. </p><p>
  61. As mentioned, there are multiple types of <acronym class="acronym">TOAST</acronym> pointer datums.
  62. The oldest and most common type is a pointer to out-of-line data stored in
  63. a <em class="firstterm"><acronym class="acronym">TOAST</acronym> table</em> that is separate from, but
  64. associated with, the table containing the <acronym class="acronym">TOAST</acronym> pointer datum
  65. itself. These <em class="firstterm">on-disk</em> pointer datums are created by the
  66. <acronym class="acronym">TOAST</acronym> management code (in <code class="filename">access/heap/tuptoaster.c</code>)
  67. when a tuple to be stored on disk is too large to be stored as-is.
  68. Further details appear in <a class="xref" href="storage-toast.html#STORAGE-TOAST-ONDISK" title="68.2.1. Out-of-Line, On-Disk TOAST Storage">Section 68.2.1</a>.
  69. Alternatively, a <acronym class="acronym">TOAST</acronym> pointer datum can contain a pointer to
  70. out-of-line data that appears elsewhere in memory. Such datums are
  71. necessarily short-lived, and will never appear on-disk, but they are very
  72. useful for avoiding copying and redundant processing of large data values.
  73. Further details appear in <a class="xref" href="storage-toast.html#STORAGE-TOAST-INMEMORY" title="68.2.2. Out-of-Line, In-Memory TOAST Storage">Section 68.2.2</a>.
  74. </p><p>
  75. The compression technique used for either in-line or out-of-line compressed
  76. data is a fairly simple and very fast member
  77. of the LZ family of compression techniques. See
  78. <code class="filename">src/common/pg_lzcompress.c</code> for the details.
  79. </p><div class="sect2" id="STORAGE-TOAST-ONDISK"><div class="titlepage"><div><div><h3 class="title">68.2.1. Out-of-Line, On-Disk TOAST Storage</h3></div></div></div><p>
  80. If any of the columns of a table are <acronym class="acronym">TOAST</acronym>-able, the table will
  81. have an associated <acronym class="acronym">TOAST</acronym> table, whose OID is stored in the table's
  82. <code class="structname">pg_class</code>.<code class="structfield">reltoastrelid</code> entry. On-disk
  83. <acronym class="acronym">TOAST</acronym>ed values are kept in the <acronym class="acronym">TOAST</acronym> table, as
  84. described in more detail below.
  85. </p><p>
  86. Out-of-line values are divided (after compression if used) into chunks of at
  87. most <code class="symbol">TOAST_MAX_CHUNK_SIZE</code> bytes (by default this value is chosen
  88. so that four chunk rows will fit on a page, making it about 2000 bytes).
  89. Each chunk is stored as a separate row in the <acronym class="acronym">TOAST</acronym> table
  90. belonging to the owning table. Every
  91. <acronym class="acronym">TOAST</acronym> table has the columns <code class="structfield">chunk_id</code> (an OID
  92. identifying the particular <acronym class="acronym">TOAST</acronym>ed value),
  93. <code class="structfield">chunk_seq</code> (a sequence number for the chunk within its value),
  94. and <code class="structfield">chunk_data</code> (the actual data of the chunk). A unique index
  95. on <code class="structfield">chunk_id</code> and <code class="structfield">chunk_seq</code> provides fast
  96. retrieval of the values. A pointer datum representing an out-of-line on-disk
  97. <acronym class="acronym">TOAST</acronym>ed value therefore needs to store the OID of the
  98. <acronym class="acronym">TOAST</acronym> table in which to look and the OID of the specific value
  99. (its <code class="structfield">chunk_id</code>). For convenience, pointer datums also store the
  100. logical datum size (original uncompressed data length) and physical stored size
  101. (different if compression was applied). Allowing for the varlena header bytes,
  102. the total size of an on-disk <acronym class="acronym">TOAST</acronym> pointer datum is therefore 18
  103. bytes regardless of the actual size of the represented value.
  104. </p><p>
  105. The <acronym class="acronym">TOAST</acronym> management code is triggered only
  106. when a row value to be stored in a table is wider than
  107. <code class="symbol">TOAST_TUPLE_THRESHOLD</code> bytes (normally 2 kB).
  108. The <acronym class="acronym">TOAST</acronym> code will compress and/or move
  109. field values out-of-line until the row value is shorter than
  110. <code class="symbol">TOAST_TUPLE_TARGET</code> bytes (also normally 2 kB, adjustable)
  111. or no more gains can be had. During an UPDATE
  112. operation, values of unchanged fields are normally preserved as-is; so an
  113. UPDATE of a row with out-of-line values incurs no <acronym class="acronym">TOAST</acronym> costs if
  114. none of the out-of-line values change.
  115. </p><p>
  116. The <acronym class="acronym">TOAST</acronym> management code recognizes four different strategies
  117. for storing <acronym class="acronym">TOAST</acronym>-able columns on disk:
  118. </p><div class="itemizedlist"><ul class="itemizedlist" style="list-style-type: disc; "><li class="listitem"><p>
  119. <code class="literal">PLAIN</code> prevents either compression or
  120. out-of-line storage; furthermore it disables use of single-byte headers
  121. for varlena types.
  122. This is the only possible strategy for
  123. columns of non-<acronym class="acronym">TOAST</acronym>-able data types.
  124. </p></li><li class="listitem"><p>
  125. <code class="literal">EXTENDED</code> allows both compression and out-of-line
  126. storage. This is the default for most <acronym class="acronym">TOAST</acronym>-able data types.
  127. Compression will be attempted first, then out-of-line storage if
  128. the row is still too big.
  129. </p></li><li class="listitem"><p>
  130. <code class="literal">EXTERNAL</code> allows out-of-line storage but not
  131. compression. Use of <code class="literal">EXTERNAL</code> will
  132. make substring operations on wide <code class="type">text</code> and
  133. <code class="type">bytea</code> columns faster (at the penalty of increased storage
  134. space) because these operations are optimized to fetch only the
  135. required parts of the out-of-line value when it is not compressed.
  136. </p></li><li class="listitem"><p>
  137. <code class="literal">MAIN</code> allows compression but not out-of-line
  138. storage. (Actually, out-of-line storage will still be performed
  139. for such columns, but only as a last resort when there is no other
  140. way to make the row small enough to fit on a page.)
  141. </p></li></ul></div><p>
  142. Each <acronym class="acronym">TOAST</acronym>-able data type specifies a default strategy for columns
  143. of that data type, but the strategy for a given table column can be altered
  144. with <a class="link" href="sql-altertable.html" title="ALTER TABLE"><code class="command">ALTER TABLE ... SET STORAGE</code></a>.
  145. </p><p>
  146. <code class="symbol">TOAST_TUPLE_TARGET</code> can be adjusted for each table using
  147. <a class="link" href="sql-altertable.html" title="ALTER TABLE"><code class="command">ALTER TABLE ... SET (toast_tuple_target = N)</code></a>
  148. </p><p>
  149. This scheme has a number of advantages compared to a more straightforward
  150. approach such as allowing row values to span pages. Assuming that queries are
  151. usually qualified by comparisons against relatively small key values, most of
  152. the work of the executor will be done using the main row entry. The big values
  153. of <acronym class="acronym">TOAST</acronym>ed attributes will only be pulled out (if selected at all)
  154. at the time the result set is sent to the client. Thus, the main table is much
  155. smaller and more of its rows fit in the shared buffer cache than would be the
  156. case without any out-of-line storage. Sort sets shrink also, and sorts will
  157. more often be done entirely in memory. A little test showed that a table
  158. containing typical HTML pages and their URLs was stored in about half of the
  159. raw data size including the <acronym class="acronym">TOAST</acronym> table, and that the main table
  160. contained only about 10% of the entire data (the URLs and some small HTML
  161. pages). There was no run time difference compared to an un-<acronym class="acronym">TOAST</acronym>ed
  162. comparison table, in which all the HTML pages were cut down to 7 kB to fit.
  163. </p></div><div class="sect2" id="STORAGE-TOAST-INMEMORY"><div class="titlepage"><div><div><h3 class="title">68.2.2. Out-of-Line, In-Memory TOAST Storage</h3></div></div></div><p>
  164. <acronym class="acronym">TOAST</acronym> pointers can point to data that is not on disk, but is
  165. elsewhere in the memory of the current server process. Such pointers
  166. obviously cannot be long-lived, but they are nonetheless useful. There
  167. are currently two sub-cases:
  168. pointers to <em class="firstterm">indirect</em> data and
  169. pointers to <em class="firstterm">expanded</em> data.
  170. </p><p>
  171. Indirect <acronym class="acronym">TOAST</acronym> pointers simply point at a non-indirect varlena
  172. value stored somewhere in memory. This case was originally created merely
  173. as a proof of concept, but it is currently used during logical decoding to
  174. avoid possibly having to create physical tuples exceeding 1 GB (as pulling
  175. all out-of-line field values into the tuple might do). The case is of
  176. limited use since the creator of the pointer datum is entirely responsible
  177. that the referenced data survives for as long as the pointer could exist,
  178. and there is no infrastructure to help with this.
  179. </p><p>
  180. Expanded <acronym class="acronym">TOAST</acronym> pointers are useful for complex data types
  181. whose on-disk representation is not especially suited for computational
  182. purposes. As an example, the standard varlena representation of a
  183. <span class="productname">PostgreSQL</span> array includes dimensionality information, a
  184. nulls bitmap if there are any null elements, then the values of all the
  185. elements in order. When the element type itself is variable-length, the
  186. only way to find the <em class="replaceable"><code>N</code></em>'th element is to scan through all the
  187. preceding elements. This representation is appropriate for on-disk storage
  188. because of its compactness, but for computations with the array it's much
  189. nicer to have an <span class="quote">“<span class="quote">expanded</span>”</span> or <span class="quote">“<span class="quote">deconstructed</span>”</span>
  190. representation in which all the element starting locations have been
  191. identified. The <acronym class="acronym">TOAST</acronym> pointer mechanism supports this need by
  192. allowing a pass-by-reference Datum to point to either a standard varlena
  193. value (the on-disk representation) or a <acronym class="acronym">TOAST</acronym> pointer that
  194. points to an expanded representation somewhere in memory. The details of
  195. this expanded representation are up to the data type, though it must have
  196. a standard header and meet the other API requirements given
  197. in <code class="filename">src/include/utils/expandeddatum.h</code>. C-level functions
  198. working with the data type can choose to handle either representation.
  199. Functions that do not know about the expanded representation, but simply
  200. apply <code class="function">PG_DETOAST_DATUM</code> to their inputs, will automatically
  201. receive the traditional varlena representation; so support for an expanded
  202. representation can be introduced incrementally, one function at a time.
  203. </p><p>
  204. <acronym class="acronym">TOAST</acronym> pointers to expanded values are further broken down
  205. into <em class="firstterm">read-write</em> and <em class="firstterm">read-only</em> pointers.
  206. The pointed-to representation is the same either way, but a function that
  207. receives a read-write pointer is allowed to modify the referenced value
  208. in-place, whereas one that receives a read-only pointer must not; it must
  209. first create a copy if it wants to make a modified version of the value.
  210. This distinction and some associated conventions make it possible to avoid
  211. unnecessary copying of expanded values during query execution.
  212. </p><p>
  213. For all types of in-memory <acronym class="acronym">TOAST</acronym> pointer, the <acronym class="acronym">TOAST</acronym>
  214. management code ensures that no such pointer datum can accidentally get
  215. stored on disk. In-memory <acronym class="acronym">TOAST</acronym> pointers are automatically
  216. expanded to normal in-line varlena values before storage — and then
  217. possibly converted to on-disk <acronym class="acronym">TOAST</acronym> pointers, if the containing
  218. tuple would otherwise be too big.
  219. </p></div></div><div class="navfooter"><hr /><table width="100%" summary="Navigation footer"><tr><td width="40%" align="left"><a accesskey="p" href="storage-file-layout.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="storage-fsm.html">Next</a></td></tr><tr><td width="40%" align="left" valign="top">68.1. Database File Layout </td><td width="20%" align="center"><a accesskey="h" href="index.html">Home</a></td><td width="40%" align="right" valign="top"> 68.3. Free Space Map</td></tr></table></div></body></html>
上海开阖软件有限公司 沪ICP备12045867号-1