1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-19 13:42:17 +03:00

Add data for WAL in pg_stat_io and backend statistics

This commit adds WAL IO stats to both pg_stat_io view and per-backend IO
statistics (pg_stat_get_backend_io()).  This change is possible since
f92c854cf4, as WAL IO is not counted in blocks in some code paths
where its stats data is measured (like WAL read in xlogreader.c).

IOContext gains IOCONTEXT_INIT and IOObject IOOBJECT_WAL, with the
following combinations allowed:
- IOOBJECT_WAL/IOCONTEXT_NORMAL is used to track I/O operations done on
already-created WAL segments.
- IOOBJECT_WAL/IOCONTEXT_INIT is used for tracking I/O operations done
when initializing WAL segments.

The core changes are done in pg_stat_io.c, backend statistics inherit
them.  Backend statistics and pg_stat_io are now available for the WAL
writer, the WAL receiver and the WAL summarizer processes.

I/O timing data is controlled by the GUC track_io_timing, like the
existing data of pg_stat_io for consistency.  The timings related to
IOOBJECT_WAL show up if the GUC is enabled (disabled by default).

Bump pgstats file version, due to the additions in IOObject and
IOContext, impacting the amount of data written for the fixed-numbered
IO stats kind in the pgstats file.

Author: Nazir Bilal Yavuz
Reviewed-by: Bertrand Drouvot, Nitin Jadhav, Amit Kapila, Michael
Paquier, Melanie Plageman, Bharath Rupireddy
Discussion: https://postgr.es/m/CAN55FZ3AiQ+ZMxUuXnBpd0Rrh1YhwJ5FudkHg=JU0P+-W8T4Vg@mail.gmail.com
This commit is contained in:
Michael Paquier
2025-02-04 16:50:00 +09:00
parent 622f678c10
commit a051e71e28
9 changed files with 216 additions and 38 deletions

View File

@@ -236,9 +236,6 @@ pgstat_tracks_backend_bktype(BackendType bktype)
case B_DEAD_END_BACKEND:
case B_ARCHIVER:
case B_LOGGER:
case B_WAL_RECEIVER:
case B_WAL_WRITER:
case B_WAL_SUMMARIZER:
case B_BG_WRITER:
case B_CHECKPOINTER:
case B_STARTUP:
@@ -249,7 +246,10 @@ pgstat_tracks_backend_bktype(BackendType bktype)
case B_BG_WORKER:
case B_STANDALONE_BACKEND:
case B_SLOTSYNC_WORKER:
case B_WAL_RECEIVER:
case B_WAL_SENDER:
case B_WAL_SUMMARIZER:
case B_WAL_WRITER:
return true;
}

View File

@@ -127,21 +127,24 @@ pgstat_count_io_op_time(IOObject io_object, IOContext io_context, IOOp io_op,
INSTR_TIME_SET_CURRENT(io_time);
INSTR_TIME_SUBTRACT(io_time, start_time);
if (io_op == IOOP_WRITE || io_op == IOOP_EXTEND)
if (io_object != IOOBJECT_WAL)
{
pgstat_count_buffer_write_time(INSTR_TIME_GET_MICROSEC(io_time));
if (io_object == IOOBJECT_RELATION)
INSTR_TIME_ADD(pgBufferUsage.shared_blk_write_time, io_time);
else if (io_object == IOOBJECT_TEMP_RELATION)
INSTR_TIME_ADD(pgBufferUsage.local_blk_write_time, io_time);
}
else if (io_op == IOOP_READ)
{
pgstat_count_buffer_read_time(INSTR_TIME_GET_MICROSEC(io_time));
if (io_object == IOOBJECT_RELATION)
INSTR_TIME_ADD(pgBufferUsage.shared_blk_read_time, io_time);
else if (io_object == IOOBJECT_TEMP_RELATION)
INSTR_TIME_ADD(pgBufferUsage.local_blk_read_time, io_time);
if (io_op == IOOP_WRITE || io_op == IOOP_EXTEND)
{
pgstat_count_buffer_write_time(INSTR_TIME_GET_MICROSEC(io_time));
if (io_object == IOOBJECT_RELATION)
INSTR_TIME_ADD(pgBufferUsage.shared_blk_write_time, io_time);
else if (io_object == IOOBJECT_TEMP_RELATION)
INSTR_TIME_ADD(pgBufferUsage.local_blk_write_time, io_time);
}
else if (io_op == IOOP_READ)
{
pgstat_count_buffer_read_time(INSTR_TIME_GET_MICROSEC(io_time));
if (io_object == IOOBJECT_RELATION)
INSTR_TIME_ADD(pgBufferUsage.shared_blk_read_time, io_time);
else if (io_object == IOOBJECT_TEMP_RELATION)
INSTR_TIME_ADD(pgBufferUsage.local_blk_read_time, io_time);
}
}
INSTR_TIME_ADD(PendingIOStats.pending_times[io_object][io_context][io_op],
@@ -249,6 +252,8 @@ pgstat_get_io_context_name(IOContext io_context)
return "bulkread";
case IOCONTEXT_BULKWRITE:
return "bulkwrite";
case IOCONTEXT_INIT:
return "init";
case IOCONTEXT_NORMAL:
return "normal";
case IOCONTEXT_VACUUM:
@@ -268,6 +273,8 @@ pgstat_get_io_object_name(IOObject io_object)
return "relation";
case IOOBJECT_TEMP_RELATION:
return "temp relation";
case IOOBJECT_WAL:
return "wal";
}
elog(ERROR, "unrecognized IOObject value: %d", io_object);
@@ -340,8 +347,6 @@ pgstat_io_snapshot_cb(void)
* - Syslogger because it is not connected to shared memory
* - Archiver because most relevant archiving IO is delegated to a
* specialized command or module
* - WAL Receiver, WAL Writer, and WAL Summarizer IO are not tracked in
* pg_stat_io for now
*
* Function returns true if BackendType participates in the cumulative stats
* subsystem for IO and false if it does not.
@@ -362,9 +367,6 @@ pgstat_tracks_io_bktype(BackendType bktype)
case B_DEAD_END_BACKEND:
case B_ARCHIVER:
case B_LOGGER:
case B_WAL_RECEIVER:
case B_WAL_WRITER:
case B_WAL_SUMMARIZER:
return false;
case B_AUTOVAC_LAUNCHER:
@@ -376,7 +378,10 @@ pgstat_tracks_io_bktype(BackendType bktype)
case B_SLOTSYNC_WORKER:
case B_STANDALONE_BACKEND:
case B_STARTUP:
case B_WAL_RECEIVER:
case B_WAL_SENDER:
case B_WAL_SUMMARIZER:
case B_WAL_WRITER:
return true;
}
@@ -402,6 +407,15 @@ pgstat_tracks_io_object(BackendType bktype, IOObject io_object,
if (!pgstat_tracks_io_bktype(bktype))
return false;
/*
* Currently, IO on IOOBJECT_WAL objects can only occur in the
* IOCONTEXT_NORMAL and IOCONTEXT_INIT IOContexts.
*/
if (io_object == IOOBJECT_WAL &&
(io_context != IOCONTEXT_NORMAL &&
io_context != IOCONTEXT_INIT))
return false;
/*
* Currently, IO on temporary relations can only occur in the
* IOCONTEXT_NORMAL IOContext.
@@ -468,14 +482,28 @@ pgstat_tracks_io_op(BackendType bktype, IOObject io_object,
/*
* Some BackendTypes will not do certain IOOps.
*/
if ((bktype == B_BG_WRITER || bktype == B_CHECKPOINTER) &&
if (bktype == B_BG_WRITER &&
(io_op == IOOP_READ || io_op == IOOP_EVICT || io_op == IOOP_HIT))
return false;
if (bktype == B_CHECKPOINTER &&
((io_object != IOOBJECT_WAL && io_op == IOOP_READ) ||
(io_op == IOOP_EVICT || io_op == IOOP_HIT)))
return false;
if ((bktype == B_AUTOVAC_LAUNCHER || bktype == B_BG_WRITER ||
bktype == B_CHECKPOINTER) && io_op == IOOP_EXTEND)
return false;
/*
* Some BackendTypes do not perform reads with IOOBJECT_WAL.
*/
if (io_object == IOOBJECT_WAL && io_op == IOOP_READ &&
(bktype == B_WAL_RECEIVER || bktype == B_BG_WRITER ||
bktype == B_AUTOVAC_WORKER || bktype == B_AUTOVAC_WORKER ||
bktype == B_WAL_WRITER))
return false;
/*
* Temporary tables are not logged and thus do not require fsync'ing.
* Writeback is not requested for temporary tables.
@@ -500,6 +528,17 @@ pgstat_tracks_io_op(BackendType bktype, IOObject io_object,
if (!strategy_io_context && io_op == IOOP_REUSE)
return false;
/*
* IOOBJECT_WAL IOObject will not do certain IOOps depending on IOContext.
*/
if (io_object == IOOBJECT_WAL && io_context == IOCONTEXT_INIT &&
!(io_op == IOOP_WRITE || io_op == IOOP_FSYNC))
return false;
if (io_object == IOOBJECT_WAL && io_context == IOCONTEXT_NORMAL &&
!(io_op == IOOP_WRITE || io_op == IOOP_READ || io_op == IOOP_FSYNC))
return false;
/*
* IOOP_FSYNC IOOps done by a backend using a BufferAccessStrategy are
* counted in the IOCONTEXT_NORMAL IOContext. See comment in