1999-12-21 01:06:44 +01:00
|
|
|
/*-------------------------------------------------------------------------
|
|
|
|
*
|
|
|
|
* tuptoaster.h
|
|
|
|
* POSTGRES definitions for external and compressed storage
|
2000-04-12 19:17:23 +02:00
|
|
|
* of variable size attributes.
|
1999-12-21 01:06:44 +01:00
|
|
|
*
|
2008-01-01 20:46:01 +01:00
|
|
|
* Copyright (c) 2000-2008, PostgreSQL Global Development Group
|
1999-12-21 01:06:44 +01:00
|
|
|
*
|
2008-07-13 22:45:47 +02:00
|
|
|
* $PostgreSQL: pgsql/src/include/access/tuptoaster.h,v 1.41 2008/07/13 20:45:47 tgl Exp $
|
1999-12-21 01:06:44 +01:00
|
|
|
*
|
|
|
|
*-------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
#ifndef TUPTOASTER_H
|
|
|
|
#define TUPTOASTER_H
|
|
|
|
|
|
|
|
#include "access/htup.h"
|
2006-07-13 19:47:02 +02:00
|
|
|
#include "storage/bufpage.h"
|
2008-06-19 02:46:06 +02:00
|
|
|
#include "utils/relcache.h"
|
2000-08-04 06:16:17 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* This enables de-toasting of index entries. Needed until VACUUM is
|
|
|
|
* smart enough to rebuild indexes from scratch.
|
|
|
|
*/
|
2000-07-22 13:18:47 +02:00
|
|
|
#define TOAST_INDEX_HACK
|
2000-07-21 12:31:31 +02:00
|
|
|
|
1999-12-21 01:06:44 +01:00
|
|
|
|
2000-08-04 06:16:17 +02:00
|
|
|
/*
|
|
|
|
* These symbols control toaster activation. If a tuple is larger than
|
|
|
|
* TOAST_TUPLE_THRESHOLD, we will try to toast it down to no more than
|
Don't MAXALIGN in the checks to decide whether a tuple is over TOAST's
threshold for tuple length. On 4-byte-MAXALIGN machines, the toast code
creates tuples that have t_len exactly TOAST_TUPLE_THRESHOLD ... but this
number is not itself maxaligned, so if heap_insert maxaligns t_len before
comparing to TOAST_TUPLE_THRESHOLD, it'll uselessly recurse back to
tuptoaster.c, wasting cycles. (It turns out that this does not happen on
8-byte-MAXALIGN machines, because for them the outer MAXALIGN in the
TOAST_MAX_CHUNK_SIZE macro reduces TOAST_MAX_CHUNK_SIZE so that toast tuples
will be less than TOAST_TUPLE_THRESHOLD in size. That MAXALIGN is really
incorrect, but we can't remove it now, see below.) There isn't any particular
value in maxaligning before comparing to the thresholds, so just don't do
that, which saves a small number of cycles in itself.
These numbers should be rejiggered to minimize wasted space on toast-relation
pages, but we can't do that in the back branches because changing
TOAST_MAX_CHUNK_SIZE would force an initdb (by changing the contents of toast
tables). We can move the toast decision thresholds a bit, though, which is
what this patch effectively does.
Thanks to Pavan Deolasee for discovering the unintended recursion.
Back-patch into 8.2, but not further, pending more testing. (HEAD is about
to get a further patch modifying the thresholds, so it won't help much
for testing this form of the patch.)
2007-02-04 21:00:37 +01:00
|
|
|
* TOAST_TUPLE_TARGET bytes. Both numbers include all tuple header overhead
|
|
|
|
* and between-fields alignment padding, but we do *not* consider any
|
|
|
|
* end-of-tuple alignment padding; hence the values can be compared directly
|
2007-04-03 06:14:26 +02:00
|
|
|
* to a tuple's t_len field.
|
2000-08-04 06:16:17 +02:00
|
|
|
*
|
2007-04-03 06:14:26 +02:00
|
|
|
* The numbers need not be the same, though they currently are. It doesn't
|
|
|
|
* make sense for TARGET to exceed THRESHOLD, but it could be useful to make
|
|
|
|
* it be smaller.
|
2007-02-05 05:22:18 +01:00
|
|
|
*
|
2007-04-03 06:14:26 +02:00
|
|
|
* Currently we choose both values to match the largest tuple size for which
|
|
|
|
* TOAST_TUPLES_PER_PAGE tuples can fit on a disk page.
|
|
|
|
*
|
|
|
|
* XXX while these can be modified without initdb, some thought needs to be
|
|
|
|
* given to needs_toast_table() in toasting.c before unleashing random
|
2007-11-05 15:11:17 +01:00
|
|
|
* changes. Also see LOBLKSIZE in large_object.h, which can *not* be
|
|
|
|
* changed without initdb.
|
2000-08-04 06:16:17 +02:00
|
|
|
*/
|
2007-04-03 06:14:26 +02:00
|
|
|
#define TOAST_TUPLES_PER_PAGE 4
|
|
|
|
|
2007-02-05 05:22:18 +01:00
|
|
|
#define TOAST_TUPLE_THRESHOLD \
|
|
|
|
MAXALIGN_DOWN((BLCKSZ - \
|
2008-07-13 22:45:47 +02:00
|
|
|
MAXALIGN(SizeOfPageHeaderData + TOAST_TUPLES_PER_PAGE * sizeof(ItemIdData))) \
|
2007-04-03 06:14:26 +02:00
|
|
|
/ TOAST_TUPLES_PER_PAGE)
|
2000-08-04 06:16:17 +02:00
|
|
|
|
2007-02-05 05:22:18 +01:00
|
|
|
#define TOAST_TUPLE_TARGET TOAST_TUPLE_THRESHOLD
|
2000-08-04 06:16:17 +02:00
|
|
|
|
2001-02-15 21:57:01 +01:00
|
|
|
/*
|
|
|
|
* If an index value is larger than TOAST_INDEX_TARGET, we will try to
|
|
|
|
* compress it (we can't move it out-of-line, however). Note that this
|
2005-03-21 02:24:04 +01:00
|
|
|
* number is per-datum, not per-tuple, for simplicity in index_form_tuple().
|
2001-02-15 21:57:01 +01:00
|
|
|
*/
|
2007-02-05 05:22:18 +01:00
|
|
|
#define TOAST_INDEX_TARGET (MaxHeapTupleSize / 16)
|
2000-08-04 06:16:17 +02:00
|
|
|
|
|
|
|
/*
|
|
|
|
* When we store an oversize datum externally, we divide it into chunks
|
2001-03-22 05:01:46 +01:00
|
|
|
* containing at most TOAST_MAX_CHUNK_SIZE data bytes. This number *must*
|
2000-08-04 06:16:17 +02:00
|
|
|
* be small enough that the completed toast-table tuple (including the
|
2007-04-03 06:14:26 +02:00
|
|
|
* ID and sequence fields and all overhead) will fit on a page.
|
|
|
|
* The coding here sets the size on the theory that we want to fit
|
|
|
|
* EXTERN_TUPLES_PER_PAGE tuples of maximum size onto a page.
|
2000-08-04 06:16:17 +02:00
|
|
|
*
|
2007-04-03 06:14:26 +02:00
|
|
|
* NB: Changing TOAST_MAX_CHUNK_SIZE requires an initdb.
|
2000-08-04 06:16:17 +02:00
|
|
|
*/
|
2007-11-15 22:14:46 +01:00
|
|
|
#define EXTERN_TUPLES_PER_PAGE 4 /* tweak only this */
|
2007-04-03 06:14:26 +02:00
|
|
|
|
|
|
|
#define EXTERN_TUPLE_MAX_SIZE \
|
|
|
|
MAXALIGN_DOWN((BLCKSZ - \
|
2008-07-13 22:45:47 +02:00
|
|
|
MAXALIGN(SizeOfPageHeaderData + EXTERN_TUPLES_PER_PAGE * sizeof(ItemIdData))) \
|
2007-04-03 06:14:26 +02:00
|
|
|
/ EXTERN_TUPLES_PER_PAGE)
|
|
|
|
|
|
|
|
#define TOAST_MAX_CHUNK_SIZE \
|
|
|
|
(EXTERN_TUPLE_MAX_SIZE - \
|
|
|
|
MAXALIGN(offsetof(HeapTupleHeaderData, t_bits)) - \
|
|
|
|
sizeof(Oid) - \
|
|
|
|
sizeof(int32) - \
|
|
|
|
VARHDRSZ)
|
2000-07-04 01:10:14 +02:00
|
|
|
|
|
|
|
|
2000-07-22 13:18:47 +02:00
|
|
|
/* ----------
|
2005-11-20 19:38:20 +01:00
|
|
|
* toast_insert_or_update -
|
2000-07-22 13:18:47 +02:00
|
|
|
*
|
2005-11-20 19:38:20 +01:00
|
|
|
* Called by heap_insert() and heap_update().
|
|
|
|
* ----------
|
|
|
|
*/
|
|
|
|
extern HeapTuple toast_insert_or_update(Relation rel,
|
2007-11-15 22:14:46 +01:00
|
|
|
HeapTuple newtup, HeapTuple oldtup,
|
|
|
|
bool use_wal, bool use_fsm);
|
2005-11-20 19:38:20 +01:00
|
|
|
|
|
|
|
/* ----------
|
|
|
|
* toast_delete -
|
2000-08-04 06:16:17 +02:00
|
|
|
*
|
2005-11-20 19:38:20 +01:00
|
|
|
* Called by heap_delete().
|
2000-07-22 13:18:47 +02:00
|
|
|
* ----------
|
|
|
|
*/
|
2005-11-20 19:38:20 +01:00
|
|
|
extern void toast_delete(Relation rel, HeapTuple oldtup);
|
1999-12-21 01:06:44 +01:00
|
|
|
|
2000-07-22 13:18:47 +02:00
|
|
|
/* ----------
|
|
|
|
* heap_tuple_fetch_attr() -
|
|
|
|
*
|
|
|
|
* Fetches an external stored attribute from the toast
|
|
|
|
* relation. Does NOT decompress it, if stored external
|
|
|
|
* in compressed format.
|
|
|
|
* ----------
|
|
|
|
*/
|
2007-11-15 22:14:46 +01:00
|
|
|
extern struct varlena *heap_tuple_fetch_attr(struct varlena * attr);
|
2000-07-22 13:18:47 +02:00
|
|
|
|
|
|
|
/* ----------
|
|
|
|
* heap_tuple_untoast_attr() -
|
|
|
|
*
|
|
|
|
* Fully detoasts one attribute, fetching and/or decompressing
|
|
|
|
* it as needed.
|
|
|
|
* ----------
|
|
|
|
*/
|
2007-11-15 22:14:46 +01:00
|
|
|
extern struct varlena *heap_tuple_untoast_attr(struct varlena * attr);
|
1999-12-21 01:06:44 +01:00
|
|
|
|
2002-03-05 06:33:31 +01:00
|
|
|
/* ----------
|
|
|
|
* heap_tuple_untoast_attr_slice() -
|
|
|
|
*
|
2002-09-04 22:31:48 +02:00
|
|
|
* Fetches only the specified portion of an attribute.
|
|
|
|
* (Handles all cases for attribute storage)
|
2002-03-05 06:33:31 +01:00
|
|
|
* ----------
|
|
|
|
*/
|
2007-11-15 22:14:46 +01:00
|
|
|
extern struct varlena *heap_tuple_untoast_attr_slice(struct varlena * attr,
|
2002-09-04 22:31:48 +02:00
|
|
|
int32 sliceoffset,
|
|
|
|
int32 slicelength);
|
2002-03-05 06:33:31 +01:00
|
|
|
|
2004-06-05 03:55:05 +02:00
|
|
|
/* ----------
|
|
|
|
* toast_flatten_tuple_attribute -
|
|
|
|
*
|
|
|
|
* If a Datum is of composite type, "flatten" it to contain no toasted fields.
|
|
|
|
* This must be invoked on any potentially-composite field that is to be
|
2004-08-29 07:07:03 +02:00
|
|
|
* inserted into a tuple. Doing this preserves the invariant that toasting
|
2004-06-05 03:55:05 +02:00
|
|
|
* goes only one level deep in a tuple.
|
|
|
|
* ----------
|
|
|
|
*/
|
|
|
|
extern Datum toast_flatten_tuple_attribute(Datum value,
|
2004-08-29 07:07:03 +02:00
|
|
|
Oid typeId, int32 typeMod);
|
2004-06-05 03:55:05 +02:00
|
|
|
|
2001-02-15 21:57:01 +01:00
|
|
|
/* ----------
|
|
|
|
* toast_compress_datum -
|
|
|
|
*
|
|
|
|
* Create a compressed version of a varlena datum, if possible
|
|
|
|
* ----------
|
|
|
|
*/
|
|
|
|
extern Datum toast_compress_datum(Datum value);
|
|
|
|
|
2001-05-07 02:43:27 +02:00
|
|
|
/* ----------
|
|
|
|
* toast_raw_datum_size -
|
|
|
|
*
|
|
|
|
* Return the raw (detoasted) size of a varlena datum
|
|
|
|
* ----------
|
|
|
|
*/
|
|
|
|
extern Size toast_raw_datum_size(Datum value);
|
1999-12-21 01:06:44 +01:00
|
|
|
|
2005-07-06 21:02:54 +02:00
|
|
|
/* ----------
|
|
|
|
* toast_datum_size -
|
|
|
|
*
|
|
|
|
* Return the storage size of a varlena datum
|
|
|
|
* ----------
|
|
|
|
*/
|
|
|
|
extern Size toast_datum_size(Datum value);
|
|
|
|
|
2001-11-05 18:46:40 +01:00
|
|
|
#endif /* TUPTOASTER_H */
|