Skip to content

Commit ee4ba01

Browse files
author
Amit Kapila
committed
Fix the bugs in selecting the transaction for streaming.
There were two problems: a. We were always selecting the next available txn instead of selecting it when it is larger than the previous transaction. b. We were selecting the transactions which haven't made any changes to the database (base snapshot is not set). Later it was hitting an Assert because we don't decode such transactions and the changes in txn remain as it is. It is better not to choose such transactions for streaming in the first place. Reported-by: Haiying Tang Author: Dilip Kumar Reviewed-by: Amit Kapila Discussion: https://postgr.es/m/OS0PR01MB61133B94E63177040F7ECDA1FB429@OS0PR01MB6113.jpnprd01.prod.outlook.com
1 parent 3c80e96 commit ee4ba01

File tree

1 file changed

+23
-15
lines changed

1 file changed

+23
-15
lines changed

src/backend/replication/logical/reorderbuffer.c

Lines changed: 23 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3362,19 +3362,22 @@ ReorderBufferLargestTXN(ReorderBuffer *rb)
33623362
* This can be seen as an optimized version of ReorderBufferLargestTXN, which
33633363
* should give us the same transaction (because we don't update memory account
33643364
* for subtransaction with streaming, so it's always 0). But we can simply
3365-
* iterate over the limited number of toplevel transactions.
3365+
* iterate over the limited number of toplevel transactions that have a base
3366+
* snapshot. There is no use of selecting a transaction that doesn't have base
3367+
* snapshot because we don't decode such transactions.
33663368
*
33673369
* Note that, we skip transactions that contains incomplete changes. There
3368-
* is a scope of optimization here such that we can select the largest transaction
3369-
* which has complete changes. But that will make the code and design quite complex
3370-
* and that might not be worth the benefit. If we plan to stream the transactions
3371-
* that contains incomplete changes then we need to find a way to partially
3372-
* stream/truncate the transaction changes in-memory and build a mechanism to
3373-
* partially truncate the spilled files. Additionally, whenever we partially
3374-
* stream the transaction we need to maintain the last streamed lsn and next time
3375-
* we need to restore from that segment and the offset in WAL. As we stream the
3376-
* changes from the top transaction and restore them subtransaction wise, we need
3377-
* to even remember the subxact from where we streamed the last change.
3370+
* is a scope of optimization here such that we can select the largest
3371+
* transaction which has incomplete changes. But that will make the code and
3372+
* design quite complex and that might not be worth the benefit. If we plan to
3373+
* stream the transactions that contains incomplete changes then we need to
3374+
* find a way to partially stream/truncate the transaction changes in-memory
3375+
* and build a mechanism to partially truncate the spilled files.
3376+
* Additionally, whenever we partially stream the transaction we need to
3377+
* maintain the last streamed lsn and next time we need to restore from that
3378+
* segment and the offset in WAL. As we stream the changes from the top
3379+
* transaction and restore them subtransaction wise, we need to even remember
3380+
* the subxact from where we streamed the last change.
33783381
*/
33793382
static ReorderBufferTXN *
33803383
ReorderBufferLargestTopTXN(ReorderBuffer *rb)
@@ -3383,14 +3386,19 @@ ReorderBufferLargestTopTXN(ReorderBuffer *rb)
33833386
Size largest_size = 0;
33843387
ReorderBufferTXN *largest = NULL;
33853388

3386-
/* Find the largest top-level transaction. */
3387-
dlist_foreach(iter, &rb->toplevel_by_lsn)
3389+
/* Find the largest top-level transaction having a base snapshot. */
3390+
dlist_foreach(iter, &rb->txns_by_base_snapshot_lsn)
33883391
{
33893392
ReorderBufferTXN *txn;
33903393

3391-
txn = dlist_container(ReorderBufferTXN, node, iter.cur);
3394+
txn = dlist_container(ReorderBufferTXN, base_snapshot_node, iter.cur);
3395+
3396+
/* must not be a subtxn */
3397+
Assert(!rbtxn_is_known_subxact(txn));
3398+
/* base_snapshot must be set */
3399+
Assert(txn->base_snapshot != NULL);
33923400

3393-
if ((largest != NULL || txn->total_size > largest_size) &&
3401+
if ((largest == NULL || txn->total_size > largest_size) &&
33943402
(txn->total_size > 0) && !(rbtxn_has_incomplete_tuple(txn)))
33953403
{
33963404
largest = txn;

0 commit comments

Comments
 (0)