improve_comments_1.patch

application/octet-stream

Filename: improve_comments_1.patch
Type: application/octet-stream
Part: 0
Message: Re: Perform streaming logical transactions by background workers and parallel apply

Patch

Same data as JSON: GET /api/v1/attachments/:id/patch the parsed metadata as JSON — format, series position, per-file stats; never the diff bytes. API reference →
Format: unified
File+
src/backend/replication/logical/worker.c 17 10
diff --git a/src/backend/replication/logical/worker.c b/src/backend/replication/logical/worker.c
index acf6494cd6..e621eb5e44 100644
--- a/src/backend/replication/logical/worker.c
+++ b/src/backend/replication/logical/worker.c
@@ -32,7 +32,12 @@
  * transaction commit is received and also wait for the worker to finish at
  * commit. This preserves commit ordering and avoids writing to and reading
  * from file in most cases. We still need to spill if there is no worker
- * available.
+ * available. It is important to maintain commit order to avoid failures
+ * due to (a) transaction dependencies, say if we insert a row in the first
+ * transaction and update it in the second transaction then allowing to apply
+ * both in parallel can lead to failure in the update. (b) deadlocks, allowing
+ * transactions that update the same set of rows/tables in opposite order to be
+ * applied in parallel can lead to deadlocks.
  *
  * 2) Write to temporary files and apply when the final commit arrives
  *
@@ -1366,14 +1371,12 @@ apply_handle_stream_stop(StringInfo s)
 		char		action = LOGICAL_REP_MSG_STREAM_STOP;
 
 		/*
-		 * There is no need to wait here to allow stream_stop to complete by
-		 * background worker to avoid deadlocks.
-		 *
-		 * The deadlock problem only occurs if relation's unique
-		 * index/constraint is different between publisher and subscriber. But
-		 * in these cases, we do not allow to apply streamed transaction in the
-		 * apply background worker (see function
-		 * apply_bgworker_relation_check).
+		 * Unlike stream_commit, we don't need to wait here for stream_stop to
+		 * finish. Allowing the other transaction to be applied before stream_stop
+		 * is finished can only lead to failures if the unique index/constraint is
+		 * different between publisher and subscriber. But for such cases, we don't
+		 * allow streamed transactions to be applied in parallel. See
+		 * apply_bgworker_relation_check.
 		 */
 		apply_bgworker_send_data(stream_apply_worker, 1, &action);
 
@@ -2764,7 +2767,11 @@ apply_handle_stream_commit(StringInfo s)
 			/* Send commit message */
 			apply_bgworker_send_data(wstate, s->len, s->data);
 
-			/* Wait for apply background worker to finish */
+			/*
+			 * Wait for apply background worker to finish. This is required to
+			 * maintain commit order which avoids failures due to transaction
+			 * dependencies and deadlocks.
+			 */
 			apply_bgworker_wait_for(wstate, APPLY_BGWORKER_FINISHED);
 
 			pgstat_report_stat(false);