LCOV - code coverage report
Current view: top level - src/backend/utils/activity - pgstat_backend.c (source / functions) Hit Total Coverage
Test: PostgreSQL 18devel Lines: 49 53 92.5 %
Date: 2025-01-18 05:15:39 Functions: 9 9 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -------------------------------------------------------------------------
       2             :  *
       3             :  * pgstat_backend.c
       4             :  *    Implementation of backend statistics.
       5             :  *
       6             :  * This file contains the implementation of backend statistics.  It is kept
       7             :  * separate from pgstat.c to enforce the line between the statistics access /
       8             :  * storage implementation and the details about individual types of
       9             :  * statistics.
      10             :  *
      11             :  * This statistics kind uses a proc number as object ID for the hash table
      12             :  * of pgstats.  Entries are created each time a process is spawned, and are
      13             :  * dropped when the process exits.  These are not written to the pgstats file
      14             :  * on disk.
      15             :  *
      16             :  * Copyright (c) 2001-2025, PostgreSQL Global Development Group
      17             :  *
      18             :  * IDENTIFICATION
      19             :  *    src/backend/utils/activity/pgstat_backend.c
      20             :  * -------------------------------------------------------------------------
      21             :  */
      22             : 
      23             : #include "postgres.h"
      24             : 
      25             : #include "utils/pgstat_internal.h"
      26             : 
      27             : /*
      28             :  * Returns statistics of a backend by proc number.
      29             :  */
      30             : PgStat_Backend *
      31          42 : pgstat_fetch_stat_backend(ProcNumber procNumber)
      32             : {
      33             :     PgStat_Backend *backend_entry;
      34             : 
      35          42 :     backend_entry = (PgStat_Backend *) pgstat_fetch_entry(PGSTAT_KIND_BACKEND,
      36             :                                                           InvalidOid, procNumber);
      37             : 
      38          42 :     return backend_entry;
      39             : }
      40             : 
      41             : /*
      42             :  * Flush out locally pending backend IO statistics.  Locking is managed
      43             :  * by the caller.
      44             :  */
      45             : static void
      46      186946 : pgstat_flush_backend_entry_io(PgStat_EntryRef *entry_ref)
      47             : {
      48             :     PgStatShared_Backend *shbackendent;
      49             :     PgStat_BackendPending *pendingent;
      50             :     PgStat_BktypeIO *bktype_shstats;
      51             :     PgStat_PendingIO *pending_io;
      52             : 
      53      186946 :     shbackendent = (PgStatShared_Backend *) entry_ref->shared_stats;
      54      186946 :     pendingent = (PgStat_BackendPending *) entry_ref->pending;
      55      186946 :     bktype_shstats = &shbackendent->stats.io_stats;
      56      186946 :     pending_io = &pendingent->pending_io;
      57             : 
      58      560838 :     for (int io_object = 0; io_object < IOOBJECT_NUM_TYPES; io_object++)
      59             :     {
      60     1869460 :         for (int io_context = 0; io_context < IOCONTEXT_NUM_TYPES; io_context++)
      61             :         {
      62    13460112 :             for (int io_op = 0; io_op < IOOP_NUM_TYPES; io_op++)
      63             :             {
      64             :                 instr_time  time;
      65             : 
      66    11964544 :                 bktype_shstats->counts[io_object][io_context][io_op] +=
      67    11964544 :                     pending_io->counts[io_object][io_context][io_op];
      68    11964544 :                 bktype_shstats->bytes[io_object][io_context][io_op] +=
      69    11964544 :                     pending_io->bytes[io_object][io_context][io_op];
      70             : 
      71    11964544 :                 time = pending_io->pending_times[io_object][io_context][io_op];
      72             : 
      73    11964544 :                 bktype_shstats->times[io_object][io_context][io_op] +=
      74    11964544 :                     INSTR_TIME_GET_MICROSEC(time);
      75             :             }
      76             :         }
      77             :     }
      78      186946 : }
      79             : 
      80             : /*
      81             :  * Wrapper routine to flush backend statistics.
      82             :  */
      83             : static bool
      84      186946 : pgstat_flush_backend_entry(PgStat_EntryRef *entry_ref, bool nowait,
      85             :                            bits32 flags)
      86             : {
      87      186946 :     if (!pgstat_tracks_backend_bktype(MyBackendType))
      88           0 :         return false;
      89             : 
      90      186946 :     if (!pgstat_lock_entry(entry_ref, nowait))
      91           0 :         return false;
      92             : 
      93             :     /* Flush requested statistics */
      94      186946 :     if (flags & PGSTAT_BACKEND_FLUSH_IO)
      95      186946 :         pgstat_flush_backend_entry_io(entry_ref);
      96             : 
      97      186946 :     pgstat_unlock_entry(entry_ref);
      98             : 
      99      186946 :     return true;
     100             : }
     101             : 
     102             : /*
     103             :  * Callback to flush out locally pending backend statistics.
     104             :  *
     105             :  * If no stats have been recorded, this function returns false.
     106             :  */
     107             : bool
     108       59532 : pgstat_backend_flush_cb(PgStat_EntryRef *entry_ref, bool nowait)
     109             : {
     110       59532 :     return pgstat_flush_backend_entry(entry_ref, nowait, PGSTAT_BACKEND_FLUSH_ALL);
     111             : }
     112             : 
     113             : /*
     114             :  * Flush out locally pending backend statistics
     115             :  *
     116             :  * "flags" parameter controls which statistics to flush.
     117             :  */
     118             : void
     119      127414 : pgstat_flush_backend(bool nowait, bits32 flags)
     120             : {
     121             :     PgStat_EntryRef *entry_ref;
     122             : 
     123      127414 :     if (!pgstat_tracks_backend_bktype(MyBackendType))
     124           0 :         return;
     125             : 
     126      127414 :     entry_ref = pgstat_get_entry_ref(PGSTAT_KIND_BACKEND, InvalidOid,
     127             :                                      MyProcNumber, false, NULL);
     128      127414 :     (void) pgstat_flush_backend_entry(entry_ref, nowait, flags);
     129             : }
     130             : 
     131             : /*
     132             :  * Create backend statistics entry for proc number.
     133             :  */
     134             : void
     135       31812 : pgstat_create_backend(ProcNumber procnum)
     136             : {
     137             :     PgStat_EntryRef *entry_ref;
     138             :     PgStatShared_Backend *shstatent;
     139             : 
     140       31812 :     entry_ref = pgstat_prep_pending_entry(PGSTAT_KIND_BACKEND, InvalidOid,
     141             :                                           procnum, NULL);
     142             : 
     143       31812 :     shstatent = (PgStatShared_Backend *) entry_ref->shared_stats;
     144             : 
     145             :     /*
     146             :      * NB: need to accept that there might be stats from an older backend,
     147             :      * e.g. if we previously used this proc number.
     148             :      */
     149       31812 :     memset(&shstatent->stats, 0, sizeof(shstatent->stats));
     150       31812 : }
     151             : 
     152             : /*
     153             :  * Find or create a local PgStat_BackendPending entry for proc number.
     154             :  */
     155             : PgStat_BackendPending *
     156   102470702 : pgstat_prep_backend_pending(ProcNumber procnum)
     157             : {
     158             :     PgStat_EntryRef *entry_ref;
     159             : 
     160   102470702 :     entry_ref = pgstat_prep_pending_entry(PGSTAT_KIND_BACKEND, InvalidOid,
     161             :                                           procnum, NULL);
     162             : 
     163   102470702 :     return entry_ref->pending;
     164             : }
     165             : 
     166             : /*
     167             :  * Backend statistics are not collected for all BackendTypes.
     168             :  *
     169             :  * The following BackendTypes do not participate in the backend stats
     170             :  * subsystem:
     171             :  * - The same and for the same reasons as in pgstat_tracks_io_bktype().
     172             :  * - B_BG_WRITER, B_CHECKPOINTER, B_STARTUP and B_AUTOVAC_LAUNCHER because their
     173             :  * I/O stats are already visible in pg_stat_io and there is only one of those.
     174             :  *
     175             :  * Function returns true if BackendType participates in the backend stats
     176             :  * subsystem and false if it does not.
     177             :  *
     178             :  * When adding a new BackendType, also consider adding relevant restrictions to
     179             :  * pgstat_tracks_io_object() and pgstat_tracks_io_op().
     180             :  */
     181             : bool
     182   114049658 : pgstat_tracks_backend_bktype(BackendType bktype)
     183             : {
     184             :     /*
     185             :      * List every type so that new backend types trigger a warning about
     186             :      * needing to adjust this switch.
     187             :      */
     188   114049658 :     switch (bktype)
     189             :     {
     190    11232784 :         case B_INVALID:
     191             :         case B_AUTOVAC_LAUNCHER:
     192             :         case B_DEAD_END_BACKEND:
     193             :         case B_ARCHIVER:
     194             :         case B_LOGGER:
     195             :         case B_WAL_RECEIVER:
     196             :         case B_WAL_WRITER:
     197             :         case B_WAL_SUMMARIZER:
     198             :         case B_BG_WRITER:
     199             :         case B_CHECKPOINTER:
     200             :         case B_STARTUP:
     201    11232784 :             return false;
     202             : 
     203   102816874 :         case B_AUTOVAC_WORKER:
     204             :         case B_BACKEND:
     205             :         case B_BG_WORKER:
     206             :         case B_STANDALONE_BACKEND:
     207             :         case B_SLOTSYNC_WORKER:
     208             :         case B_WAL_SENDER:
     209   102816874 :             return true;
     210             :     }
     211             : 
     212           0 :     return false;
     213             : }
     214             : 
     215             : void
     216           6 : pgstat_backend_reset_timestamp_cb(PgStatShared_Common *header, TimestampTz ts)
     217             : {
     218           6 :     ((PgStatShared_Backend *) header)->stats.stat_reset_timestamp = ts;
     219           6 : }

Generated by: LCOV version 1.14