Header And Logo

PostgreSQL
| The world's most advanced open source database.

heapam_xlog.h

Go to the documentation of this file.
00001 /*-------------------------------------------------------------------------
00002  *
00003  * heapam_xlog.h
00004  *    POSTGRES heap access XLOG definitions.
00005  *
00006  *
00007  * Portions Copyright (c) 1996-2013, PostgreSQL Global Development Group
00008  * Portions Copyright (c) 1994, Regents of the University of California
00009  *
00010  * src/include/access/heapam_xlog.h
00011  *
00012  *-------------------------------------------------------------------------
00013  */
00014 #ifndef HEAPAM_XLOG_H
00015 #define HEAPAM_XLOG_H
00016 
00017 #include "access/htup.h"
00018 #include "access/xlog.h"
00019 #include "storage/bufpage.h"
00020 #include "storage/relfilenode.h"
00021 #include "utils/relcache.h"
00022 
00023 
00024 /*
00025  * WAL record definitions for heapam.c's WAL operations
00026  *
00027  * XLOG allows to store some information in high 4 bits of log
00028  * record xl_info field.  We use 3 for opcode and one for init bit.
00029  */
00030 #define XLOG_HEAP_INSERT        0x00
00031 #define XLOG_HEAP_DELETE        0x10
00032 #define XLOG_HEAP_UPDATE        0x20
00033 /* 0x030 is free, was XLOG_HEAP_MOVE */
00034 #define XLOG_HEAP_HOT_UPDATE    0x40
00035 #define XLOG_HEAP_NEWPAGE       0x50
00036 #define XLOG_HEAP_LOCK          0x60
00037 #define XLOG_HEAP_INPLACE       0x70
00038 
00039 #define XLOG_HEAP_OPMASK        0x70
00040 /*
00041  * When we insert 1st item on new page in INSERT, UPDATE, HOT_UPDATE,
00042  * or MULTI_INSERT, we can (and we do) restore entire page in redo
00043  */
00044 #define XLOG_HEAP_INIT_PAGE     0x80
00045 /*
00046  * We ran out of opcodes, so heapam.c now has a second RmgrId.  These opcodes
00047  * are associated with RM_HEAP2_ID, but are not logically different from
00048  * the ones above associated with RM_HEAP_ID.  XLOG_HEAP_OPMASK applies to
00049  * these, too.
00050  */
00051 #define XLOG_HEAP2_FREEZE       0x00
00052 #define XLOG_HEAP2_CLEAN        0x10
00053 /* 0x20 is free, was XLOG_HEAP2_CLEAN_MOVE */
00054 #define XLOG_HEAP2_CLEANUP_INFO 0x30
00055 #define XLOG_HEAP2_VISIBLE      0x40
00056 #define XLOG_HEAP2_MULTI_INSERT 0x50
00057 #define XLOG_HEAP2_LOCK_UPDATED 0x60
00058 
00059 /*
00060  * All what we need to find changed tuple
00061  *
00062  * NB: on most machines, sizeof(xl_heaptid) will include some trailing pad
00063  * bytes for alignment.  We don't want to store the pad space in the XLOG,
00064  * so use SizeOfHeapTid for space calculations.  Similar comments apply for
00065  * the other xl_FOO structs.
00066  */
00067 typedef struct xl_heaptid
00068 {
00069     RelFileNode node;
00070     ItemPointerData tid;        /* changed tuple id */
00071 } xl_heaptid;
00072 
00073 #define SizeOfHeapTid       (offsetof(xl_heaptid, tid) + SizeOfIptrData)
00074 
00075 /* This is what we need to know about delete */
00076 typedef struct xl_heap_delete
00077 {
00078     xl_heaptid  target;         /* deleted tuple id */
00079     TransactionId xmax;         /* xmax of the deleted tuple */
00080     uint8       infobits_set;   /* infomask bits */
00081     bool        all_visible_cleared;    /* PD_ALL_VISIBLE was cleared */
00082 } xl_heap_delete;
00083 
00084 #define SizeOfHeapDelete    (offsetof(xl_heap_delete, all_visible_cleared) + sizeof(bool))
00085 
00086 /*
00087  * We don't store the whole fixed part (HeapTupleHeaderData) of an inserted
00088  * or updated tuple in WAL; we can save a few bytes by reconstructing the
00089  * fields that are available elsewhere in the WAL record, or perhaps just
00090  * plain needn't be reconstructed.  These are the fields we must store.
00091  * NOTE: t_hoff could be recomputed, but we may as well store it because
00092  * it will come for free due to alignment considerations.
00093  */
00094 typedef struct xl_heap_header
00095 {
00096     uint16      t_infomask2;
00097     uint16      t_infomask;
00098     uint8       t_hoff;
00099 } xl_heap_header;
00100 
00101 #define SizeOfHeapHeader    (offsetof(xl_heap_header, t_hoff) + sizeof(uint8))
00102 
00103 /* This is what we need to know about insert */
00104 typedef struct xl_heap_insert
00105 {
00106     xl_heaptid  target;         /* inserted tuple id */
00107     bool        all_visible_cleared;    /* PD_ALL_VISIBLE was cleared */
00108     /* xl_heap_header & TUPLE DATA FOLLOWS AT END OF STRUCT */
00109 } xl_heap_insert;
00110 
00111 #define SizeOfHeapInsert    (offsetof(xl_heap_insert, all_visible_cleared) + sizeof(bool))
00112 
00113 /*
00114  * This is what we need to know about a multi-insert. The record consists of
00115  * xl_heap_multi_insert header, followed by a xl_multi_insert_tuple and tuple
00116  * data for each tuple. 'offsets' array is omitted if the whole page is
00117  * reinitialized (XLOG_HEAP_INIT_PAGE)
00118  */
00119 typedef struct xl_heap_multi_insert
00120 {
00121     RelFileNode node;
00122     BlockNumber blkno;
00123     bool        all_visible_cleared;
00124     uint16      ntuples;
00125     OffsetNumber offsets[1];
00126 
00127     /* TUPLE DATA (xl_multi_insert_tuples) FOLLOW AT END OF STRUCT */
00128 } xl_heap_multi_insert;
00129 
00130 #define SizeOfHeapMultiInsert   offsetof(xl_heap_multi_insert, offsets)
00131 
00132 typedef struct xl_multi_insert_tuple
00133 {
00134     uint16      datalen;        /* size of tuple data that follows */
00135     uint16      t_infomask2;
00136     uint16      t_infomask;
00137     uint8       t_hoff;
00138     /* TUPLE DATA FOLLOWS AT END OF STRUCT */
00139 } xl_multi_insert_tuple;
00140 
00141 #define SizeOfMultiInsertTuple  (offsetof(xl_multi_insert_tuple, t_hoff) + sizeof(uint8))
00142 
00143 /* This is what we need to know about update|hot_update */
00144 typedef struct xl_heap_update
00145 {
00146     xl_heaptid  target;         /* deleted tuple id */
00147     TransactionId old_xmax;     /* xmax of the old tuple */
00148     TransactionId new_xmax;     /* xmax of the new tuple */
00149     ItemPointerData newtid;     /* new inserted tuple id */
00150     uint8       old_infobits_set;   /* infomask bits to set on old tuple */
00151     bool        all_visible_cleared;    /* PD_ALL_VISIBLE was cleared */
00152     bool        new_all_visible_cleared;        /* same for the page of newtid */
00153     /* NEW TUPLE xl_heap_header AND TUPLE DATA FOLLOWS AT END OF STRUCT */
00154 } xl_heap_update;
00155 
00156 #define SizeOfHeapUpdate    (offsetof(xl_heap_update, new_all_visible_cleared) + sizeof(bool))
00157 
00158 /*
00159  * This is what we need to know about vacuum page cleanup/redirect
00160  *
00161  * The array of OffsetNumbers following the fixed part of the record contains:
00162  *  * for each redirected item: the item offset, then the offset redirected to
00163  *  * for each now-dead item: the item offset
00164  *  * for each now-unused item: the item offset
00165  * The total number of OffsetNumbers is therefore 2*nredirected+ndead+nunused.
00166  * Note that nunused is not explicitly stored, but may be found by reference
00167  * to the total record length.
00168  */
00169 typedef struct xl_heap_clean
00170 {
00171     RelFileNode node;
00172     BlockNumber block;
00173     TransactionId latestRemovedXid;
00174     uint16      nredirected;
00175     uint16      ndead;
00176     /* OFFSET NUMBERS FOLLOW */
00177 } xl_heap_clean;
00178 
00179 #define SizeOfHeapClean (offsetof(xl_heap_clean, ndead) + sizeof(uint16))
00180 
00181 /*
00182  * Cleanup_info is required in some cases during a lazy VACUUM.
00183  * Used for reporting the results of HeapTupleHeaderAdvanceLatestRemovedXid()
00184  * see vacuumlazy.c for full explanation
00185  */
00186 typedef struct xl_heap_cleanup_info
00187 {
00188     RelFileNode node;
00189     TransactionId latestRemovedXid;
00190 } xl_heap_cleanup_info;
00191 
00192 #define SizeOfHeapCleanupInfo (sizeof(xl_heap_cleanup_info))
00193 
00194 /* This is for replacing a page's contents in toto */
00195 /* NB: this is used for indexes as well as heaps */
00196 typedef struct xl_heap_newpage
00197 {
00198     RelFileNode node;
00199     ForkNumber  forknum;
00200     BlockNumber blkno;          /* location of new page */
00201     /* entire page contents follow at end of record */
00202 } xl_heap_newpage;
00203 
00204 #define SizeOfHeapNewpage   (offsetof(xl_heap_newpage, blkno) + sizeof(BlockNumber))
00205 
00206 /* flags for infobits_set */
00207 #define XLHL_XMAX_IS_MULTI      0x01
00208 #define XLHL_XMAX_LOCK_ONLY     0x02
00209 #define XLHL_XMAX_EXCL_LOCK     0x04
00210 #define XLHL_XMAX_KEYSHR_LOCK   0x08
00211 #define XLHL_KEYS_UPDATED       0x10
00212 
00213 /* This is what we need to know about lock */
00214 typedef struct xl_heap_lock
00215 {
00216     xl_heaptid  target;         /* locked tuple id */
00217     TransactionId locking_xid;  /* might be a MultiXactId not xid */
00218     int8        infobits_set;   /* infomask and infomask2 bits to set */
00219 } xl_heap_lock;
00220 
00221 #define SizeOfHeapLock  (offsetof(xl_heap_lock, infobits_set) + sizeof(int8))
00222 
00223 /* This is what we need to know about locking an updated version of a row */
00224 typedef struct xl_heap_lock_updated
00225 {
00226     xl_heaptid  target;
00227     TransactionId   xmax;
00228     uint8       infobits_set;
00229 } xl_heap_lock_updated;
00230 
00231 #define SizeOfHeapLockUpdated   (offsetof(xl_heap_lock_updated, infobits_set) + sizeof(uint8))
00232 
00233 /* This is what we need to know about in-place update */
00234 typedef struct xl_heap_inplace
00235 {
00236     xl_heaptid  target;         /* updated tuple id */
00237     /* TUPLE DATA FOLLOWS AT END OF STRUCT */
00238 } xl_heap_inplace;
00239 
00240 #define SizeOfHeapInplace   (offsetof(xl_heap_inplace, target) + SizeOfHeapTid)
00241 
00242 /* This is what we need to know about tuple freezing during vacuum */
00243 typedef struct xl_heap_freeze
00244 {
00245     RelFileNode node;
00246     BlockNumber block;
00247     TransactionId cutoff_xid;
00248     MultiXactId cutoff_multi;
00249     /* TUPLE OFFSET NUMBERS FOLLOW AT THE END */
00250 } xl_heap_freeze;
00251 
00252 #define SizeOfHeapFreeze (offsetof(xl_heap_freeze, cutoff_multi) + sizeof(MultiXactId))
00253 
00254 /* This is what we need to know about setting a visibility map bit */
00255 typedef struct xl_heap_visible
00256 {
00257     RelFileNode node;
00258     BlockNumber block;
00259     TransactionId cutoff_xid;
00260 } xl_heap_visible;
00261 
00262 #define SizeOfHeapVisible (offsetof(xl_heap_visible, cutoff_xid) + sizeof(TransactionId))
00263 
00264 extern void HeapTupleHeaderAdvanceLatestRemovedXid(HeapTupleHeader tuple,
00265                                        TransactionId *latestRemovedXid);
00266 
00267 extern void heap_redo(XLogRecPtr lsn, XLogRecord *rptr);
00268 extern void heap_desc(StringInfo buf, uint8 xl_info, char *rec);
00269 extern void heap2_redo(XLogRecPtr lsn, XLogRecord *rptr);
00270 extern void heap2_desc(StringInfo buf, uint8 xl_info, char *rec);
00271 
00272 extern XLogRecPtr log_heap_cleanup_info(RelFileNode rnode,
00273                       TransactionId latestRemovedXid);
00274 extern XLogRecPtr log_heap_clean(Relation reln, Buffer buffer,
00275                OffsetNumber *redirected, int nredirected,
00276                OffsetNumber *nowdead, int ndead,
00277                OffsetNumber *nowunused, int nunused,
00278                TransactionId latestRemovedXid);
00279 extern XLogRecPtr log_heap_freeze(Relation reln, Buffer buffer,
00280                 TransactionId cutoff_xid, MultiXactId cutoff_multi,
00281                 OffsetNumber *offsets, int offcnt);
00282 extern XLogRecPtr log_heap_visible(RelFileNode rnode, Buffer heap_buffer,
00283                  Buffer vm_buffer, TransactionId cutoff_xid);
00284 extern XLogRecPtr log_newpage(RelFileNode *rnode, ForkNumber forkNum,
00285             BlockNumber blk, Page page);
00286 extern XLogRecPtr log_newpage_buffer(Buffer buffer);
00287 
00288 #endif   /* HEAPAM_XLOG_H */