walreceiver: tweak pg_stat_wal_receiver behavior
authorAlvaro Herrera <[email protected]>
Fri, 1 Jul 2016 17:53:46 +0000 (13:53 -0400)
committerAlvaro Herrera <[email protected]>
Fri, 1 Jul 2016 17:53:46 +0000 (13:53 -0400)
There are two problems in the original coding: one is that if one
walreceiver process exits, the ready_to_display flag remains set in
shared memory, exposing the conninfo of the next walreceiver before
obfuscating.  Fix by having WalRcvDie reset the flag.

Second, the sleep-and-retry behavior that waited until walreceiver had
set ready_to_display wasn't liked; the preference is to have it return
no data instead, so let's do that.

Bugs in 9ed551e0a reported by Fujii Masao and Michël Paquier.

Author: Michaël Paquier

src/backend/replication/walreceiver.c

index d552f04901cd3f2ed9b69d4e5ba8e461996aac26..413ee3a5c18e756e2bc083b92d1593c97dc0bcb2 100644 (file)
@@ -246,6 +246,7 @@ WalReceiverMain(void)
    walrcv->walRcvState = WALRCV_STREAMING;
 
    /* Fetch information required to start streaming */
+   walrcv->ready_to_display = false;
    strlcpy(conninfo, (char *) walrcv->conninfo, MAXCONNINFO);
    strlcpy(slotname, (char *) walrcv->slotname, NAMEDATALEN);
    startpoint = walrcv->receiveStart;
@@ -770,6 +771,7 @@ WalRcvDie(int code, Datum arg)
    Assert(walrcv->pid == MyProcPid);
    walrcv->walRcvState = WALRCV_STOPPED;
    walrcv->pid = 0;
+   walrcv->ready_to_display = false;
    SpinLockRelease(&walrcv->mutex);
 
    /* Terminate the connection gracefully. */
@@ -1343,24 +1345,12 @@ pg_stat_get_wal_receiver(PG_FUNCTION_ARGS)
    char       *slotname;
    char       *conninfo;
 
-   /* No WAL receiver, just return a tuple with NULL values */
-   if (walrcv->pid == 0)
-       PG_RETURN_NULL();
-
    /*
-    * Users attempting to read this data mustn't be shown security sensitive
-    * data, so sleep until everything has been properly obfuscated.
+    * No WAL receiver (or not ready yet), just return a tuple with NULL
+    * values
     */
-retry:
-   SpinLockAcquire(&walrcv->mutex);
-   if (!walrcv->ready_to_display)
-   {
-       SpinLockRelease(&walrcv->mutex);
-       CHECK_FOR_INTERRUPTS();
-       pg_usleep(1000);
-       goto retry;
-   }
-   SpinLockRelease(&walrcv->mutex);
+   if (walrcv->pid == 0 || !walrcv->ready_to_display)
+       PG_RETURN_NULL();
 
    /* determine result type */
    if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)