pg_stat_bgwriter.buffers_backend is pretty meaningless (and more?)
Andres Freund <andres@anarazel.de>
Hi,
Currently pg_stat_bgwriter.buffers_backend is pretty useless to gauge
whether backends are doing writes they shouldn't do. That's because it
counts things that are either unavoidably or unlikely doable by other
parts of the system (checkpointer, bgwriter).
In particular extending the file can not currently be done by any
another type of process, yet is counted. When using a buffer access
strategy it is also very likely that writes have to be done by the
'dirtying' backend itself, as the buffer will be reused soon after (when
not previously in s_b that is).
Additionally pg_stat_bgwriter.buffers_backend also counts writes done by
autovacuum et al.
I think it'd make sense to at least split buffers_backend into
buffers_backend_extend,
buffers_backend_write,
buffers_backend_write_strat
but it could also be worthwhile to expand it into
buffers_backend_extend,
buffers_{backend,checkpoint,bgwriter,autovacuum}_write
buffers_{backend,autovacuum}_write_stat
Possibly by internally, in contrast to SQL level, having just counter
arrays indexed by backend types.
It's also noteworthy that buffers_backend is accounted in an absurd
manner. One might think that writes are accounted from backend -> shared
memory or such. But instead it works like this:
1) backend flushes buffer in bufmgr.c, accounts for backend *write time*
2) mdwrite writes and registers a sync request, which forwards the sync request to checkpointer
3) ForwardSyncRequest(), when not called by bgwriter, increments CheckpointerShmem->num_backend_writes
4) checkpointer, whenever doing AbsorbSyncRequests(), moves
CheckpointerShmem->num_backend_writes to
BgWriterStats.m_buf_written_backend (local memory!)
5) Occasionally it calls pgstat_send_bgwriter(), which sends the data to
pgstat (which bgwriter also does)
6) Which then updates the shared memory used by the display functions
Worthwhile to note that backend buffer read/write *time* is accounted
differently. That's done via pgstat_send_tabstat().
I think there's very little excuse for the indirection via checkpointer,
besides architectually being weird, it actually requires that we
continue to wake up checkpointer over and over instead of optimizing how
and when we submit fsync requests.
As far as I can tell we're also simply not accounting at all for writes
done outside of shared buffers. All writes done directly through
smgrwrite()/extend() aren't accounted anywhere as far as I can tell.
I think we also count things as writes that aren't writes: mdtruncate()
is AFAICT counted as one backend write for each segment. Which seems
weird to me.
Lastly, I don't understand what the point of sending fixed size stats,
like the stuff underlying pg_stat_bgwriter, through pgstats IPC. While
I don't like it's architecture, we obviously need something like pgstat
to handle variable amounts of stats (database, table level etc
stats). But that doesn't at all apply to these types of global stats.
Greetings,
Andres Freund
Commits
-
Stabilize pg_stat_io writes test
- ef719e7b32fc 16.0 landed
-
Fix flakey pg_stat_io test
- 1be0fdb9de55 16.0 landed
-
Suppress more compiler warnings in new pgstats code.
- b1b86820d84e 16.0 landed
-
Suppress compiler warnings in new pgstats code.
- 728560db7d86 16.0 landed
-
Add tests for pg_stat_io
- 10a082bf7215 16.0 landed
-
Create regress_tblspc in test_setup
- 9c83bbcf7ef6 16.0 landed
-
Add pg_stat_io view, providing more detailed IO statistics
- a9c70b46dbe1 16.0 landed
-
pgstat: Track more detailed relation IO statistics
- f30d62c2fc60 16.0 landed
-
pgstat: Infrastructure for more detailed IO statistics
- 28e626bde00e 16.0 landed
-
doc: Fix some issues in logical replication section
- 4f74f5641d53 16.0 cited
-
Manual cleanup and pgindent of pgstat and bufmgr related code
- 250c8ee07ede 16.0 landed
-
Have the planner consider Incremental Sort for DISTINCT
- 3c6fc58209f2 16.0 cited
-
Use actual backend IDs in pg_stat_get_backend_idset() and friends.
- d7e39d72ca1c 16.0 cited
-
Remove redundant call to pgstat_report_wal()
- 1bdd54e662d5 16.0 landed
-
Add BackendType for standalone backends
- 0c679464a837 16.0 landed
-
Initialize backend status reporting during bootstrap.
- 3b34645678d1 15.0 landed