]> granicus.if.org Git - postgresql/commitdiff
walreceiver: tweak pg_stat_wal_receiver behavior
authorAlvaro Herrera <alvherre@alvh.no-ip.org>
Fri, 1 Jul 2016 17:53:46 +0000 (13:53 -0400)
committerAlvaro Herrera <alvherre@alvh.no-ip.org>
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)