diff options
Diffstat (limited to 'src/include/access/htup.h')
-rw-r--r-- | src/include/access/htup.h | 128 |
1 files changed, 107 insertions, 21 deletions
diff --git a/src/include/access/htup.h b/src/include/access/htup.h index ee816c568a8..32a27c972cb 100644 --- a/src/include/access/htup.h +++ b/src/include/access/htup.h @@ -7,7 +7,7 @@ * Portions Copyright (c) 1996-2007, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/include/access/htup.h,v 1.93 2007/04/06 04:21:43 tgl Exp $ + * $PostgreSQL: pgsql/src/include/access/htup.h,v 1.94 2007/09/20 17:56:32 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -184,8 +184,12 @@ typedef HeapTupleHeaderData *HeapTupleHeader; /* * information stored in t_infomask2: */ -#define HEAP_NATTS_MASK 0x7FF /* 11 bits for number of attributes */ -/* bits 0xF800 are currently unused */ +#define HEAP_NATTS_MASK 0x07FF /* 11 bits for number of attributes */ +/* bits 0x3800 are available */ +#define HEAP_HOT_UPDATED 0x4000 /* tuple was HOT-updated */ +#define HEAP_ONLY_TUPLE 0x8000 /* this is heap-only tuple */ + +#define HEAP2_XACT_MASK 0xC000 /* visibility-related bits */ /* * HeapTupleHeader accessor macros @@ -201,7 +205,7 @@ typedef HeapTupleHeaderData *HeapTupleHeader; #define HeapTupleHeaderSetXmin(tup, xid) \ ( \ - TransactionIdStore((xid), &(tup)->t_choice.t_heap.t_xmin) \ + (tup)->t_choice.t_heap.t_xmin = (xid) \ ) #define HeapTupleHeaderGetXmax(tup) \ @@ -211,7 +215,7 @@ typedef HeapTupleHeaderData *HeapTupleHeader; #define HeapTupleHeaderSetXmax(tup, xid) \ ( \ - TransactionIdStore((xid), &(tup)->t_choice.t_heap.t_xmax) \ + (tup)->t_choice.t_heap.t_xmax = (xid) \ ) /* @@ -255,7 +259,7 @@ do { \ #define HeapTupleHeaderSetXvac(tup, xid) \ do { \ Assert((tup)->t_infomask & HEAP_MOVED); \ - TransactionIdStore((xid), &(tup)->t_choice.t_heap.t_field3.t_xvac); \ + (tup)->t_choice.t_heap.t_field3.t_xvac = (xid); \ } while (0) #define HeapTupleHeaderGetDatumLength(tup) \ @@ -298,6 +302,43 @@ do { \ *((Oid *) ((char *)(tup) + (tup)->t_hoff - sizeof(Oid))) = (oid); \ } while (0) +/* + * Note that we stop considering a tuple HOT-updated as soon as it is known + * aborted or the would-be updating transaction is known aborted. For best + * efficiency, check tuple visibility before using this macro, so that the + * INVALID bits will be as up to date as possible. + */ +#define HeapTupleHeaderIsHotUpdated(tup) \ +( \ + ((tup)->t_infomask2 & HEAP_HOT_UPDATED) != 0 && \ + ((tup)->t_infomask & (HEAP_XMIN_INVALID | HEAP_XMAX_INVALID)) == 0 \ +) + +#define HeapTupleHeaderSetHotUpdated(tup) \ +( \ + (tup)->t_infomask2 |= HEAP_HOT_UPDATED \ +) + +#define HeapTupleHeaderClearHotUpdated(tup) \ +( \ + (tup)->t_infomask2 &= ~HEAP_HOT_UPDATED \ +) + +#define HeapTupleHeaderIsHeapOnly(tup) \ +( \ + (tup)->t_infomask2 & HEAP_ONLY_TUPLE \ +) + +#define HeapTupleHeaderSetHeapOnly(tup) \ +( \ + (tup)->t_infomask2 |= HEAP_ONLY_TUPLE \ +) + +#define HeapTupleHeaderClearHeapOnly(tup) \ +( \ + (tup)->t_infomask2 &= ~HEAP_ONLY_TUPLE \ +) + #define HeapTupleHeaderGetNatts(tup) \ ((tup)->t_infomask2 & HEAP_NATTS_MASK) @@ -331,6 +372,11 @@ do { \ * fit on one heap page. (Note that indexes could have more, because they * use a smaller tuple header.) We arrive at the divisor because each tuple * must be maxaligned, and it must have an associated item pointer. + * + * Note: with HOT, there could theoretically be more line pointers (not actual + * tuples) than this on a heap page. However we constrain the number of line + * pointers to this anyway, to avoid excessive line-pointer bloat and not + * require increases in the size of work arrays. */ #define MaxHeapTuplesPerPage \ ((int) ((BLCKSZ - offsetof(PageHeaderData, pd_linp)) / \ @@ -484,6 +530,24 @@ typedef HeapTupleData *HeapTuple; #define HeapTupleHasExternal(tuple) \ (((tuple)->t_data->t_infomask & HEAP_HASEXTERNAL) != 0) +#define HeapTupleIsHotUpdated(tuple) \ + HeapTupleHeaderIsHotUpdated((tuple)->t_data) + +#define HeapTupleSetHotUpdated(tuple) \ + HeapTupleHeaderSetHotUpdated((tuple)->t_data) + +#define HeapTupleClearHotUpdated(tuple) \ + HeapTupleHeaderClearHotUpdated((tuple)->t_data) + +#define HeapTupleIsHeapOnly(tuple) \ + HeapTupleHeaderIsHeapOnly((tuple)->t_data) + +#define HeapTupleSetHeapOnly(tuple) \ + HeapTupleHeaderSetHeapOnly((tuple)->t_data) + +#define HeapTupleClearHeapOnly(tuple) \ + HeapTupleHeaderClearHeapOnly((tuple)->t_data) + #define HeapTupleGetOid(tuple) \ HeapTupleHeaderGetOid((tuple)->t_data) @@ -497,27 +561,30 @@ typedef HeapTupleData *HeapTuple; * XLOG allows to store some information in high 4 bits of log * record xl_info field. We use 3 for opcode and one for init bit. */ -#define XLOG_HEAP_INSERT 0x00 -#define XLOG_HEAP_DELETE 0x10 -#define XLOG_HEAP_UPDATE 0x20 -#define XLOG_HEAP_MOVE 0x30 -#define XLOG_HEAP_CLEAN 0x40 -#define XLOG_HEAP_NEWPAGE 0x50 -#define XLOG_HEAP_LOCK 0x60 -#define XLOG_HEAP_INPLACE 0x70 -#define XLOG_HEAP_OPMASK 0x70 +#define XLOG_HEAP_INSERT 0x00 +#define XLOG_HEAP_DELETE 0x10 +#define XLOG_HEAP_UPDATE 0x20 +#define XLOG_HEAP_MOVE 0x30 +#define XLOG_HEAP_HOT_UPDATE 0x40 +#define XLOG_HEAP_NEWPAGE 0x50 +#define XLOG_HEAP_LOCK 0x60 +#define XLOG_HEAP_INPLACE 0x70 + +#define XLOG_HEAP_OPMASK 0x70 /* * When we insert 1st item on new page in INSERT/UPDATE * we can (and we do) restore entire page in redo */ -#define XLOG_HEAP_INIT_PAGE 0x80 +#define XLOG_HEAP_INIT_PAGE 0x80 /* * We ran out of opcodes, so heapam.c now has a second RmgrId. These opcodes * are associated with RM_HEAP2_ID, but are not logically different from * the ones above associated with RM_HEAP_ID. We apply XLOG_HEAP_OPMASK, * although currently XLOG_HEAP_INIT_PAGE is not used for any of these. */ -#define XLOG_HEAP2_FREEZE 0x00 +#define XLOG_HEAP2_FREEZE 0x00 +#define XLOG_HEAP2_CLEAN 0x10 +#define XLOG_HEAP2_CLEAN_MOVE 0x20 /* * All what we need to find changed tuple @@ -569,7 +636,7 @@ typedef struct xl_heap_insert #define SizeOfHeapInsert (offsetof(xl_heap_insert, target) + SizeOfHeapTid) -/* This is what we need to know about update|move */ +/* This is what we need to know about update|move|hot_update */ typedef struct xl_heap_update { xl_heaptid target; /* deleted tuple id */ @@ -580,15 +647,34 @@ typedef struct xl_heap_update #define SizeOfHeapUpdate (offsetof(xl_heap_update, newtid) + SizeOfIptrData) -/* This is what we need to know about vacuum page cleanup */ +/* + * This is what we need to know about vacuum page cleanup/redirect + * + * The array of OffsetNumbers following the fixed part of the record contains: + * * for each redirected item: the item offset, then the offset redirected to + * * for each now-dead item: the item offset + * * for each now-unused item: the item offset + * The total number of OffsetNumbers is therefore 2*nredirected+ndead+nunused. + * Note that nunused is not explicitly stored, but may be found by reference + * to the total record length. + * + * If the opcode is CLEAN_MOVE instead of CLEAN, then each redirection pair + * should be interpreted as physically moving the "to" item pointer to the + * "from" slot, rather than placing a redirection item in the "from" slot. + * The moved pointers should be replaced by LP_UNUSED items (there will not + * be explicit entries in the "now-unused" list for this). Also, the + * HEAP_ONLY bit in the moved tuples must be turned off. + */ typedef struct xl_heap_clean { RelFileNode node; BlockNumber block; - /* UNUSED OFFSET NUMBERS FOLLOW AT THE END */ + uint16 nredirected; + uint16 ndead; + /* OFFSET NUMBERS FOLLOW */ } xl_heap_clean; -#define SizeOfHeapClean (offsetof(xl_heap_clean, block) + sizeof(BlockNumber)) +#define SizeOfHeapClean (offsetof(xl_heap_clean, ndead) + sizeof(uint16)) /* This is for replacing a page's contents in toto */ /* NB: this is used for indexes as well as heaps */ |