diff options
author | Andres Freund <andres@anarazel.de> | 2017-06-18 18:48:22 -0700 |
---|---|---|
committer | Andres Freund <andres@anarazel.de> | 2017-06-18 19:13:50 -0700 |
commit | 1ba1adf772e60e9dde0e5b21b71f89609b10464c (patch) | |
tree | 04eacb4c0f72fc3d74ee3551b2d665affb859fc7 /src/backend/replication/logical/reorderbuffer.c | |
parent | 501e6f8b7875a1d7928653d0a0a01b84db6c1257 (diff) | |
download | postgresql-1ba1adf772e60e9dde0e5b21b71f89609b10464c.tar.gz postgresql-1ba1adf772e60e9dde0e5b21b71f89609b10464c.zip |
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
Diffstat (limited to 'src/backend/replication/logical/reorderbuffer.c')
-rw-r--r-- | src/backend/replication/logical/reorderbuffer.c | 7 |
1 files changed, 4 insertions, 3 deletions
diff --git a/src/backend/replication/logical/reorderbuffer.c b/src/backend/replication/logical/reorderbuffer.c index a924772964d..ccbbcddc0b1 100644 --- a/src/backend/replication/logical/reorderbuffer.c +++ b/src/backend/replication/logical/reorderbuffer.c @@ -873,7 +873,7 @@ ReorderBufferIterTXNInit(ReorderBuffer *rb, ReorderBufferTXN *txn) { ReorderBufferChange *cur_change; - if (txn->nentries != txn->nentries_mem) + if (txn->serialized) { /* serialize remaining changes */ ReorderBufferSerializeTXN(rb, txn); @@ -902,7 +902,7 @@ ReorderBufferIterTXNInit(ReorderBuffer *rb, ReorderBufferTXN *txn) { ReorderBufferChange *cur_change; - if (cur_txn->nentries != cur_txn->nentries_mem) + if (cur_txn->serialized) { /* serialize remaining changes */ ReorderBufferSerializeTXN(rb, cur_txn); @@ -1124,7 +1124,7 @@ ReorderBufferCleanupTXN(ReorderBuffer *rb, ReorderBufferTXN *txn) Assert(found); /* remove entries spilled to disk */ - if (txn->nentries != txn->nentries_mem) + if (txn->serialized) ReorderBufferRestoreCleanup(rb, txn); /* deallocate */ @@ -2086,6 +2086,7 @@ ReorderBufferSerializeTXN(ReorderBuffer *rb, ReorderBufferTXN *txn) Assert(spilled == txn->nentries_mem); Assert(dlist_is_empty(&txn->changes)); txn->nentries_mem = 0; + txn->serialized = true; if (fd != -1) CloseTransientFile(fd); |