Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 8103444

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 a9a5eb3 commit 8103444

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
@@ -934,7 +934,7 @@ ReorderBufferIterTXNInit(ReorderBuffer *rb, ReorderBufferTXN *txn)
934934
{
935935
ReorderBufferChange *cur_change;
936936

937-
if (txn->nentries != txn->nentries_mem)
937+
if (txn->serialized)
938938
{
939939
/* serialize remaining changes */
940940
ReorderBufferSerializeTXN(rb, txn);
@@ -963,7 +963,7 @@ ReorderBufferIterTXNInit(ReorderBuffer *rb, ReorderBufferTXN *txn)
963963
{
964964
ReorderBufferChange *cur_change;
965965

966-
if (cur_txn->nentries != cur_txn->nentries_mem)
966+
if (cur_txn->serialized)
967967
{
968968
/* serialize remaining changes */
969969
ReorderBufferSerializeTXN(rb, cur_txn);
@@ -1185,7 +1185,7 @@ ReorderBufferCleanupTXN(ReorderBuffer *rb, ReorderBufferTXN *txn)
11851185
Assert(found);
11861186

11871187
/* remove entries spilled to disk */
1188-
if (txn->nentries != txn->nentries_mem)
1188+
if (txn->serialized)
11891189
ReorderBufferRestoreCleanup(rb, txn);
11901190

11911191
/* deallocate */
@@ -2167,6 +2167,7 @@ ReorderBufferSerializeTXN(ReorderBuffer *rb, ReorderBufferTXN *txn)
21672167
Assert(spilled == txn->nentries_mem);
21682168
Assert(dlist_is_empty(&txn->changes));
21692169
txn->nentries_mem = 0;
2170+
txn->serialized = true;
21702171

21712172
if (fd != -1)
21722173
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)