From a06deb303b60274945cfb64dce5afb14b0d4b577 Mon Sep 17 00:00:00 2001 From: Hayato Kuroda Date: Mon, 27 Nov 2023 10:15:01 +0000 Subject: [PATCH v202311272 4/4] (WIP) add is_transactional attribute in xl_seq_rec --- src/backend/commands/sequence.c | 12 + src/backend/replication/logical/decode.c | 75 +--- .../replication/logical/reorderbuffer.c | 402 ------------------ src/include/access/rmgrlist.h | 2 +- src/include/access/xlog_internal.h | 2 +- src/include/commands/sequence.h | 1 + src/include/replication/decode.h | 1 - src/include/replication/reorderbuffer.h | 13 - 8 files changed, 19 insertions(+), 489 deletions(-) diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c index 616b8685e3..bc1749bdba 100644 --- a/src/backend/commands/sequence.c +++ b/src/backend/commands/sequence.c @@ -110,6 +110,7 @@ static void init_params(ParseState *pstate, List *options, bool for_identity, List **owned_by); static void do_setval(Oid relid, int64 next, bool iscalled); static void process_owned_by(Relation seqrel, List *owned_by, bool for_identity); +static inline bool is_sequence_transactional(Relation seqrel); /* @@ -253,6 +254,13 @@ DefineSequence(ParseState *pstate, CreateSeqStmt *seq) return address; } +static inline bool +is_sequence_transactional(Relation seqrel) +{ + return (seqrel->rd_newRelfilelocatorSubid != InvalidSubTransactionId) || + (seqrel->rd_createSubid != InvalidSubTransactionId); +} + /* * Reset a sequence to its initial value. * @@ -439,6 +447,7 @@ fill_seq_fork_with_data(Relation rel, HeapTuple tuple, ForkNumber forkNum) XLogRegisterBuffer(0, buf, REGBUF_WILL_INIT); xlrec.locator = rel->rd_locator; + xlrec.is_transactional = is_sequence_transactional(rel); XLogRegisterData((char *) &xlrec, sizeof(xl_seq_rec)); XLogRegisterData((char *) tuple->t_data, tuple->t_len); @@ -903,6 +912,7 @@ nextval_internal(Oid relid, bool check_permissions) seq->log_cnt = 0; xlrec.locator = seqrel->rd_locator; + xlrec.is_transactional = is_sequence_transactional(seqrel); XLogRegisterData((char *) &xlrec, sizeof(xl_seq_rec)); XLogRegisterData((char *) seqdatatuple.t_data, seqdatatuple.t_len); @@ -1104,6 +1114,8 @@ do_setval(Oid relid, int64 next, bool iscalled) XLogRegisterBuffer(0, buf, REGBUF_WILL_INIT); xlrec.locator = seqrel->rd_locator; + xlrec.is_transactional = is_sequence_transactional(seqrel); + XLogRegisterData((char *) &xlrec, sizeof(xl_seq_rec)); XLogRegisterData((char *) seqdatatuple.t_data, seqdatatuple.t_len); diff --git a/src/backend/replication/logical/decode.c b/src/backend/replication/logical/decode.c index 70bf94d8fb..230cf49a1a 100644 --- a/src/backend/replication/logical/decode.c +++ b/src/backend/replication/logical/decode.c @@ -1390,6 +1390,7 @@ seq_decode(LogicalDecodingContext *ctx, XLogRecordBuffer *buf) Snapshot snapshot = NULL; RepOriginId origin_id = XLogRecGetOrigin(r); bool transactional; + xl_seq_rec *xlrec; /* ignore sequences when the plugin does not have the callbacks */ if (!ctx->sequences) @@ -1432,14 +1433,10 @@ seq_decode(LogicalDecodingContext *ctx, XLogRecordBuffer *buf) /* * Should we handle the sequence change as transactional or not? * - * If the relfilenode was created in the current transaction, treat the - * change as transactional and queue it. Otherwise it needs to be treated - * as non-transactional, in which case we just send it to the plugin right - * away. + * XXX: can xlrec be combined with tupledata? */ - transactional = ReorderBufferSequenceIsTransactional(ctx->reorder, - target_locator, - xid, NULL); + xlrec = (xl_seq_rec *) XLogRecGetData(r); + transactional = xlrec->is_transactional; /* Skip the change if already processed (per the snapshot). */ if (transactional && @@ -1486,67 +1483,3 @@ seq_decode(LogicalDecodingContext *ctx, XLogRecordBuffer *buf) origin_id, target_locator, transactional, tuplebuf); } - -/* - * Decode relfilenode change - * - * Decode SMGR records, so that we can later decide which sequence changes - * need to be treated as transactional. Most sequence changes are going to - * be non-transactional (applied as if outside the decoded transaction, not - * subject to rollback, etc.). Changes for sequences created/altered in the - * transaction need to be handled as transactional (i.e. applied as part of - * the decoded transaction, same as all other changes). - * - * To decide which of those cases is it we decode XLOG_SMGR_CREATE records - * and track relfilenodes created in each (sub)transaction. Changes for - * these relfilenodes are then queued and treated as transactional, while - * remaining changes are treated as non-transactional. - * - * We only care about XLOG_SMGR_CREATE records for "our" database (logical - * decoding is restricted to a single database), and we do the filtering - * and skipping, as appropriate. - */ -void -smgr_decode(LogicalDecodingContext *ctx, XLogRecordBuffer *buf) -{ - SnapBuild *builder = ctx->snapshot_builder; - XLogReaderState *r = buf->record; - TransactionId xid = XLogRecGetXid(r); - uint8 info = XLogRecGetInfo(buf->record) & ~XLR_INFO_MASK; - xl_smgr_create *xlrec; - - /* - * Bail out when not decoding sequences, which is currently the only case - * when we need to know about relfilenodes created in a transaction. - */ - if (!ctx->sequences) - return; - - /* - * We only care about XLOG_SMGR_CREATE, because that's what determines if - * the following sequence changes are transactional. - */ - if (info != XLOG_SMGR_CREATE) - return; - - ReorderBufferProcessXid(ctx->reorder, XLogRecGetXid(r), buf->origptr); - - /* - * If we don't have snapshot or we are just fast-forwarding, there is no - * point in decoding relfilenode information. - */ - if (SnapBuildCurrentState(builder) < SNAPBUILD_FULL_SNAPSHOT || - ctx->fast_forward) - return; - - /* only interested in our database */ - xlrec = (xl_smgr_create *) XLogRecGetData(r); - if (xlrec->rlocator.dbOid != ctx->slot->data.database) - return; - - /* output plugin doesn't look for this origin, no need to queue */ - if (FilterByOrigin(ctx, XLogRecGetOrigin(r))) - return; - - ReorderBufferAddRelFileLocator(ctx->reorder, xid, buf->endptr, xlrec->rlocator); -} diff --git a/src/backend/replication/logical/reorderbuffer.c b/src/backend/replication/logical/reorderbuffer.c index b88b460ae1..4121269a09 100644 --- a/src/backend/replication/logical/reorderbuffer.c +++ b/src/backend/replication/logical/reorderbuffer.c @@ -268,7 +268,6 @@ static void ReorderBufferTransferSnapToParent(ReorderBufferTXN *txn, ReorderBufferTXN *subtxn); static void AssertTXNLsnOrder(ReorderBuffer *rb); -static void AssertCheckSequences(ReorderBuffer *rb); /* --------------------------------------- * support functions for lsn-order iterating over the ->changes of a @@ -500,48 +499,12 @@ ReorderBufferReturnTXN(ReorderBuffer *rb, ReorderBufferTXN *txn) txn->invalidations = NULL; } - if (txn->sequences_hash != NULL) - { - hash_destroy(txn->sequences_hash); - txn->sequences_hash = NULL; - } - /* Reset the toast hash */ ReorderBufferToastReset(rb, txn); pfree(txn); } -/* - * Initialize hash table of relfilenodes created by the transaction. - * - * Each entry maps the relfilenode to the (sub)transaction that created the - * relfilenode - which is also the transaction the sequence change needs to - * be part of (in transactional case). - * - * We don't do this in ReorderBufferGetTXN because that'd allocate the hash - * for all transactions, and we expect new relfilenodes to be fairly rare. - * So only do that when adding the first entry. - */ -static void -ReorderBufferTXNSequencesInit(ReorderBuffer *rb, ReorderBufferTXN *txn) -{ - HASHCTL hash_ctl; - - /* bail out if already initialized */ - if (txn->sequences_hash) - return; - - /* hash table of sequences, mapping relfilelocator to transaction */ - hash_ctl.keysize = sizeof(RelFileLocator); - hash_ctl.entrysize = sizeof(ReorderBufferSequenceEnt); - hash_ctl.hcxt = rb->context; - - /* we expect relfilenodes to be created only rarely, so 32 seems enough */ - txn->sequences_hash = hash_create("ReorderBufferTXNSequenceHash", 32, &hash_ctl, - HASH_ELEM | HASH_BLOBS | HASH_CONTEXT); -} - /* * Get a fresh ReorderBufferChange. */ @@ -983,116 +946,6 @@ ReorderBufferQueueMessage(ReorderBuffer *rb, TransactionId xid, } } -/* - * Treat the sequence change as transactional? - * - * To decide if a sequence change should be handled as transactional or applied - * immediately, we need to decide if the relfilenode was created by a running - * transaction. Each transaction has a hash table of such relfilenodes. - * - * A naive approach would be to just loop through all transactions and check - * each of them, but there may be (easily thousands) of subtransactions, and - * the check happens for each sequence change. So this could be very costly. - * - * To limit the number of transactions we need to check, we transfer the - * relfilenodes to the top-level xact, which allows us to check just the - * top-level xacts (and there should be a very limited number of those). We - * expect relfilenode creation to be a quite rare thing, so this should not - * waste too much memory. OTOH sequence changes are very common, so making - * the check cheaper seems like a good trade off. - * - * Returns true for transactional changes, false otherwise. - * - * Optionaly (when the "xid" parameter is set) returns XID of the (sub)xact - * to use for queueing transactional changes. - * - * XXX As an optimization, maybe we should try searching the current xact (or - * it's top-level xact) first. If the change is transactional, where we'd - * find the match. - */ -bool -ReorderBufferSequenceIsTransactional(ReorderBuffer *rb, - RelFileLocator rlocator, - TransactionId xidin, - TransactionId *xidout) -{ - bool found = false; - ReorderBufferTXN *txn; - ReorderBufferSequenceEnt *entry; - - AssertCheckSequences(rb); - - /* - * Try to lookup transaction with the XID of the change. If it exists, the - * relfilenode would have to be either in it or the top-level transaction - * (if it was created in some earlier subtransaction). - * - * If this is a subxact, we'll search just the top-level hash table. That's - * simpler and likely faster than having to search two hash tables. - */ - txn = ReorderBufferTXNByXid(rb, xidin, false, NULL, InvalidXLogRecPtr, - false); - - if (!txn) - return false; - - - /* If there's top-level transaction, search that one. */ - txn = (txn->toptxn) ? txn->toptxn : txn; - - /* transaction has no relfilenodes, can't be transactional */ - if (!txn->sequences_hash) - return false; - - entry = hash_search(txn->sequences_hash, - (void *) &rlocator, - HASH_FIND, - &found); - - if (!found) - return false; - - if (xidout) - *xidout = entry->txn->xid; - - return true; -} - -/* - * Cleanup sequences after a subtransaction got aborted. - * - * The hash table will get destroyed in ReorderBufferReturnTXN, so we don't - * need to worry about that. But the entries were copied to the parent xact, - * and that's still being decoded - we make sure to remove the entries from - * the aborted one. - */ -static void -ReorderBufferSequenceCleanup(ReorderBufferTXN *txn) -{ - HASH_SEQ_STATUS scan_status; - ReorderBufferSequenceEnt *ent; - - /* Bail out if not a subxact, or if there are no entries. */ - if (!rbtxn_is_known_subxact(txn)) - return; - - if (!txn->sequences_hash) - return; - - /* - * Scan the top-level transaction hash and remove the entries from it. If - * we have entries for subxact, the top-level hash must have been - * initialized. - */ - hash_seq_init(&scan_status, txn->sequences_hash); - while ((ent = (ReorderBufferSequenceEnt *) hash_seq_search(&scan_status)) != NULL) - { - (void) hash_search(txn->toptxn->sequences_hash, - (void *) &ent->rlocator, - HASH_REMOVE, NULL); - } -} - /* * A transactional sequence change is queued to be processed upon commit * and a non-transactional change gets processed immediately. @@ -1108,8 +961,6 @@ ReorderBufferQueueSequence(ReorderBuffer *rb, TransactionId xid, RelFileLocator rlocator, bool transactional, ReorderBufferTupleBuf *tuplebuf) { - AssertCheckSequences(rb); - /* * Change needs to be handled as transactional, because the sequence was * created in a transaction that is still seen as running. In that case @@ -1143,9 +994,6 @@ ReorderBufferQueueSequence(ReorderBuffer *rb, TransactionId xid, change->data.sequence.tuple = tuplebuf; - /* lookup the XID for transaction that created the relfilenode */ - ReorderBufferSequenceIsTransactional(rb, rlocator, xid, &xid); - /* the XID should be valid for a transactional change */ Assert(TransactionIdIsValid(xid)); @@ -1168,9 +1016,6 @@ ReorderBufferQueueSequence(ReorderBuffer *rb, TransactionId xid, /* non-transactional changes require a valid snapshot */ Assert(snapshot_now); - /* Make sure the sequence is not in any of the hash tables */ - Assert(!ReorderBufferSequenceIsTransactional(rb, rlocator, xid, NULL)); - if (xid != InvalidTransactionId) txn = ReorderBufferTXNByXid(rb, xid, true, NULL, lsn, true); @@ -1252,80 +1097,7 @@ ReorderBufferQueueSequence(ReorderBuffer *rb, TransactionId xid, } } -/* - * ReorderBufferAddRelFileLocator - * Add newly created relfilenode to the hash table for transaction. - * - * If the transaction is already known to be a subtransaction, we add the same - * entry into the parent transaction (but it still points at the subxact, so - * that we know where to queue changes or what to discard in case of an abort). - */ -void -ReorderBufferAddRelFileLocator(ReorderBuffer *rb, TransactionId xid, - XLogRecPtr lsn, RelFileLocator rlocator) -{ - bool found; - ReorderBufferSequenceEnt *entry; - ReorderBufferTXN *txn; - - AssertCheckSequences(rb); - - /* - * We only care about sequence relfilenodes for now, and those always have - * a XID. So if there's no XID, don't bother adding them to the hash. - */ - if (xid == InvalidTransactionId) - return; - /* - * This might be the first change decoded for this transaction, so make - * sure we create it if needed. - */ - txn = ReorderBufferTXNByXid(rb, xid, true, NULL, lsn, true); - - /* - * First add it to the top-level transaction, but make sure it links to - * the correct subtransaction (so that we add later changes to it). - */ - if (txn->toptxn) - { - /* make sure the hash table is initialized */ - ReorderBufferTXNSequencesInit(rb, txn->toptxn); - - /* search the lookup table */ - entry = hash_search(txn->toptxn->sequences_hash, - (void *) &rlocator, - HASH_ENTER, - &found); - - /* - * We've just decoded creation of the relfilenode, so if we found it - * in the hash table, something is wrong. - */ - Assert(!found); - - entry->txn = txn; - } - - /* make sure the hash table is initialized */ - ReorderBufferTXNSequencesInit(rb, txn); - - /* search the lookup table */ - entry = hash_search(txn->sequences_hash, - (void *) &rlocator, - HASH_ENTER, - &found); - - /* - * We've just decoded creation of the relfilenode, so if we found it in - * the hash table, something is wrong. - */ - Assert(!found); - - entry->txn = txn; - - AssertCheckSequences(rb); -} /* * AssertTXNLsnOrder @@ -1401,161 +1173,6 @@ AssertTXNLsnOrder(ReorderBuffer *rb) #endif } -/* - * AssertCheckSequences - * Verify consistency of hash tables tracking new relfilenodes. - * - * We check that the hash table in the top-level transaction is consistent with - * respect to the hash tables in it's subxacts. That is, each entry has to be - * either from the top-level xact or one of it's subtransactions. Likewise, each - * entry in subxact hash table has to have a match in the top-level hash table. - */ -static void -AssertCheckSequences(ReorderBuffer *rb) -{ -#ifdef USE_ASSERT_CHECKING - LogicalDecodingContext *ctx = rb->private_data; - dlist_iter iter; - - /* - * Skip the verification if we don't reach the LSN at which we start - * decoding the contents of transactions yet because until we reach the - * LSN, we could have transactions that don't have the association between - * the top-level transaction and subtransaction yet and consequently have - * the same LSN. We don't guarantee this association until we try to - * decode the actual contents of transaction. The ordering of the records - * prior to the start_decoding_at LSN should have been checked before the - * restart. - */ - if (SnapBuildXactNeedsSkip(ctx->snapshot_builder, ctx->reader->EndRecPtr)) - return; - - /* - * Make sure the relfilenodes from subxacts are properly recorded in the - * top-level transaction hash table. - */ - dlist_foreach(iter, &rb->toplevel_by_lsn) - { - int nentries = 0, - nsubentries = 0; - dlist_iter subiter; - ReorderBufferTXN *txn = dlist_container(ReorderBufferTXN, node, - iter.cur); - - /* - * We don't skip top-level transactions without relfilenodes, because - * there might be a subtransaction with some, and we want to detect - * such cases too. - */ - if (txn->sequences_hash) - nentries = hash_get_num_entries(txn->sequences_hash); - - /* walk all subxacts, and check the hash table in each one */ - dlist_foreach(subiter, &txn->subtxns) - { - HASH_SEQ_STATUS scan_status; - ReorderBufferSequenceEnt *entry; - - ReorderBufferTXN *subtxn = dlist_container(ReorderBufferTXN, node, - subiter.cur); - - /* - * If this subxact has no relfilenodes, skip it. We'll do the - * check in the opposite direction (that all top-level - * relfilenodes are in the correct subxact) later. - */ - if (!subtxn->sequences_hash) - continue; - - /* add number of relfilenodes in this subxact */ - nsubentries += hash_get_num_entries(subtxn->sequences_hash); - - /* - * Check that all subxact relfilenodes are in the top-level txn - * too, and are pointing to this subtransaction. - */ - hash_seq_init(&scan_status, subtxn->sequences_hash); - while ((entry = (ReorderBufferSequenceEnt *) hash_seq_search(&scan_status)) != NULL) - { - bool found = false; - ReorderBufferSequenceEnt *subentry; - - /* search for the same relfilenode in the top-level txn */ - subentry = hash_search(txn->sequences_hash, - (void *) &entry->rlocator, - HASH_FIND, - &found); - - /* - * The top-level txn hash should have the relfilenode too, and - * it should point to this subxact. - */ - Assert(found); - - /* - * The entry has to point to the subxact - there's no subxact - * "below" this one to which the relfilenode could belong. - */ - Assert(subentry->txn == subtxn); - } - } - - /* - * We shouldn't have more relfilenodes in subtransactions than in the - * top-level one. There might be relfilenodes in the top-level one - * directly, so this needs to be inequality. - */ - Assert(nentries >= nsubentries); - - /* - * Now do the check in the opposite direction - check that every entry - * in the top-level txn (except those pointing to the top-level txn - * itself) point to one of the subxacts, and there's an entry in the - * subxact hash. - */ - if (txn->sequences_hash) - { - HASH_SEQ_STATUS scan_status; - ReorderBufferSequenceEnt *entry; - - hash_seq_init(&scan_status, txn->sequences_hash); - while ((entry = (ReorderBufferSequenceEnt *) hash_seq_search(&scan_status)) != NULL) - { - bool found = false; - ReorderBufferSequenceEnt *subentry; - - /* Skip entries for the top-level txn itself. */ - if (entry->txn == txn) - continue; - - /* Is it a subxact of this txn? */ - Assert(rbtxn_is_known_subxact(entry->txn)); - Assert(entry->txn->toptxn == txn); - - /* - * Search for the same relfilenode in the subxact (it should - * be initialized, as we expect it to contain the - * relfilenode). - */ - subentry = hash_search(entry->txn->sequences_hash, - (void *) &entry->rlocator, - HASH_FIND, - &found); - - Assert(found); - - /* - * Check the txn pointer in the top-level hash table entry is - * consistent with the subxact hash table (we already checked - * the subxact entry points to the subxact itself). - */ - Assert(subentry->txn = entry->txn); - } - } - } -#endif -} - /* * AssertChangeLsnOrder * @@ -1681,9 +1298,6 @@ ReorderBufferAssignChild(ReorderBuffer *rb, TransactionId xid, subtxn->toplevel_xid = xid; Assert(subtxn->nsubtxns == 0); - /* There should be no sequence relfilenodes in the subxact yet. */ - Assert(!subtxn->sequences_hash); - /* set the reference to top-level transaction */ subtxn->toptxn = txn; @@ -3517,9 +3131,6 @@ ReorderBufferFinishPrepared(ReorderBuffer *rb, TransactionId xid, ReorderBufferExecuteInvalidations(txn->ninvalidations, txn->invalidations); - /* cleanup: remove sequence relfilenodes from the top-level txn */ - ReorderBufferSequenceCleanup(txn); - ReorderBufferCleanupTXN(rb, txn); } @@ -3569,13 +3180,8 @@ ReorderBufferAbort(ReorderBuffer *rb, TransactionId xid, XLogRecPtr lsn, /* cosmetic... */ txn->final_lsn = lsn; - /* remove sequence relfilenodes from the top-level txn */ - ReorderBufferSequenceCleanup(txn); - /* remove potential on-disk data, and deallocate */ ReorderBufferCleanupTXN(rb, txn); - - AssertCheckSequences(rb); } /* @@ -3611,13 +3217,8 @@ ReorderBufferAbortOld(ReorderBuffer *rb, TransactionId oldestRunningXid) if (rbtxn_is_streamed(txn)) rb->stream_abort(rb, txn, InvalidXLogRecPtr); - /* remove sequence relfilenodes from the top-level txn */ - ReorderBufferSequenceCleanup(txn); - /* remove potential on-disk data, and deallocate this tx */ ReorderBufferCleanupTXN(rb, txn); - - AssertCheckSequences(rb); } else return; @@ -3666,9 +3267,6 @@ ReorderBufferForget(ReorderBuffer *rb, TransactionId xid, XLogRecPtr lsn) else Assert(txn->ninvalidations == 0); - /* remove sequence relfilenodes from a top-level txn */ - ReorderBufferSequenceCleanup(txn); - /* remove potential on-disk data, and deallocate */ ReorderBufferCleanupTXN(rb, txn); } diff --git a/src/include/access/rmgrlist.h b/src/include/access/rmgrlist.h index 305ca49a55..c7c60fcbc8 100644 --- a/src/include/access/rmgrlist.h +++ b/src/include/access/rmgrlist.h @@ -27,7 +27,7 @@ /* symbol name, textual name, redo, desc, identify, startup, cleanup, mask, decode */ PG_RMGR(RM_XLOG_ID, "XLOG", xlog_redo, xlog_desc, xlog_identify, NULL, NULL, NULL, xlog_decode) PG_RMGR(RM_XACT_ID, "Transaction", xact_redo, xact_desc, xact_identify, NULL, NULL, NULL, xact_decode) -PG_RMGR(RM_SMGR_ID, "Storage", smgr_redo, smgr_desc, smgr_identify, NULL, NULL, NULL, smgr_decode) +PG_RMGR(RM_SMGR_ID, "Storage", smgr_redo, smgr_desc, smgr_identify, NULL, NULL, NULL, NULL) PG_RMGR(RM_CLOG_ID, "CLOG", clog_redo, clog_desc, clog_identify, NULL, NULL, NULL, NULL) PG_RMGR(RM_DBASE_ID, "Database", dbase_redo, dbase_desc, dbase_identify, NULL, NULL, NULL, NULL) PG_RMGR(RM_TBLSPC_ID, "Tablespace", tblspc_redo, tblspc_desc, tblspc_identify, NULL, NULL, NULL, NULL) diff --git a/src/include/access/xlog_internal.h b/src/include/access/xlog_internal.h index a6380905fe..c55974f164 100644 --- a/src/include/access/xlog_internal.h +++ b/src/include/access/xlog_internal.h @@ -31,7 +31,7 @@ /* * Each page of XLOG file has a header like this: */ -#define XLOG_PAGE_MAGIC 0xD114 /* can be used as WAL version indicator */ +#define XLOG_PAGE_MAGIC 0xD115 /* can be used as WAL version indicator */ typedef struct XLogPageHeaderData { diff --git a/src/include/commands/sequence.h b/src/include/commands/sequence.h index 7db7b3da7b..d94a9022b2 100644 --- a/src/include/commands/sequence.h +++ b/src/include/commands/sequence.h @@ -48,6 +48,7 @@ typedef FormData_pg_sequence_data *Form_pg_sequence_data; typedef struct xl_seq_rec { RelFileLocator locator; + bool is_transactional; /* SEQUENCE TUPLE DATA FOLLOWS AT THE END */ } xl_seq_rec; diff --git a/src/include/replication/decode.h b/src/include/replication/decode.h index 8d06247165..0f8b82c02d 100644 --- a/src/include/replication/decode.h +++ b/src/include/replication/decode.h @@ -28,7 +28,6 @@ extern void xact_decode(LogicalDecodingContext *ctx, XLogRecordBuffer *buf); extern void standby_decode(LogicalDecodingContext *ctx, XLogRecordBuffer *buf); extern void logicalmsg_decode(LogicalDecodingContext *ctx, XLogRecordBuffer *buf); extern void seq_decode(LogicalDecodingContext *ctx, XLogRecordBuffer *buf); -extern void smgr_decode(LogicalDecodingContext *ctx, XLogRecordBuffer *buf); extern void LogicalDecodingProcessRecord(LogicalDecodingContext *ctx, XLogReaderState *record); diff --git a/src/include/replication/reorderbuffer.h b/src/include/replication/reorderbuffer.h index a44a0f4dfb..a9e41f9a26 100644 --- a/src/include/replication/reorderbuffer.h +++ b/src/include/replication/reorderbuffer.h @@ -400,12 +400,6 @@ typedef struct ReorderBufferTXN */ HTAB *toast_hash; - /* - * Sequence relfilenodes created in this transaction (also includes - * altered sequences, which assigns new relfilenode). - */ - HTAB *sequences_hash; - /* * non-hierarchical list of subtransactions that are *not* aborted. Only * used in toplevel transactions. @@ -786,11 +780,4 @@ extern void ReorderBufferSetRestartPoint(ReorderBuffer *rb, XLogRecPtr ptr); extern void StartupReorderBuffer(void); -extern void ReorderBufferAddRelFileLocator(ReorderBuffer *rb, TransactionId xid, - XLogRecPtr lsn, RelFileLocator rlocator); -extern bool ReorderBufferSequenceIsTransactional(ReorderBuffer *rb, - RelFileLocator locator, - TransactionId xidin, - TransactionId *xidout); - #endif -- 2.27.0