diff options
Diffstat (limited to 'src/backend/replication')
-rw-r--r-- | src/backend/replication/walreceiver.c | 62 | ||||
-rw-r--r-- | src/backend/replication/walreceiverfuncs.c | 28 |
2 files changed, 51 insertions, 39 deletions
diff --git a/src/backend/replication/walreceiver.c b/src/backend/replication/walreceiver.c index 25e0333c9e1..a1459ca7f69 100644 --- a/src/backend/replication/walreceiver.c +++ b/src/backend/replication/walreceiver.c @@ -15,6 +15,12 @@ * WalRcv->receivedUpto variable in shared memory, to inform the startup * process of how far it can proceed with XLOG replay. * + * A WAL receiver cannot directly load GUC parameters used when establishing + * its connection to the primary. Instead it relies on parameter values + * that are passed down by the startup process when streaming is requested. + * This applies, for example, to the replication slot and the connection + * string to be used for the connection with the primary. + * * If the primary server ends streaming, but doesn't disconnect, walreceiver * goes into "waiting" mode, and waits for the startup process to give new * instructions. The startup process will treat that the same as @@ -73,8 +79,11 @@ #include "utils/timestamp.h" -/* GUC variables */ -bool wal_receiver_create_temp_slot; +/* + * GUC variables. (Other variables that affect walreceiver are in xlog.c + * because they're passed down from the startup process, for better + * synchronization.) + */ int wal_receiver_status_interval; int wal_receiver_timeout; bool hot_standby_feedback; @@ -236,6 +245,12 @@ WalReceiverMain(void) startpoint = walrcv->receiveStart; startpointTLI = walrcv->receiveStartTLI; + /* + * At most one of is_temp_slot and slotname can be set; otherwise, + * RequestXLogStreaming messed up. + */ + Assert(!is_temp_slot || (slotname[0] == '\0')); + /* Initialise to a sanish value */ walrcv->lastMsgSendTime = walrcv->lastMsgReceiptTime = walrcv->latestWalEndTime = now; @@ -349,42 +364,21 @@ WalReceiverMain(void) WalRcvFetchTimeLineHistoryFiles(startpointTLI, primaryTLI); /* - * Create temporary replication slot if no slot name is configured or - * the slot from the previous run was temporary, unless - * wal_receiver_create_temp_slot is disabled. We also need to handle - * the case where the previous run used a temporary slot but - * wal_receiver_create_temp_slot was changed in the meantime. In that - * case, we delete the old slot name in shared memory. (This would - * all be a bit easier if we just didn't copy the slot name into - * shared memory, since we won't need it again later, but then we - * can't see the slot name in the stats views.) + * Create temporary replication slot if requested, and update slot + * name in shared memory. (Note the slot name cannot already be set + * in this case.) */ - if (slotname[0] == '\0' || is_temp_slot) + if (is_temp_slot) { - bool changed = false; - - if (wal_receiver_create_temp_slot) - { - snprintf(slotname, sizeof(slotname), - "pg_walreceiver_%lld", - (long long int) walrcv_get_backend_pid(wrconn)); + snprintf(slotname, sizeof(slotname), + "pg_walreceiver_%lld", + (long long int) walrcv_get_backend_pid(wrconn)); - walrcv_create_slot(wrconn, slotname, true, 0, NULL); - changed = true; - } - else if (slotname[0] != '\0') - { - slotname[0] = '\0'; - changed = true; - } + walrcv_create_slot(wrconn, slotname, true, 0, NULL); - if (changed) - { - SpinLockAcquire(&walrcv->mutex); - strlcpy(walrcv->slotname, slotname, NAMEDATALEN); - walrcv->is_temp_slot = wal_receiver_create_temp_slot; - SpinLockRelease(&walrcv->mutex); - } + SpinLockAcquire(&walrcv->mutex); + strlcpy(walrcv->slotname, slotname, NAMEDATALEN); + SpinLockRelease(&walrcv->mutex); } /* diff --git a/src/backend/replication/walreceiverfuncs.c b/src/backend/replication/walreceiverfuncs.c index 89c903e45af..21d18236076 100644 --- a/src/backend/replication/walreceiverfuncs.c +++ b/src/backend/replication/walreceiverfuncs.c @@ -215,13 +215,19 @@ ShutdownWalRcv(void) /* * Request postmaster to start walreceiver. * - * recptr indicates the position where streaming should begin, conninfo - * is a libpq connection string to use, and slotname is, optionally, the name - * of a replication slot to acquire. + * "recptr" indicates the position where streaming should begin. "conninfo" + * is a libpq connection string to use. "slotname" is, optionally, the name + * of a replication slot to acquire. "create_temp_slot" indicates to create + * a temporary slot when no "slotname" is given. + * + * WAL receivers do not directly load GUC parameters used for the connection + * to the primary, and rely on the values passed down by the caller of this + * routine instead. Hence, the addition of any new parameters should happen + * through this code path. */ void RequestXLogStreaming(TimeLineID tli, XLogRecPtr recptr, const char *conninfo, - const char *slotname) + const char *slotname, bool create_temp_slot) { WalRcvData *walrcv = WalRcv; bool launch = false; @@ -248,10 +254,22 @@ RequestXLogStreaming(TimeLineID tli, XLogRecPtr recptr, const char *conninfo, else walrcv->conninfo[0] = '\0'; - if (slotname != NULL) + /* + * Use configured replication slot if present, and ignore the value + * of create_temp_slot as the slot name should be persistent. Otherwise, + * use create_temp_slot to determine whether this WAL receiver should + * create a temporary slot by itself and use it, or not. + */ + if (slotname != NULL && slotname[0] != '\0') + { strlcpy((char *) walrcv->slotname, slotname, NAMEDATALEN); + walrcv->is_temp_slot = false; + } else + { walrcv->slotname[0] = '\0'; + walrcv->is_temp_slot = create_temp_slot; + } if (walrcv->walRcvState == WALRCV_STOPPED) { |