reorderbuffer.h 12 KB

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