@@ -224,6 +224,8 @@ static void maybe_reread_subscription(void);
224224/* prototype needed because of stream_commit */
225225static void apply_dispatch (StringInfo s );
226226
227+ static void apply_handle_commit_internal (StringInfo s ,
228+ LogicalRepCommitData * commit_data );
227229static void apply_handle_insert_internal (ResultRelInfo * relinfo ,
228230 EState * estate , TupleTableSlot * remoteslot );
229231static void apply_handle_update_internal (ResultRelInfo * relinfo ,
@@ -709,29 +711,7 @@ apply_handle_commit(StringInfo s)
709711
710712 Assert (commit_data .commit_lsn == remote_final_lsn );
711713
712- /* The synchronization worker runs in single transaction. */
713- if (IsTransactionState () && !am_tablesync_worker ())
714- {
715- /*
716- * Update origin state so we can restart streaming from correct
717- * position in case of crash.
718- */
719- replorigin_session_origin_lsn = commit_data .end_lsn ;
720- replorigin_session_origin_timestamp = commit_data .committime ;
721-
722- CommitTransactionCommand ();
723- pgstat_report_stat (false);
724-
725- store_flush_position (commit_data .end_lsn );
726- }
727- else
728- {
729- /* Process any invalidation messages that might have accumulated. */
730- AcceptInvalidationMessages ();
731- maybe_reread_subscription ();
732- }
733-
734- in_remote_transaction = false;
714+ apply_handle_commit_internal (s , & commit_data );
735715
736716 /* Process any tables that are being synchronized in parallel. */
737717 process_syncing_tables (commit_data .end_lsn );
@@ -772,8 +752,10 @@ apply_handle_stream_start(StringInfo s)
772752
773753 /*
774754 * Start a transaction on stream start, this transaction will be committed
775- * on the stream stop. We need the transaction for handling the buffile,
776- * used for serializing the streaming data and subxact info.
755+ * on the stream stop unless it is a tablesync worker in which case it will
756+ * be committed after processing all the messages. We need the transaction
757+ * for handling the buffile, used for serializing the streaming data and
758+ * subxact info.
777759 */
778760 ensure_transaction ();
779761
@@ -825,8 +807,12 @@ apply_handle_stream_stop(StringInfo s)
825807 /* We must be in a valid transaction state */
826808 Assert (IsTransactionState ());
827809
828- /* Commit the per-stream transaction */
829- CommitTransactionCommand ();
810+ /* The synchronization worker runs in single transaction. */
811+ if (!am_tablesync_worker ())
812+ {
813+ /* Commit the per-stream transaction */
814+ CommitTransactionCommand ();
815+ }
830816
831817 in_streamed_transaction = false;
832818
@@ -902,7 +888,10 @@ apply_handle_stream_abort(StringInfo s)
902888 {
903889 /* Cleanup the subxact info */
904890 cleanup_subxact_info ();
905- CommitTransactionCommand ();
891+
892+ /* The synchronization worker runs in single transaction */
893+ if (!am_tablesync_worker ())
894+ CommitTransactionCommand ();
906895 return ;
907896 }
908897
@@ -928,7 +917,9 @@ apply_handle_stream_abort(StringInfo s)
928917
929918 /* write the updated subxact list */
930919 subxact_info_write (MyLogicalRepWorker -> subid , xid );
931- CommitTransactionCommand ();
920+
921+ if (!am_tablesync_worker ())
922+ CommitTransactionCommand ();
932923 }
933924}
934925
@@ -1048,35 +1039,54 @@ apply_handle_stream_commit(StringInfo s)
10481039
10491040 BufFileClose (fd );
10501041
1051- /*
1052- * Update origin state so we can restart streaming from correct position
1053- * in case of crash.
1054- */
1055- replorigin_session_origin_lsn = commit_data .end_lsn ;
1056- replorigin_session_origin_timestamp = commit_data .committime ;
1057-
10581042 pfree (buffer );
10591043 pfree (s2 .data );
10601044
1061- CommitTransactionCommand ();
1062- pgstat_report_stat (false);
1063-
1064- store_flush_position (commit_data .end_lsn );
1065-
10661045 elog (DEBUG1 , "replayed %d (all) changes from file \"%s\"" ,
10671046 nchanges , path );
10681047
1069- in_remote_transaction = false;
1070-
1071- /* Process any tables that are being synchronized in parallel. */
1072- process_syncing_tables (commit_data .end_lsn );
1048+ apply_handle_commit_internal (s , & commit_data );
10731049
10741050 /* unlink the files with serialized changes and subxact info */
10751051 stream_cleanup_files (MyLogicalRepWorker -> subid , xid );
10761052
1053+ /* Process any tables that are being synchronized in parallel. */
1054+ process_syncing_tables (commit_data .end_lsn );
1055+
10771056 pgstat_report_activity (STATE_IDLE , NULL );
10781057}
10791058
1059+ /*
1060+ * Helper function for apply_handle_commit and apply_handle_stream_commit.
1061+ */
1062+ static void
1063+ apply_handle_commit_internal (StringInfo s , LogicalRepCommitData * commit_data )
1064+ {
1065+ /* The synchronization worker runs in single transaction. */
1066+ if (IsTransactionState () && !am_tablesync_worker ())
1067+ {
1068+ /*
1069+ * Update origin state so we can restart streaming from correct
1070+ * position in case of crash.
1071+ */
1072+ replorigin_session_origin_lsn = commit_data -> end_lsn ;
1073+ replorigin_session_origin_timestamp = commit_data -> committime ;
1074+
1075+ CommitTransactionCommand ();
1076+ pgstat_report_stat (false);
1077+
1078+ store_flush_position (commit_data -> end_lsn );
1079+ }
1080+ else
1081+ {
1082+ /* Process any invalidation messages that might have accumulated. */
1083+ AcceptInvalidationMessages ();
1084+ maybe_reread_subscription ();
1085+ }
1086+
1087+ in_remote_transaction = false;
1088+ }
1089+
10801090/*
10811091 * Handle RELATION message.
10821092 *
0 commit comments