heaptoast.h 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. /*-------------------------------------------------------------------------
  2. *
  3. * heaptoast.h
  4. * Heap-specific definitions for external and compressed storage
  5. * of variable size attributes.
  6. *
  7. * Copyright (c) 2000-2022, PostgreSQL Global Development Group
  8. *
  9. * src/include/access/heaptoast.h
  10. *
  11. *-------------------------------------------------------------------------
  12. */
  13. #ifndef HEAPTOAST_H
  14. #define HEAPTOAST_H
  15. #include "access/htup_details.h"
  16. #include "storage/lockdefs.h"
  17. #include "utils/relcache.h"
  18. /*
  19. * Find the maximum size of a tuple if there are to be N tuples per page.
  20. */
  21. #define MaximumBytesPerTuple(tuplesPerPage) \
  22. MAXALIGN_DOWN((BLCKSZ - \
  23. MAXALIGN(SizeOfPageHeaderData + (tuplesPerPage) * sizeof(ItemIdData))) \
  24. / (tuplesPerPage))
  25. /*
  26. * These symbols control toaster activation. If a tuple is larger than
  27. * TOAST_TUPLE_THRESHOLD, we will try to toast it down to no more than
  28. * TOAST_TUPLE_TARGET bytes through compressing compressible fields and
  29. * moving EXTENDED and EXTERNAL data out-of-line.
  30. *
  31. * The numbers need not be the same, though they currently are. It doesn't
  32. * make sense for TARGET to exceed THRESHOLD, but it could be useful to make
  33. * it be smaller.
  34. *
  35. * Currently we choose both values to match the largest tuple size for which
  36. * TOAST_TUPLES_PER_PAGE tuples can fit on a heap page.
  37. *
  38. * XXX while these can be modified without initdb, some thought needs to be
  39. * given to needs_toast_table() in toasting.c before unleashing random
  40. * changes. Also see LOBLKSIZE in large_object.h, which can *not* be
  41. * changed without initdb.
  42. */
  43. #define TOAST_TUPLES_PER_PAGE 4
  44. #define TOAST_TUPLE_THRESHOLD MaximumBytesPerTuple(TOAST_TUPLES_PER_PAGE)
  45. #define TOAST_TUPLE_TARGET TOAST_TUPLE_THRESHOLD
  46. /*
  47. * The code will also consider moving MAIN data out-of-line, but only as a
  48. * last resort if the previous steps haven't reached the target tuple size.
  49. * In this phase we use a different target size, currently equal to the
  50. * largest tuple that will fit on a heap page. This is reasonable since
  51. * the user has told us to keep the data in-line if at all possible.
  52. */
  53. #define TOAST_TUPLES_PER_PAGE_MAIN 1
  54. #define TOAST_TUPLE_TARGET_MAIN MaximumBytesPerTuple(TOAST_TUPLES_PER_PAGE_MAIN)
  55. /*
  56. * If an index value is larger than TOAST_INDEX_TARGET, we will try to
  57. * compress it (we can't move it out-of-line, however). Note that this
  58. * number is per-datum, not per-tuple, for simplicity in index_form_tuple().
  59. */
  60. #define TOAST_INDEX_TARGET (MaxHeapTupleSize / 16)
  61. /*
  62. * When we store an oversize datum externally, we divide it into chunks
  63. * containing at most TOAST_MAX_CHUNK_SIZE data bytes. This number *must*
  64. * be small enough that the completed toast-table tuple (including the
  65. * ID and sequence fields and all overhead) will fit on a page.
  66. * The coding here sets the size on the theory that we want to fit
  67. * EXTERN_TUPLES_PER_PAGE tuples of maximum size onto a page.
  68. *
  69. * NB: Changing TOAST_MAX_CHUNK_SIZE requires an initdb.
  70. */
  71. #define EXTERN_TUPLES_PER_PAGE 4 /* tweak only this */
  72. #define EXTERN_TUPLE_MAX_SIZE MaximumBytesPerTuple(EXTERN_TUPLES_PER_PAGE)
  73. #define TOAST_MAX_CHUNK_SIZE \
  74. (EXTERN_TUPLE_MAX_SIZE - \
  75. MAXALIGN(SizeofHeapTupleHeader) - \
  76. sizeof(Oid) - \
  77. sizeof(int32) - \
  78. VARHDRSZ)
  79. /* ----------
  80. * heap_toast_insert_or_update -
  81. *
  82. * Called by heap_insert() and heap_update().
  83. * ----------
  84. */
  85. extern HeapTuple heap_toast_insert_or_update(Relation rel, HeapTuple newtup,
  86. HeapTuple oldtup, int options);
  87. /* ----------
  88. * heap_toast_delete -
  89. *
  90. * Called by heap_delete().
  91. * ----------
  92. */
  93. extern void heap_toast_delete(Relation rel, HeapTuple oldtup,
  94. bool is_speculative);
  95. /* ----------
  96. * toast_flatten_tuple -
  97. *
  98. * "Flatten" a tuple to contain no out-of-line toasted fields.
  99. * (This does not eliminate compressed or short-header datums.)
  100. * ----------
  101. */
  102. extern HeapTuple toast_flatten_tuple(HeapTuple tup, TupleDesc tupleDesc);
  103. /* ----------
  104. * toast_flatten_tuple_to_datum -
  105. *
  106. * "Flatten" a tuple containing out-of-line toasted fields into a Datum.
  107. * ----------
  108. */
  109. extern Datum toast_flatten_tuple_to_datum(HeapTupleHeader tup,
  110. uint32 tup_len,
  111. TupleDesc tupleDesc);
  112. /* ----------
  113. * toast_build_flattened_tuple -
  114. *
  115. * Build a tuple containing no out-of-line toasted fields.
  116. * (This does not eliminate compressed or short-header datums.)
  117. * ----------
  118. */
  119. extern HeapTuple toast_build_flattened_tuple(TupleDesc tupleDesc,
  120. Datum *values,
  121. bool *isnull);
  122. /* ----------
  123. * heap_fetch_toast_slice
  124. *
  125. * Fetch a slice from a toast value stored in a heap table.
  126. * ----------
  127. */
  128. extern void heap_fetch_toast_slice(Relation toastrel, Oid valueid,
  129. int32 attrsize, int32 sliceoffset,
  130. int32 slicelength, struct varlena *result);
  131. #endif /* HEAPTOAST_H */