mirror of
https://github.com/postgres/postgres.git
synced 2025-07-27 12:41:57 +03:00
Refactor some code related to backend statistics
This commit changes the way pending backend statistics are tracked by moving them into a new structure called PgStat_BackendPending, removing PgStat_BackendPendingIO. PgStat_BackendPending currently only includes PgStat_PendingIO for the pending I/O stats. pgstat_flush_backend() is extended with a "flags" argument to control which parts of the stats of a backend should be flushed. With this refactoring, it becomes easier to plug into backend statistics more data. A patch to add information related to WAL in this stats kind is under discussion. Author: Bertrand Drouvot Discussion: https://postgr.es/m/Z3zqc4o09dM/Ezyz@ip-10-97-1-34.eu-west-3.compute.internal
This commit is contained in:
@ -370,7 +370,7 @@ static const PgStat_KindInfo pgstat_kind_builtin_infos[PGSTAT_KIND_BUILTIN_SIZE]
|
|||||||
.shared_size = sizeof(PgStatShared_Backend),
|
.shared_size = sizeof(PgStatShared_Backend),
|
||||||
.shared_data_off = offsetof(PgStatShared_Backend, stats),
|
.shared_data_off = offsetof(PgStatShared_Backend, stats),
|
||||||
.shared_data_len = sizeof(((PgStatShared_Backend *) 0)->stats),
|
.shared_data_len = sizeof(((PgStatShared_Backend *) 0)->stats),
|
||||||
.pending_size = sizeof(PgStat_BackendPendingIO),
|
.pending_size = sizeof(PgStat_BackendPending),
|
||||||
|
|
||||||
.flush_pending_cb = pgstat_backend_flush_cb,
|
.flush_pending_cb = pgstat_backend_flush_cb,
|
||||||
.reset_timestamp_cb = pgstat_backend_reset_timestamp_cb,
|
.reset_timestamp_cb = pgstat_backend_reset_timestamp_cb,
|
||||||
|
@ -39,23 +39,21 @@ pgstat_fetch_stat_backend(ProcNumber procNumber)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Flush out locally pending backend statistics
|
* Flush out locally pending backend IO statistics. Locking is managed
|
||||||
*
|
* by the caller.
|
||||||
* If no stats have been recorded, this function returns false.
|
|
||||||
*/
|
*/
|
||||||
bool
|
static void
|
||||||
pgstat_backend_flush_cb(PgStat_EntryRef *entry_ref, bool nowait)
|
pgstat_flush_backend_entry_io(PgStat_EntryRef *entry_ref)
|
||||||
{
|
{
|
||||||
PgStatShared_Backend *shbackendioent;
|
PgStatShared_Backend *shbackendent;
|
||||||
PgStat_BackendPendingIO *pendingent;
|
PgStat_BackendPending *pendingent;
|
||||||
PgStat_BktypeIO *bktype_shstats;
|
PgStat_BktypeIO *bktype_shstats;
|
||||||
|
PgStat_PendingIO *pending_io;
|
||||||
|
|
||||||
if (!pgstat_lock_entry(entry_ref, nowait))
|
shbackendent = (PgStatShared_Backend *) entry_ref->shared_stats;
|
||||||
return false;
|
pendingent = (PgStat_BackendPending *) entry_ref->pending;
|
||||||
|
bktype_shstats = &shbackendent->stats.io_stats;
|
||||||
shbackendioent = (PgStatShared_Backend *) entry_ref->shared_stats;
|
pending_io = &pendingent->pending_io;
|
||||||
bktype_shstats = &shbackendioent->stats.stats;
|
|
||||||
pendingent = (PgStat_BackendPendingIO *) entry_ref->pending;
|
|
||||||
|
|
||||||
for (int io_object = 0; io_object < IOOBJECT_NUM_TYPES; io_object++)
|
for (int io_object = 0; io_object < IOOBJECT_NUM_TYPES; io_object++)
|
||||||
{
|
{
|
||||||
@ -66,15 +64,33 @@ pgstat_backend_flush_cb(PgStat_EntryRef *entry_ref, bool nowait)
|
|||||||
instr_time time;
|
instr_time time;
|
||||||
|
|
||||||
bktype_shstats->counts[io_object][io_context][io_op] +=
|
bktype_shstats->counts[io_object][io_context][io_op] +=
|
||||||
pendingent->counts[io_object][io_context][io_op];
|
pending_io->counts[io_object][io_context][io_op];
|
||||||
|
|
||||||
time = pendingent->pending_times[io_object][io_context][io_op];
|
time = pending_io->pending_times[io_object][io_context][io_op];
|
||||||
|
|
||||||
bktype_shstats->times[io_object][io_context][io_op] +=
|
bktype_shstats->times[io_object][io_context][io_op] +=
|
||||||
INSTR_TIME_GET_MICROSEC(time);
|
INSTR_TIME_GET_MICROSEC(time);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Wrapper routine to flush backend statistics.
|
||||||
|
*/
|
||||||
|
static bool
|
||||||
|
pgstat_flush_backend_entry(PgStat_EntryRef *entry_ref, bool nowait,
|
||||||
|
bits32 flags)
|
||||||
|
{
|
||||||
|
if (!pgstat_tracks_backend_bktype(MyBackendType))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if (!pgstat_lock_entry(entry_ref, nowait))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
/* Flush requested statistics */
|
||||||
|
if (flags & PGSTAT_BACKEND_FLUSH_IO)
|
||||||
|
pgstat_flush_backend_entry_io(entry_ref);
|
||||||
|
|
||||||
pgstat_unlock_entry(entry_ref);
|
pgstat_unlock_entry(entry_ref);
|
||||||
|
|
||||||
@ -82,10 +98,23 @@ pgstat_backend_flush_cb(PgStat_EntryRef *entry_ref, bool nowait)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Simpler wrapper of pgstat_backend_flush_cb()
|
* Callback to flush out locally pending backend statistics.
|
||||||
|
*
|
||||||
|
* If no stats have been recorded, this function returns false.
|
||||||
|
*/
|
||||||
|
bool
|
||||||
|
pgstat_backend_flush_cb(PgStat_EntryRef *entry_ref, bool nowait)
|
||||||
|
{
|
||||||
|
return pgstat_flush_backend_entry(entry_ref, nowait, PGSTAT_BACKEND_FLUSH_ALL);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Flush out locally pending backend statistics
|
||||||
|
*
|
||||||
|
* "flags" parameter controls which statistics to flush.
|
||||||
*/
|
*/
|
||||||
void
|
void
|
||||||
pgstat_flush_backend(bool nowait)
|
pgstat_flush_backend(bool nowait, bits32 flags)
|
||||||
{
|
{
|
||||||
PgStat_EntryRef *entry_ref;
|
PgStat_EntryRef *entry_ref;
|
||||||
|
|
||||||
@ -94,7 +123,7 @@ pgstat_flush_backend(bool nowait)
|
|||||||
|
|
||||||
entry_ref = pgstat_get_entry_ref(PGSTAT_KIND_BACKEND, InvalidOid,
|
entry_ref = pgstat_get_entry_ref(PGSTAT_KIND_BACKEND, InvalidOid,
|
||||||
MyProcNumber, false, NULL);
|
MyProcNumber, false, NULL);
|
||||||
(void) pgstat_backend_flush_cb(entry_ref, nowait);
|
(void) pgstat_flush_backend_entry(entry_ref, nowait, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -119,9 +148,9 @@ pgstat_create_backend(ProcNumber procnum)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Find or create a local PgStat_BackendPendingIO entry for proc number.
|
* Find or create a local PgStat_BackendPending entry for proc number.
|
||||||
*/
|
*/
|
||||||
PgStat_BackendPendingIO *
|
PgStat_BackendPending *
|
||||||
pgstat_prep_backend_pending(ProcNumber procnum)
|
pgstat_prep_backend_pending(ProcNumber procnum)
|
||||||
{
|
{
|
||||||
PgStat_EntryRef *entry_ref;
|
PgStat_EntryRef *entry_ref;
|
||||||
|
@ -81,10 +81,10 @@ pgstat_count_io_op_n(IOObject io_object, IOContext io_context, IOOp io_op, uint3
|
|||||||
|
|
||||||
if (pgstat_tracks_backend_bktype(MyBackendType))
|
if (pgstat_tracks_backend_bktype(MyBackendType))
|
||||||
{
|
{
|
||||||
PgStat_PendingIO *entry_ref;
|
PgStat_BackendPending *entry_ref;
|
||||||
|
|
||||||
entry_ref = pgstat_prep_backend_pending(MyProcNumber);
|
entry_ref = pgstat_prep_backend_pending(MyProcNumber);
|
||||||
entry_ref->counts[io_object][io_context][io_op] += cnt;
|
entry_ref->pending_io.counts[io_object][io_context][io_op] += cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
PendingIOStats.counts[io_object][io_context][io_op] += cnt;
|
PendingIOStats.counts[io_object][io_context][io_op] += cnt;
|
||||||
@ -151,10 +151,10 @@ pgstat_count_io_op_time(IOObject io_object, IOContext io_context, IOOp io_op,
|
|||||||
|
|
||||||
if (pgstat_tracks_backend_bktype(MyBackendType))
|
if (pgstat_tracks_backend_bktype(MyBackendType))
|
||||||
{
|
{
|
||||||
PgStat_PendingIO *entry_ref;
|
PgStat_BackendPending *entry_ref;
|
||||||
|
|
||||||
entry_ref = pgstat_prep_backend_pending(MyProcNumber);
|
entry_ref = pgstat_prep_backend_pending(MyProcNumber);
|
||||||
INSTR_TIME_ADD(entry_ref->pending_times[io_object][io_context][io_op],
|
INSTR_TIME_ADD(entry_ref->pending_io.pending_times[io_object][io_context][io_op],
|
||||||
io_time);
|
io_time);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -264,7 +264,7 @@ pgstat_report_vacuum(Oid tableoid, bool shared,
|
|||||||
* VACUUM command has processed all tables and committed.
|
* VACUUM command has processed all tables and committed.
|
||||||
*/
|
*/
|
||||||
pgstat_flush_io(false);
|
pgstat_flush_io(false);
|
||||||
pgstat_flush_backend(false);
|
pgstat_flush_backend(false, PGSTAT_BACKEND_FLUSH_IO);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -351,7 +351,7 @@ pgstat_report_analyze(Relation rel,
|
|||||||
|
|
||||||
/* see pgstat_report_vacuum() */
|
/* see pgstat_report_vacuum() */
|
||||||
pgstat_flush_io(false);
|
pgstat_flush_io(false);
|
||||||
pgstat_flush_backend(false);
|
pgstat_flush_backend(false, PGSTAT_BACKEND_FLUSH_IO);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1544,7 +1544,7 @@ pg_stat_get_backend_io(PG_FUNCTION_ARGS)
|
|||||||
if (bktype == B_INVALID)
|
if (bktype == B_INVALID)
|
||||||
return (Datum) 0;
|
return (Datum) 0;
|
||||||
|
|
||||||
bktype_stats = &backend_stats->stats;
|
bktype_stats = &backend_stats->io_stats;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* In Assert builds, we can afford an extra loop through all of the
|
* In Assert builds, we can afford an extra loop through all of the
|
||||||
|
@ -375,15 +375,24 @@ typedef struct PgStat_IO
|
|||||||
PgStat_BktypeIO stats[BACKEND_NUM_TYPES];
|
PgStat_BktypeIO stats[BACKEND_NUM_TYPES];
|
||||||
} PgStat_IO;
|
} PgStat_IO;
|
||||||
|
|
||||||
/* Backend statistics store the same amount of IO data as PGSTAT_KIND_IO */
|
|
||||||
typedef PgStat_PendingIO PgStat_BackendPendingIO;
|
|
||||||
|
|
||||||
typedef struct PgStat_Backend
|
typedef struct PgStat_Backend
|
||||||
{
|
{
|
||||||
TimestampTz stat_reset_timestamp;
|
TimestampTz stat_reset_timestamp;
|
||||||
PgStat_BktypeIO stats;
|
PgStat_BktypeIO io_stats;
|
||||||
} PgStat_Backend;
|
} PgStat_Backend;
|
||||||
|
|
||||||
|
/* ---------
|
||||||
|
* PgStat_BackendPending Non-flushed backend stats.
|
||||||
|
* ---------
|
||||||
|
*/
|
||||||
|
typedef struct PgStat_BackendPending
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Backend statistics store the same amount of IO data as PGSTAT_KIND_IO.
|
||||||
|
*/
|
||||||
|
PgStat_PendingIO pending_io;
|
||||||
|
} PgStat_BackendPending;
|
||||||
|
|
||||||
typedef struct PgStat_StatDBEntry
|
typedef struct PgStat_StatDBEntry
|
||||||
{
|
{
|
||||||
PgStat_Counter xact_commit;
|
PgStat_Counter xact_commit;
|
||||||
|
@ -613,9 +613,12 @@ extern void pgstat_archiver_snapshot_cb(void);
|
|||||||
* Functions in pgstat_backend.c
|
* Functions in pgstat_backend.c
|
||||||
*/
|
*/
|
||||||
|
|
||||||
extern void pgstat_flush_backend(bool nowait);
|
/* flags for pgstat_flush_backend() */
|
||||||
|
#define PGSTAT_BACKEND_FLUSH_IO (1 << 0) /* Flush I/O statistics */
|
||||||
|
#define PGSTAT_BACKEND_FLUSH_ALL (PGSTAT_BACKEND_FLUSH_IO)
|
||||||
|
|
||||||
extern PgStat_BackendPendingIO *pgstat_prep_backend_pending(ProcNumber procnum);
|
extern void pgstat_flush_backend(bool nowait, bits32 flags);
|
||||||
|
extern PgStat_BackendPending *pgstat_prep_backend_pending(ProcNumber procnum);
|
||||||
extern bool pgstat_backend_flush_cb(PgStat_EntryRef *entry_ref, bool nowait);
|
extern bool pgstat_backend_flush_cb(PgStat_EntryRef *entry_ref, bool nowait);
|
||||||
extern void pgstat_backend_reset_timestamp_cb(PgStatShared_Common *header, TimestampTz ts);
|
extern void pgstat_backend_reset_timestamp_cb(PgStatShared_Common *header, TimestampTz ts);
|
||||||
|
|
||||||
|
@ -2140,7 +2140,7 @@ PgStatShared_Subscription
|
|||||||
PgStatShared_Wal
|
PgStatShared_Wal
|
||||||
PgStat_ArchiverStats
|
PgStat_ArchiverStats
|
||||||
PgStat_Backend
|
PgStat_Backend
|
||||||
PgStat_BackendPendingIO
|
PgStat_BackendPending
|
||||||
PgStat_BackendSubEntry
|
PgStat_BackendSubEntry
|
||||||
PgStat_BgWriterStats
|
PgStat_BgWriterStats
|
||||||
PgStat_BktypeIO
|
PgStat_BktypeIO
|
||||||
|
Reference in New Issue
Block a user