diff --git a/src/backend/replication/logical/reorderbuffer.c b/src/backend/replication/logical/reorderbuffer.c index 0f607ba..bbeb494 100644 --- a/src/backend/replication/logical/reorderbuffer.c +++ b/src/backend/replication/logical/reorderbuffer.c @@ -1075,6 +1075,21 @@ ReorderBufferCleanupTXN(ReorderBuffer *rb, ReorderBufferTXN *txn) bool found; dlist_mutable_iter iter; + /* + * Before cleaning up, do a preparation. + * If this transaction encountered crash during transaction, + * txn->final_lsn remains initial value. + * To properly remove entries which were spilled to disk, we need valid + * final_lsn. + * So set final_lsn to the lsn of last ReorderBufferChange. + */ + if (txn->final_lsn == 0) + { + ReorderBufferChange *last_change = + dlist_tail_element(ReorderBufferChange, node, &txn->changes); + txn->final_lsn = last_change->lsn; + } + /* cleanup subtransactions & their changes */ dlist_foreach_modify(iter, &txn->subtxns) { diff --git a/src/include/replication/reorderbuffer.h b/src/include/replication/reorderbuffer.h index 86effe1..cd1acbd 100644 --- a/src/include/replication/reorderbuffer.h +++ b/src/include/replication/reorderbuffer.h @@ -168,6 +168,8 @@ typedef struct ReorderBufferTXN * * plain abort record * * prepared transaction abort * * error during decoding + * Only when this xact encountered server crash, this value is set to + * the lsn of last ReorderBufferChange for cleaning up spilled files. * ---- */ XLogRecPtr final_lsn;