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