Patch reverted because of random buildfarm failures:

---------------------------------------------------------------------------

Delay write of pg_stats file to once every five minutes, during
shutdown, or when requested by a backend:

It changes so the file is only written once every 5 minutes (changeable
of course, I just picked something) instead of once every half second.
It's still written when the stats collector shuts down, just as before.
And it is now also written on backend request. A backend requests a
rewrite by simply sending a special stats message. It operates on the
assumption that the backends aren't actually going to read the
statistics file very often, compared to how frequent it's written today.

Magnus Hagander
This commit is contained in:
Bruce Momjian 2006-05-30 02:35:39 +00:00
parent 63cb35c41c
commit e8ea69e3fa
2 changed files with 14 additions and 121 deletions

View File

@ -13,7 +13,7 @@
*
* Copyright (c) 2001-2006, PostgreSQL Global Development Group
*
* $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.126 2006/05/19 19:08:26 alvherre Exp $
* $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.127 2006/05/30 02:35:39 momjian Exp $
* ----------
*/
#include "postgres.h"
@ -28,7 +28,6 @@
#include <arpa/inet.h>
#include <signal.h>
#include <time.h>
#include <sys/stat.h>
#include "pgstat.h"
@ -67,15 +66,12 @@
* Timer definitions.
* ----------
*/
#define PGSTAT_STAT_INTERVAL 500 /* How often to write the status file;
* in milliseconds. */
/* How often to write the status file, in milliseconds. */
#define PGSTAT_STAT_INTERVAL (5*60*1000)
/*
* How often to attempt to restart a failed statistics collector; in ms.
* Must be at least PGSTAT_STAT_INTERVAL.
*/
#define PGSTAT_RESTART_INTERVAL (5*60*1000)
#define PGSTAT_RESTART_INTERVAL 60 /* How often to attempt to restart a
* failed statistics collector; in
* seconds. */
/* ----------
* Amount of space reserved in pgstat_recvbuffer().
@ -176,12 +172,11 @@ static void pgstat_drop_database(Oid databaseid);
static void pgstat_write_statsfile(void);
static void pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
PgStat_StatBeEntry **betab,
int *numbackends, bool rewrite);
int *numbackends);
static void backend_read_statsfile(void);
static void pgstat_setheader(PgStat_MsgHdr *hdr, StatMsgType mtype);
static void pgstat_send(void *msg, int len);
static void pgstat_send_rewrite(void);
static void pgstat_recv_bestart(PgStat_MsgBestart *msg, int len);
static void pgstat_recv_beterm(PgStat_MsgBeterm *msg, int len);
@ -1458,24 +1453,6 @@ pgstat_send(void *msg, int len)
#endif
}
/*
* pgstat_send_rewrite() -
*
* Send a command to the collector to rewrite the stats file.
* ----------
*/
static void
pgstat_send_rewrite(void)
{
PgStat_MsgRewrite msg;
if (pgStatSock < 0)
return;
pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_REWRITE);
pgstat_send(&msg, sizeof(msg));
}
/* ----------
* PgstatBufferMain() -
@ -1576,7 +1553,7 @@ PgstatCollectorMain(int argc, char *argv[])
fd_set rfds;
int readPipe;
int len = 0;
struct itimerval timeout, canceltimeout;
struct itimerval timeout;
bool need_timer = false;
MyProcPid = getpid(); /* reset MyProcPid */
@ -1631,15 +1608,12 @@ PgstatCollectorMain(int argc, char *argv[])
timeout.it_value.tv_sec = PGSTAT_STAT_INTERVAL / 1000;
timeout.it_value.tv_usec = PGSTAT_STAT_INTERVAL % 1000;
/* Values set to zero will cancel the active timer */
MemSet(&canceltimeout, 0, sizeof(struct itimerval));
/*
* Read in an existing statistics stats file or initialize the stats to
* zero.
*/
pgStatRunningInCollector = true;
pgstat_read_statsfile(&pgStatDBHash, InvalidOid, NULL, NULL, false);
pgstat_read_statsfile(&pgStatDBHash, InvalidOid, NULL, NULL);
/*
* Create the known backends table
@ -1794,12 +1768,6 @@ PgstatCollectorMain(int argc, char *argv[])
pgstat_recv_analyze((PgStat_MsgAnalyze *) &msg, nread);
break;
case PGSTAT_MTYPE_REWRITE:
need_statwrite = true;
/* Disable the timer - it will be restarted on next data update */
setitimer(ITIMER_REAL, &canceltimeout, NULL);
break;
default:
break;
}
@ -2380,7 +2348,7 @@ comparePids(const void *v1, const void *v2)
*/
static void
pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
PgStat_StatBeEntry **betab, int *numbackends, bool rewrite)
PgStat_StatBeEntry **betab, int *numbackends)
{
PgStat_StatDBEntry *dbentry;
PgStat_StatDBEntry dbbuf;
@ -2399,71 +2367,6 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
MemoryContext use_mcxt;
int mcxt_flags;
if (rewrite)
{
/*
* To force a rewrite of the stats file from the collector, send
* a REWRITE message to the stats collector. Then wait for the file
* to change. On Unix, we wait for the inode to change (as the file
* is renamed into place from a different file). Win32 has no concept
* of inodes, so we wait for the date on the file to change instead.
* We can do this on win32 because we have high-res timing on the
* file dates, but we can't on unix, because it has 1sec resolution
* on the fields in struct stat.
*/
int i;
#ifndef WIN32
struct stat st1, st2;
if (stat(PGSTAT_STAT_FILENAME, &st1))
{
/* Assume no file there yet */
st1.st_ino = 0;
}
st2.st_ino = 0;
#else
WIN32_FILE_ATTRIBUTE_DATA fd1, fd2;
if (!GetFileAttributesEx(PGSTAT_STAT_FILENAME, GetFileExInfoStandard, &fd1))
{
fd1.ftLastWriteTime.dwLowDateTime = 0;
fd1.ftLastWriteTime.dwHighDateTime = 0;
}
fd2.ftLastWriteTime.dwLowDateTime = 0;
fd2.ftLastWriteTime.dwHighDateTime = 0;
#endif
/* Send rewrite message */
pgstat_send_rewrite();
/* Now wait for the file to change */
for (i=0; i < 50; i++)
{
#ifndef WIN32
if (!stat(PGSTAT_STAT_FILENAME, &st2))
{
if (st2.st_ino != st1.st_ino)
break;
}
#else
if (GetFileAttributesEx(PGSTAT_STAT_FILENAME, GetFileExInfoStandard, &fd2))
{
if (fd1.ftLastWriteTime.dwLowDateTime != fd2.ftLastWriteTime.dwLowDateTime ||
fd1.ftLastWriteTime.dwHighDateTime != fd2.ftLastWriteTime.dwHighDateTime)
break;
}
#endif
pg_usleep(50000);
}
if (i >= 50)
ereport(WARNING,
(errmsg("pgstat update timeout")));
/* Fallthrough and read the old file anyway - old data better than no data */
}
/*
* If running in the collector or the autovacuum process, we use the
* DynaHashCxt memory context. If running in a backend, we use the
@ -2782,7 +2685,7 @@ backend_read_statsfile(void)
return;
Assert(!pgStatRunningInCollector);
pgstat_read_statsfile(&pgStatDBHash, InvalidOid,
&pgStatBeTable, &pgStatNumBackends, true);
&pgStatBeTable, &pgStatNumBackends);
}
else
{
@ -2792,7 +2695,7 @@ backend_read_statsfile(void)
{
Assert(!pgStatRunningInCollector);
pgstat_read_statsfile(&pgStatDBHash, MyDatabaseId,
&pgStatBeTable, &pgStatNumBackends, true);
&pgStatBeTable, &pgStatNumBackends);
pgStatDBHashXact = topXid;
}
}

View File

@ -5,7 +5,7 @@
*
* Copyright (c) 2001-2006, PostgreSQL Global Development Group
*
* $PostgreSQL: pgsql/src/include/pgstat.h,v 1.45 2006/05/19 19:08:26 alvherre Exp $
* $PostgreSQL: pgsql/src/include/pgstat.h,v 1.46 2006/05/30 02:35:39 momjian Exp $
* ----------
*/
#ifndef PGSTAT_H
@ -32,8 +32,7 @@ typedef enum StatMsgType
PGSTAT_MTYPE_RESETCOUNTER,
PGSTAT_MTYPE_AUTOVAC_START,
PGSTAT_MTYPE_VACUUM,
PGSTAT_MTYPE_ANALYZE,
PGSTAT_MTYPE_REWRITE
PGSTAT_MTYPE_ANALYZE
} StatMsgType;
/* ----------
@ -108,15 +107,6 @@ typedef struct PgStat_MsgDummy
char m_dummy[512];
} PgStat_MsgDummy;
/* ----------
* PgStat_MsgRewrite Sent by backends to cause a rewrite of the stats file
* ----------
*/
typedef struct Pgstat_MsgRewrite
{
PgStat_MsgHdr m_hdr;
} PgStat_MsgRewrite;
/* ----------
* PgStat_MsgBestart Sent by the backend on startup
* ----------