Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit fb3dbdf

Browse files
committed
Rethink prior patch to filter out dead backend entries from the pgstats
file. The original code probed the PGPROC array separately for each PID, which was not good for large numbers of backends: not only is the runtime O(N^2) but most of it is spent holding ProcArrayLock. Instead, take the lock just once and copy the active PIDs into an array, then use qsort and bsearch so that the lookup time is more like O(N log N).
1 parent 4ce6be4 commit fb3dbdf

File tree

3 files changed

+64
-7
lines changed

3 files changed

+64
-7
lines changed

src/backend/postmaster/pgstat.c

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
*
1414
* Copyright (c) 2001-2005, PostgreSQL Global Development Group
1515
*
16-
* $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.112 2005/11/22 18:17:17 momjian Exp $
16+
* $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.113 2005/12/16 04:03:40 tgl Exp $
1717
* ----------
1818
*/
1919
#include "postgres.h"
@@ -2453,6 +2453,16 @@ pgstat_write_statsfile(void)
24532453
}
24542454
}
24552455

2456+
/*
2457+
* qsort/bsearch comparison routine for PIDs
2458+
*
2459+
* We assume PIDs are nonnegative, so there's no overflow risk
2460+
*/
2461+
static int
2462+
comparePids(const void *v1, const void *v2)
2463+
{
2464+
return *((const int *) v1) - *((const int *) v2);
2465+
}
24562466

24572467
/* ----------
24582468
* pgstat_read_statsfile() -
@@ -2478,7 +2488,7 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
24782488
int maxbackends = 0;
24792489
int havebackends = 0;
24802490
bool found;
2481-
bool check_pids;
2491+
int *live_pids;
24822492
MemoryContext use_mcxt;
24832493
int mcxt_flags;
24842494

@@ -2497,13 +2507,17 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
24972507
{
24982508
use_mcxt = NULL;
24992509
mcxt_flags = 0;
2500-
check_pids = false;
2510+
live_pids = NULL;
25012511
}
25022512
else
25032513
{
25042514
use_mcxt = TopTransactionContext;
25052515
mcxt_flags = HASH_CONTEXT;
2506-
check_pids = true;
2516+
live_pids = GetAllBackendPids();
2517+
/* Sort the PID array so we can use bsearch */
2518+
if (live_pids[0] > 1)
2519+
qsort((void *) &live_pids[1], live_pids[0], sizeof(int),
2520+
comparePids);
25072521
}
25082522

25092523
/*
@@ -2706,7 +2720,13 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
27062720
/*
27072721
* If possible, check PID to verify still running
27082722
*/
2709-
if (check_pids && !IsBackendPid(beentry->procpid))
2723+
if (live_pids &&
2724+
(live_pids[0] == 0 ||
2725+
bsearch((void *) &beentry->procpid,
2726+
(void *) &live_pids[1],
2727+
live_pids[0],
2728+
sizeof(int),
2729+
comparePids) == NULL))
27102730
{
27112731
/*
27122732
* Note: we could send a BETERM message to tell the

src/backend/storage/ipc/procarray.c

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
*
2424
*
2525
* IDENTIFICATION
26-
* $PostgreSQL: pgsql/src/backend/storage/ipc/procarray.c,v 1.9 2005/12/11 21:02:18 tgl Exp $
26+
* $PostgreSQL: pgsql/src/backend/storage/ipc/procarray.c,v 1.10 2005/12/16 04:03:40 tgl Exp $
2727
*
2828
*-------------------------------------------------------------------------
2929
*/
@@ -732,6 +732,42 @@ IsBackendPid(int pid)
732732
return (BackendPidGetProc(pid) != NULL);
733733
}
734734

735+
/*
736+
* GetAllBackendPids -- get an array of all current backends' PIDs
737+
*
738+
* The result is a palloc'd array with the number of active backends in
739+
* entry [0], their PIDs in entries [1] .. [n]. The caller must bear in
740+
* mind that the result may already be obsolete when returned.
741+
*/
742+
int *
743+
GetAllBackendPids(void)
744+
{
745+
int *result;
746+
int npids;
747+
ProcArrayStruct *arrayP = procArray;
748+
int index;
749+
750+
result = (int *) palloc((MaxBackends + 1) * sizeof(int));
751+
npids = 0;
752+
753+
LWLockAcquire(ProcArrayLock, LW_SHARED);
754+
755+
for (index = 0; index < arrayP->numProcs; index++)
756+
{
757+
PGPROC *proc = arrayP->procs[index];
758+
759+
if (proc->pid != 0) /* ignore dummy procs */
760+
result[++npids] = proc->pid;
761+
}
762+
763+
LWLockRelease(ProcArrayLock);
764+
765+
Assert(npids <= MaxBackends);
766+
767+
result[0] = npids;
768+
return result;
769+
}
770+
735771
/*
736772
* CountActiveBackends --- count backends (other than myself) that are in
737773
* active transactions. This is used as a heuristic to decide if

src/include/storage/procarray.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
* Portions Copyright (c) 1996-2005, PostgreSQL Global Development Group
88
* Portions Copyright (c) 1994, Regents of the University of California
99
*
10-
* $PostgreSQL: pgsql/src/include/storage/procarray.h,v 1.6 2005/10/15 02:49:46 momjian Exp $
10+
* $PostgreSQL: pgsql/src/include/storage/procarray.h,v 1.7 2005/12/16 04:03:40 tgl Exp $
1111
*
1212
*-------------------------------------------------------------------------
1313
*/
@@ -29,6 +29,7 @@ extern TransactionId GetOldestXmin(bool allDbs);
2929
extern PGPROC *BackendPidGetProc(int pid);
3030
extern int BackendXidGetPid(TransactionId xid);
3131
extern bool IsBackendPid(int pid);
32+
extern int *GetAllBackendPids(void);
3233
extern bool DatabaseHasActiveBackends(Oid databaseId, bool ignoreMyself);
3334

3435
extern int CountActiveBackends(void);

0 commit comments

Comments
 (0)