mirror of
https://github.com/postgres/postgres.git
synced 2025-09-03 15:22:11 +03:00
Put the logic to decide which synchronous standby is active into a function.
This avoids duplicating the code. Michael Paquier, reviewed by Simon Riggs and me
This commit is contained in:
@@ -2741,9 +2741,7 @@ pg_stat_get_wal_senders(PG_FUNCTION_ARGS)
|
||||
Tuplestorestate *tupstore;
|
||||
MemoryContext per_query_ctx;
|
||||
MemoryContext oldcontext;
|
||||
int *sync_priority;
|
||||
int priority = 0;
|
||||
int sync_standby = -1;
|
||||
WalSnd *sync_standby;
|
||||
int i;
|
||||
|
||||
/* check to see if caller supports us returning a tuplestore */
|
||||
@@ -2772,38 +2770,10 @@ pg_stat_get_wal_senders(PG_FUNCTION_ARGS)
|
||||
MemoryContextSwitchTo(oldcontext);
|
||||
|
||||
/*
|
||||
* Get the priorities of sync standbys all in one go, to minimise lock
|
||||
* acquisitions and to allow us to evaluate who is the current sync
|
||||
* standby. This code must match the code in SyncRepReleaseWaiters().
|
||||
* Get the currently active synchronous standby.
|
||||
*/
|
||||
sync_priority = palloc(sizeof(int) * max_wal_senders);
|
||||
LWLockAcquire(SyncRepLock, LW_SHARED);
|
||||
for (i = 0; i < max_wal_senders; i++)
|
||||
{
|
||||
/* use volatile pointer to prevent code rearrangement */
|
||||
volatile WalSnd *walsnd = &WalSndCtl->walsnds[i];
|
||||
|
||||
if (walsnd->pid != 0)
|
||||
{
|
||||
/*
|
||||
* Treat a standby such as a pg_basebackup background process
|
||||
* which always returns an invalid flush location, as an
|
||||
* asynchronous standby.
|
||||
*/
|
||||
sync_priority[i] = XLogRecPtrIsInvalid(walsnd->flush) ?
|
||||
0 : walsnd->sync_standby_priority;
|
||||
|
||||
if (walsnd->state == WALSNDSTATE_STREAMING &&
|
||||
walsnd->sync_standby_priority > 0 &&
|
||||
(priority == 0 ||
|
||||
priority > walsnd->sync_standby_priority) &&
|
||||
!XLogRecPtrIsInvalid(walsnd->flush))
|
||||
{
|
||||
priority = walsnd->sync_standby_priority;
|
||||
sync_standby = i;
|
||||
}
|
||||
}
|
||||
}
|
||||
sync_standby = SyncRepGetSynchronousStandby();
|
||||
LWLockRelease(SyncRepLock);
|
||||
|
||||
for (i = 0; i < max_wal_senders; i++)
|
||||
@@ -2814,6 +2784,7 @@ pg_stat_get_wal_senders(PG_FUNCTION_ARGS)
|
||||
XLogRecPtr write;
|
||||
XLogRecPtr flush;
|
||||
XLogRecPtr apply;
|
||||
int priority;
|
||||
WalSndState state;
|
||||
Datum values[PG_STAT_GET_WAL_SENDERS_COLS];
|
||||
bool nulls[PG_STAT_GET_WAL_SENDERS_COLS];
|
||||
@@ -2827,6 +2798,7 @@ pg_stat_get_wal_senders(PG_FUNCTION_ARGS)
|
||||
write = walsnd->write;
|
||||
flush = walsnd->flush;
|
||||
apply = walsnd->apply;
|
||||
priority = walsnd->sync_standby_priority;
|
||||
SpinLockRelease(&walsnd->mutex);
|
||||
|
||||
memset(nulls, 0, sizeof(nulls));
|
||||
@@ -2857,15 +2829,22 @@ pg_stat_get_wal_senders(PG_FUNCTION_ARGS)
|
||||
nulls[5] = true;
|
||||
values[5] = LSNGetDatum(apply);
|
||||
|
||||
values[6] = Int32GetDatum(sync_priority[i]);
|
||||
/*
|
||||
* Treat a standby such as a pg_basebackup background process
|
||||
* which always returns an invalid flush location, as an
|
||||
* asynchronous standby.
|
||||
*/
|
||||
priority = XLogRecPtrIsInvalid(walsnd->flush) ? 0 : priority;
|
||||
|
||||
values[6] = Int32GetDatum(priority);
|
||||
|
||||
/*
|
||||
* More easily understood version of standby state. This is purely
|
||||
* informational, not different from priority.
|
||||
*/
|
||||
if (sync_priority[i] == 0)
|
||||
if (priority == 0)
|
||||
values[7] = CStringGetTextDatum("async");
|
||||
else if (i == sync_standby)
|
||||
else if (walsnd == sync_standby)
|
||||
values[7] = CStringGetTextDatum("sync");
|
||||
else
|
||||
values[7] = CStringGetTextDatum("potential");
|
||||
@@ -2873,7 +2852,6 @@ pg_stat_get_wal_senders(PG_FUNCTION_ARGS)
|
||||
|
||||
tuplestore_putvalues(tupstore, tupdesc, values, nulls);
|
||||
}
|
||||
pfree(sync_priority);
|
||||
|
||||
/* clean up and return the tuplestore */
|
||||
tuplestore_donestoring(tupstore);
|
||||
|
Reference in New Issue
Block a user