PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
reorderbuffer.h
Go to the documentation of this file.
1 /*
2  * reorderbuffer.h
3  * PostgreSQL logical replay/reorder buffer management.
4  *
5  * Copyright (c) 2012-2017, PostgreSQL Global Development Group
6  *
7  * src/include/replication/reorderbuffer.h
8  */
9 #ifndef REORDERBUFFER_H
10 #define REORDERBUFFER_H
11 
12 #include "access/htup_details.h"
13 #include "lib/ilist.h"
14 #include "storage/sinval.h"
15 #include "utils/hsearch.h"
16 #include "utils/relcache.h"
17 #include "utils/snapshot.h"
18 #include "utils/timestamp.h"
19 
20 /* an individual tuple, stored in one chunk of memory */
21 typedef struct ReorderBufferTupleBuf
22 {
23  /* position in preallocated list */
25 
26  /* tuple header, the interesting bit for users of logical decoding */
28 
29  /* pre-allocated size of tuple buffer, different from tuple size */
31 
32  /* actual tuple data follows */
34 
35 /* pointer to the data stored in a TupleBuf */
36 #define ReorderBufferTupleBufData(p) \
37  ((HeapTupleHeader) MAXALIGN(((char *) p) + sizeof(ReorderBufferTupleBuf)))
38 
39 /*
40  * Types of the change passed to a 'change' callback.
41  *
42  * For efficiency and simplicity reasons we want to keep Snapshots, CommandIds
43  * and ComboCids in the same list with the user visible INSERT/UPDATE/DELETE
44  * changes. Users of the decoding facilities will never see changes with
45  * *_INTERNAL_* actions.
46  *
47  * The INTERNAL_SPEC_INSERT and INTERNAL_SPEC_CONFIRM changes concern
48  * "speculative insertions", and their confirmation respectively. They're
49  * used by INSERT .. ON CONFLICT .. UPDATE. Users of logical decoding don't
50  * have to care about these.
51  */
53 {
63 };
64 
65 /*
66  * a single 'change', can be an insert (with one tuple), an update (old, new),
67  * or a delete (old).
68  *
69  * The same struct is also used internally for other purposes but that should
70  * never be visible outside reorderbuffer.c.
71  */
72 typedef struct ReorderBufferChange
73 {
75 
76  /* The type of change. */
78 
80 
81  /*
82  * Context data for the change. Which part of the union is valid depends
83  * on action.
84  */
85  union
86  {
87  /* Old, new tuples when action == *_INSERT|UPDATE|DELETE */
88  struct
89  {
90  /* relation that has been changed */
92 
93  /* no previously reassembled toast chunks are necessary anymore */
95 
96  /* valid for DELETE || UPDATE */
98  /* valid for INSERT || UPDATE */
100  } tp;
101 
102  /* Message with arbitrary data. */
103  struct
104  {
105  char *prefix;
107  char *message;
108  } msg;
109 
110  /* New snapshot, set when action == *_INTERNAL_SNAPSHOT */
112 
113  /*
114  * New command id for existing snapshot in a catalog changing tx. Set
115  * when action == *_INTERNAL_COMMAND_ID.
116  */
118 
119  /*
120  * New cid mapping for catalog changing transaction, set when action
121  * == *_INTERNAL_TUPLECID.
122  */
123  struct
124  {
130  } tuplecid;
131  } data;
132 
133  /*
134  * While in use this is how a change is linked into a transactions,
135  * otherwise it's the preallocated list.
136  */
139 
140 typedef struct ReorderBufferTXN
141 {
142  /*
143  * The transactions transaction id, can be a toplevel or sub xid.
144  */
146 
147  /* did the TX have catalog changes */
149 
150  /*
151  * Do we know this is a subxact?
152  */
154 
155  /*
156  * LSN of the first data carrying, WAL record with knowledge about this
157  * xid. This is allowed to *not* be first record adorned with this xid, if
158  * the previous records aren't relevant for logical decoding.
159  */
161 
162  /* ----
163  * LSN of the record that lead to this xact to be committed or
164  * aborted. This can be a
165  * * plain commit record
166  * * plain commit record, of a parent transaction
167  * * prepared transaction commit
168  * * plain abort record
169  * * prepared transaction abort
170  * * error during decoding
171  * ----
172  */
174 
175  /*
176  * LSN pointing to the end of the commit record + 1.
177  */
179 
180  /*
181  * LSN of the last lsn at which snapshot information reside, so we can
182  * restart decoding from there and fully recover this transaction from
183  * WAL.
184  */
186 
187  /* origin of the change that caused this transaction */
190 
191  /*
192  * Commit time, only known when we read the actual commit record.
193  */
195 
196  /*
197  * Base snapshot or NULL.
198  */
201 
202  /*
203  * How many ReorderBufferChange's do we have in this txn.
204  *
205  * Changes in subtransactions are *not* included but tracked separately.
206  */
207  uint64 nentries;
208 
209  /*
210  * How many of the above entries are stored in memory in contrast to being
211  * spilled to disk.
212  */
213  uint64 nentries_mem;
214 
215  /*
216  * List of ReorderBufferChange structs, including new Snapshots and new
217  * CommandIds
218  */
220 
221  /*
222  * List of (relation, ctid) => (cmin, cmax) mappings for catalog tuples.
223  * Those are always assigned to the toplevel transaction. (Keep track of
224  * #entries to create a hash of the right size)
225  */
227  uint64 ntuplecids;
228 
229  /*
230  * On-demand built hash for looking up the above values.
231  */
233 
234  /*
235  * Hash containing (potentially partial) toast entries. NULL if no toast
236  * tuples have been found for the current change.
237  */
239 
240  /*
241  * non-hierarchical list of subtransactions that are *not* aborted. Only
242  * used in toplevel transactions.
243  */
246 
247  /*
248  * Stored cache invalidations. This is not a linked list because we get
249  * all the invalidations at once.
250  */
253 
254  /* ---
255  * Position in one of three lists:
256  * * list of subtransactions if we are *known* to be subxact
257  * * list of toplevel xacts (can be an as-yet unknown subxact)
258  * * list of preallocated ReorderBufferTXNs
259  * ---
260  */
262 
264 
265 /* so we can define the callbacks used inside struct ReorderBuffer itself */
267 
268 /* change callback signature */
269 typedef void (*ReorderBufferApplyChangeCB) (
270  ReorderBuffer *rb,
271  ReorderBufferTXN *txn,
272  Relation relation,
273  ReorderBufferChange *change);
274 
275 /* begin callback signature */
276 typedef void (*ReorderBufferBeginCB) (
277  ReorderBuffer *rb,
278  ReorderBufferTXN *txn);
279 
280 /* commit callback signature */
281 typedef void (*ReorderBufferCommitCB) (
282  ReorderBuffer *rb,
283  ReorderBufferTXN *txn,
284  XLogRecPtr commit_lsn);
285 
286 /* message callback signature */
287 typedef void (*ReorderBufferMessageCB) (
288  ReorderBuffer *rb,
289  ReorderBufferTXN *txn,
290  XLogRecPtr message_lsn,
291  bool transactional,
292  const char *prefix, Size sz,
293  const char *message);
294 
296 {
297  /*
298  * xid => ReorderBufferTXN lookup table
299  */
301 
302  /*
303  * Transactions that could be a toplevel xact, ordered by LSN of the first
304  * record bearing that xid.
305  */
307 
308  /*
309  * one-entry sized cache for by_txn. Very frequently the same txn gets
310  * looked up over and over again.
311  */
314 
315  /*
316  * Callbacks to be called when a transactions commits.
317  */
322 
323  /*
324  * Pointer that will be passed untouched to the callbacks.
325  */
327 
328  /*
329  * Private memory context.
330  */
332 
333  /*
334  * Memory contexts for specific types objects
335  */
338 
339  /*
340  * Data structure slab cache.
341  *
342  * We allocate/deallocate some structures very frequently, to avoid bigger
343  * overhead we cache some unused ones here.
344  *
345  * The maximum number of cached entries is controlled by const variables
346  * on top of reorderbuffer.c
347  */
348 
349  /* cached ReorderBufferTupleBufs */
352 
354 
355  /* buffer for disk<->memory conversions */
356  char *outbuf;
358 };
359 
360 
363 
368 
371  bool transactional, const char *prefix,
372  Size message_size, const char *message);
374  XLogRecPtr commit_lsn, XLogRecPtr end_lsn,
375  TimestampTz commit_time, RepOriginId origin_id, XLogRecPtr origin_lsn);
378  XLogRecPtr commit_lsn, XLogRecPtr end_lsn);
382 
386  CommandId cid);
388  RelFileNode node, ItemPointerData pt,
389  CommandId cmin, CommandId cmax, CommandId combocid);
391  Size nmsgs, SharedInvalidationMessage *msgs);
393  SharedInvalidationMessage *invalidations);
398 
400 
402 
403 void StartupReorderBuffer(void);
404 
405 #endif
ReorderBuffer * ReorderBufferAllocate(void)
XLogRecPtr first_lsn
uint32 CommandId
Definition: c.h:411
TimestampTz commit_time
void(* ReorderBufferBeginCB)(ReorderBuffer *rb, ReorderBufferTXN *txn)
ReorderBufferTupleBuf * ReorderBufferGetTupleBuf(ReorderBuffer *, Size tuple_len)
struct ReorderBufferChange::@50::@52 msg
void ReorderBufferCommit(ReorderBuffer *, TransactionId, XLogRecPtr commit_lsn, XLogRecPtr end_lsn, TimestampTz commit_time, RepOriginId origin_id, XLogRecPtr origin_lsn)
Snapshot base_snapshot
bool ReorderBufferXidHasCatalogChanges(ReorderBuffer *, TransactionId xid)
void ReorderBufferQueueMessage(ReorderBuffer *, TransactionId, Snapshot snapshot, XLogRecPtr lsn, bool transactional, const char *prefix, Size message_size, const char *message)
ReorderBufferApplyChangeCB apply_change
void * private_data
RepOriginId origin_id
ReorderBufferTupleBuf * oldtuple
Definition: reorderbuffer.h:97
void ReorderBufferProcessXid(ReorderBuffer *, TransactionId xid, XLogRecPtr lsn)
uint32 TransactionId
Definition: c.h:397
bool ReorderBufferXidHasBaseSnapshot(ReorderBuffer *, TransactionId xid)
void ReorderBufferAssignChild(ReorderBuffer *, TransactionId, TransactionId, XLogRecPtr commit_lsn)
TransactionId by_txn_last_xid
void ReorderBufferAddSnapshot(ReorderBuffer *, TransactionId, XLogRecPtr lsn, struct SnapshotData *snap)
int64 TimestampTz
Definition: timestamp.h:39
XLogRecPtr current_restart_decoding_lsn
void StartupReorderBuffer(void)
uint16 RepOriginId
Definition: xlogdefs.h:51
void ReorderBufferForget(ReorderBuffer *, TransactionId, XLogRecPtr lsn)
ReorderBufferCommitCB commit
void ReorderBufferQueueChange(ReorderBuffer *, TransactionId, XLogRecPtr lsn, ReorderBufferChange *)
XLogRecPtr base_snapshot_lsn
enum ReorderBufferChangeType action
Definition: reorderbuffer.h:77
MemoryContext change_context
void ReorderBufferAddInvalidations(ReorderBuffer *, TransactionId, XLogRecPtr lsn, Size nmsgs, SharedInvalidationMessage *msgs)
XLogRecPtr origin_lsn
union ReorderBufferChange::@50 data
void ReorderBufferCommitChild(ReorderBuffer *, TransactionId, TransactionId, XLogRecPtr commit_lsn, XLogRecPtr end_lsn)
void ReorderBufferReturnTupleBuf(ReorderBuffer *, ReorderBufferTupleBuf *tuple)
ReorderBufferChange * ReorderBufferGetChange(ReorderBuffer *)
Definition: dynahash.c:193
ReorderBufferChangeType
Definition: reorderbuffer.h:52
ReorderBufferTupleBuf * newtuple
Definition: reorderbuffer.h:99
dlist_head changes
void ReorderBufferSetBaseSnapshot(ReorderBuffer *, TransactionId, XLogRecPtr lsn, struct SnapshotData *snap)
void ReorderBufferSetRestartPoint(ReorderBuffer *, XLogRecPtr ptr)
HeapTupleData tuple
Definition: reorderbuffer.h:27
unsigned int uint32
Definition: c.h:268
XLogRecPtr final_lsn
ItemPointerData tid
ReorderBufferMessageCB message
struct ReorderBufferChange::@50::@51 tp
void ReorderBufferXidSetCatalogChanges(ReorderBuffer *, TransactionId xid, XLogRecPtr lsn)
RepOriginId origin_id
Definition: reorderbuffer.h:79
void ReorderBufferAddNewTupleCids(ReorderBuffer *, TransactionId, XLogRecPtr lsn, RelFileNode node, ItemPointerData pt, CommandId cmin, CommandId cmax, CommandId combocid)
MemoryContext context
void ReorderBufferFree(ReorderBuffer *)
ReorderBufferTXN * by_txn_last_txn
void ReorderBufferAbort(ReorderBuffer *, TransactionId, XLogRecPtr lsn)
dlist_head toplevel_by_lsn
TransactionId xid
ReorderBufferTXN * ReorderBufferGetOldestTXN(ReorderBuffer *)
void ReorderBufferAddNewCommandId(ReorderBuffer *, TransactionId, XLogRecPtr lsn, CommandId cid)
void(* ReorderBufferCommitCB)(ReorderBuffer *rb, ReorderBufferTXN *txn, XLogRecPtr commit_lsn)
uint64 XLogRecPtr
Definition: xlogdefs.h:21
struct ReorderBufferTupleBuf ReorderBufferTupleBuf
XLogRecPtr end_lsn
void ReorderBufferAbortOld(ReorderBuffer *, TransactionId xid)
size_t Size
Definition: c.h:356
void(* ReorderBufferApplyChangeCB)(ReorderBuffer *rb, ReorderBufferTXN *txn, Relation relation, ReorderBufferChange *change)
struct ReorderBufferChange::@50::@53 tuplecid
SharedInvalidationMessage * invalidations
void ReorderBufferReturnChange(ReorderBuffer *, ReorderBufferChange *)
dlist_head subtxns
void ReorderBufferImmediateInvalidation(ReorderBuffer *, uint32 ninvalidations, SharedInvalidationMessage *invalidations)
Size nr_cached_tuplebufs
XLogRecPtr restart_decoding_lsn
void(* ReorderBufferMessageCB)(ReorderBuffer *rb, ReorderBufferTXN *txn, XLogRecPtr message_lsn, bool transactional, const char *prefix, Size sz, const char *message)
ReorderBufferBeginCB begin
MemoryContext txn_context
dlist_head tuplecids
slist_head cached_tuplebufs
struct ReorderBufferTXN ReorderBufferTXN
struct ReorderBufferChange ReorderBufferChange
RelFileNode relnode
Definition: reorderbuffer.h:91