mirror of
https://github.com/postgres/postgres.git
synced 2025-11-22 12:22:45 +03:00
This commit adds the infrastructure for more detailed IO statistics. The calls to actually count IOs, a system view to access the new statistics, documentation and tests will be added in subsequent commits, to make review easier. While we already had some IO statistics, e.g. in pg_stat_bgwriter and pg_stat_database, they did not provide sufficient detail to understand what the main sources of IO are, or whether configuration changes could avoid IO. E.g., pg_stat_bgwriter.buffers_backend does contain the number of buffers written out by a backend, but as that includes extending relations (always done by backends) and writes triggered by the use of buffer access strategies, it cannot easily be used to tune background writer or checkpointer. Similarly, pg_stat_database.blks_read cannot easily be used to tune shared_buffers / compute a cache hit ratio, as the use of buffer access strategies will often prevent a large fraction of the read blocks to end up in shared_buffers. The new IO statistics count IO operations (evict, extend, fsync, read, reuse, and write), and are aggregated for each combination of backend type (backend, autovacuum worker, bgwriter, etc), target object of the IO (relations, temp relations) and context of the IO (normal, vacuum, bulkread, bulkwrite). What is tracked in this series of patches, is sufficient to perform the aforementioned analyses. Further details, e.g. tracking the number of buffer hits, would make that even easier, but was left out for now, to keep the scope of the already large patchset manageable. Bumps PGSTAT_FILE_FORMAT_ID. Author: Melanie Plageman <melanieplageman@gmail.com> Reviewed-by: Andres Freund <andres@anarazel.de> Reviewed-by: Justin Pryzby <pryzby@telsasoft.com> Reviewed-by: Kyotaro Horiguchi <horikyota.ntt@gmail.com> Discussion: https://postgr.es/m/20200124195226.lth52iydq2n2uilq@alap3.anarazel.de
127 lines
3.7 KiB
C
127 lines
3.7 KiB
C
/* -------------------------------------------------------------------------
|
|
*
|
|
* pgstat_checkpointer.c
|
|
* Implementation of checkpoint statistics.
|
|
*
|
|
* This file contains the implementation of checkpoint statistics. It is kept
|
|
* separate from pgstat.c to enforce the line between the statistics access /
|
|
* storage implementation and the details about individual types of
|
|
* statistics.
|
|
*
|
|
* Copyright (c) 2001-2023, PostgreSQL Global Development Group
|
|
*
|
|
* IDENTIFICATION
|
|
* src/backend/utils/activity/pgstat_checkpointer.c
|
|
* -------------------------------------------------------------------------
|
|
*/
|
|
|
|
#include "postgres.h"
|
|
|
|
#include "utils/pgstat_internal.h"
|
|
|
|
|
|
PgStat_CheckpointerStats PendingCheckpointerStats = {0};
|
|
|
|
|
|
/*
|
|
* Report checkpointer and IO statistics
|
|
*/
|
|
void
|
|
pgstat_report_checkpointer(void)
|
|
{
|
|
/* We assume this initializes to zeroes */
|
|
static const PgStat_CheckpointerStats all_zeroes;
|
|
PgStatShared_Checkpointer *stats_shmem = &pgStatLocal.shmem->checkpointer;
|
|
|
|
Assert(!pgStatLocal.shmem->is_shutdown);
|
|
pgstat_assert_is_up();
|
|
|
|
/*
|
|
* This function can be called even if nothing at all has happened. In
|
|
* this case, avoid unnecessarily modifying the stats entry.
|
|
*/
|
|
if (memcmp(&PendingCheckpointerStats, &all_zeroes,
|
|
sizeof(all_zeroes)) == 0)
|
|
return;
|
|
|
|
pgstat_begin_changecount_write(&stats_shmem->changecount);
|
|
|
|
#define CHECKPOINTER_ACC(fld) stats_shmem->stats.fld += PendingCheckpointerStats.fld
|
|
CHECKPOINTER_ACC(timed_checkpoints);
|
|
CHECKPOINTER_ACC(requested_checkpoints);
|
|
CHECKPOINTER_ACC(checkpoint_write_time);
|
|
CHECKPOINTER_ACC(checkpoint_sync_time);
|
|
CHECKPOINTER_ACC(buf_written_checkpoints);
|
|
CHECKPOINTER_ACC(buf_written_backend);
|
|
CHECKPOINTER_ACC(buf_fsync_backend);
|
|
#undef CHECKPOINTER_ACC
|
|
|
|
pgstat_end_changecount_write(&stats_shmem->changecount);
|
|
|
|
/*
|
|
* Clear out the statistics buffer, so it can be re-used.
|
|
*/
|
|
MemSet(&PendingCheckpointerStats, 0, sizeof(PendingCheckpointerStats));
|
|
|
|
/*
|
|
* Report IO statistics
|
|
*/
|
|
pgstat_flush_io(false);
|
|
}
|
|
|
|
/*
|
|
* pgstat_fetch_stat_checkpointer() -
|
|
*
|
|
* Support function for the SQL-callable pgstat* functions. Returns
|
|
* a pointer to the checkpointer statistics struct.
|
|
*/
|
|
PgStat_CheckpointerStats *
|
|
pgstat_fetch_stat_checkpointer(void)
|
|
{
|
|
pgstat_snapshot_fixed(PGSTAT_KIND_CHECKPOINTER);
|
|
|
|
return &pgStatLocal.snapshot.checkpointer;
|
|
}
|
|
|
|
void
|
|
pgstat_checkpointer_reset_all_cb(TimestampTz ts)
|
|
{
|
|
PgStatShared_Checkpointer *stats_shmem = &pgStatLocal.shmem->checkpointer;
|
|
|
|
/* see explanation above PgStatShared_Checkpointer for the reset protocol */
|
|
LWLockAcquire(&stats_shmem->lock, LW_EXCLUSIVE);
|
|
pgstat_copy_changecounted_stats(&stats_shmem->reset_offset,
|
|
&stats_shmem->stats,
|
|
sizeof(stats_shmem->stats),
|
|
&stats_shmem->changecount);
|
|
LWLockRelease(&stats_shmem->lock);
|
|
}
|
|
|
|
void
|
|
pgstat_checkpointer_snapshot_cb(void)
|
|
{
|
|
PgStatShared_Checkpointer *stats_shmem = &pgStatLocal.shmem->checkpointer;
|
|
PgStat_CheckpointerStats *reset_offset = &stats_shmem->reset_offset;
|
|
PgStat_CheckpointerStats reset;
|
|
|
|
pgstat_copy_changecounted_stats(&pgStatLocal.snapshot.checkpointer,
|
|
&stats_shmem->stats,
|
|
sizeof(stats_shmem->stats),
|
|
&stats_shmem->changecount);
|
|
|
|
LWLockAcquire(&stats_shmem->lock, LW_SHARED);
|
|
memcpy(&reset, reset_offset, sizeof(stats_shmem->stats));
|
|
LWLockRelease(&stats_shmem->lock);
|
|
|
|
/* compensate by reset offsets */
|
|
#define CHECKPOINTER_COMP(fld) pgStatLocal.snapshot.checkpointer.fld -= reset.fld;
|
|
CHECKPOINTER_COMP(timed_checkpoints);
|
|
CHECKPOINTER_COMP(requested_checkpoints);
|
|
CHECKPOINTER_COMP(checkpoint_write_time);
|
|
CHECKPOINTER_COMP(checkpoint_sync_time);
|
|
CHECKPOINTER_COMP(buf_written_checkpoints);
|
|
CHECKPOINTER_COMP(buf_written_backend);
|
|
CHECKPOINTER_COMP(buf_fsync_backend);
|
|
#undef CHECKPOINTER_COMP
|
|
}
|