v1-0002-Fix-Coredump-On-AssertTXNLsnOrder.patch

application/octet-stream

Filename: v1-0002-Fix-Coredump-On-AssertTXNLsnOrder.patch
Type: application/octet-stream
Part: 2
Message: Re:BUG #18369: logical decoding core on AssertTXNLsnOrder()

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: unified
Series: patch v1-0002
File+
src/backend/replication/logical/decode.c 2 2
src/backend/replication/logical/reorderbuffer.c 6 4
src/backend/replication/logical/snapbuild.c 3 3
src/include/replication/reorderbuffer.h 1 1
diff --git a/src/backend/replication/logical/decode.c b/src/backend/replication/logical/decode.c
index 1c0058fc8f..29871a4117 100644
--- a/src/backend/replication/logical/decode.c
+++ b/src/backend/replication/logical/decode.c
@@ -336,7 +336,7 @@ DecodeXactOp(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
 													  invals->nmsgs,
 													  invals->msgs);
 					ReorderBufferXidSetCatalogChanges(ctx->reorder, xid,
-													  buf->origptr);
+													  buf->origptr, true);
 				}
 				else if ((!ctx->fast_forward))
 					ReorderBufferImmediateInvalidation(ctx->reorder,
@@ -563,7 +563,7 @@ DecodeHeapOp(LogicalDecodingContext *ctx, XLogRecordBuffer *buf)
 				break;
 
 			SnapBuildProcessChange(builder, xid, buf->origptr);
-			ReorderBufferXidSetCatalogChanges(ctx->reorder, xid, buf->origptr);
+			ReorderBufferXidSetCatalogChanges(ctx->reorder, xid, buf->origptr, true);
 			break;
 
 		case XLOG_HEAP_CONFIRM:
diff --git a/src/backend/replication/logical/reorderbuffer.c b/src/backend/replication/logical/reorderbuffer.c
index 264c253a87..4726f6a507 100644
--- a/src/backend/replication/logical/reorderbuffer.c
+++ b/src/backend/replication/logical/reorderbuffer.c
@@ -1060,7 +1060,8 @@ ReorderBufferAssignChild(ReorderBuffer *rb, TransactionId xid,
 			 * list of top-level txns.  Now that we know it's not top-level,
 			 * remove it from there.
 			 */
-			dlist_delete(&subtxn->node);
+			if (subtxn->node.next != NULL)
+				dlist_delete(&subtxn->node);
 		}
 	}
 
@@ -1550,7 +1551,8 @@ ReorderBufferCleanupTXN(ReorderBuffer *rb, ReorderBufferTXN *txn)
 	 * count too high, but we don't care.  Otherwise, we are deleting the TXN
 	 * from the LSN-ordered list of toplevel TXNs.
 	 */
-	dlist_delete(&txn->node);
+	if (txn->node.next != NULL)
+		dlist_delete(&txn->node);
 
 	/* now remove reference from buffer */
 	hash_search(rb->by_txn,
@@ -3297,11 +3299,11 @@ ReorderBufferExecuteInvalidations(uint32 nmsgs, SharedInvalidationMessage *msgs)
  */
 void
 ReorderBufferXidSetCatalogChanges(ReorderBuffer *rb, TransactionId xid,
-								  XLogRecPtr lsn)
+								  XLogRecPtr lsn, bool is_top)
 {
 	ReorderBufferTXN *txn;
 
-	txn = ReorderBufferTXNByXid(rb, xid, true, NULL, lsn, true);
+	txn = ReorderBufferTXNByXid(rb, xid, true, NULL, lsn, is_top);
 
 	txn->txn_flags |= RBTXN_HAS_CATALOG_CHANGES;
 
diff --git a/src/backend/replication/logical/snapbuild.c b/src/backend/replication/logical/snapbuild.c
index 4f8c00f717..aec87c11ae 100644
--- a/src/backend/replication/logical/snapbuild.c
+++ b/src/backend/replication/logical/snapbuild.c
@@ -818,7 +818,7 @@ SnapBuildProcessNewCid(SnapBuild *builder, TransactionId xid,
 	 * 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);
+	ReorderBufferXidSetCatalogChanges(builder->reorder, xid, lsn, true);
 
 	ReorderBufferAddNewTupleCids(builder->reorder, xlrec->top_xid, lsn,
 								 xlrec->target_node, xlrec->target_tid,
@@ -2131,9 +2131,9 @@ SnapBuildXidSetCatalogChanges(SnapBuild *builder, TransactionId xid, int subxcnt
 	if (bsearch(&xid, InitialRunningXacts, NInitialRunningXacts,
 				sizeof(TransactionId), xidComparator) != NULL)
 	{
-		ReorderBufferXidSetCatalogChanges(builder->reorder, xid, lsn);
+		ReorderBufferXidSetCatalogChanges(builder->reorder, xid, lsn, true);
 
 		for (int i = 0; i < subxcnt; i++)
-			ReorderBufferXidSetCatalogChanges(builder->reorder, subxacts[i], lsn);
+			ReorderBufferXidSetCatalogChanges(builder->reorder, subxacts[i], lsn, false);
 	}
 }
diff --git a/src/include/replication/reorderbuffer.h b/src/include/replication/reorderbuffer.h
index ba257d81b5..55b9bede87 100644
--- a/src/include/replication/reorderbuffer.h
+++ b/src/include/replication/reorderbuffer.h
@@ -661,7 +661,7 @@ void		ReorderBufferImmediateInvalidation(ReorderBuffer *, uint32 ninvalidations,
 											   SharedInvalidationMessage *invalidations);
 void		ReorderBufferProcessXid(ReorderBuffer *, TransactionId xid, XLogRecPtr lsn);
 
-void		ReorderBufferXidSetCatalogChanges(ReorderBuffer *, TransactionId xid, XLogRecPtr lsn);
+void		ReorderBufferXidSetCatalogChanges(ReorderBuffer *, TransactionId xid, XLogRecPtr lsn, bool is_top);
 bool		ReorderBufferXidHasCatalogChanges(ReorderBuffer *, TransactionId xid);
 bool		ReorderBufferXidHasBaseSnapshot(ReorderBuffer *, TransactionId xid);