From a5a584b28d63f7e692fc8403da641f80ae2b4771 Mon Sep 17 00:00:00 2001 From: Neil Chen Date: Thu, 8 Jan 2026 11:18:34 +0800 Subject: [PATCH] Optimize SnapBuildPurgeOlderTxn to purge committed xids in-place --- src/backend/replication/logical/snapbuild.c | 29 ++++++++------------- 1 file changed, 11 insertions(+), 18 deletions(-) diff --git a/src/backend/replication/logical/snapbuild.c b/src/backend/replication/logical/snapbuild.c index 7f79621b57e..63f7b42a135 100644 --- a/src/backend/replication/logical/snapbuild.c +++ b/src/backend/replication/logical/snapbuild.c @@ -862,39 +862,32 @@ static void SnapBuildPurgeOlderTxn(SnapBuild *builder) { int off; - TransactionId *workspace; int surviving_xids = 0; /* not ready yet */ if (!TransactionIdIsNormal(builder->xmin)) return; - /* TODO: Neater algorithm than just copying and iterating? */ - workspace = - MemoryContextAlloc(builder->context, - builder->committed.xcnt * sizeof(TransactionId)); - - /* copy xids that still are interesting to workspace */ + /* Purge xids in ->committed */ for (off = 0; off < builder->committed.xcnt; off++) { - if (NormalTransactionIdPrecedes(builder->committed.xip[off], - builder->xmin)) - ; /* remove */ - else - workspace[surviving_xids++] = builder->committed.xip[off]; + /* Check if this xid should be retained */ + if (!NormalTransactionIdPrecedes(builder->committed.xip[off], builder->xmin)) + { + /* Skip self-assignment */ + if (surviving_xids != off) + { + builder->committed.xip[surviving_xids] = builder->committed.xip[off]; + } + surviving_xids++; + } } - /* copy workspace back to persistent state */ - memcpy(builder->committed.xip, workspace, - surviving_xids * sizeof(TransactionId)); - elog(DEBUG3, "purged committed transactions from %u to %u, xmin: %u, xmax: %u", (uint32) builder->committed.xcnt, (uint32) surviving_xids, builder->xmin, builder->xmax); builder->committed.xcnt = surviving_xids; - pfree(workspace); - /* * Purge xids in ->catchange as well. The purged array must also be sorted * in xidComparator order. -- 2.43.0