From 6f0a67ca2474498e22bfeefba68e1fd73edcc4bd Mon Sep 17 00:00:00 2001 From: ChangAo Chen Date: Wed, 10 Dec 2025 11:34:02 +0800 Subject: [PATCH v4] Handle XLOG_HEAP2_NEW_CID in heap2_decode() even if fast-forwarding. We need to mark the transaction as containing catalog modifications during decoding XLOG_HEAP2_NEW_CID even if fast-forwarding to maintain the snapshot correctly. Otherwise, an incorrect historic snapshot may be serialized to disk during fast-forwarding because the snapshot only track catalog modified transaction. --- src/backend/replication/logical/decode.c | 12 ++++++++++-- src/backend/replication/logical/snapbuild.c | 9 ++------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/backend/replication/logical/decode.c b/src/backend/replication/logical/decode.c index cc03f0706e9..31d22c51290 100644 --- a/src/backend/replication/logical/decode.c +++ b/src/backend/replication/logical/decode.c @@ -429,15 +429,23 @@ heap2_decode(LogicalDecodingContext *ctx, XLogRecordBuffer *buf) DecodeMultiInsert(ctx, buf); break; case XLOG_HEAP2_NEW_CID: + /* + * We only log new_cid's if a catalog tuple was modified, so mark the + * transaction as containing catalog modifications. + * + * Note: we do this even in fast-forward mode, as we need to maintain + * the snapshot correctly. + */ + ReorderBufferXidSetCatalogChanges(ctx->reorder, xid, buf->origptr); + if (!ctx->fast_forward) { xl_heap_new_cid *xlrec; xlrec = (xl_heap_new_cid *) XLogRecGetData(buf->record); SnapBuildProcessNewCid(builder, xid, buf->origptr, xlrec); - - break; } + break; case XLOG_HEAP2_REWRITE: /* diff --git a/src/backend/replication/logical/snapbuild.c b/src/backend/replication/logical/snapbuild.c index d6ab1e017eb..ab5ca82ff9f 100644 --- a/src/backend/replication/logical/snapbuild.c +++ b/src/backend/replication/logical/snapbuild.c @@ -682,7 +682,8 @@ SnapBuildProcessChange(SnapBuild *builder, TransactionId xid, XLogRecPtr lsn) /* * Do CommandId/combo CID handling after reading an xl_heap_new_cid record. * This implies that a transaction has done some form of write to system - * catalogs. + * catalogs. Caller must mark the transaction as containing catalog + * modifications in the reorder buffer. */ void SnapBuildProcessNewCid(SnapBuild *builder, TransactionId xid, @@ -690,12 +691,6 @@ SnapBuildProcessNewCid(SnapBuild *builder, TransactionId xid, { CommandId cid; - /* - * we only log new_cid's if a catalog tuple was modified, so mark the - * transaction as containing catalog modifications - */ - ReorderBufferXidSetCatalogChanges(builder->reorder, xid, lsn); - ReorderBufferAddNewTupleCids(builder->reorder, xlrec->top_xid, lsn, xlrec->target_locator, xlrec->target_tid, xlrec->cmin, xlrec->cmax, -- 2.34.1