LCOV - differential code coverage report
Current view: top level - src/backend/executor - instrument.c (source / functions) Coverage Total Hit UNC UBC GNC CBC DUB DCB
Current: 0e5ff9b9b45a657aea12440478dc002e9b01f138 vs 0123ce131fca454009439dfa3b2266d1d40737d7 Lines: 94.0 % 151 142 3 6 12 130 2 10
Current Date: 2026-03-14 14:10:32 -0400 Functions: 100.0 % 14 14 6 8
Baseline: lcov-20260315-024220-baseline Branches: 66.0 % 50 33 6 11 6 27 7 7
Baseline Date: 2026-03-14 15:27:56 +0100 Line coverage date bins:
Legend: Lines:     hit not hit
Branches: + taken - not taken # not executed
(7,30] days: 60.0 % 5 3 2 3
(30,360] days: 90.0 % 10 9 1 9
(360..) days: 95.6 % 136 130 6 130
Function coverage date bins:
(360..) days: 100.0 % 14 14 6 8
Branch coverage date bins:
(7,30] days: 37.5 % 8 3 5 3
(30,360] days: 75.0 % 4 3 1 3
(360..) days: 71.1 % 38 27 11 27

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /*-------------------------------------------------------------------------
                                  2                 :                :  *
                                  3                 :                :  * instrument.c
                                  4                 :                :  *   functions for instrumentation of plan execution
                                  5                 :                :  *
                                  6                 :                :  *
                                  7                 :                :  * Copyright (c) 2001-2026, PostgreSQL Global Development Group
                                  8                 :                :  *
                                  9                 :                :  * IDENTIFICATION
                                 10                 :                :  *    src/backend/executor/instrument.c
                                 11                 :                :  *
                                 12                 :                :  *-------------------------------------------------------------------------
                                 13                 :                :  */
                                 14                 :                : #include "postgres.h"
                                 15                 :                : 
                                 16                 :                : #include <unistd.h>
                                 17                 :                : 
                                 18                 :                : #include "executor/instrument.h"
                                 19                 :                : 
                                 20                 :                : BufferUsage pgBufferUsage;
                                 21                 :                : static BufferUsage save_pgBufferUsage;
                                 22                 :                : WalUsage    pgWalUsage;
                                 23                 :                : static WalUsage save_pgWalUsage;
                                 24                 :                : 
                                 25                 :                : static void BufferUsageAdd(BufferUsage *dst, const BufferUsage *add);
                                 26                 :                : static void WalUsageAdd(WalUsage *dst, WalUsage *add);
                                 27                 :                : 
                                 28                 :                : 
                                 29                 :                : /* Allocate new instrumentation structure(s) */
                                 30                 :                : Instrumentation *
 1768 efujita@postgresql.o       31                 :CBC       46842 : InstrAlloc(int n, int instrument_options, bool async_mode)
                                 32                 :                : {
                                 33                 :                :     Instrumentation *instr;
                                 34                 :                : 
                                 35                 :                :     /* initialize all fields to zeroes, then modify as needed */
 5934 rhaas@postgresql.org       36                 :          46842 :     instr = palloc0(n * sizeof(Instrumentation));
 2171 akapila@postgresql.o       37         [ +  + ]:          46842 :     if (instrument_options & (INSTRUMENT_BUFFERS | INSTRUMENT_TIMER | INSTRUMENT_WAL))
                                 38                 :                :     {
 4784 tgl@sss.pgh.pa.us          39                 :          44318 :         bool        need_buffers = (instrument_options & INSTRUMENT_BUFFERS) != 0;
 2171 akapila@postgresql.o       40                 :          44318 :         bool        need_wal = (instrument_options & INSTRUMENT_WAL) != 0;
 4784 tgl@sss.pgh.pa.us          41                 :          44318 :         bool        need_timer = (instrument_options & INSTRUMENT_TIMER) != 0;
                                 42                 :                :         int         i;
                                 43                 :                : 
 5934 rhaas@postgresql.org       44         [ +  + ]:          88636 :         for (i = 0; i < n; i++)
                                 45                 :                :         {
 5150                            46                 :          44318 :             instr[i].need_bufusage = need_buffers;
 2171 akapila@postgresql.o       47                 :          44318 :             instr[i].need_walusage = need_wal;
 5150 rhaas@postgresql.org       48                 :          44318 :             instr[i].need_timer = need_timer;
 1768 efujita@postgresql.o       49                 :          44318 :             instr[i].async_mode = async_mode;
                                 50                 :                :         }
                                 51                 :                :     }
                                 52                 :                : 
 8944 tgl@sss.pgh.pa.us          53                 :          46842 :     return instr;
                                 54                 :                : }
                                 55                 :                : 
                                 56                 :                : /* Initialize a pre-allocated instrumentation structure. */
                                 57                 :                : void
 3821 rhaas@postgresql.org       58                 :            840 : InstrInit(Instrumentation *instr, int instrument_options)
                                 59                 :                : {
                                 60                 :            840 :     memset(instr, 0, sizeof(Instrumentation));
                                 61                 :            840 :     instr->need_bufusage = (instrument_options & INSTRUMENT_BUFFERS) != 0;
 2171 akapila@postgresql.o       62                 :            840 :     instr->need_walusage = (instrument_options & INSTRUMENT_WAL) != 0;
 3821 rhaas@postgresql.org       63                 :            840 :     instr->need_timer = (instrument_options & INSTRUMENT_TIMER) != 0;
                                 64                 :            840 : }
                                 65                 :                : 
                                 66                 :                : /* Entry to a plan node */
                                 67                 :                : void
 8944 tgl@sss.pgh.pa.us          68                 :        6845946 : InstrStartNode(Instrumentation *instr)
                                 69                 :                : {
   17 andres@anarazel.de         70         [ +  + ]:GNC     6845946 :     if (instr->need_timer)
                                 71                 :                :     {
                                 72         [ -  + ]:        5421852 :         if (!INSTR_TIME_IS_ZERO(instr->starttime))
   17 andres@anarazel.de         73         [ #  # ]:UNC           0 :             elog(ERROR, "InstrStartNode called twice in a row");
                                 74                 :                :         else
   17 andres@anarazel.de         75                 :GNC     5421852 :             INSTR_TIME_SET_CURRENT(instr->starttime);
                                 76                 :                :     }
                                 77                 :                : 
                                 78                 :                :     /* save buffer usage totals at node entry, if needed */
 5288 tgl@sss.pgh.pa.us          79         [ +  + ]:CBC     6845946 :     if (instr->need_bufusage)
 5934 rhaas@postgresql.org       80                 :        5382460 :         instr->bufusage_start = pgBufferUsage;
                                 81                 :                : 
 2171 akapila@postgresql.o       82         [ +  + ]:        6845946 :     if (instr->need_walusage)
                                 83                 :          81685 :         instr->walusage_start = pgWalUsage;
 8944 tgl@sss.pgh.pa.us          84                 :        6845946 : }
                                 85                 :                : 
                                 86                 :                : /* Exit from a plan node */
                                 87                 :                : void
 7229 bruce@momjian.us           88                 :        6844355 : InstrStopNode(Instrumentation *instr, double nTuples)
                                 89                 :                : {
 1768 efujita@postgresql.o       90                 :        6844355 :     double      save_tuplecount = instr->tuplecount;
                                 91                 :                :     instr_time  endtime;
                                 92                 :                : 
                                 93                 :                :     /* count the returned tuples */
 7229 bruce@momjian.us           94                 :        6844355 :     instr->tuplecount += nTuples;
                                 95                 :                : 
                                 96                 :                :     /* let's update the time only if the timer was requested */
 5150 rhaas@postgresql.org       97         [ +  + ]:        6844355 :     if (instr->need_timer)
                                 98                 :                :     {
                                 99         [ -  + ]:        5420267 :         if (INSTR_TIME_IS_ZERO(instr->starttime))
 4784 tgl@sss.pgh.pa.us         100         [ #  # ]:UBC           0 :             elog(ERROR, "InstrStopNode called without start");
                                101                 :                : 
 5150 rhaas@postgresql.org      102                 :CBC     5420267 :         INSTR_TIME_SET_CURRENT(endtime);
                                103                 :        5420267 :         INSTR_TIME_ACCUM_DIFF(instr->counter, endtime, instr->starttime);
                                104                 :                : 
                                105                 :        5420267 :         INSTR_TIME_SET_ZERO(instr->starttime);
                                106                 :                :     }
                                107                 :                : 
                                108                 :                :     /* Add delta of buffer usage since entry to node's totals */
 5288 tgl@sss.pgh.pa.us         109         [ +  + ]:        6844355 :     if (instr->need_bufusage)
 5934 rhaas@postgresql.org      110                 :        5380875 :         BufferUsageAccumDiff(&instr->bufusage,
 5861 bruce@momjian.us          111                 :        5380875 :                              &pgBufferUsage, &instr->bufusage_start);
                                112                 :                : 
 2171 akapila@postgresql.o      113         [ +  + ]:        6844355 :     if (instr->need_walusage)
                                114                 :          80100 :         WalUsageAccumDiff(&instr->walusage,
                                115                 :          80100 :                           &pgWalUsage, &instr->walusage_start);
                                116                 :                : 
                                117                 :                :     /* Is this the first tuple of this cycle? */
 8944 tgl@sss.pgh.pa.us         118         [ +  + ]:        6844355 :     if (!instr->running)
                                119                 :                :     {
                                120                 :          65803 :         instr->running = true;
   65 andres@anarazel.de        121                 :GNC       65803 :         instr->firsttuple = instr->counter;
                                122                 :                :     }
                                123                 :                :     else
                                124                 :                :     {
                                125                 :                :         /*
                                126                 :                :          * In async mode, if the plan node hadn't emitted any tuples before,
                                127                 :                :          * this might be the first tuple
                                128                 :                :          */
 1768 efujita@postgresql.o      129   [ -  +  -  - ]:CBC     6778552 :         if (instr->async_mode && save_tuplecount < 1.0)
   65 andres@anarazel.de        130                 :UNC           0 :             instr->firsttuple = instr->counter;
                                131                 :                :     }
 1768 efujita@postgresql.o      132                 :CBC     6844355 : }
                                133                 :                : 
                                134                 :                : /* Update tuple count */
                                135                 :                : void
                                136                 :              2 : InstrUpdateTupleCount(Instrumentation *instr, double nTuples)
                                137                 :                : {
                                138                 :                :     /* count the returned tuples */
                                139                 :              2 :     instr->tuplecount += nTuples;
 7638 tgl@sss.pgh.pa.us         140                 :              2 : }
                                141                 :                : 
                                142                 :                : /* Finish a run cycle for a plan node */
                                143                 :                : void
 8944                           144                 :          66707 : InstrEndLoop(Instrumentation *instr)
                                145                 :                : {
                                146                 :                :     /* Skip if nothing has happened, or already shut down */
                                147         [ +  + ]:          66707 :     if (!instr->running)
                                148                 :           1077 :         return;
                                149                 :                : 
 7638                           150         [ -  + ]:          65630 :     if (!INSTR_TIME_IS_ZERO(instr->starttime))
 4784 tgl@sss.pgh.pa.us         151         [ #  # ]:UBC           0 :         elog(ERROR, "InstrEndLoop called on running node");
                                152                 :                : 
                                153                 :                :     /* Accumulate per-cycle statistics into totals */
   65 andres@anarazel.de        154                 :GNC       65630 :     INSTR_TIME_ADD(instr->startup, instr->firsttuple);
                                155                 :          65630 :     INSTR_TIME_ADD(instr->total, instr->counter);
 8944 tgl@sss.pgh.pa.us         156                 :CBC       65630 :     instr->ntuples += instr->tuplecount;
                                157                 :          65630 :     instr->nloops += 1;
                                158                 :                : 
                                159                 :                :     /* Reset for next cycle (if any) */
                                160                 :          65630 :     instr->running = false;
 7665                           161                 :          65630 :     INSTR_TIME_SET_ZERO(instr->starttime);
                                162                 :          65630 :     INSTR_TIME_SET_ZERO(instr->counter);
   65 andres@anarazel.de        163                 :GNC       65630 :     INSTR_TIME_SET_ZERO(instr->firsttuple);
 8944 tgl@sss.pgh.pa.us         164                 :CBC       65630 :     instr->tuplecount = 0;
                                165                 :                : }
                                166                 :                : 
                                167                 :                : /* aggregate instrumentation information */
                                168                 :                : void
 3821 rhaas@postgresql.org      169                 :           2028 : InstrAggNode(Instrumentation *dst, Instrumentation *add)
                                170                 :                : {
                                171   [ +  +  -  + ]:           2028 :     if (!dst->running && add->running)
                                172                 :                :     {
 3821 rhaas@postgresql.org      173                 :UBC           0 :         dst->running = true;
                                174                 :              0 :         dst->firsttuple = add->firsttuple;
                                175                 :                :     }
   65 andres@anarazel.de        176   [ +  +  -  + ]:GNC        2028 :     else if (dst->running && add->running &&
   17 andres@anarazel.de        177         [ #  # ]:UNC           0 :              INSTR_TIME_GT(dst->firsttuple, add->firsttuple))
 3821 rhaas@postgresql.org      178                 :UBC           0 :         dst->firsttuple = add->firsttuple;
                                179                 :                : 
 3821 rhaas@postgresql.org      180                 :CBC        2028 :     INSTR_TIME_ADD(dst->counter, add->counter);
                                181                 :                : 
                                182                 :           2028 :     dst->tuplecount += add->tuplecount;
   65 andres@anarazel.de        183                 :GNC        2028 :     INSTR_TIME_ADD(dst->startup, add->startup);
                                184                 :           2028 :     INSTR_TIME_ADD(dst->total, add->total);
 3821 rhaas@postgresql.org      185                 :CBC        2028 :     dst->ntuples += add->ntuples;
 2896 alvherre@alvh.no-ip.      186                 :           2028 :     dst->ntuples2 += add->ntuples2;
 3821 rhaas@postgresql.org      187                 :           2028 :     dst->nloops += add->nloops;
                                188                 :           2028 :     dst->nfiltered1 += add->nfiltered1;
                                189                 :           2028 :     dst->nfiltered2 += add->nfiltered2;
                                190                 :                : 
                                191                 :                :     /* Add delta of buffer usage since entry to node's totals */
                                192         [ +  + ]:           2028 :     if (dst->need_bufusage)
                                193                 :            954 :         BufferUsageAdd(&dst->bufusage, &add->bufusage);
                                194                 :                : 
 2171 akapila@postgresql.o      195         [ -  + ]:           2028 :     if (dst->need_walusage)
 2171 akapila@postgresql.o      196                 :UBC           0 :         WalUsageAdd(&dst->walusage, &add->walusage);
 3821 rhaas@postgresql.org      197                 :CBC        2028 : }
                                198                 :                : 
                                199                 :                : /* note current values during parallel executor startup */
                                200                 :                : void
                                201                 :           1491 : InstrStartParallelQuery(void)
                                202                 :                : {
                                203                 :           1491 :     save_pgBufferUsage = pgBufferUsage;
 2171 akapila@postgresql.o      204                 :           1491 :     save_pgWalUsage = pgWalUsage;
 3821 rhaas@postgresql.org      205                 :           1491 : }
                                206                 :                : 
                                207                 :                : /* report usage after parallel executor shutdown */
                                208                 :                : void
 2171 akapila@postgresql.o      209                 :           1485 : InstrEndParallelQuery(BufferUsage *bufusage, WalUsage *walusage)
                                210                 :                : {
 2166                           211                 :           1485 :     memset(bufusage, 0, sizeof(BufferUsage));
                                212                 :           1485 :     BufferUsageAccumDiff(bufusage, &pgBufferUsage, &save_pgBufferUsage);
 2171                           213                 :           1485 :     memset(walusage, 0, sizeof(WalUsage));
                                214                 :           1485 :     WalUsageAccumDiff(walusage, &pgWalUsage, &save_pgWalUsage);
 3821 rhaas@postgresql.org      215                 :           1485 : }
                                216                 :                : 
                                217                 :                : /* accumulate work done by workers in leader's stats */
                                218                 :                : void
 2171 akapila@postgresql.o      219                 :           1485 : InstrAccumParallelQuery(BufferUsage *bufusage, WalUsage *walusage)
                                220                 :                : {
 2166                           221                 :           1485 :     BufferUsageAdd(&pgBufferUsage, bufusage);
 2171                           222                 :           1485 :     WalUsageAdd(&pgWalUsage, walusage);
 3821 rhaas@postgresql.org      223                 :           1485 : }
                                224                 :                : 
                                225                 :                : /* dst += add */
                                226                 :                : static void
                                227                 :           2439 : BufferUsageAdd(BufferUsage *dst, const BufferUsage *add)
                                228                 :                : {
                                229                 :           2439 :     dst->shared_blks_hit += add->shared_blks_hit;
                                230                 :           2439 :     dst->shared_blks_read += add->shared_blks_read;
                                231                 :           2439 :     dst->shared_blks_dirtied += add->shared_blks_dirtied;
                                232                 :           2439 :     dst->shared_blks_written += add->shared_blks_written;
                                233                 :           2439 :     dst->local_blks_hit += add->local_blks_hit;
                                234                 :           2439 :     dst->local_blks_read += add->local_blks_read;
                                235                 :           2439 :     dst->local_blks_dirtied += add->local_blks_dirtied;
                                236                 :           2439 :     dst->local_blks_written += add->local_blks_written;
                                237                 :           2439 :     dst->temp_blks_read += add->temp_blks_read;
                                238                 :           2439 :     dst->temp_blks_written += add->temp_blks_written;
  878 michael@paquier.xyz       239                 :           2439 :     INSTR_TIME_ADD(dst->shared_blk_read_time, add->shared_blk_read_time);
                                240                 :           2439 :     INSTR_TIME_ADD(dst->shared_blk_write_time, add->shared_blk_write_time);
                                241                 :           2439 :     INSTR_TIME_ADD(dst->local_blk_read_time, add->local_blk_read_time);
                                242                 :           2439 :     INSTR_TIME_ADD(dst->local_blk_write_time, add->local_blk_write_time);
 1437                           243                 :           2439 :     INSTR_TIME_ADD(dst->temp_blk_read_time, add->temp_blk_read_time);
                                244                 :           2439 :     INSTR_TIME_ADD(dst->temp_blk_write_time, add->temp_blk_write_time);
 3821 rhaas@postgresql.org      245                 :           2439 : }
                                246                 :                : 
                                247                 :                : /* dst += add - sub */
                                248                 :                : void
 5934                           249                 :        5408662 : BufferUsageAccumDiff(BufferUsage *dst,
                                250                 :                :                      const BufferUsage *add,
                                251                 :                :                      const BufferUsage *sub)
                                252                 :                : {
                                253                 :        5408662 :     dst->shared_blks_hit += add->shared_blks_hit - sub->shared_blks_hit;
                                254                 :        5408662 :     dst->shared_blks_read += add->shared_blks_read - sub->shared_blks_read;
 5135                           255                 :        5408662 :     dst->shared_blks_dirtied += add->shared_blks_dirtied - sub->shared_blks_dirtied;
 5934                           256                 :        5408662 :     dst->shared_blks_written += add->shared_blks_written - sub->shared_blks_written;
                                257                 :        5408662 :     dst->local_blks_hit += add->local_blks_hit - sub->local_blks_hit;
                                258                 :        5408662 :     dst->local_blks_read += add->local_blks_read - sub->local_blks_read;
 5135                           259                 :        5408662 :     dst->local_blks_dirtied += add->local_blks_dirtied - sub->local_blks_dirtied;
 5934                           260                 :        5408662 :     dst->local_blks_written += add->local_blks_written - sub->local_blks_written;
                                261                 :        5408662 :     dst->temp_blks_read += add->temp_blks_read - sub->temp_blks_read;
                                262                 :        5408662 :     dst->temp_blks_written += add->temp_blks_written - sub->temp_blks_written;
  878 michael@paquier.xyz       263                 :        5408662 :     INSTR_TIME_ACCUM_DIFF(dst->shared_blk_read_time,
                                264                 :                :                           add->shared_blk_read_time, sub->shared_blk_read_time);
                                265                 :        5408662 :     INSTR_TIME_ACCUM_DIFF(dst->shared_blk_write_time,
                                266                 :                :                           add->shared_blk_write_time, sub->shared_blk_write_time);
                                267                 :        5408662 :     INSTR_TIME_ACCUM_DIFF(dst->local_blk_read_time,
                                268                 :                :                           add->local_blk_read_time, sub->local_blk_read_time);
                                269                 :        5408662 :     INSTR_TIME_ACCUM_DIFF(dst->local_blk_write_time,
                                270                 :                :                           add->local_blk_write_time, sub->local_blk_write_time);
 1437                           271                 :        5408662 :     INSTR_TIME_ACCUM_DIFF(dst->temp_blk_read_time,
                                272                 :                :                           add->temp_blk_read_time, sub->temp_blk_read_time);
                                273                 :        5408662 :     INSTR_TIME_ACCUM_DIFF(dst->temp_blk_write_time,
                                274                 :                :                           add->temp_blk_write_time, sub->temp_blk_write_time);
 5934 rhaas@postgresql.org      275                 :        5408662 : }
                                276                 :                : 
                                277                 :                : /* helper functions for WAL usage accumulation */
                                278                 :                : static void
 2171 akapila@postgresql.o      279                 :           1485 : WalUsageAdd(WalUsage *dst, WalUsage *add)
                                280                 :                : {
                                281                 :           1485 :     dst->wal_bytes += add->wal_bytes;
                                282                 :           1485 :     dst->wal_records += add->wal_records;
 2140                           283                 :           1485 :     dst->wal_fpi += add->wal_fpi;
  138 michael@paquier.xyz       284                 :GNC        1485 :     dst->wal_fpi_bytes += add->wal_fpi_bytes;
  391 michael@paquier.xyz       285                 :CBC        1485 :     dst->wal_buffers_full += add->wal_buffers_full;
 2171 akapila@postgresql.o      286                 :           1485 : }
                                287                 :                : 
                                288                 :                : void
                                289                 :         128235 : WalUsageAccumDiff(WalUsage *dst, const WalUsage *add, const WalUsage *sub)
                                290                 :                : {
                                291                 :         128235 :     dst->wal_bytes += add->wal_bytes - sub->wal_bytes;
                                292                 :         128235 :     dst->wal_records += add->wal_records - sub->wal_records;
 2140                           293                 :         128235 :     dst->wal_fpi += add->wal_fpi - sub->wal_fpi;
  138 michael@paquier.xyz       294                 :GNC      128235 :     dst->wal_fpi_bytes += add->wal_fpi_bytes - sub->wal_fpi_bytes;
  391 michael@paquier.xyz       295                 :CBC      128235 :     dst->wal_buffers_full += add->wal_buffers_full - sub->wal_buffers_full;
 2171 akapila@postgresql.o      296                 :         128235 : }
        

Generated by: LCOV version 2.4-beta