OSDN Git Service

rebuid:
[eos/hostdependX86MAC64.git] / util / X86MAC64 / include / postgresql / server / replication / reorderbuffer.h
1 /*
2  * reorderbuffer.h
3  *        PostgreSQL logical replay/reorder buffer management.
4  *
5  * Copyright (c) 2012-2014, 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
14 #include "lib/ilist.h"
15
16 #include "storage/sinval.h"
17
18 #include "utils/hsearch.h"
19 #include "utils/rel.h"
20 #include "utils/snapshot.h"
21 #include "utils/timestamp.h"
22
23 /* an individual tuple, stored in one chunk of memory */
24 typedef struct ReorderBufferTupleBuf
25 {
26         /* position in preallocated list */
27         slist_node      node;
28
29         /* tuple, stored sequentially */
30         HeapTupleData tuple;
31         HeapTupleHeaderData header;
32         char            data[MaxHeapTupleSize];
33 } ReorderBufferTupleBuf;
34
35 /*
36  * Types of the change passed to a 'change' callback.
37  *
38  * For efficiency and simplicity reasons we want to keep Snapshots, CommandIds
39  * and ComboCids in the same list with the user visible INSERT/UPDATE/DELETE
40  * changes. Users of the decoding facilities will never see changes with
41  * *_INTERNAL_* actions.
42  */
43 enum ReorderBufferChangeType
44 {
45         REORDER_BUFFER_CHANGE_INSERT,
46         REORDER_BUFFER_CHANGE_UPDATE,
47         REORDER_BUFFER_CHANGE_DELETE,
48         REORDER_BUFFER_CHANGE_INTERNAL_SNAPSHOT,
49         REORDER_BUFFER_CHANGE_INTERNAL_COMMAND_ID,
50         REORDER_BUFFER_CHANGE_INTERNAL_TUPLECID
51 };
52
53 /*
54  * a single 'change', can be an insert (with one tuple), an update (old, new),
55  * or a delete (old).
56  *
57  * The same struct is also used internally for other purposes but that should
58  * never be visible outside reorderbuffer.c.
59  */
60 typedef struct ReorderBufferChange
61 {
62         XLogRecPtr      lsn;
63
64         /* The type of change. */
65         enum ReorderBufferChangeType action;
66
67         /*
68          * Context data for the change, which part of the union is valid depends
69          * on action/action_internal.
70          */
71         union
72         {
73                 /* Old, new tuples when action == *_INSERT|UPDATE|DELETE */
74                 struct
75                 {
76                         /* relation that has been changed */
77                         RelFileNode relnode;
78
79                         /* no previously reassembled toast chunks are necessary anymore */
80                         bool clear_toast_afterwards;
81
82                         /* valid for DELETE || UPDATE */
83                         ReorderBufferTupleBuf *oldtuple;
84                         /* valid for INSERT || UPDATE */
85                         ReorderBufferTupleBuf *newtuple;
86                 }                       tp;
87
88                 /* New snapshot, set when action == *_INTERNAL_SNAPSHOT */
89                 Snapshot        snapshot;
90
91                 /*
92                  * New command id for existing snapshot in a catalog changing tx. Set
93                  * when action == *_INTERNAL_COMMAND_ID.
94                  */
95                 CommandId       command_id;
96
97                 /*
98                  * New cid mapping for catalog changing transaction, set when action
99                  * == *_INTERNAL_TUPLECID.
100                  */
101                 struct
102                 {
103                         RelFileNode node;
104                         ItemPointerData tid;
105                         CommandId       cmin;
106                         CommandId       cmax;
107                         CommandId       combocid;
108                 }                       tuplecid;
109         }                       data;
110
111         /*
112          * While in use this is how a change is linked into a transactions,
113          * otherwise it's the preallocated list.
114          */
115         dlist_node      node;
116 } ReorderBufferChange;
117
118 typedef struct ReorderBufferTXN
119 {
120         /*
121          * The transactions transaction id, can be a toplevel or sub xid.
122          */
123         TransactionId xid;
124
125         /* did the TX have catalog changes */
126         bool            has_catalog_changes;
127
128         /*
129          * Do we know this is a subxact?
130          */
131         bool            is_known_as_subxact;
132
133         /*
134          * LSN of the first data carrying, WAL record with knowledge about this
135          * xid. This is allowed to *not* be first record adorned with this xid, if
136          * the previous records aren't relevant for logical decoding.
137          */
138         XLogRecPtr      first_lsn;
139
140         /* ----
141          * LSN of the record that lead to this xact to be committed or
142          * aborted. This can be a
143          * * plain commit record
144          * * plain commit record, of a parent transaction
145          * * prepared transaction commit
146          * * plain abort record
147          * * prepared transaction abort
148          * * error during decoding
149          * ----
150          */
151         XLogRecPtr      final_lsn;
152
153         /*
154          * LSN pointing to the end of the commit record + 1.
155          */
156         XLogRecPtr      end_lsn;
157
158         /*
159          * LSN of the last lsn at which snapshot information reside, so we can
160          * restart decoding from there and fully recover this transaction from
161          * WAL.
162          */
163         XLogRecPtr      restart_decoding_lsn;
164
165         /*
166          * Commit time, only known when we read the actual commit record.
167          */
168         TimestampTz commit_time;
169
170         /*
171          * Base snapshot or NULL.
172          */
173         Snapshot        base_snapshot;
174         XLogRecPtr      base_snapshot_lsn;
175
176         /*
177          * How many ReorderBufferChange's do we have in this txn.
178          *
179          * Changes in subtransactions are *not* included but tracked separately.
180          */
181         uint64          nentries;
182
183         /*
184          * How many of the above entries are stored in memory in contrast to being
185          * spilled to disk.
186          */
187         uint64          nentries_mem;
188
189         /*
190          * List of ReorderBufferChange structs, including new Snapshots and new
191          * CommandIds
192          */
193         dlist_head      changes;
194
195         /*
196          * List of (relation, ctid) => (cmin, cmax) mappings for catalog tuples.
197          * Those are always assigned to the toplevel transaction. (Keep track of
198          * #entries to create a hash of the right size)
199          */
200         dlist_head      tuplecids;
201         uint64          ntuplecids;
202
203         /*
204          * On-demand built hash for looking up the above values.
205          */
206         HTAB       *tuplecid_hash;
207
208         /*
209          * Hash containing (potentially partial) toast entries. NULL if no toast
210          * tuples have been found for the current change.
211          */
212         HTAB       *toast_hash;
213
214         /*
215          * non-hierarchical list of subtransactions that are *not* aborted. Only
216          * used in toplevel transactions.
217          */
218         dlist_head      subtxns;
219         uint32          nsubtxns;
220
221         /*
222          * Stored cache invalidations. This is not a linked list because we get
223          * all the invalidations at once.
224          */
225         uint32          ninvalidations;
226         SharedInvalidationMessage *invalidations;
227
228         /* ---
229          * Position in one of three lists:
230          * * list of subtransactions if we are *known* to be subxact
231          * * list of toplevel xacts (can be a as-yet unknown subxact)
232          * * list of preallocated ReorderBufferTXNs
233          * ---
234          */
235         dlist_node      node;
236
237 } ReorderBufferTXN;
238
239 /* so we can define the callbacks used inside struct ReorderBuffer itself */
240 typedef struct ReorderBuffer ReorderBuffer;
241
242 /* change callback signature */
243 typedef void (*ReorderBufferApplyChangeCB) (
244                                                                                                                 ReorderBuffer *rb,
245                                                                                                                 ReorderBufferTXN *txn,
246                                                                                                                 Relation relation,
247                                                                                                 ReorderBufferChange *change);
248
249 /* begin callback signature */
250 typedef void (*ReorderBufferBeginCB) (
251                                                                                                   ReorderBuffer *rb,
252                                                                                                   ReorderBufferTXN *txn);
253
254 /* commit callback signature */
255 typedef void (*ReorderBufferCommitCB) (
256                                                                                                    ReorderBuffer *rb,
257                                                                                                    ReorderBufferTXN *txn,
258                                                                                                    XLogRecPtr commit_lsn);
259
260 struct ReorderBuffer
261 {
262         /*
263          * xid => ReorderBufferTXN lookup table
264          */
265         HTAB       *by_txn;
266
267         /*
268          * Transactions that could be a toplevel xact, ordered by LSN of the first
269          * record bearing that xid..
270          */
271         dlist_head      toplevel_by_lsn;
272
273         /*
274          * one-entry sized cache for by_txn. Very frequently the same txn gets
275          * looked up over and over again.
276          */
277         TransactionId by_txn_last_xid;
278         ReorderBufferTXN *by_txn_last_txn;
279
280         /*
281          * Callacks to be called when a transactions commits.
282          */
283         ReorderBufferBeginCB begin;
284         ReorderBufferApplyChangeCB apply_change;
285         ReorderBufferCommitCB commit;
286
287         /*
288          * Pointer that will be passed untouched to the callbacks.
289          */
290         void       *private_data;
291
292         /*
293          * Private memory context.
294          */
295         MemoryContext context;
296
297         /*
298          * Data structure slab cache.
299          *
300          * We allocate/deallocate some structures very frequently, to avoid bigger
301          * overhead we cache some unused ones here.
302          *
303          * The maximum number of cached entries is controlled by const variables
304          * ontop of reorderbuffer.c
305          */
306
307         /* cached ReorderBufferTXNs */
308         dlist_head      cached_transactions;
309         Size            nr_cached_transactions;
310
311         /* cached ReorderBufferChanges */
312         dlist_head      cached_changes;
313         Size            nr_cached_changes;
314
315         /* cached ReorderBufferTupleBufs */
316         slist_head      cached_tuplebufs;
317         Size            nr_cached_tuplebufs;
318
319         XLogRecPtr      current_restart_decoding_lsn;
320
321         /* buffer for disk<->memory conversions */
322         char       *outbuf;
323         Size            outbufsize;
324 };
325
326
327 ReorderBuffer *ReorderBufferAllocate(void);
328 void            ReorderBufferFree(ReorderBuffer *);
329
330 ReorderBufferTupleBuf *ReorderBufferGetTupleBuf(ReorderBuffer *);
331 void            ReorderBufferReturnTupleBuf(ReorderBuffer *, ReorderBufferTupleBuf *tuple);
332 ReorderBufferChange *ReorderBufferGetChange(ReorderBuffer *);
333 void            ReorderBufferReturnChange(ReorderBuffer *, ReorderBufferChange *);
334
335 void            ReorderBufferQueueChange(ReorderBuffer *, TransactionId, XLogRecPtr lsn, ReorderBufferChange *);
336 void ReorderBufferCommit(ReorderBuffer *, TransactionId,
337                                         XLogRecPtr commit_lsn, XLogRecPtr end_lsn,
338                                         TimestampTz commit_time);
339 void            ReorderBufferAssignChild(ReorderBuffer *, TransactionId, TransactionId, XLogRecPtr commit_lsn);
340 void ReorderBufferCommitChild(ReorderBuffer *, TransactionId, TransactionId,
341                                                  XLogRecPtr commit_lsn, XLogRecPtr end_lsn);
342 void            ReorderBufferAbort(ReorderBuffer *, TransactionId, XLogRecPtr lsn);
343 void            ReorderBufferAbortOld(ReorderBuffer *, TransactionId xid);
344 void            ReorderBufferForget(ReorderBuffer *, TransactionId, XLogRecPtr lsn);
345
346 void            ReorderBufferSetBaseSnapshot(ReorderBuffer *, TransactionId, XLogRecPtr lsn, struct SnapshotData *snap);
347 void            ReorderBufferAddSnapshot(ReorderBuffer *, TransactionId, XLogRecPtr lsn, struct SnapshotData *snap);
348 void ReorderBufferAddNewCommandId(ReorderBuffer *, TransactionId, XLogRecPtr lsn,
349                                                          CommandId cid);
350 void ReorderBufferAddNewTupleCids(ReorderBuffer *, TransactionId, XLogRecPtr lsn,
351                                                          RelFileNode node, ItemPointerData pt,
352                                                  CommandId cmin, CommandId cmax, CommandId combocid);
353 void ReorderBufferAddInvalidations(ReorderBuffer *, TransactionId, XLogRecPtr lsn,
354                                                           Size nmsgs, SharedInvalidationMessage *msgs);
355 bool            ReorderBufferIsXidKnown(ReorderBuffer *, TransactionId xid);
356 void            ReorderBufferXidSetCatalogChanges(ReorderBuffer *, TransactionId xid, XLogRecPtr lsn);
357 bool            ReorderBufferXidHasCatalogChanges(ReorderBuffer *, TransactionId xid);
358 bool            ReorderBufferXidHasBaseSnapshot(ReorderBuffer *, TransactionId xid);
359
360 ReorderBufferTXN *ReorderBufferGetOldestTXN(ReorderBuffer *);
361
362 void            ReorderBufferSetRestartPoint(ReorderBuffer *, XLogRecPtr ptr);
363
364 void            StartupReorderBuffer(void);
365
366 #endif