Skip to content

Commit 3bdea16

Browse files
committed
Fix leaking of small spilled subtransactions during logical decoding.
When, during logical decoding, a transaction gets too big, it's contents get spilled to disk. Not just the top-transaction gets spilled, but *also* all of its subtransactions, even if they're not that large themselves. Unfortunately we didn't clean up such small spilled subtransactions from disk. Fix that, by keeping better track of whether a transaction has been spilled to disk. Author: Andres Freund Reported-By: Dmitriy Sarafannikov, Fabrízio de Royes Mello Discussion: https://postgr.es/m/1457621358.355011041@f382.i.mail.ru https://postgr.es/m/CAFcNs+qNMhNYii4nxpO6gqsndiyxNDYV0S=JNq0v_sEE+9PHXg@mail.gmail.com Backpatch: 9.4-, where logical decoding was introduced
1 parent b4166a8 commit 3bdea16

File tree

2 files changed

+13
-3
lines changed

2 files changed

+13
-3
lines changed

src/backend/replication/logical/reorderbuffer.c

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -893,7 +893,7 @@ ReorderBufferIterTXNInit(ReorderBuffer *rb, ReorderBufferTXN *txn)
893893
{
894894
ReorderBufferChange *cur_change;
895895

896-
if (txn->nentries != txn->nentries_mem)
896+
if (txn->serialized)
897897
{
898898
/* serialize remaining changes */
899899
ReorderBufferSerializeTXN(rb, txn);
@@ -922,7 +922,7 @@ ReorderBufferIterTXNInit(ReorderBuffer *rb, ReorderBufferTXN *txn)
922922
{
923923
ReorderBufferChange *cur_change;
924924

925-
if (cur_txn->nentries != cur_txn->nentries_mem)
925+
if (cur_txn->serialized)
926926
{
927927
/* serialize remaining changes */
928928
ReorderBufferSerializeTXN(rb, cur_txn);
@@ -1142,7 +1142,7 @@ ReorderBufferCleanupTXN(ReorderBuffer *rb, ReorderBufferTXN *txn)
11421142
Assert(found);
11431143

11441144
/* remove entries spilled to disk */
1145-
if (txn->nentries != txn->nentries_mem)
1145+
if (txn->serialized)
11461146
ReorderBufferRestoreCleanup(rb, txn);
11471147

11481148
/* deallocate */
@@ -2124,6 +2124,7 @@ ReorderBufferSerializeTXN(ReorderBuffer *rb, ReorderBufferTXN *txn)
21242124
Assert(spilled == txn->nentries_mem);
21252125
Assert(dlist_is_empty(&txn->changes));
21262126
txn->nentries_mem = 0;
2127+
txn->serialized = true;
21272128

21282129
if (fd != -1)
21292130
CloseTransientFile(fd);

src/include/replication/reorderbuffer.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,15 @@ typedef struct ReorderBufferTXN
212212
*/
213213
uint64 nentries_mem;
214214

215+
/*
216+
* Has this transaction been spilled to disk? It's not always possible to
217+
* deduce that fact by comparing nentries with nentries_mem, because
218+
* e.g. subtransactions of a large transaction might get serialized
219+
* together with the parent - if they're restored to memory they'd have
220+
* nentries_mem == nentries.
221+
*/
222+
bool serialized;
223+
215224
/*
216225
* List of ReorderBufferChange structs, including new Snapshots and new
217226
* CommandIds

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy