Oid *subrel_local_oids,
int subrel_count,
char *subname);
-static void check_pub_dead_tuple_retention(WalReceiverConn *wrconn);
static void check_duplicates_in_publist(List *publist, Datum *datums);
static List *merge_publications(List *oldpublist, List *newpublist, bool addpub, const char *subname);
static void ReportSlotConnectionError(List *rstates, Oid subid, char *slotname, char *err);
NULL, 0, stmt->subname);
if (opts.retaindeadtuples)
- check_pub_dead_tuple_retention(wrconn);
+ CheckPubDeadTupleRetention(wrconn);
/*
* Set sync state based on if we were asked to do data copy or
ApplyLauncherWakeupAtCommit();
update_tuple = true;
-
- /*
- * The subscription might be initially created with
- * connect=false and retain_dead_tuples=true, meaning the
- * remote server's status may not be checked. Ensure this
- * check is conducted now.
- */
- check_pub_rdt = sub->retaindeadtuples && opts.enabled;
break;
}
PG_TRY();
{
if (retain_dead_tuples)
- check_pub_dead_tuple_retention(wrconn);
+ CheckPubDeadTupleRetention(wrconn);
check_publications_origin_tables(wrconn, sub->publications, false,
retain_dead_tuples, origin, NULL, 0,
* than the PG19, or if the publisher is in recovery (i.e., it is a standby
* server).
*
+ * This is used both at DDL time (as a convenience, when a connection to the
+ * publisher is already being made) and by the apply worker when it connects,
+ * which is the authoritative check because the publisher's version and
+ * recovery status can change after the DDL command.
+ *
* See comments atop worker.c for a detailed explanation.
*/
-static void
-check_pub_dead_tuple_retention(WalReceiverConn *wrconn)
+void
+CheckPubDeadTupleRetention(WalReceiverConn *wrconn)
{
WalRcvExecResult *res;
Oid RecoveryRow[1] = {BOOLOID};
*/
(void) walrcv_identify_system(LogRepWorkerWalRcvConn, &startpointTLI, NULL);
+ /*
+ * If retain_dead_tuples is enabled, verify that the publisher is
+ * suitable, that is, it runs a version that supports the feature and is
+ * not in recovery. This is the authoritative check. Although the same
+ * validation is performed opportunistically at DDL time, the publisher's
+ * version or recovery status may have changed since then, for example
+ * after a failover.
+ */
+ if (MySubscription->retaindeadtuples)
+ {
+ StartTransactionCommand();
+ CheckPubDeadTupleRetention(LogRepWorkerWalRcvConn);
+ CommitTransactionCommand();
+ }
+
set_apply_error_context_origin(originname);
set_stream_options(&options, slotname, &origin_startpos);
#include "catalog/objectaddress.h"
#include "parser/parse_node.h"
+struct WalReceiverConn; /* avoid pulling in walreceiver.h here */
+
extern ObjectAddress CreateSubscription(ParseState *pstate, CreateSubscriptionStmt *stmt,
bool isTopLevel);
extern ObjectAddress AlterSubscription(ParseState *pstate, AlterSubscriptionStmt *stmt, bool isTopLevel);
bool retention_active,
bool max_retention_set);
+extern void CheckPubDeadTupleRetention(struct WalReceiverConn *wrconn);
+
#endif /* SUBSCRIPTIONCMDS_H */