pending_sync_fix_tblsp_subxact.patch
text/x-patch
Filename: pending_sync_fix_tblsp_subxact.patch
Type: text/x-patch
Part: 1
Patch
Format: unified
| File | + | − |
|---|---|---|
| src/backend/access/transam/xact.c | 4 | 0 |
| src/backend/catalog/storage.c | 37 | 7 |
diff --git a/src/backend/access/transam/xact.c b/src/backend/access/transam/xact.c
index d1210de8f4..3ce69b7a40 100644
--- a/src/backend/access/transam/xact.c
+++ b/src/backend/access/transam/xact.c
@@ -4037,6 +4037,8 @@ ReleaseSavepoint(const char *name)
(errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
errmsg("savepoint \"%s\" does not exist within current savepoint level", name)));
+ smgrProcessPendingSyncRemoval(s->subTransactionId, true);
+
/*
* Mark "commit pending" all subtransactions up to the target
* subtransaction. The actual commits will happen when control gets to
@@ -4146,6 +4148,8 @@ RollbackToSavepoint(const char *name)
(errcode(ERRCODE_S_E_INVALID_SPECIFICATION),
errmsg("savepoint \"%s\" does not exist within current savepoint level", name)));
+ smgrProcessPendingSyncRemoval(s->subTransactionId, false);
+
/*
* Mark "abort pending" all subtransactions up to the target
* subtransaction. The actual aborts will happen when control gets to
diff --git a/src/backend/catalog/storage.c b/src/backend/catalog/storage.c
index 26dc3ddb1b..ad4a1e5127 100644
--- a/src/backend/catalog/storage.c
+++ b/src/backend/catalog/storage.c
@@ -99,6 +99,7 @@ typedef struct PendingRelSync
BlockNumber sync_above; /* WAL-logging skipped for blocks >=
* sync_above */
BlockNumber truncated_to; /* truncation WAL record was written */
+ SubTransactionId removed_xid; /* subxid where this is removed */
} PendingRelSync;
/* Relations that need to be fsync'd at commit */
@@ -405,6 +406,7 @@ getPendingSyncEntry(Relation rel, bool create)
{
pendsync_entry->truncated_to = InvalidBlockNumber;
pendsync_entry->sync_above = InvalidBlockNumber;
+ pendsync_entry->removed_xid = InvalidSubTransactionId;
}
/* hold shortcut in Relation */
@@ -498,14 +500,17 @@ void
RelationRemovePendingSync(Relation rel)
{
bool found;
+ PendingRelSync *pending_sync;
- rel->pending_sync = NULL;
- rel->no_pending_sync = true;
- if (pendingSyncs)
- {
- elog(DEBUG2, "RelationRemovePendingSync: accessing hash");
- hash_search(pendingSyncs, (void *) &rel->rd_node, HASH_REMOVE, &found);
- }
+ if (rel->no_pending_sync)
+ return;
+
+ pending_sync = getPendingSyncEntry(rel, false);
+
+ if (pending_sync)
+ return;
+
+ rel->pending_sync->removed_xid = GetCurrentSubTransactionId();
}
@@ -693,6 +698,31 @@ smgrDoPendingSyncs(bool isCommit)
pendingSyncs = NULL;
}
+void
+smgrProcessPendingSyncRemoval(SubTransactionId sxid, bool isCommit)
+{
+ HASH_SEQ_STATUS status;
+ PendingRelSync *pending;
+
+ if (!pendingSyncs)
+ return;
+
+ hash_seq_init(&status, pendingSyncs);
+
+ while ((pending = hash_seq_search(&status)) != NULL)
+ {
+ if (pending->removed_xid == sxid)
+ {
+ pending->removed_xid = InvalidSubTransactionId;
+ if (isCommit)
+ {
+ pending->sync_above = InvalidBlockNumber;
+ pending->truncated_to = InvalidBlockNumber;
+ }
+ }
+ }
+}
+
/*
* PostPrepare_smgr -- Clean up after a successful PREPARE
*