LCOV - differential code coverage report
Current view: top level - src/backend/utils/activity - pgstat_wal.c (source / functions) Coverage Total Hit UIC GBC GIC GNC CBC ECB DCB
Current: Differential Code Coverage HEAD vs 15 Lines: 98.0 % 51 50 1 1 22 11 16 27 7
Current Date: 2023-04-08 15:15:32 Functions: 100.0 % 7 7 6 1 6
Baseline: 15
Baseline Date: 2023-04-08 15:09:40
Legend: Lines: hit not hit

           TLA  Line data    Source code
       1                 : /* -------------------------------------------------------------------------
       2                 :  *
       3                 :  * pgstat_wal.c
       4                 :  *    Implementation of WAL statistics.
       5                 :  *
       6                 :  * This file contains the implementation of WAL 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                 :  * Copyright (c) 2001-2023, PostgreSQL Global Development Group
      12                 :  *
      13                 :  * IDENTIFICATION
      14                 :  *    src/backend/utils/activity/pgstat_wal.c
      15                 :  * -------------------------------------------------------------------------
      16                 :  */
      17                 : 
      18                 : #include "postgres.h"
      19                 : 
      20                 : #include "utils/pgstat_internal.h"
      21                 : #include "executor/instrument.h"
      22                 : 
      23                 : 
      24                 : PgStat_PendingWalStats PendingWalStats = {0};
      25                 : 
      26                 : /*
      27                 :  * WAL usage counters saved from pgWALUsage at the previous call to
      28                 :  * pgstat_report_wal(). This is used to calculate how much WAL usage
      29                 :  * happens between pgstat_report_wal() calls, by subtracting
      30                 :  * the previous counters from the current ones.
      31                 :  */
      32                 : static WalUsage prevWalUsage;
      33                 : 
      34                 : 
      35                 : /*
      36                 :  * Calculate how much WAL usage counters have increased and update
      37                 :  * shared WAL and IO statistics.
      38                 :  *
      39                 :  * Must be called by processes that generate WAL, that do not call
      40                 :  * pgstat_report_stat(), like walwriter.
      41                 :  */
      42                 : void
      43 CBC       19881 : pgstat_report_wal(bool force)
      44                 : {
      45           19881 :     pgstat_flush_wal(force);
      46                 : 
      47 GNC       19881 :     pgstat_flush_io(force);
      48 GIC       19881 : }
      49 ECB             : 
      50                 : /*
      51                 :  * Support function for the SQL-callable pgstat* functions. Returns
      52                 :  * a pointer to the WAL statistics struct.
      53                 :  */
      54                 : PgStat_WalStats *
      55 GIC          41 : pgstat_fetch_stat_wal(void)
      56                 : {
      57 CBC          41 :     pgstat_snapshot_fixed(PGSTAT_KIND_WAL);
      58                 : 
      59              41 :     return &pgStatLocal.snapshot.wal;
      60                 : }
      61 ECB             : 
      62                 : /*
      63                 :  * Calculate how much WAL usage counters have increased by subtracting the
      64                 :  * previous counters from the current ones.
      65                 :  *
      66                 :  * If nowait is true, this function returns true if the lock could not be
      67                 :  * acquired. Otherwise return false.
      68                 :  */
      69                 : bool
      70 GIC       44337 : pgstat_flush_wal(bool nowait)
      71                 : {
      72 CBC       44337 :     PgStatShared_Wal *stats_shmem = &pgStatLocal.shmem->wal;
      73 GNC       44337 :     WalUsage    wal_usage_diff = {0};
      74 ECB             : 
      75 CBC       44337 :     Assert(IsUnderPostmaster || !IsPostmasterEnvironment);
      76 GIC       44337 :     Assert(pgStatLocal.shmem != NULL &&
      77 ECB             :            !pgStatLocal.shmem->is_shutdown);
      78                 : 
      79                 :     /*
      80                 :      * This function can be called even if nothing at all has happened. Avoid
      81                 :      * taking lock for nothing in that case.
      82                 :      */
      83 GIC       44337 :     if (!pgstat_have_pending_wal())
      84           30513 :         return false;
      85 ECB             : 
      86                 :     /*
      87                 :      * We don't update the WAL usage portion of the local WalStats elsewhere.
      88                 :      * Calculate how much WAL usage counters were increased by subtracting the
      89                 :      * previous counters from the current ones.
      90                 :      */
      91 GNC       13824 :     WalUsageAccumDiff(&wal_usage_diff, &pgWalUsage, &prevWalUsage);
      92 ECB             : 
      93 CBC       13824 :     if (!nowait)
      94           10931 :         LWLockAcquire(&stats_shmem->lock, LW_EXCLUSIVE);
      95 GBC        2893 :     else if (!LWLockConditionalAcquire(&stats_shmem->lock, LW_EXCLUSIVE))
      96 UIC           0 :         return true;
      97                 : 
      98                 : #define WALSTAT_ACC(fld, var_to_add) \
      99                 :     (stats_shmem->stats.fld += var_to_add.fld)
     100                 : #define WALSTAT_ACC_INSTR_TIME(fld) \
     101                 :     (stats_shmem->stats.fld += INSTR_TIME_GET_MICROSEC(PendingWalStats.fld))
     102 GNC       13824 :     WALSTAT_ACC(wal_records, wal_usage_diff);
     103           13824 :     WALSTAT_ACC(wal_fpi, wal_usage_diff);
     104           13824 :     WALSTAT_ACC(wal_bytes, wal_usage_diff);
     105           13824 :     WALSTAT_ACC(wal_buffers_full, PendingWalStats);
     106           13824 :     WALSTAT_ACC(wal_write, PendingWalStats);
     107           13824 :     WALSTAT_ACC(wal_sync, PendingWalStats);
     108           13824 :     WALSTAT_ACC_INSTR_TIME(wal_write_time);
     109           13824 :     WALSTAT_ACC_INSTR_TIME(wal_sync_time);
     110                 : #undef WALSTAT_ACC_INSTR_TIME
     111 ECB             : #undef WALSTAT_ACC
     112                 : 
     113 GIC       13824 :     LWLockRelease(&stats_shmem->lock);
     114                 : 
     115                 :     /*
     116 ECB             :      * Save the current counters for the subsequent calculation of WAL usage.
     117                 :      */
     118 GIC       13824 :     prevWalUsage = pgWalUsage;
     119                 : 
     120                 :     /*
     121 ECB             :      * Clear out the statistics buffer, so it can be re-used.
     122                 :      */
     123 GIC       82944 :     MemSet(&PendingWalStats, 0, sizeof(PendingWalStats));
     124                 : 
     125           13824 :     return false;
     126 ECB             : }
     127                 : 
     128                 : void
     129 GIC       13302 : pgstat_init_wal(void)
     130                 : {
     131                 :     /*
     132 ECB             :      * Initialize prevWalUsage with pgWalUsage so that pgstat_flush_wal() can
     133                 :      * calculate how much pgWalUsage counters are increased by subtracting
     134                 :      * prevWalUsage from pgWalUsage.
     135                 :      */
     136 GIC       13302 :     prevWalUsage = pgWalUsage;
     137           13302 : }
     138                 : 
     139 ECB             : /*
     140                 :  * To determine whether any WAL activity has occurred since last time, not
     141                 :  * only the number of generated WAL records but also the numbers of WAL
     142                 :  * writes and syncs need to be checked. Because even transaction that
     143                 :  * generates no WAL records can write or sync WAL data when flushing the
     144                 :  * data pages.
     145                 :  */
     146                 : bool
     147 GIC       50685 : pgstat_have_pending_wal(void)
     148                 : {
     149           92438 :     return pgWalUsage.wal_records != prevWalUsage.wal_records ||
     150 CBC       87488 :         PendingWalStats.wal_write != 0 ||
     151 GIC       36803 :         PendingWalStats.wal_sync != 0;
     152 ECB             : }
     153                 : 
     154                 : void
     155 GIC         442 : pgstat_wal_reset_all_cb(TimestampTz ts)
     156                 : {
     157             442 :     PgStatShared_Wal *stats_shmem = &pgStatLocal.shmem->wal;
     158 ECB             : 
     159 GIC         442 :     LWLockAcquire(&stats_shmem->lock, LW_EXCLUSIVE);
     160 CBC         442 :     memset(&stats_shmem->stats, 0, sizeof(stats_shmem->stats));
     161 GIC         442 :     stats_shmem->stats.stat_reset_timestamp = ts;
     162 CBC         442 :     LWLockRelease(&stats_shmem->lock);
     163             442 : }
     164 ECB             : 
     165                 : void
     166 CBC        1033 : pgstat_wal_snapshot_cb(void)
     167                 : {
     168 GIC        1033 :     PgStatShared_Wal *stats_shmem = &pgStatLocal.shmem->wal;
     169 ECB             : 
     170 GIC        1033 :     LWLockAcquire(&stats_shmem->lock, LW_SHARED);
     171 CBC        1033 :     memcpy(&pgStatLocal.snapshot.wal, &stats_shmem->stats,
     172                 :            sizeof(pgStatLocal.snapshot.wal));
     173            1033 :     LWLockRelease(&stats_shmem->lock);
     174            1033 : }
        

Generated by: LCOV version v1.16-55-g56c0a2a