From fc58da41802f966dd269679921a5daa33d21a291 Mon Sep 17 00:00:00 2001 From: Dilip Kumar Date: Tue, 25 May 2021 14:51:45 +0530 Subject: [PATCH v1] Fix bug while streaming the multi-insert toast changes While processing the multi-insert we can not clean the toast untill we get the last insert of the multi-insert. So mark the transaction incomplete for streaming if we get any multi-insert change, and keep it set until we get the last tuple of the multi-insert. --- src/backend/replication/logical/reorderbuffer.c | 11 +++++++++++ src/include/replication/reorderbuffer.h | 11 ++++++++++- 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/backend/replication/logical/reorderbuffer.c b/src/backend/replication/logical/reorderbuffer.c index b0ab91c..b715992 100644 --- a/src/backend/replication/logical/reorderbuffer.c +++ b/src/backend/replication/logical/reorderbuffer.c @@ -732,6 +732,17 @@ ReorderBufferProcessPartialChange(ReorderBuffer *rb, ReorderBufferTXN *txn, } /* + * Set the multi insert bit whenever we get the clear_toast_afterwards + * as false otherwise reset it if this is set. + */ + if (!change->data.tp.clear_toast_afterwards) + { + toptxn->txn_flags |= RBTXN_HAS_MULTI_INSERT; + } + else if rbtxn_has_multi_insert(toptxn) + toptxn->txn_flags &= ~RBTXN_HAS_MULTI_INSERT; + + /* * Stream the transaction if it is serialized before and the changes are * now complete in the top-level transaction. * diff --git a/src/include/replication/reorderbuffer.h b/src/include/replication/reorderbuffer.h index 53cdfa5..cd36a8d 100644 --- a/src/include/replication/reorderbuffer.h +++ b/src/include/replication/reorderbuffer.h @@ -176,6 +176,7 @@ typedef struct ReorderBufferChange #define RBTXN_HAS_SPEC_INSERT 0x0040 #define RBTXN_PREPARE 0x0080 #define RBTXN_SKIPPED_PREPARE 0x0100 +#define RBTXN_HAS_MULTI_INSERT 0x0200 /* Does the transaction have catalog changes? */ #define rbtxn_has_catalog_changes(txn) \ @@ -214,11 +215,19 @@ typedef struct ReorderBufferChange ( \ ((txn)->txn_flags & RBTXN_HAS_SPEC_INSERT) != 0 \ ) +/* + * This transaction's changes has multi insert, without last + * multi insert tuple. + */ +#define rbtxn_has_multi_insert(txn) \ +( \ + ((txn)->txn_flags & RBTXN_HAS_MULTI_INSERT) != 0 \ +) /* Check whether this transaction has an incomplete change. */ #define rbtxn_has_incomplete_tuple(txn) \ ( \ - rbtxn_has_toast_insert(txn) || rbtxn_has_spec_insert(txn) \ + rbtxn_has_toast_insert(txn) || rbtxn_has_spec_insert(txn) || rbtxn_has_multi_insert(txn) \ ) /* -- 1.8.3.1