diff --git a/src/backend/replication/walreceiver.c b/src/backend/replication/walreceiver.c index 3474514adc..32994f11a9 100644 --- a/src/backend/replication/walreceiver.c +++ b/src/backend/replication/walreceiver.c @@ -196,6 +196,7 @@ WalReceiverMain(void) bool first_stream; WalRcvData *walrcv = WalRcv; TimestampTz last_recv_timestamp; + TimestampTz current_timestamp; bool ping_sent; char *err; @@ -205,6 +206,12 @@ WalReceiverMain(void) */ Assert(walrcv != NULL); + /* + * Acquire timestamp before acquiring the WAL receiver spin lock. + * External calls should not happen in such sections. + */ + current_timestamp = GetCurrentTimestamp(); + /* * Mark walreceiver as running in shared memory. * @@ -234,6 +241,7 @@ WalReceiverMain(void) case WALRCV_STREAMING: case WALRCV_RESTARTING: default: + SpinLockRelease(&walrcv->mutex); /* Shouldn't happen */ elog(PANIC, "walreceiver still running according to shared memory state"); } @@ -249,7 +257,7 @@ WalReceiverMain(void) startpointTLI = walrcv->receiveStartTLI; /* Initialise to a sanish value */ - walrcv->lastMsgSendTime = walrcv->lastMsgReceiptTime = walrcv->latestWalEndTime = GetCurrentTimestamp(); + walrcv->lastMsgSendTime = walrcv->lastMsgReceiptTime = walrcv->latestWalEndTime = current_timestamp; SpinLockRelease(&walrcv->mutex); @@ -308,13 +316,13 @@ WalReceiverMain(void) SpinLockAcquire(&walrcv->mutex); memset(walrcv->conninfo, 0, MAXCONNINFO); if (tmp_conninfo) - { strlcpy((char *) walrcv->conninfo, tmp_conninfo, MAXCONNINFO); - pfree(tmp_conninfo); - } walrcv->ready_to_display = true; SpinLockRelease(&walrcv->mutex); + if (tmp_conninfo) + pfree(tmp_conninfo); + first_stream = true; for (;;) { @@ -1393,6 +1401,9 @@ pg_stat_get_wal_receiver(PG_FUNCTION_ARGS) char *slotname; char *conninfo; + slotname = (char *) palloc(NAMEDATALEN); + conninfo = (char *) palloc(MAXCONNINFO); + /* Take a lock to ensure value consistency */ SpinLockAcquire(&WalRcv->mutex); pid = (int) WalRcv->pid; @@ -1406,8 +1417,8 @@ pg_stat_get_wal_receiver(PG_FUNCTION_ARGS) last_receipt_time = WalRcv->lastMsgReceiptTime; latest_end_lsn = WalRcv->latestWalEnd; latest_end_time = WalRcv->latestWalEndTime; - slotname = pstrdup(WalRcv->slotname); - conninfo = pstrdup(WalRcv->conninfo); + memcpy(slotname, WalRcv->slotname, NAMEDATALEN); + memcpy(conninfo, WalRcv->conninfo, MAXCONNINFO); SpinLockRelease(&WalRcv->mutex); /*