Skip to content

Commit 944a17b

Browse files
committed
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
1 parent a1e5331 commit 944a17b

File tree

2 files changed

+121
-14
lines changed

2 files changed

+121
-14
lines changed

src/backend/postmaster/pgstat.c

Lines changed: 109 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
*
1414
* Copyright (c) 2001-2006, PostgreSQL Global Development Group
1515
*
16-
* $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.123 2006/04/20 10:51:32 momjian Exp $
16+
* $PostgreSQL: pgsql/src/backend/postmaster/pgstat.c,v 1.124 2006/04/27 00:06:58 momjian Exp $
1717
* ----------
1818
*/
1919
#include "postgres.h"
@@ -28,6 +28,7 @@
2828
#include <arpa/inet.h>
2929
#include <signal.h>
3030
#include <time.h>
31+
#include <sys/stat.h>
3132

3233
#include "pgstat.h"
3334

@@ -66,12 +67,15 @@
6667
* Timer definitions.
6768
* ----------
6869
*/
69-
#define PGSTAT_STAT_INTERVAL 500 /* How often to write the status file;
70-
* in milliseconds. */
7170

72-
#define PGSTAT_RESTART_INTERVAL 60 /* How often to attempt to restart a
73-
* failed statistics collector; in
74-
* seconds. */
71+
/* How often to write the status file, in milliseconds. */
72+
#define PGSTAT_STAT_INTERVAL (5*60*1000)
73+
74+
/*
75+
* How often to attempt to restart a failed statistics collector; in ms.
76+
* Must be at least PGSTAT_STAT_INTERVAL.
77+
*/
78+
#define PGSTAT_RESTART_INTERVAL (5*60*1000)
7579

7680
/* ----------
7781
* Amount of space reserved in pgstat_recvbuffer().
@@ -172,11 +176,12 @@ static void pgstat_drop_database(Oid databaseid);
172176
static void pgstat_write_statsfile(void);
173177
static void pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
174178
PgStat_StatBeEntry **betab,
175-
int *numbackends);
179+
int *numbackends, bool rewrite);
176180
static void backend_read_statsfile(void);
177181

178182
static void pgstat_setheader(PgStat_MsgHdr *hdr, StatMsgType mtype);
179183
static void pgstat_send(void *msg, int len);
184+
static void pgstat_send_rewrite(void);
180185

181186
static void pgstat_recv_bestart(PgStat_MsgBestart *msg, int len);
182187
static void pgstat_recv_beterm(PgStat_MsgBeterm *msg, int len);
@@ -1449,6 +1454,24 @@ pgstat_send(void *msg, int len)
14491454
#endif
14501455
}
14511456

1457+
/*
1458+
* pgstat_send_rewrite() -
1459+
*
1460+
* Send a command to the collector to rewrite the stats file.
1461+
* ----------
1462+
*/
1463+
static void
1464+
pgstat_send_rewrite(void)
1465+
{
1466+
PgStat_MsgRewrite msg;
1467+
1468+
if (pgStatSock < 0)
1469+
return;
1470+
1471+
pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_REWRITE);
1472+
pgstat_send(&msg, sizeof(msg));
1473+
}
1474+
14521475

14531476
/* ----------
14541477
* PgstatBufferMain() -
@@ -1549,7 +1572,7 @@ PgstatCollectorMain(int argc, char *argv[])
15491572
fd_set rfds;
15501573
int readPipe;
15511574
int len = 0;
1552-
struct itimerval timeout;
1575+
struct itimerval timeout, canceltimeout;
15531576
bool need_timer = false;
15541577

15551578
MyProcPid = getpid(); /* reset MyProcPid */
@@ -1604,12 +1627,15 @@ PgstatCollectorMain(int argc, char *argv[])
16041627
timeout.it_value.tv_sec = PGSTAT_STAT_INTERVAL / 1000;
16051628
timeout.it_value.tv_usec = PGSTAT_STAT_INTERVAL % 1000;
16061629

1630+
/* Values set to zero will cancel the active timer */
1631+
MemSet(&canceltimeout, 0, sizeof(struct itimerval));
1632+
16071633
/*
16081634
* Read in an existing statistics stats file or initialize the stats to
16091635
* zero.
16101636
*/
16111637
pgStatRunningInCollector = true;
1612-
pgstat_read_statsfile(&pgStatDBHash, InvalidOid, NULL, NULL);
1638+
pgstat_read_statsfile(&pgStatDBHash, InvalidOid, NULL, NULL, false);
16131639

16141640
/*
16151641
* Create the known backends table
@@ -1764,6 +1790,12 @@ PgstatCollectorMain(int argc, char *argv[])
17641790
pgstat_recv_analyze((PgStat_MsgAnalyze *) &msg, nread);
17651791
break;
17661792

1793+
case PGSTAT_MTYPE_REWRITE:
1794+
need_statwrite = true;
1795+
/* Disable the timer - it will be restarted on next data update */
1796+
setitimer(ITIMER_REAL, &canceltimeout, NULL);
1797+
break;
1798+
17671799
default:
17681800
break;
17691801
}
@@ -2344,7 +2376,7 @@ comparePids(const void *v1, const void *v2)
23442376
*/
23452377
static void
23462378
pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
2347-
PgStat_StatBeEntry **betab, int *numbackends)
2379+
PgStat_StatBeEntry **betab, int *numbackends, bool rewrite)
23482380
{
23492381
PgStat_StatDBEntry *dbentry;
23502382
PgStat_StatDBEntry dbbuf;
@@ -2363,6 +2395,71 @@ pgstat_read_statsfile(HTAB **dbhash, Oid onlydb,
23632395
MemoryContext use_mcxt;
23642396
int mcxt_flags;
23652397

2398+
2399+
if (rewrite)
2400+
{
2401+
/*
2402+
* To force a rewrite of the stats file from the collector, send
2403+
* a REWRITE message to the stats collector. Then wait for the file
2404+
* to change. On Unix, we wait for the inode to change (as the file
2405+
* is renamed into place from a different file). Win32 has no concept
2406+
* of inodes, so we wait for the date on the file to change instead.
2407+
* We can do this on win32 because we have high-res timing on the
2408+
* file dates, but we can't on unix, because it has 1sec resolution
2409+
* on the fields in struct stat.
2410+
*/
2411+
int i;
2412+
#ifndef WIN32
2413+
struct stat st1, st2;
2414+
2415+
if (stat(PGSTAT_STAT_FILENAME, &st1))
2416+
{
2417+
/* Assume no file there yet */
2418+
st1.st_ino = 0;
2419+
}
2420+
st2.st_ino = 0;
2421+
#else
2422+
WIN32_FILE_ATTRIBUTE_DATA fd1, fd2;
2423+
2424+
if (!GetFileAttributesEx(PGSTAT_STAT_FILENAME, GetFileExInfoStandard, &fd1))
2425+
{
2426+
fd1.ftLastWriteTime.dwLowDateTime = 0;
2427+
fd1.ftLastWriteTime.dwHighDateTime = 0;
2428+
}
2429+
fd2.ftLastWriteTime.dwLowDateTime = 0;
2430+
fd2.ftLastWriteTime.dwHighDateTime = 0;
2431+
#endif
2432+
2433+
2434+
/* Send rewrite message */
2435+
pgstat_send_rewrite();
2436+
2437+
/* Now wait for the file to change */
2438+
for (i=0; i < 50; i++)
2439+
{
2440+
#ifndef WIN32
2441+
if (!stat(PGSTAT_STAT_FILENAME, &st2))
2442+
{
2443+
if (st2.st_ino != st1.st_ino)
2444+
break;
2445+
}
2446+
#else
2447+
if (GetFileAttributesEx(PGSTAT_STAT_FILENAME, GetFileExInfoStandard, &fd2))
2448+
{
2449+
if (fd1.ftLastWriteTime.dwLowDateTime != fd2.ftLastWriteTime.dwLowDateTime ||
2450+
fd1.ftLastWriteTime.dwHighDateTime != fd2.ftLastWriteTime.dwHighDateTime)
2451+
break;
2452+
}
2453+
#endif
2454+
2455+
pg_usleep(50000);
2456+
}
2457+
if (i >= 50)
2458+
ereport(WARNING,
2459+
(errmsg("pgstat update timeout")));
2460+
/* Fallthrough and read the old file anyway - old data better than no data */
2461+
}
2462+
23662463
/*
23672464
* If running in the collector or the autovacuum process, we use the
23682465
* DynaHashCxt memory context. If running in a backend, we use the
@@ -2681,7 +2778,7 @@ backend_read_statsfile(void)
26812778
return;
26822779
Assert(!pgStatRunningInCollector);
26832780
pgstat_read_statsfile(&pgStatDBHash, InvalidOid,
2684-
&pgStatBeTable, &pgStatNumBackends);
2781+
&pgStatBeTable, &pgStatNumBackends, true);
26852782
}
26862783
else
26872784
{
@@ -2691,7 +2788,7 @@ backend_read_statsfile(void)
26912788
{
26922789
Assert(!pgStatRunningInCollector);
26932790
pgstat_read_statsfile(&pgStatDBHash, MyDatabaseId,
2694-
&pgStatBeTable, &pgStatNumBackends);
2791+
&pgStatBeTable, &pgStatNumBackends, true);
26952792
pgStatDBHashXact = topXid;
26962793
}
26972794
}

src/include/pgstat.h

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
*
66
* Copyright (c) 2001-2006, PostgreSQL Global Development Group
77
*
8-
* $PostgreSQL: pgsql/src/include/pgstat.h,v 1.43 2006/04/06 20:38:00 tgl Exp $
8+
* $PostgreSQL: pgsql/src/include/pgstat.h,v 1.44 2006/04/27 00:06:59 momjian Exp $
99
* ----------
1010
*/
1111
#ifndef PGSTAT_H
@@ -32,7 +32,8 @@ typedef enum StatMsgType
3232
PGSTAT_MTYPE_RESETCOUNTER,
3333
PGSTAT_MTYPE_AUTOVAC_START,
3434
PGSTAT_MTYPE_VACUUM,
35-
PGSTAT_MTYPE_ANALYZE
35+
PGSTAT_MTYPE_ANALYZE,
36+
PGSTAT_MTYPE_REWRITE
3637
} StatMsgType;
3738

3839
/* ----------
@@ -107,6 +108,15 @@ typedef struct PgStat_MsgDummy
107108
char m_dummy[512];
108109
} PgStat_MsgDummy;
109110

111+
/* ----------
112+
* PgStat_MsgRewrite Sent by backends to cause a rewrite of the stats file
113+
* ----------
114+
*/
115+
typedef struct Pgstat_MsgRewrite
116+
{
117+
PgStat_MsgHdr m_hdr;
118+
} PgStat_MsgRewrite;
119+
110120
/* ----------
111121
* PgStat_MsgBestart Sent by the backend on startup
112122
* ----------

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy