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

Commit 1bc8e7b

Browse files
committed
pgstat: split reporting/fetching of bgwriter and checkpointer stats.
These have been unrelated since bgwriter and checkpointer were split into two processes in 806a2ae. As there several pending patches (shared memory stats, extending the set of tracked IO / buffer statistics) that are made a bit more awkward by the grouping, split them. Done separately to make reviewing easier. This does *not* change the contents of pg_stat_bgwriter or move fields out of bgwriter/checkpointer stats that arguably do not belong in either. However pgstat_fetch_global() was renamed and split into pgstat_fetch_stat_checkpointer() and pgstat_fetch_stat_bgwriter(). Author: Andres Freund <andres@anarazel.de> Discussion: https://postgr.es/m/20210405092914.mmxqe7j56lsjfsej@alap3.anarazel.de
1 parent cc8033e commit 1bc8e7b

File tree

6 files changed

+185
-67
lines changed

6 files changed

+185
-67
lines changed

src/backend/access/transam/xlog.c

+2-2
Original file line numberDiff line numberDiff line change
@@ -8721,8 +8721,8 @@ LogCheckpointEnd(bool restartpoint)
87218721
CheckpointStats.ckpt_sync_end_t);
87228722

87238723
/* Accumulate checkpoint timing summary data, in milliseconds. */
8724-
BgWriterStats.m_checkpoint_write_time += write_msecs;
8725-
BgWriterStats.m_checkpoint_sync_time += sync_msecs;
8724+
PendingCheckpointerStats.m_checkpoint_write_time += write_msecs;
8725+
PendingCheckpointerStats.m_checkpoint_sync_time += sync_msecs;
87268726

87278727
/*
87288728
* All of the published timing statistics are accounted for. Only

src/backend/postmaster/checkpointer.c

+12-14
Original file line numberDiff line numberDiff line change
@@ -357,7 +357,7 @@ CheckpointerMain(void)
357357
if (((volatile CheckpointerShmemStruct *) CheckpointerShmem)->ckpt_flags)
358358
{
359359
do_checkpoint = true;
360-
BgWriterStats.m_requested_checkpoints++;
360+
PendingCheckpointerStats.m_requested_checkpoints++;
361361
}
362362

363363
/*
@@ -371,7 +371,7 @@ CheckpointerMain(void)
371371
if (elapsed_secs >= CheckPointTimeout)
372372
{
373373
if (!do_checkpoint)
374-
BgWriterStats.m_timed_checkpoints++;
374+
PendingCheckpointerStats.m_timed_checkpoints++;
375375
do_checkpoint = true;
376376
flags |= CHECKPOINT_CAUSE_TIME;
377377
}
@@ -493,13 +493,9 @@ CheckpointerMain(void)
493493
CheckArchiveTimeout();
494494

495495
/*
496-
* Send off activity statistics to the stats collector. (The reason
497-
* why we re-use bgwriter-related code for this is that the bgwriter
498-
* and checkpointer used to be just one process. It's probably not
499-
* worth the trouble to split the stats support into two independent
500-
* stats message types.)
496+
* Send off activity statistics to the stats collector.
501497
*/
502-
pgstat_send_bgwriter();
498+
pgstat_send_checkpointer();
503499

504500
/* Send WAL statistics to the stats collector. */
505501
pgstat_send_wal(true);
@@ -577,9 +573,9 @@ HandleCheckpointerInterrupts(void)
577573
* updates the statistics, increment the checkpoint request and send
578574
* the statistics to the stats collector.
579575
*/
580-
BgWriterStats.m_requested_checkpoints++;
576+
PendingCheckpointerStats.m_requested_checkpoints++;
581577
ShutdownXLOG(0, 0);
582-
pgstat_send_bgwriter();
578+
pgstat_send_checkpointer();
583579
pgstat_send_wal(true);
584580

585581
/* Normal exit from the checkpointer is here */
@@ -719,9 +715,9 @@ CheckpointWriteDelay(int flags, double progress)
719715
CheckArchiveTimeout();
720716

721717
/*
722-
* Report interim activity statistics to the stats collector.
718+
* Report interim activity statistics.
723719
*/
724-
pgstat_send_bgwriter();
720+
pgstat_send_checkpointer();
725721

726722
/*
727723
* This sleep used to be connected to bgwriter_delay, typically 200ms.
@@ -1265,8 +1261,10 @@ AbsorbSyncRequests(void)
12651261
LWLockAcquire(CheckpointerCommLock, LW_EXCLUSIVE);
12661262

12671263
/* Transfer stats counts into pending pgstats message */
1268-
BgWriterStats.m_buf_written_backend += CheckpointerShmem->num_backend_writes;
1269-
BgWriterStats.m_buf_fsync_backend += CheckpointerShmem->num_backend_fsync;
1264+
PendingCheckpointerStats.m_buf_written_backend
1265+
+= CheckpointerShmem->num_backend_writes;
1266+
PendingCheckpointerStats.m_buf_fsync_backend
1267+
+= CheckpointerShmem->num_backend_fsync;
12701268

12711269
CheckpointerShmem->num_backend_writes = 0;
12721270
CheckpointerShmem->num_backend_fsync = 0;

src/backend/postmaster/pgstat.c

+103-21
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,8 @@ char *pgstat_stat_tmpname = NULL;
128128
* Stored directly in a stats message structure so they can be sent
129129
* without needing to copy things around. We assume these init to zeroes.
130130
*/
131-
PgStat_MsgBgWriter BgWriterStats;
131+
PgStat_MsgBgWriter PendingBgWriterStats;
132+
PgStat_MsgCheckpointer PendingCheckpointerStats;
132133
PgStat_MsgWal WalStats;
133134

134135
/*
@@ -348,6 +349,7 @@ static void pgstat_recv_analyze(PgStat_MsgAnalyze *msg, int len);
348349
static void pgstat_recv_anl_ancestors(PgStat_MsgAnlAncestors *msg, int len);
349350
static void pgstat_recv_archiver(PgStat_MsgArchiver *msg, int len);
350351
static void pgstat_recv_bgwriter(PgStat_MsgBgWriter *msg, int len);
352+
static void pgstat_recv_checkpointer(PgStat_MsgCheckpointer *msg, int len);
351353
static void pgstat_recv_wal(PgStat_MsgWal *msg, int len);
352354
static void pgstat_recv_slru(PgStat_MsgSLRU *msg, int len);
353355
static void pgstat_recv_funcstat(PgStat_MsgFuncstat *msg, int len);
@@ -2830,6 +2832,37 @@ pgstat_fetch_stat_archiver(void)
28302832
return &archiverStats;
28312833
}
28322834

2835+
/*
2836+
* ---------
2837+
* pgstat_fetch_stat_bgwriter() -
2838+
*
2839+
* Support function for the SQL-callable pgstat* functions. Returns
2840+
* a pointer to the bgwriter statistics struct.
2841+
* ---------
2842+
*/
2843+
PgStat_BgWriterStats *
2844+
pgstat_fetch_stat_bgwriter(void)
2845+
{
2846+
backend_read_statsfile();
2847+
2848+
return &globalStats.bgwriter;
2849+
}
2850+
2851+
/*
2852+
* ---------
2853+
* pgstat_fetch_stat_checkpointer() -
2854+
*
2855+
* Support function for the SQL-callable pgstat* functions. Returns
2856+
* a pointer to the checkpointer statistics struct.
2857+
* ---------
2858+
*/
2859+
PgStat_CheckpointerStats *
2860+
pgstat_fetch_stat_checkpointer(void)
2861+
{
2862+
backend_read_statsfile();
2863+
2864+
return &globalStats.checkpointer;
2865+
}
28332866

28342867
/*
28352868
* ---------
@@ -3025,19 +3058,51 @@ pgstat_send_bgwriter(void)
30253058
* this case, avoid sending a completely empty message to the stats
30263059
* collector.
30273060
*/
3028-
if (memcmp(&BgWriterStats, &all_zeroes, sizeof(PgStat_MsgBgWriter)) == 0)
3061+
if (memcmp(&PendingBgWriterStats, &all_zeroes, sizeof(PgStat_MsgBgWriter)) == 0)
3062+
return;
3063+
3064+
/*
3065+
* Prepare and send the message
3066+
*/
3067+
pgstat_setheader(&PendingBgWriterStats.m_hdr, PGSTAT_MTYPE_BGWRITER);
3068+
pgstat_send(&PendingBgWriterStats, sizeof(PendingBgWriterStats));
3069+
3070+
/*
3071+
* Clear out the statistics buffer, so it can be re-used.
3072+
*/
3073+
MemSet(&PendingBgWriterStats, 0, sizeof(PendingBgWriterStats));
3074+
}
3075+
3076+
/* ----------
3077+
* pgstat_send_checkpointer() -
3078+
*
3079+
* Send checkpointer statistics to the collector
3080+
* ----------
3081+
*/
3082+
void
3083+
pgstat_send_checkpointer(void)
3084+
{
3085+
/* We assume this initializes to zeroes */
3086+
static const PgStat_MsgCheckpointer all_zeroes;
3087+
3088+
/*
3089+
* This function can be called even if nothing at all has happened. In
3090+
* this case, avoid sending a completely empty message to the stats
3091+
* collector.
3092+
*/
3093+
if (memcmp(&PendingCheckpointerStats, &all_zeroes, sizeof(PgStat_MsgCheckpointer)) == 0)
30293094
return;
30303095

30313096
/*
30323097
* Prepare and send the message
30333098
*/
3034-
pgstat_setheader(&BgWriterStats.m_hdr, PGSTAT_MTYPE_BGWRITER);
3035-
pgstat_send(&BgWriterStats, sizeof(BgWriterStats));
3099+
pgstat_setheader(&PendingCheckpointerStats.m_hdr, PGSTAT_MTYPE_CHECKPOINTER);
3100+
pgstat_send(&PendingCheckpointerStats, sizeof(PendingCheckpointerStats));
30363101

30373102
/*
30383103
* Clear out the statistics buffer, so it can be re-used.
30393104
*/
3040-
MemSet(&BgWriterStats, 0, sizeof(BgWriterStats));
3105+
MemSet(&PendingCheckpointerStats, 0, sizeof(PendingCheckpointerStats));
30413106
}
30423107

30433108
/* ----------
@@ -3382,6 +3447,10 @@ PgstatCollectorMain(int argc, char *argv[])
33823447
pgstat_recv_bgwriter(&msg.msg_bgwriter, len);
33833448
break;
33843449

3450+
case PGSTAT_MTYPE_CHECKPOINTER:
3451+
pgstat_recv_checkpointer(&msg.msg_checkpointer, len);
3452+
break;
3453+
33853454
case PGSTAT_MTYPE_WAL:
33863455
pgstat_recv_wal(&msg.msg_wal, len);
33873456
break;
@@ -3934,6 +4003,7 @@ pgstat_read_statsfiles(Oid onlydb, bool permanent, bool deep)
39344003
bool found;
39354004
const char *statfile = permanent ? PGSTAT_STAT_PERMANENT_FILENAME : pgstat_stat_filename;
39364005
int i;
4006+
TimestampTz ts;
39374007

39384008
/*
39394009
* The tables will live in pgStatLocalContext.
@@ -3962,15 +4032,16 @@ pgstat_read_statsfiles(Oid onlydb, bool permanent, bool deep)
39624032
* Set the current timestamp (will be kept only in case we can't load an
39634033
* existing statsfile).
39644034
*/
3965-
globalStats.stat_reset_timestamp = GetCurrentTimestamp();
3966-
archiverStats.stat_reset_timestamp = globalStats.stat_reset_timestamp;
3967-
walStats.stat_reset_timestamp = globalStats.stat_reset_timestamp;
4035+
ts = GetCurrentTimestamp();
4036+
globalStats.bgwriter.stat_reset_timestamp = ts;
4037+
archiverStats.stat_reset_timestamp = ts;
4038+
walStats.stat_reset_timestamp = ts;
39684039

39694040
/*
39704041
* Set the same reset timestamp for all SLRU items too.
39714042
*/
39724043
for (i = 0; i < SLRU_NUM_ELEMENTS; i++)
3973-
slruStats[i].stat_reset_timestamp = globalStats.stat_reset_timestamp;
4044+
slruStats[i].stat_reset_timestamp = ts;
39744045

39754046
/*
39764047
* Try to open the stats file. If it doesn't exist, the backends simply
@@ -5055,9 +5126,9 @@ pgstat_recv_resetsharedcounter(PgStat_MsgResetsharedcounter *msg, int len)
50555126
{
50565127
if (msg->m_resettarget == RESET_BGWRITER)
50575128
{
5058-
/* Reset the global background writer statistics for the cluster. */
5129+
/* Reset the global, bgwriter and checkpointer statistics for the cluster. */
50595130
memset(&globalStats, 0, sizeof(globalStats));
5060-
globalStats.stat_reset_timestamp = GetCurrentTimestamp();
5131+
globalStats.bgwriter.stat_reset_timestamp = GetCurrentTimestamp();
50615132
}
50625133
else if (msg->m_resettarget == RESET_ARCHIVER)
50635134
{
@@ -5345,16 +5416,27 @@ pgstat_recv_archiver(PgStat_MsgArchiver *msg, int len)
53455416
static void
53465417
pgstat_recv_bgwriter(PgStat_MsgBgWriter *msg, int len)
53475418
{
5348-
globalStats.timed_checkpoints += msg->m_timed_checkpoints;
5349-
globalStats.requested_checkpoints += msg->m_requested_checkpoints;
5350-
globalStats.checkpoint_write_time += msg->m_checkpoint_write_time;
5351-
globalStats.checkpoint_sync_time += msg->m_checkpoint_sync_time;
5352-
globalStats.buf_written_checkpoints += msg->m_buf_written_checkpoints;
5353-
globalStats.buf_written_clean += msg->m_buf_written_clean;
5354-
globalStats.maxwritten_clean += msg->m_maxwritten_clean;
5355-
globalStats.buf_written_backend += msg->m_buf_written_backend;
5356-
globalStats.buf_fsync_backend += msg->m_buf_fsync_backend;
5357-
globalStats.buf_alloc += msg->m_buf_alloc;
5419+
globalStats.bgwriter.buf_written_clean += msg->m_buf_written_clean;
5420+
globalStats.bgwriter.maxwritten_clean += msg->m_maxwritten_clean;
5421+
globalStats.bgwriter.buf_alloc += msg->m_buf_alloc;
5422+
}
5423+
5424+
/* ----------
5425+
* pgstat_recv_checkpointer() -
5426+
*
5427+
* Process a CHECKPOINTER message.
5428+
* ----------
5429+
*/
5430+
static void
5431+
pgstat_recv_checkpointer(PgStat_MsgCheckpointer *msg, int len)
5432+
{
5433+
globalStats.checkpointer.timed_checkpoints += msg->m_timed_checkpoints;
5434+
globalStats.checkpointer.requested_checkpoints += msg->m_requested_checkpoints;
5435+
globalStats.checkpointer.checkpoint_write_time += msg->m_checkpoint_write_time;
5436+
globalStats.checkpointer.checkpoint_sync_time += msg->m_checkpoint_sync_time;
5437+
globalStats.checkpointer.buf_written_checkpoints += msg->m_buf_written_checkpoints;
5438+
globalStats.checkpointer.buf_written_backend += msg->m_buf_written_backend;
5439+
globalStats.checkpointer.buf_fsync_backend += msg->m_buf_fsync_backend;
53585440
}
53595441

53605442
/* ----------

src/backend/storage/buffer/bufmgr.c

+4-4
Original file line numberDiff line numberDiff line change
@@ -2137,7 +2137,7 @@ BufferSync(int flags)
21372137
if (SyncOneBuffer(buf_id, false, &wb_context) & BUF_WRITTEN)
21382138
{
21392139
TRACE_POSTGRESQL_BUFFER_SYNC_WRITTEN(buf_id);
2140-
BgWriterStats.m_buf_written_checkpoints++;
2140+
PendingCheckpointerStats.m_buf_written_checkpoints++;
21412141
num_written++;
21422142
}
21432143
}
@@ -2247,7 +2247,7 @@ BgBufferSync(WritebackContext *wb_context)
22472247
strategy_buf_id = StrategySyncStart(&strategy_passes, &recent_alloc);
22482248

22492249
/* Report buffer alloc counts to pgstat */
2250-
BgWriterStats.m_buf_alloc += recent_alloc;
2250+
PendingBgWriterStats.m_buf_alloc += recent_alloc;
22512251

22522252
/*
22532253
* If we're not running the LRU scan, just stop after doing the stats
@@ -2437,15 +2437,15 @@ BgBufferSync(WritebackContext *wb_context)
24372437
reusable_buffers++;
24382438
if (++num_written >= bgwriter_lru_maxpages)
24392439
{
2440-
BgWriterStats.m_maxwritten_clean++;
2440+
PendingBgWriterStats.m_maxwritten_clean++;
24412441
break;
24422442
}
24432443
}
24442444
else if (sync_state & BUF_REUSABLE)
24452445
reusable_buffers++;
24462446
}
24472447

2448-
BgWriterStats.m_buf_written_clean += num_written;
2448+
PendingBgWriterStats.m_buf_written_clean += num_written;
24492449

24502450
#ifdef BGW_DEBUG
24512451
elog(DEBUG1, "bgwriter: recent_alloc=%u smoothed=%.2f delta=%ld ahead=%d density=%.2f reusable_est=%d upcoming_est=%d scanned=%d wrote=%d reusable=%d",

0 commit comments

Comments
 (0)