mirror of
https://github.com/postgres/postgres.git
synced 2025-05-20 00:03:14 -04:00
Make backends that are reading the pgstats file verify each backend PID
against the PGPROC array. Anything in the file that isn't in PGPROC gets rejected as being a stale entry. This should solve complaints about stale entries in pg_stat_activity after a BETERM message has been dropped due to overload.
This commit is contained in:
parent
f80cf69031
commit
c7bba5e21c
@ -13,7 +13,7 @@
|
|||||||
*
|
*
|
||||||
* Copyright (c) 2001-2005, PostgreSQL Global Development Group
|
* Copyright (c) 2001-2005, PostgreSQL Global Development Group
|
||||||
*
|
*
|
||||||
* $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.103 2005/08/08 03:11:40 tgl Exp $
|
* $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.104 2005/08/09 21:14:55 tgl Exp $
|
||||||
* ----------
|
* ----------
|
||||||
*/
|
*/
|
||||||
#include "postgres.h"
|
#include "postgres.h"
|
||||||
@ -46,6 +46,7 @@
|
|||||||
#include "storage/ipc.h"
|
#include "storage/ipc.h"
|
||||||
#include "storage/pg_shmem.h"
|
#include "storage/pg_shmem.h"
|
||||||
#include "storage/pmsignal.h"
|
#include "storage/pmsignal.h"
|
||||||
|
#include "storage/procarray.h"
|
||||||
#include "tcop/tcopprot.h"
|
#include "tcop/tcopprot.h"
|
||||||
#include "utils/hsearch.h"
|
#include "utils/hsearch.h"
|
||||||
#include "utils/memutils.h"
|
#include "utils/memutils.h"
|
||||||
@ -1605,8 +1606,8 @@ PgstatCollectorMain(int argc, char *argv[])
|
|||||||
/*
|
/*
|
||||||
* Create the known backends table
|
* Create the known backends table
|
||||||
*/
|
*/
|
||||||
pgStatBeTable = (PgStat_StatBeEntry *) palloc0(
|
pgStatBeTable = (PgStat_StatBeEntry *)
|
||||||
sizeof(PgStat_StatBeEntry) * MaxBackends);
|
palloc0(sizeof(PgStat_StatBeEntry) * MaxBackends);
|
||||||
|
|
||||||
readPipe = pgStatPipe[0];
|
readPipe = pgStatPipe[0];
|
||||||
|
|
||||||
@ -2456,6 +2457,7 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
|
|||||||
PgStat_StatDBEntry dbbuf;
|
PgStat_StatDBEntry dbbuf;
|
||||||
PgStat_StatTabEntry *tabentry;
|
PgStat_StatTabEntry *tabentry;
|
||||||
PgStat_StatTabEntry tabbuf;
|
PgStat_StatTabEntry tabbuf;
|
||||||
|
PgStat_StatBeEntry *beentry;
|
||||||
HASHCTL hash_ctl;
|
HASHCTL hash_ctl;
|
||||||
HTAB *tabhash = NULL;
|
HTAB *tabhash = NULL;
|
||||||
FILE *fpin;
|
FILE *fpin;
|
||||||
@ -2463,6 +2465,7 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
|
|||||||
int maxbackends = 0;
|
int maxbackends = 0;
|
||||||
int havebackends = 0;
|
int havebackends = 0;
|
||||||
bool found;
|
bool found;
|
||||||
|
bool check_pids;
|
||||||
MemoryContext use_mcxt;
|
MemoryContext use_mcxt;
|
||||||
int mcxt_flags;
|
int mcxt_flags;
|
||||||
|
|
||||||
@ -2472,16 +2475,22 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
|
|||||||
* TopTransactionContext instead, so the caller must only know the last
|
* TopTransactionContext instead, so the caller must only know the last
|
||||||
* XactId when this call happened to know if his tables are still valid or
|
* XactId when this call happened to know if his tables are still valid or
|
||||||
* already gone!
|
* already gone!
|
||||||
|
*
|
||||||
|
* Also, if running in a regular backend, we check backend entries against
|
||||||
|
* the PGPROC array so that we can detect stale entries. This lets us
|
||||||
|
* discard entries whose BETERM message got lost for some reason.
|
||||||
*/
|
*/
|
||||||
if (pgStatRunningInCollector || IsAutoVacuumProcess())
|
if (pgStatRunningInCollector || IsAutoVacuumProcess())
|
||||||
{
|
{
|
||||||
use_mcxt = NULL;
|
use_mcxt = NULL;
|
||||||
mcxt_flags = 0;
|
mcxt_flags = 0;
|
||||||
|
check_pids = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
use_mcxt = TopTransactionContext;
|
use_mcxt = TopTransactionContext;
|
||||||
mcxt_flags = HASH_CONTEXT;
|
mcxt_flags = HASH_CONTEXT;
|
||||||
|
check_pids = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -2665,11 +2674,15 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
|
|||||||
if (betab == NULL || numbackends == NULL || *betab == NULL)
|
if (betab == NULL || numbackends == NULL || *betab == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
if (havebackends >= maxbackends)
|
||||||
|
goto done;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read it directly into the table.
|
* Read it directly into the table.
|
||||||
*/
|
*/
|
||||||
if (fread(&(*betab)[havebackends], 1,
|
beentry = &(*betab)[havebackends];
|
||||||
sizeof(PgStat_StatBeEntry), fpin) !=
|
|
||||||
|
if (fread(beentry, 1, sizeof(PgStat_StatBeEntry), fpin) !=
|
||||||
sizeof(PgStat_StatBeEntry))
|
sizeof(PgStat_StatBeEntry))
|
||||||
{
|
{
|
||||||
ereport(pgStatRunningInCollector ? LOG : WARNING,
|
ereport(pgStatRunningInCollector ? LOG : WARNING,
|
||||||
@ -2677,20 +2690,36 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If possible, check PID to verify still running
|
||||||
|
*/
|
||||||
|
if (check_pids && !IsBackendPid(beentry->procpid))
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Note: we could send a BETERM message to tell the
|
||||||
|
* collector to drop the entry, but I'm a bit worried
|
||||||
|
* about race conditions. For now, just silently ignore
|
||||||
|
* dead entries; they'll get recycled eventually anyway.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/* Don't accept the entry */
|
||||||
|
memset(beentry, 0, sizeof(PgStat_StatBeEntry));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Count backends per database here.
|
* Count backends per database here.
|
||||||
*/
|
*/
|
||||||
dbentry = (PgStat_StatDBEntry *) hash_search(*dbhash,
|
dbentry = (PgStat_StatDBEntry *)
|
||||||
(void *) &((*betab)[havebackends].databaseid),
|
hash_search(*dbhash,
|
||||||
HASH_FIND, NULL);
|
&(beentry->databaseid),
|
||||||
|
HASH_FIND,
|
||||||
|
NULL);
|
||||||
if (dbentry)
|
if (dbentry)
|
||||||
dbentry->n_backends++;
|
dbentry->n_backends++;
|
||||||
|
|
||||||
havebackends++;
|
havebackends++;
|
||||||
if (numbackends != 0)
|
|
||||||
*numbackends = havebackends;
|
*numbackends = havebackends;
|
||||||
if (havebackends >= maxbackends)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -2728,10 +2757,10 @@ backend_read_statsfile(void)
|
|||||||
{
|
{
|
||||||
if (IsAutoVacuumProcess())
|
if (IsAutoVacuumProcess())
|
||||||
{
|
{
|
||||||
Assert(!pgStatRunningInCollector);
|
|
||||||
/* already read it? */
|
/* already read it? */
|
||||||
if (pgStatDBHash)
|
if (pgStatDBHash)
|
||||||
return;
|
return;
|
||||||
|
Assert(!pgStatRunningInCollector);
|
||||||
pgstat_read_statsfile(&pgStatDBHash, InvalidOid,
|
pgstat_read_statsfile(&pgStatDBHash, InvalidOid,
|
||||||
&pgStatBeTable, &pgStatNumBackends);
|
&pgStatBeTable, &pgStatNumBackends);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user