@@ -128,7 +128,8 @@ char *pgstat_stat_tmpname = NULL;
128
128
* Stored directly in a stats message structure so they can be sent
129
129
* without needing to copy things around. We assume these init to zeroes.
130
130
*/
131
- PgStat_MsgBgWriter BgWriterStats ;
131
+ PgStat_MsgBgWriter PendingBgWriterStats ;
132
+ PgStat_MsgCheckpointer PendingCheckpointerStats ;
132
133
PgStat_MsgWal WalStats ;
133
134
134
135
/*
@@ -348,6 +349,7 @@ static void pgstat_recv_analyze(PgStat_MsgAnalyze *msg, int len);
348
349
static void pgstat_recv_anl_ancestors (PgStat_MsgAnlAncestors * msg , int len );
349
350
static void pgstat_recv_archiver (PgStat_MsgArchiver * msg , int len );
350
351
static void pgstat_recv_bgwriter (PgStat_MsgBgWriter * msg , int len );
352
+ static void pgstat_recv_checkpointer (PgStat_MsgCheckpointer * msg , int len );
351
353
static void pgstat_recv_wal (PgStat_MsgWal * msg , int len );
352
354
static void pgstat_recv_slru (PgStat_MsgSLRU * msg , int len );
353
355
static void pgstat_recv_funcstat (PgStat_MsgFuncstat * msg , int len );
@@ -2830,6 +2832,37 @@ pgstat_fetch_stat_archiver(void)
2830
2832
return & archiverStats ;
2831
2833
}
2832
2834
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
+ }
2833
2866
2834
2867
/*
2835
2868
* ---------
@@ -3025,19 +3058,51 @@ pgstat_send_bgwriter(void)
3025
3058
* this case, avoid sending a completely empty message to the stats
3026
3059
* collector.
3027
3060
*/
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 )
3029
3094
return ;
3030
3095
3031
3096
/*
3032
3097
* Prepare and send the message
3033
3098
*/
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 ));
3036
3101
3037
3102
/*
3038
3103
* Clear out the statistics buffer, so it can be re-used.
3039
3104
*/
3040
- MemSet (& BgWriterStats , 0 , sizeof (BgWriterStats ));
3105
+ MemSet (& PendingCheckpointerStats , 0 , sizeof (PendingCheckpointerStats ));
3041
3106
}
3042
3107
3043
3108
/* ----------
@@ -3382,6 +3447,10 @@ PgstatCollectorMain(int argc, char *argv[])
3382
3447
pgstat_recv_bgwriter (& msg .msg_bgwriter , len );
3383
3448
break ;
3384
3449
3450
+ case PGSTAT_MTYPE_CHECKPOINTER :
3451
+ pgstat_recv_checkpointer (& msg .msg_checkpointer , len );
3452
+ break ;
3453
+
3385
3454
case PGSTAT_MTYPE_WAL :
3386
3455
pgstat_recv_wal (& msg .msg_wal , len );
3387
3456
break ;
@@ -3934,6 +4003,7 @@ pgstat_read_statsfiles(Oid onlydb, bool permanent, bool deep)
3934
4003
bool found ;
3935
4004
const char * statfile = permanent ? PGSTAT_STAT_PERMANENT_FILENAME : pgstat_stat_filename ;
3936
4005
int i ;
4006
+ TimestampTz ts ;
3937
4007
3938
4008
/*
3939
4009
* The tables will live in pgStatLocalContext.
@@ -3962,15 +4032,16 @@ pgstat_read_statsfiles(Oid onlydb, bool permanent, bool deep)
3962
4032
* Set the current timestamp (will be kept only in case we can't load an
3963
4033
* existing statsfile).
3964
4034
*/
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 ;
3968
4039
3969
4040
/*
3970
4041
* Set the same reset timestamp for all SLRU items too.
3971
4042
*/
3972
4043
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 ;
3974
4045
3975
4046
/*
3976
4047
* 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)
5055
5126
{
5056
5127
if (msg -> m_resettarget == RESET_BGWRITER )
5057
5128
{
5058
- /* Reset the global background writer statistics for the cluster. */
5129
+ /* Reset the global, bgwriter and checkpointer statistics for the cluster. */
5059
5130
memset (& globalStats , 0 , sizeof (globalStats ));
5060
- globalStats .stat_reset_timestamp = GetCurrentTimestamp ();
5131
+ globalStats .bgwriter . stat_reset_timestamp = GetCurrentTimestamp ();
5061
5132
}
5062
5133
else if (msg -> m_resettarget == RESET_ARCHIVER )
5063
5134
{
@@ -5345,16 +5416,27 @@ pgstat_recv_archiver(PgStat_MsgArchiver *msg, int len)
5345
5416
static void
5346
5417
pgstat_recv_bgwriter (PgStat_MsgBgWriter * msg , int len )
5347
5418
{
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 ;
5358
5440
}
5359
5441
5360
5442
/* ----------
0 commit comments