tuptoaster.h 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228
  1. /*-------------------------------------------------------------------------
  2. *
  3. * tuptoaster.h
  4. * POSTGRES definitions for external and compressed storage
  5. * of variable size attributes.
  6. *
  7. * Copyright (c) 2000-2016, PostgreSQL Global Development Group
  8. *
  9. * src/include/access/tuptoaster.h
  10. *
  11. *-------------------------------------------------------------------------
  12. */
  13. #ifndef TUPTOASTER_H
  14. #define TUPTOASTER_H
  15. #include "access/htup_details.h"
  16. #include "storage/lockdefs.h"
  17. #include "utils/relcache.h"
  18. /*
  19. * This enables de-toasting of index entries. Needed until VACUUM is
  20. * smart enough to rebuild indexes from scratch.
  21. */
  22. #define TOAST_INDEX_HACK
  23. /*
  24. * Find the maximum size of a tuple if there are to be N tuples per page.
  25. */
  26. #define MaximumBytesPerTuple(tuplesPerPage) \
  27. MAXALIGN_DOWN((BLCKSZ - \
  28. MAXALIGN(SizeOfPageHeaderData + (tuplesPerPage) * sizeof(ItemIdData))) \
  29. / (tuplesPerPage))
  30. /*
  31. * These symbols control toaster activation. If a tuple is larger than
  32. * TOAST_TUPLE_THRESHOLD, we will try to toast it down to no more than
  33. * TOAST_TUPLE_TARGET bytes through compressing compressible fields and
  34. * moving EXTENDED and EXTERNAL data out-of-line.
  35. *
  36. * The numbers need not be the same, though they currently are. It doesn't
  37. * make sense for TARGET to exceed THRESHOLD, but it could be useful to make
  38. * it be smaller.
  39. *
  40. * Currently we choose both values to match the largest tuple size for which
  41. * TOAST_TUPLES_PER_PAGE tuples can fit on a heap page.
  42. *
  43. * XXX while these can be modified without initdb, some thought needs to be
  44. * given to needs_toast_table() in toasting.c before unleashing random
  45. * changes. Also see LOBLKSIZE in large_object.h, which can *not* be
  46. * changed without initdb.
  47. */
  48. #define TOAST_TUPLES_PER_PAGE 4
  49. #define TOAST_TUPLE_THRESHOLD MaximumBytesPerTuple(TOAST_TUPLES_PER_PAGE)
  50. #define TOAST_TUPLE_TARGET TOAST_TUPLE_THRESHOLD
  51. /*
  52. * The code will also consider moving MAIN data out-of-line, but only as a
  53. * last resort if the previous steps haven't reached the target tuple size.
  54. * In this phase we use a different target size, currently equal to the
  55. * largest tuple that will fit on a heap page. This is reasonable since
  56. * the user has told us to keep the data in-line if at all possible.
  57. */
  58. #define TOAST_TUPLES_PER_PAGE_MAIN 1
  59. #define TOAST_TUPLE_TARGET_MAIN MaximumBytesPerTuple(TOAST_TUPLES_PER_PAGE_MAIN)
  60. /*
  61. * If an index value is larger than TOAST_INDEX_TARGET, we will try to
  62. * compress it (we can't move it out-of-line, however). Note that this
  63. * number is per-datum, not per-tuple, for simplicity in index_form_tuple().
  64. */
  65. #define TOAST_INDEX_TARGET (MaxHeapTupleSize / 16)
  66. /*
  67. * When we store an oversize datum externally, we divide it into chunks
  68. * containing at most TOAST_MAX_CHUNK_SIZE data bytes. This number *must*
  69. * be small enough that the completed toast-table tuple (including the
  70. * ID and sequence fields and all overhead) will fit on a page.
  71. * The coding here sets the size on the theory that we want to fit
  72. * EXTERN_TUPLES_PER_PAGE tuples of maximum size onto a page.
  73. *
  74. * NB: Changing TOAST_MAX_CHUNK_SIZE requires an initdb.
  75. */
  76. #define EXTERN_TUPLES_PER_PAGE 4 /* tweak only this */
  77. #define EXTERN_TUPLE_MAX_SIZE MaximumBytesPerTuple(EXTERN_TUPLES_PER_PAGE)
  78. #define TOAST_MAX_CHUNK_SIZE \
  79. (EXTERN_TUPLE_MAX_SIZE - \
  80. MAXALIGN(SizeofHeapTupleHeader) - \
  81. sizeof(Oid) - \
  82. sizeof(int32) - \
  83. VARHDRSZ)
  84. /* Size of an EXTERNAL datum that contains a standard TOAST pointer */
  85. #define TOAST_POINTER_SIZE (VARHDRSZ_EXTERNAL + sizeof(varatt_external))
  86. /* Size of an EXTERNAL datum that contains an indirection pointer */
  87. #define INDIRECT_POINTER_SIZE (VARHDRSZ_EXTERNAL + sizeof(varatt_indirect))
  88. /*
  89. * Testing whether an externally-stored value is compressed now requires
  90. * comparing extsize (the actual length of the external data) to rawsize
  91. * (the original uncompressed datum's size). The latter includes VARHDRSZ
  92. * overhead, the former doesn't. We never use compression unless it actually
  93. * saves space, so we expect either equality or less-than.
  94. */
  95. #define VARATT_EXTERNAL_IS_COMPRESSED(toast_pointer) \
  96. ((toast_pointer).va_extsize < (toast_pointer).va_rawsize - VARHDRSZ)
  97. /*
  98. * Macro to fetch the possibly-unaligned contents of an EXTERNAL datum
  99. * into a local "struct varatt_external" toast pointer. This should be
  100. * just a memcpy, but some versions of gcc seem to produce broken code
  101. * that assumes the datum contents are aligned. Introducing an explicit
  102. * intermediate "varattrib_1b_e *" variable seems to fix it.
  103. */
  104. #define VARATT_EXTERNAL_GET_POINTER(toast_pointer, attr) \
  105. do { \
  106. varattrib_1b_e *attre = (varattrib_1b_e *) (attr); \
  107. Assert(VARATT_IS_EXTERNAL(attre)); \
  108. Assert(VARSIZE_EXTERNAL(attre) == sizeof(toast_pointer) + VARHDRSZ_EXTERNAL); \
  109. memcpy(&(toast_pointer), VARDATA_EXTERNAL(attre), sizeof(toast_pointer)); \
  110. } while (0)
  111. /* ----------
  112. * toast_insert_or_update -
  113. *
  114. * Called by heap_insert() and heap_update().
  115. * ----------
  116. */
  117. extern HeapTuple toast_insert_or_update(Relation rel,
  118. HeapTuple newtup, HeapTuple oldtup,
  119. int options);
  120. /* ----------
  121. * toast_delete -
  122. *
  123. * Called by heap_delete().
  124. * ----------
  125. */
  126. extern void toast_delete(Relation rel, HeapTuple oldtup, bool is_speculative);
  127. /* ----------
  128. * heap_tuple_fetch_attr() -
  129. *
  130. * Fetches an external stored attribute from the toast
  131. * relation. Does NOT decompress it, if stored external
  132. * in compressed format.
  133. * ----------
  134. */
  135. extern struct varlena *heap_tuple_fetch_attr(struct varlena * attr);
  136. /* ----------
  137. * heap_tuple_untoast_attr() -
  138. *
  139. * Fully detoasts one attribute, fetching and/or decompressing
  140. * it as needed.
  141. * ----------
  142. */
  143. extern struct varlena *heap_tuple_untoast_attr(struct varlena * attr);
  144. /* ----------
  145. * heap_tuple_untoast_attr_slice() -
  146. *
  147. * Fetches only the specified portion of an attribute.
  148. * (Handles all cases for attribute storage)
  149. * ----------
  150. */
  151. extern struct varlena *heap_tuple_untoast_attr_slice(struct varlena * attr,
  152. int32 sliceoffset,
  153. int32 slicelength);
  154. /* ----------
  155. * toast_flatten_tuple -
  156. *
  157. * "Flatten" a tuple to contain no out-of-line toasted fields.
  158. * (This does not eliminate compressed or short-header datums.)
  159. * ----------
  160. */
  161. extern HeapTuple toast_flatten_tuple(HeapTuple tup, TupleDesc tupleDesc);
  162. /* ----------
  163. * toast_flatten_tuple_to_datum -
  164. *
  165. * "Flatten" a tuple containing out-of-line toasted fields into a Datum.
  166. * ----------
  167. */
  168. extern Datum toast_flatten_tuple_to_datum(HeapTupleHeader tup,
  169. uint32 tup_len,
  170. TupleDesc tupleDesc);
  171. /* ----------
  172. * toast_compress_datum -
  173. *
  174. * Create a compressed version of a varlena datum, if possible
  175. * ----------
  176. */
  177. extern Datum toast_compress_datum(Datum value);
  178. /* ----------
  179. * toast_raw_datum_size -
  180. *
  181. * Return the raw (detoasted) size of a varlena datum
  182. * ----------
  183. */
  184. extern Size toast_raw_datum_size(Datum value);
  185. /* ----------
  186. * toast_datum_size -
  187. *
  188. * Return the storage size of a varlena datum
  189. * ----------
  190. */
  191. extern Size toast_datum_size(Datum value);
  192. /* ----------
  193. * toast_get_valid_index -
  194. *
  195. * Return OID of valid index associated to a toast relation
  196. * ----------
  197. */
  198. extern Oid toast_get_valid_index(Oid toastoid, LOCKMODE lock);
  199. #endif /* TUPTOASTER_H */