@@ -67,18 +67,11 @@ bool MtmIsReceiver;
67
67
68
68
typedef struct
69
69
{
70
- MtmReceiverWorkerContext w ;
71
- PGconn * conn ;
70
+ MtmReceiverWorkerContext w ;
71
+ XLogRecPtr last_reported_flush ;
72
+ PGconn * conn ;
72
73
} MtmReceiverContext ;
73
74
74
- typedef struct MtmFlushPosition
75
- {
76
- dlist_node node ;
77
- int node_id ;
78
- XLogRecPtr local_end ;
79
- XLogRecPtr remote_end ;
80
- } MtmFlushPosition ;
81
-
82
75
char const * const MtmReplicationModeMnem [] =
83
76
{
84
77
"disabled" ,
@@ -96,6 +89,9 @@ static volatile sig_atomic_t got_sighup = false;
96
89
static void fe_sendint64 (int64 i , char * buf );
97
90
static int64 fe_recvint64 (char * buf );
98
91
92
+ static void MtmMaybeAdvanceSlot (MtmReceiverContext * rctx , char * conninfo );
93
+ static PGconn * receiver_connect (char * conninfo );
94
+
99
95
void pglogical_receiver_main (Datum main_arg );
100
96
101
97
static void
@@ -156,6 +152,47 @@ sendFeedback(PGconn *conn, int64 now, int node_id)
156
152
return true;
157
153
}
158
154
155
+ /*
156
+ * pg_replication_slot_advance sender slot if we can do that further last
157
+ * advancement. Note that decoding session startup is quite heavy operation as
158
+ * we must read all unacked WAL + earlier chunk up to suitable snapshot
159
+ * serialization point (which is created mostly each
160
+ * LOG_SNAPSHOT_INTERVAL_MS).
161
+ */
162
+ static void
163
+ MtmMaybeAdvanceSlot (MtmReceiverContext * rctx , char * conninfo )
164
+ {
165
+ XLogRecPtr upto = GetRecoveryHorizon (rctx -> w .sender_node_id );
166
+ char * upto_text ;
167
+ char * sql ;
168
+ PGresult * res ;
169
+
170
+ /* already acked this */
171
+ if (upto <= rctx -> last_reported_flush )
172
+ return ;
173
+
174
+ rctx -> conn = receiver_connect (conninfo );
175
+
176
+ upto_text = pg_lsn_out_c (upto );
177
+ sql = psprintf ("select pg_replication_slot_advance('" MULTIMASTER_SLOT_PATTERN "', '%s');" ,
178
+ Mtm -> my_node_id ,
179
+ upto_text );
180
+
181
+ res = PQexec (rctx -> conn , sql );
182
+ if (PQresultStatus (res ) != PGRES_TUPLES_OK )
183
+ {
184
+ mtm_log (ERROR , "%s at node %d failed: %s" ,
185
+ sql , rctx -> w .sender_node_id , PQresultErrorMessage (res ));
186
+ }
187
+ rctx -> last_reported_flush = upto ;
188
+ mtm_log (MtmReceiverFeedback , "advanced slot to %s" , upto_text );
189
+
190
+ pfree (upto_text );
191
+ pfree (sql );
192
+ PQfinish (rctx -> conn );
193
+ rctx -> conn = NULL ;
194
+ }
195
+
159
196
/*
160
197
* Converts an int64 to network byte order.
161
198
*/
549
586
pglogical_receiver_main (Datum main_arg )
550
587
{
551
588
/* Variables for replication connection */
589
+ char * conninfo ;
552
590
PQExpBuffer query ;
553
591
PGresult * res ;
554
592
MtmReceiverContext * rctx ;
@@ -607,6 +645,7 @@ pglogical_receiver_main(Datum main_arg)
607
645
ActivePortal -> sourceText = "" ;
608
646
609
647
receiver_mtm_cfg = MtmLoadConfig ();
648
+ conninfo = MtmNodeById (receiver_mtm_cfg , sender )-> conninfo ;
610
649
611
650
/* Keep us informed about subscription changes. */
612
651
CacheRegisterSyscacheCallback (SUBSCRIPTIONOID ,
@@ -621,7 +660,6 @@ pglogical_receiver_main(Datum main_arg)
621
660
XLogRecPtr remote_start ;
622
661
Syncpoint * spvector = NULL ;
623
662
HTAB * filter_map = NULL ;
624
- char * conninfo ;
625
663
nodemask_t connected_mask ;
626
664
627
665
/*
@@ -651,6 +689,14 @@ pglogical_receiver_main(Datum main_arg)
651
689
if (rctx -> w .mode != REPLMODE_DISABLED )
652
690
break ; /* success */
653
691
692
+ /*
693
+ * So this receiver can't work which usually means we are in
694
+ * recovery and donor is not our sender. Attempt to advance our
695
+ * sender slot then -- this allows to trim WAL on non-donors
696
+ * during recovery which may be very long.
697
+ */
698
+ MtmMaybeAdvanceSlot (rctx , conninfo );
699
+
654
700
ConditionVariableSleep (& Mtm -> receivers_cv , PG_WAIT_EXTENSION );
655
701
}
656
702
ConditionVariableCancelSleep ();
@@ -678,7 +724,6 @@ pglogical_receiver_main(Datum main_arg)
678
724
}
679
725
680
726
/* Establish connection to the remote server */
681
- conninfo = MtmNodeById (receiver_mtm_cfg , sender )-> conninfo ;
682
727
rctx -> conn = receiver_connect (conninfo );
683
728
684
729
/* Create new slot if needed */
@@ -819,8 +864,8 @@ pglogical_receiver_main(Datum main_arg)
819
864
if (got_sighup )
820
865
{
821
866
/* Process config file */
822
- ProcessConfigFile (PGC_SIGHUP );
823
867
got_sighup = false;
868
+ ProcessConfigFile (PGC_SIGHUP );
824
869
ereport (LOG , (MTM_ERRMSG ("%s: processed SIGHUP" ,
825
870
MyBgworkerEntry -> bgw_name )));
826
871
}
0 commit comments