pending_sync_fix_tblsp_subxact.patch

text/x-patch

Filename: pending_sync_fix_tblsp_subxact.patch
Type: text/x-patch
Part: 1
Message: Re: [HACKERS] WAL logging problem in 9.4.3?

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
  *