@@ -73,6 +73,14 @@ typedef struct LogicalRepCtxStruct
73
73
74
74
LogicalRepCtxStruct * LogicalRepCtx ;
75
75
76
+ typedef struct LogicalRepWorkerId
77
+ {
78
+ Oid subid ;
79
+ Oid relid ;
80
+ } LogicalRepWorkerId ;
81
+
82
+ static List * on_commit_stop_workers = NIL ;
83
+
76
84
static void ApplyLauncherWakeup (void );
77
85
static void logicalrep_launcher_onexit (int code , Datum arg );
78
86
static void logicalrep_worker_onexit (int code , Datum arg );
@@ -249,6 +257,30 @@ logicalrep_worker_find(Oid subid, Oid relid, bool only_running)
249
257
return res ;
250
258
}
251
259
260
+ /*
261
+ * Similar to logicalrep_worker_find(), but returns list of all workers for
262
+ * the subscription, instead just one.
263
+ */
264
+ List *
265
+ logicalrep_workers_find (Oid subid , bool only_running )
266
+ {
267
+ int i ;
268
+ List * res = NIL ;
269
+
270
+ Assert (LWLockHeldByMe (LogicalRepWorkerLock ));
271
+
272
+ /* Search for attached worker for a given subscription id. */
273
+ for (i = 0 ; i < max_logical_replication_workers ; i ++ )
274
+ {
275
+ LogicalRepWorker * w = & LogicalRepCtx -> workers [i ];
276
+
277
+ if (w -> in_use && w -> subid == subid && (!only_running || w -> proc ))
278
+ res = lappend (res , w );
279
+ }
280
+
281
+ return res ;
282
+ }
283
+
252
284
/*
253
285
* Start new apply background worker.
254
286
*/
@@ -513,6 +545,27 @@ logicalrep_worker_stop(Oid subid, Oid relid)
513
545
LWLockRelease (LogicalRepWorkerLock );
514
546
}
515
547
548
+ /*
549
+ * Request worker for specified sub/rel to be stopped on commit.
550
+ */
551
+ void
552
+ logicalrep_worker_stop_at_commit (Oid subid , Oid relid )
553
+ {
554
+ LogicalRepWorkerId * wid ;
555
+ MemoryContext oldctx ;
556
+
557
+ /* Make sure we store the info in context that survives until commit. */
558
+ oldctx = MemoryContextSwitchTo (TopTransactionContext );
559
+
560
+ wid = palloc (sizeof (LogicalRepWorkerId ));
561
+ wid -> subid = subid ;
562
+ wid -> relid = relid ;
563
+
564
+ on_commit_stop_workers = lappend (on_commit_stop_workers , wid );
565
+
566
+ MemoryContextSwitchTo (oldctx );
567
+ }
568
+
516
569
/*
517
570
* Wake up (using latch) any logical replication worker for specified sub/rel.
518
571
*/
@@ -753,15 +806,41 @@ ApplyLauncherShmemInit(void)
753
806
}
754
807
}
755
808
809
+ /*
810
+ * Check whether current transaction has manipulated logical replication
811
+ * workers.
812
+ */
813
+ bool
814
+ XactManipulatesLogicalReplicationWorkers (void )
815
+ {
816
+ return (on_commit_stop_workers != NIL );
817
+ }
818
+
756
819
/*
757
820
* Wakeup the launcher on commit if requested.
758
821
*/
759
822
void
760
823
AtEOXact_ApplyLauncher (bool isCommit )
761
824
{
762
- if (isCommit && on_commit_launcher_wakeup )
763
- ApplyLauncherWakeup ();
825
+ if (isCommit )
826
+ {
827
+ ListCell * lc ;
764
828
829
+ foreach (lc , on_commit_stop_workers )
830
+ {
831
+ LogicalRepWorkerId * wid = lfirst (lc );
832
+ logicalrep_worker_stop (wid -> subid , wid -> relid );
833
+ }
834
+
835
+ if (on_commit_launcher_wakeup )
836
+ ApplyLauncherWakeup ();
837
+ }
838
+
839
+ /*
840
+ * No need to pfree on_commit_stop_workers. It was allocated in
841
+ * transaction memory context, which is going to be cleaned soon.
842
+ */
843
+ on_commit_stop_workers = NIL ;
765
844
on_commit_launcher_wakeup = false;
766
845
}
767
846
0 commit comments