Hi,

I put many queries into one transaction and made ReorderBuffer spill
data to disk, and sent SIGKILL to postgres before the end of the
transaction.

After starting up postgres again, I observed the files spilled to
data wasn't deleted.

I think these files should be deleted because its transaction was no
more valid, so no one can use these files.


Below is a reproduction instructions.

------------------------------------------------
1. Create table and publication at publiser.

  @pub =# CREATE TABLE t1(
      id INT PRIMARY KEY,
      name TEXT);

  @pub =# CREATE PUBLICATION pub FOR TABLE t1;

2. Create table and subscription at subscriber.

  @sub =# CREATE TABLE t1(
      id INT PRIMARY KEY,
      name TEXT
      );

  @sub =# CREATE SUBSCRIPTION sub
      CONNECTION 'host=[hostname] port=[port] dbname=[dbname]'
      PUBLICATION pub;

3. Put many queries into one transaction.

  @pub =# BEGIN;
        INSERT INTO t1
        SELECT
          i,
          'aaaaaaaaaa'
        FROM
        generate_series(1, 1000000) as i;

4. Then we can see spilled files.

  @pub $ ls -1 ${PGDATA}/pg_replslot/sub/
    state
    xid-561-lsn-0-1000000.snap
    xid-561-lsn-0-2000000.snap
    xid-561-lsn-0-3000000.snap
    xid-561-lsn-0-4000000.snap
    xid-561-lsn-0-5000000.snap
    xid-561-lsn-0-6000000.snap
    xid-561-lsn-0-7000000.snap
    xid-561-lsn-0-8000000.snap
    xid-561-lsn-0-9000000.snap

5. Kill publisher's postgres process before COMMIT.

  @pub $ kill -s SIGKILL [pid of postgres]

6. Start publisher's postgres process.

  @pub $ pg_ctl start -D ${PGDATA}

7. After a while, we can see the files remaining.
  (Immediately after starting publiser, we can not see these files.)

  @pub $ pg_ctl start -D ${PGDATA}

  When I configured with '--enable-cassert', below assertion error
  was appeared.

TRAP: FailedAssertion("!(txn->final_lsn != 0)", File: "reorderbuffer.c", Line: 2576)
------------------------------------------------

Attached patch sets final_lsn to the last ReorderBufferChange if
final_lsn == 0.

--
Atsushi Torikoshi
NIPPON TELEGRAPH AND TELEPHONE CORPORATION
NTT Open Source Software Center

diff --git a/src/backend/replication/logical/reorderbuffer.c 
b/src/backend/replication/logical/reorderbuffer.c
index 0f607ba..51d5b71 100644
--- a/src/backend/replication/logical/reorderbuffer.c
+++ b/src/backend/replication/logical/reorderbuffer.c
@@ -1093,6 +1093,20 @@ ReorderBufferCleanupTXN(ReorderBuffer *rb, 
ReorderBufferTXN *txn)
                ReorderBufferCleanupTXN(rb, subtxn);
        }
 
+       /*
+        * 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 we set final_lsn to the lsn of the last ReorderBufferChange.
+        */
+       if (txn->final_lsn == 0)
+       {
+               ReorderBufferChange *last_change =
+               dlist_tail_element(ReorderBufferChange, node, &txn->changes);
+               txn->final_lsn = last_change->lsn;
+       }
+
        /* cleanup changes in the toplevel txn */
        dlist_foreach_modify(iter, &txn->changes)
        {

Reply via email to