- tandby-slot-names" xreflabel="standby_slot_names">
- standby_slot_name s (string )
+ ynchronized-standby-slots" xreflabel="synchronized_standby_slots">
+ synchronized_standby_slot s (string )
-
standby_slot_name s configuration parameter
+
synchronized_standby_slot s configuration parameter
after the standby is promoted, the physical replication slot for the
standby should be listed here. Note that logical replication will not
proceed if the slots specified in the
- standby_slot_name s do not exist or are invalidated.
+ synchronized_standby_slot s do not exist or are invalidated.
Additionally, the replication management functions
pg_replication_slot_advance ,
pg_logical_slot_peek_changes ,
when used with logical failover slots, will block until all
- physical slots specified in standby_slot_name s have
+ physical slots specified in synchronized_standby_slot s have
confirmed WAL receipt.
The standbys corresponding to the physical replication slots in
- standby_slot_name s must configure
+ synchronized_standby_slot s must configure
sync_replication_slots = true so they can receive
logical failover slot changes from the primary.
adding the rows produced when decoding each new transaction commit.
If the specified slot is a logical failover slot then the function will
not return until all physical slots specified in
- tandby-slot-names">standby_slot_names
+ ynchronized-standby-slots">synchronized_standby_slots
have confirmed WAL receipt.
slot may return to an earlier position. If the specified slot is a
logical failover slot then the function will not return until all
physical slots specified in
- tandby-slot-names">standby_slot_names
+ ynchronized-standby-slots">synchronized_standby_slots
have confirmed WAL receipt.
server before the failover happens. To ensure a successful failover, the
standby server must be ahead of the subscriber. This can be achieved by
configuring
- tandby-slot-names">standby_slot_names .
+ ynchronized-standby-slots">synchronized_standby_slots .
dbname in the
primary_conninfo .
It's highly recommended that the said physical replication slot is named in
- tandby-slot-names">standby_slot_names
+ ynchronized-standby-slots">synchronized_standby_slots
list on the primary, to prevent the subscriber from consuming changes
faster than the hot standby. Even when correctly configured, some latency
is expected when sending changes to logical subscribers due to the waiting
on slots named in
- tandby-slot-names">standby_slot_names .
- When standby_slot_name s is utilized, the
+ ynchronized-standby-slots">synchronized_standby_slots .
+ When synchronized_standby_slot s is utilized, the
primary server will not completely shut down until the corresponding
standbys, associated with the physical replication slots specified
- in standby_slot_name s , have confirmed
+ in synchronized_standby_slot s , have confirmed
receiving the WAL up to the latest flushed position on the primary server.
- The new server variable is tandby-slot-names"/>.
+ The new server variable is ynchronized-standby-slots"/>.
if (remote_slot->confirmed_lsn > latestFlushPtr)
{
/*
- * Can get here only if GUC 'standby_slot_names' on the primary server
- * was not configured correctly.
+ * Can get here only if GUC 'synchronized_standby_slots' on the
+ * primary server was not configured correctly.
*/
ereport(AmLogicalSlotSyncWorkerProcess() ? LOG : ERROR,
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
} ReplicationSlotOnDisk;
/*
- * Struct for the configuration of standby_slot_name s.
+ * Struct for the configuration of synchronized_standby_slot s.
*
* Note: this must be a flat representation that can be held in a single chunk
* of guc_malloc'd memory, so that it can be stored as the "extra" data for the
- * standby_slot_name s GUC.
+ * synchronized_standby_slot s GUC.
*/
typedef struct
{
* slot_names contains 'nslotnames' consecutive null-terminated C strings.
*/
char slot_names[FLEXIBLE_ARRAY_MEMBER];
-} StandbySlotName sConfigData;
+} SyncStandbySlot sConfigData;
/*
* Lookup table for slot invalidation causes.
* This GUC lists streaming replication standby server slot names that
* logical WAL sender processes will wait for.
*/
-char *standby_slot_name s;
+char *synchronized_standby_slot s;
-/* This is the parsed and cached configuration for standby_slot_name s */
-static StandbySlotNamesConfigData *standby_slot_name s_config;
+/* This is the parsed and cached configuration for synchronized_standby_slot s */
+static SyncStandbySlotsConfigData *synchronized_standby_slot s_config;
/*
* Oldest LSN that has been confirmed to be flushed to the standbys
- * corresponding to the physical slots specified in the standby_slot_name s GUC.
+ * corresponding to the physical slots specified in the synchronized_standby_slot s GUC.
*/
static XLogRecPtr ss_oldest_flush_lsn = InvalidXLogRecPtr;
}
/*
- * A helper function to validate slots specified in GUC standby_slot_name s.
+ * A helper function to validate slots specified in GUC synchronized_standby_slot s.
*
* The rawname will be parsed, and the result will be saved into *elemlist.
*/
static bool
-validate_standby_slots(char *rawname, List **elemlist)
+validate_sync_s tandby_slots(char *rawname, List **elemlist)
{
bool ok;
}
/*
- * GUC check_hook for standby_slot_name s
+ * GUC check_hook for synchronized_standby_slot s
*/
bool
-check_standby_slot_name s(char **newval, void **extra, GucSource source)
+check_synchronized_standby_slot s(char **newval, void **extra, GucSource source)
{
char *rawname;
char *ptr;
List *elemlist;
int size;
bool ok;
- StandbySlotName sConfigData *config;
+ SyncStandbySlot sConfigData *config;
if ((*newval)[0] == '\0')
return true;
rawname = pstrdup(*newval);
/* Now verify if the specified slots exist and have correct type */
- ok = validate_standby_slots(rawname, &elemlist);
+ ok = validate_sync_s tandby_slots(rawname, &elemlist);
if (!ok || elemlist == NIL)
{
return ok;
}
- /* Compute the size required for the StandbySlotName sConfigData struct */
- size = offsetof(StandbySlotName sConfigData, slot_names);
+ /* Compute the size required for the SyncStandbySlot sConfigData struct */
+ size = offsetof(SyncStandbySlot sConfigData, slot_names);
foreach_ptr(char, slot_name, elemlist)
size += strlen(slot_name) + 1;
/* GUC extra value must be guc_malloc'd, not palloc'd */
- config = (StandbySlotName sConfigData *) guc_malloc(LOG, size);
+ config = (SyncStandbySlot sConfigData *) guc_malloc(LOG, size);
- /* Transform the data into StandbySlotName sConfigData */
+ /* Transform the data into SyncStandbySlot sConfigData */
config->nslotnames = list_length(elemlist);
ptr = config->slot_names;
}
/*
- * GUC assign_hook for standby_slot_name s
+ * GUC assign_hook for synchronized_standby_slot s
*/
void
-assign_standby_slot_name s(const char *newval, void *extra)
+assign_synchronized_standby_slot s(const char *newval, void *extra)
{
/*
* The standby slots may have changed, so we must recompute the oldest
*/
ss_oldest_flush_lsn = InvalidXLogRecPtr;
- standby_slot_names_config = (StandbySlotName sConfigData *) extra;
+ synchronized_standby_slots_config = (SyncStandbySlot sConfigData *) extra;
}
/*
- * Check if the passed slot_name is specified in the standby_slot_name s GUC.
+ * Check if the passed slot_name is specified in the synchronized_standby_slot s GUC.
*/
bool
-SlotExistsInStandbySlotName s(const char *slot_name)
+SlotExistsInSyncStandbySlot s(const char *slot_name)
{
const char *standby_slot_name;
- /* Return false if there is no value in standby_slot_name s */
- if (standby_slot_name s_config == NULL)
+ /* Return false if there is no value in synchronized_standby_slot s */
+ if (synchronized_standby_slot s_config == NULL)
return false;
/*
* shouldn't hurt but if that turns out not to be true then we can cache
* this information for each WalSender as well.
*/
- standby_slot_name = standby_slot_name s_config->slot_names;
- for (int i = 0; i < standby_slot_name s_config->nslotnames; i++)
+ standby_slot_name = synchronized_standby_slot s_config->slot_names;
+ for (int i = 0; i < synchronized_standby_slot s_config->nslotnames; i++)
{
if (strcmp(standby_slot_name, slot_name) == 0)
return true;
}
/*
- * Return true if the slots specified in standby_slot_name s have caught up to
+ * Return true if the slots specified in synchronized_standby_slot s have caught up to
* the given WAL location, false otherwise.
*
* The elevel parameter specifies the error level used for logging messages
/*
* Don't need to wait for the standbys to catch up if there is no value in
- * standby_slot_name s.
+ * synchronized_standby_slot s.
*/
- if (standby_slot_name s_config == NULL)
+ if (synchronized_standby_slot s_config == NULL)
return true;
/*
*/
LWLockAcquire(ReplicationSlotControlLock, LW_SHARED);
- name = standby_slot_name s_config->slot_names;
- for (int i = 0; i < standby_slot_name s_config->nslotnames; i++)
+ name = synchronized_standby_slot s_config->slot_names;
+ for (int i = 0; i < synchronized_standby_slot s_config->nslotnames; i++)
{
XLogRecPtr restart_lsn;
bool invalidated;
if (!slot)
{
/*
- * If a slot name provided in standby_slot_names does not exist,
- * report a message and exit the loop. A user can specify a slot
- * name that does not exist just before the server startup. The
- * GUC check_hook(validate_standby_slots) cannot validate such a
- * slot during startup as the ReplicationSlotCtl shared memory is
- * not initialized at that time. It is also possible for a user to
- * drop the slot in standby_slot_names afterwards.
+ * If a slot name provided in synchronized_standby_slots does not
+ * exist, report a message and exit the loop. A user can specify a
+ * slot name that does not exist just before the server startup.
+ * The GUC check_hook(validate_sync_standby_slots) cannot validate
+ * such a slot during startup as the ReplicationSlotCtl shared
+ * memory is not initialized at that time. It is also possible for
+ * a user to drop the slot in synchronized_standby_slots
+ * afterwards.
*/
ereport(elevel,
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("replication slot \"%s\" specified in parameter %s does not exist",
- name, "standby_slot_name s"),
+ name, "synchronized_standby_slot s"),
errdetail("Logical replication is waiting on the standby associated with \"%s\".",
name),
errhint("Consider creating the slot \"%s\" or amend parameter %s.",
- name, "standby_slot_name s"));
+ name, "synchronized_standby_slot s"));
break;
}
if (SlotIsLogical(slot))
{
/*
- * If a logical slot name is provided in standby_slot_names,
- * report a message and exit the loop. Similar to the non-existent
- * case, a user can specify a logical slot name in
- * standby_slot_names before the server startup, or drop an
- * existing physical slot and recreate a logical slot with the
- * same name.
+ * If a logical slot name is provided in
+ * synchronized_standby_slots, report a message and exit the loop.
+ * Similar to the non-existent case, a user can specify a logical
+ * slot name in synchronized_standby_slots before the server
+ * startup, or drop an existing physical slot and recreate a
+ * logical slot with the same name.
*/
ereport(elevel,
errcode(ERRCODE_INVALID_PARAMETER_VALUE),
errmsg("cannot have logical replication slot \"%s\" in parameter %s",
- name, "standby_slot_name s"),
+ name, "synchronized_standby_slot s"),
errdetail("Logical replication is waiting for correction on \"%s\".",
name),
errhint("Consider removing logical slot \"%s\" from parameter %s.",
- name, "standby_slot_name s"));
+ name, "synchronized_standby_slot s"));
break;
}
ereport(elevel,
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("physical slot \"%s\" specified in parameter %s has been invalidated",
- name, "standby_slot_name s"),
+ name, "synchronized_standby_slot s"),
errdetail("Logical replication is waiting on the standby associated with \"%s\".",
name),
errhint("Consider dropping and recreating the slot \"%s\" or amend parameter %s.",
- name, "standby_slot_name s"));
+ name, "synchronized_standby_slot s"));
break;
}
ereport(elevel,
errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
errmsg("replication slot \"%s\" specified in parameter %s does not have active_pid",
- name, "standby_slot_name s"),
+ name, "synchronized_standby_slot s"),
errdetail("Logical replication is waiting on the standby associated with \"%s\".",
name),
errhint("Consider starting standby associated with \"%s\" or amend parameter %s.",
- name, "standby_slot_name s"));
+ name, "synchronized_standby_slot s"));
/* Continue if the current slot hasn't caught up. */
break;
* Return false if not all the standbys have caught up to the specified
* WAL location.
*/
- if (caught_up_slot_num != standby_slot_name s_config->nslotnames)
+ if (caught_up_slot_num != synchronized_standby_slot s_config->nslotnames)
return false;
/* The ss_oldest_flush_lsn must not retreat. */
* Wait for physical standbys to confirm receiving the given lsn.
*
* Used by logical decoding SQL functions. It waits for physical standbys
- * corresponding to the physical slots specified in the standby_slot_name s GUC.
+ * corresponding to the physical slots specified in the synchronized_standby_slot s GUC.
*/
void
WaitForStandbyConfirmation(XLogRecPtr wait_for_lsn)
/*
* Don't need to wait for the standby to catch up if the current acquired
* slot is not a logical failover slot, or there is no value in
- * standby_slot_name s.
+ * synchronized_standby_slot s.
*/
- if (!MyReplicationSlot->data.failover || !standby_slot_name s_config)
+ if (!MyReplicationSlot->data.failover || !synchronized_standby_slot s_config)
return;
ConditionVariablePrepareToSleep(&WalSndCtl->wal_confirm_rcv_cv);
break;
/*
- * Wait for the slots in the standby_slot_names to catch up, but use a
- * timeout (1s) so we can also check if the standby_slot_names has
- * been changed.
+ * Wait for the slots in the synchronized_standby_slots to catch up,
+ * but use a timeout (1s) so we can also check if the
+ * synchronized_standby_slots has been changed.
*/
ConditionVariableTimedSleep(&WalSndCtl->wal_confirm_rcv_cv, 1000,
WAIT_EVENT_WAIT_FOR_STANDBY_CONFIRMATION);
/*
* Wake up the logical walsender processes with logical failover slots if the
- * currently acquired physical slot is specified in standby_slot_name s GUC.
+ * currently acquired physical slot is specified in synchronized_standby_slot s GUC.
*/
void
PhysicalWakeupLogicalWalSnd(void)
if (RecoveryInProgress())
return;
- if (SlotExistsInStandbySlotName s(NameStr(MyReplicationSlot->data.name)))
+ if (SlotExistsInSyncStandbySlot s(NameStr(MyReplicationSlot->data.name)))
ConditionVariableBroadcast(&WalSndCtl->wal_confirm_rcv_cv);
}
},
{
- {"standby_slot_name s", PGC_SIGHUP, REPLICATION_PRIMARY,
+ {"synchronized_standby_slot s", PGC_SIGHUP, REPLICATION_PRIMARY,
gettext_noop("Lists streaming replication standby server slot "
"names that logical WAL sender processes will wait for."),
gettext_noop("Logical WAL sender processes will send decoded "
"replication slots confirm receiving WAL."),
GUC_LIST_INPUT
},
- &standby_slot_name s,
+ &synchronized_standby_slot s,
"",
- check_standby_slot_names, assign_standby_slot_name s, NULL
+ check_synchronized_standby_slots, assign_synchronized_standby_slot s, NULL
},
/* End-of-list marker */
# method to choose sync standbys, number of sync standbys,
# and comma-separated list of application_name
# from standby(s); '*' = all
-#standby_slot_names = '' # streaming replication standby server slot names tha t
- # logical walsender processes will wait for
+#synchronized_standby_slots = '' # streaming replication standby server slo t
+ # names that logical walsender processes will wait for
# - Standby Servers -
/* GUCs */
extern PGDLLIMPORT int max_replication_slots;
-extern PGDLLIMPORT char *standby_slot_name s;
+extern PGDLLIMPORT char *synchronized_standby_slot s;
/* shmem initialization functions */
extern Size ReplicationSlotsShmemSize(void);
extern ReplicationSlotInvalidationCause
GetSlotInvalidationCause(const char *invalidation_reason);
-extern bool SlotExistsInStandbySlotName s(const char *slot_name);
+extern bool SlotExistsInSyncStandbySlot s(const char *slot_name);
extern bool StandbySlotsHaveCaughtup(XLogRecPtr wait_for_lsn, int elevel);
extern void WaitForStandbyConfirmation(XLogRecPtr wait_for_lsn);
/*
* Used by physical walsenders holding slots specified in
- * standby_slot_names to wake up logical walsenders holding logical
- * failover slots when a walreceiver confirms the receipt of LSN.
+ * synchronized_standby_slots to wake up logical walsenders holding
+ * logical failover slots when a walreceiver confirms the receipt of LSN.
*/
ConditionVariable wal_confirm_rcv_cv;
extern void assign_wal_consistency_checking(const char *newval, void *extra);
extern bool check_wal_segment_size(int *newval, void **extra, GucSource source);
extern void assign_wal_sync_method(int new_wal_sync_method, void *extra);
-extern bool check_standby_slot_name s(char **newval, void **extra,
- GucSource source);
-extern void assign_standby_slot_name s(const char *newval, void *extra);
+extern bool check_synchronized_standby_slot s(char **newval, void **extra,
+ GucSource source);
+extern void assign_synchronized_standby_slot s(const char *newval, void *extra);
#endif /* GUC_HOOKS_H */
# | ----> subscriber1 (failover = true, slot_name = lsub1_slot)
# | ----> subscriber2 (failover = false, slot_name = lsub2_slot)
#
-# standby_slot_name s = 'sb1_slot'
+# synchronized_standby_slot s = 'sb1_slot'
#
# The setup is configured in such a way that the logical slot of subscriber1 is
# enabled for failover, and thus the subscriber1 will wait for the physical
# from getting ahead of the specified physical replication slot (sb1_slot).
$primary->append_conf(
'postgresql.conf', qq(
-standby_slot_name s = 'sb1_slot'
+synchronized_standby_slot s = 'sb1_slot'
));
$primary->reload;
# Wait until the primary server logs a warning indicating that it is waiting
# for the sb1_slot to catch up.
$primary->wait_for_log(
- qr/replication slot \"sb1_slot\" specified in parameter standby_slot_name s does not have active_pid/,
+ qr/replication slot \"sb1_slot\" specified in parameter synchronized_standby_slot s does not have active_pid/,
$offset);
# The regress_mysub1 was enabled for failover so it doesn't get the data from
-# primary and keeps waiting for the standby specified in standby_slot_name s
+# primary and keeps waiting for the standby specified in synchronized_standby_slot s
# (sb1_slot aka standby1).
$result =
$subscriber1->safe_psql('postgres',
"subscriber1 doesn't get data from primary until standby1 acknowledges changes"
);
-# Start the standby specified in standby_slot_name s (sb1_slot aka standby1) and
+# Start the standby specified in synchronized_standby_slot s (sb1_slot aka standby1) and
# wait for it to catch up with the primary.
$standby1->start;
$primary->wait_for_replay_catchup($standby1);
"SELECT count(*) = $primary_row_count FROM tab_int;");
is($result, 't', "standby1 gets data from primary");
-# Now that the standby specified in standby_slot_name s is up and running, the
+# Now that the standby specified in synchronized_standby_slot s is up and running, the
# primary can send the decoded changes to the subscription enabled for failover
# (i.e. regress_mysub1). While the standby was down, regress_mysub1 didn't
# receive any data from the primary. i.e. the primary didn't allow it to go
##################################################
# Verify that when using pg_logical_slot_get_changes to consume changes from a
# logical failover slot, it will also wait for the slots specified in
-# standby_slot_name s to catch up.
+# synchronized_standby_slot s to catch up.
##################################################
# Stop the standby associated with the specified physical replication slot so
# that the logical replication slot won't receive changes until the standby
# slot's restart_lsn is advanced or the slot is removed from the
-# standby_slot_name s list.
+# synchronized_standby_slot s list.
$primary->safe_psql('postgres', "TRUNCATE tab_int;");
$primary->wait_for_catchup('regress_mysub1');
$standby1->stop;
# Wait until the primary server logs a warning indicating that it is waiting
# for the sb1_slot to catch up.
$primary->wait_for_log(
- qr/replication slot \"sb1_slot\" specified in parameter standby_slot_name s does not have active_pid/,
+ qr/replication slot \"sb1_slot\" specified in parameter synchronized_standby_slot s does not have active_pid/,
$offset);
-# Remove the standby from the standby_slot_name s list and reload the
+# Remove the standby from the synchronized_standby_slot s list and reload the
# configuration.
-$primary->adjust_conf('postgresql.conf', 'standby_slot_name s', "''");
+$primary->adjust_conf('postgresql.conf', 'synchronized_standby_slot s', "''");
$primary->reload;
-# Since there are no slots in standby_slot_name s, the function
+# Since there are no slots in synchronized_standby_slot s, the function
# pg_logical_slot_get_changes should now return, and the session can be
# stopped.
$back_q->quit;
$primary->safe_psql('postgres',
"SELECT pg_drop_replication_slot('test_slot');");
-# Add the physical slot (sb1_slot) back to the standby_slot_name s for further
+# Add the physical slot (sb1_slot) back to the synchronized_standby_slot s for further
# tests.
-$primary->adjust_conf('postgresql.conf', 'standby_slot_names', "'sb1_slot'");
+$primary->adjust_conf('postgresql.conf', 'synchronized_standby_slots',
+ "'sb1_slot'");
$primary->reload;
# Enable the regress_mysub1 for further tests
##################################################
# Test that logical replication will wait for the user-created inactive
-# physical slot to catch up until we remove the slot from standby_slot_name s.
+# physical slot to catch up until we remove the slot from synchronized_standby_slot s.
##################################################
$offset = -s $primary->logfile;
# Wait until the primary server logs a warning indicating that it is waiting
# for the sb1_slot to catch up.
$primary->wait_for_log(
- qr/replication slot \"sb1_slot\" specified in parameter standby_slot_name s does not have active_pid/,
+ qr/replication slot \"sb1_slot\" specified in parameter synchronized_standby_slot s does not have active_pid/,
$offset);
# The regress_mysub1 doesn't get the data from primary because the specified
-# standby slot (sb1_slot) in standby_slot_name s is inactive.
+# standby slot (sb1_slot) in synchronized_standby_slot s is inactive.
$result =
$subscriber1->safe_psql('postgres', "SELECT count(*) = 0 FROM tab_int;");
is($result, 't',
"subscriber1 doesn't get data as the sb1_slot doesn't catch up");
-# Remove the standby from the standby_slot_name s list and reload the
+# Remove the standby from the synchronized_standby_slot s list and reload the
# configuration.
-$primary->adjust_conf('postgresql.conf', 'standby_slot_name s', "''");
+$primary->adjust_conf('postgresql.conf', 'synchronized_standby_slot s', "''");
$primary->reload;
-# Since there are no slots in standby_slot_name s, the primary server should now
+# Since there are no slots in synchronized_standby_slot s, the primary server should now
# send the decoded changes to the subscription.
$primary->wait_for_catchup('regress_mysub1');
$result = $subscriber1->safe_psql('postgres',
"SELECT count(*) = $primary_row_count FROM tab_int;");
is($result, 't',
- "subscriber1 gets data from primary after standby1 is removed from the standby_slot_name s list"
+ "subscriber1 gets data from primary after standby1 is removed from the synchronized_standby_slot s list"
);
-# Add the physical slot (sb1_slot) back to the standby_slot_name s for further
+# Add the physical slot (sb1_slot) back to the synchronized_standby_slot s for further
# tests.
-$primary->adjust_conf('postgresql.conf', 'standby_slot_names', "'sb1_slot'");
+$primary->adjust_conf('postgresql.conf', 'synchronized_standby_slots',
+ "'sb1_slot'");
$primary->reload;
##################################################
SplitTextOutputData
SplitVar
StackElem
-StandbySlotNamesConfigData
StartDataPtrType
StartLOPtrType
StartLOsPtrType
SyncRepStandbyData
SyncRequestHandler
SyncRequestType
+SyncStandbySlotsConfigData
SyncingTablesState
SysFKRelationship
SysScanDesc