Hi,

On 2023-01-03 15:19:18 +0100, Drouvot, Bertrand wrote:
> diff --git a/src/backend/access/common/relation.c 
> b/src/backend/access/common/relation.c
> index 4017e175e3..fca166a063 100644
> --- a/src/backend/access/common/relation.c
> +++ b/src/backend/access/common/relation.c
> @@ -73,7 +73,10 @@ relation_open(Oid relationId, LOCKMODE lockmode)
>       if (RelationUsesLocalBuffers(r))
>               MyXactFlags |= XACT_FLAGS_ACCESSEDTEMPNAMESPACE;
>  
> -     pgstat_init_relation(r);
> +     if (r->rd_rel->relkind == RELKIND_INDEX)
> +             pgstat_init_index(r);
> +     else
> +             pgstat_init_table(r);
>  
>       return r;
>  }
> @@ -123,7 +126,10 @@ try_relation_open(Oid relationId, LOCKMODE lockmode)
>       if (RelationUsesLocalBuffers(r))
>               MyXactFlags |= XACT_FLAGS_ACCESSEDTEMPNAMESPACE;
>  
> -     pgstat_init_relation(r);
> +     if (r->rd_rel->relkind == RELKIND_INDEX)
> +             pgstat_init_index(r);
> +     else
> +             pgstat_init_table(r);
>  
>       return r;
>  }

Not this patch's fault, but the functions in relation.c have gotten duplicated
to an almost ridiculous degree :(


> diff --git a/src/backend/storage/buffer/bufmgr.c 
> b/src/backend/storage/buffer/bufmgr.c
> index 3fb38a25cf..98bb230b95 100644
> --- a/src/backend/storage/buffer/bufmgr.c
> +++ b/src/backend/storage/buffer/bufmgr.c
> @@ -776,11 +776,19 @@ ReadBufferExtended(Relation reln, ForkNumber forkNum, 
> BlockNumber blockNum,
>        * Read the buffer, and update pgstat counters to reflect a cache hit or
>        * miss.
>        */
> -     pgstat_count_buffer_read(reln);
> +     if (reln->rd_rel->relkind == RELKIND_INDEX)
> +             pgstat_count_index_buffer_read(reln);
> +     else
> +             pgstat_count_table_buffer_read(reln);
>       buf = ReadBuffer_common(RelationGetSmgr(reln), 
> reln->rd_rel->relpersistence,
>                                                       forkNum, blockNum, 
> mode, strategy, &hit);
>       if (hit)
> -             pgstat_count_buffer_hit(reln);
> +     {
> +             if (reln->rd_rel->relkind == RELKIND_INDEX)
> +                     pgstat_count_index_buffer_hit(reln);
> +             else
> +                     pgstat_count_table_buffer_hit(reln);
> +     }
>       return buf;
>  }

Not nice to have additional branches here :(.

I think going forward we should move buffer stats to a "per-relfilenode" stats
entry (which would allow to track writes too), then thiw branch would be
removed again.


> +/* -------------------------------------------------------------------------
> + *
> + * pgstat_index.c
> + *     Implementation of index statistics.

This is a fair bit of duplicated code. Perhaps it'd be worth keeping
pgstat_relation with code common to table/index stats?


> +bool
> +pgstat_index_flush_cb(PgStat_EntryRef *entry_ref, bool nowait)
> +{
> +     static const PgStat_IndexCounts all_zeroes;
> +     Oid                     dboid;
> +
> +     PgStat_IndexStatus *lstats; /* pending stats entry  */
> +     PgStatShared_Index *shrelcomstats;

What does "com" stand for in shrelcomstats?


> +     PgStat_StatIndEntry *indentry;  /* index entry of shared stats */
> +     PgStat_StatDBEntry *dbentry;    /* pending database entry */
> +
> +     dboid = entry_ref->shared_entry->key.dboid;
> +     lstats = (PgStat_IndexStatus *) entry_ref->pending;
> +     shrelcomstats = (PgStatShared_Index *) entry_ref->shared_stats;
> +
> +     /*
> +      * Ignore entries that didn't accumulate any actual counts, such as
> +      * indexes that were opened by the planner but not used.
> +      */
> +     if (memcmp(&lstats->i_counts, &all_zeroes,
> +                        sizeof(PgStat_IndexCounts)) == 0)
> +     {
> +             return true;
> +     }

I really need to propose pg_memiszero().



>  Datum
> -pg_stat_get_xact_numscans(PG_FUNCTION_ARGS)
> +pg_stat_get_tab_xact_numscans(PG_FUNCTION_ARGS)
>  {
>       Oid                     relid = PG_GETARG_OID(0);
>       int64           result;
> @@ -1360,17 +1413,32 @@ pg_stat_get_xact_numscans(PG_FUNCTION_ARGS)
>       PG_RETURN_INT64(result);
>  }
>  
> +Datum
> +pg_stat_get_ind_xact_numscans(PG_FUNCTION_ARGS)
> +{
> +     Oid                     relid = PG_GETARG_OID(0);
> +     int64           result;
> +     PgStat_IndexStatus *indentry;
> +
> +     if ((indentry = find_indstat_entry(relid)) == NULL)
> +             result = 0;
> +     else
> +             result = (int64) (indentry->i_counts.i_numscans);
> +
> +     PG_RETURN_INT64(result);
> +}

Why didn't all these get converted to the same macro based approach as the
!xact versions?


>  Datum
>  pg_stat_get_xact_tuples_returned(PG_FUNCTION_ARGS)
>  {
>       Oid                     relid = PG_GETARG_OID(0);
>       int64           result;
> -     PgStat_TableStatus *tabentry;
> +     PgStat_IndexStatus *indentry;
>  
> -     if ((tabentry = find_tabstat_entry(relid)) == NULL)
> +     if ((indentry = find_indstat_entry(relid)) == NULL)
>               result = 0;
>       else
> -             result = (int64) (tabentry->t_counts.t_tuples_returned);
> +             result = (int64) (indentry->i_counts.i_tuples_returned);
>  
>       PG_RETURN_INT64(result);
>  }

There's a bunch of changes like this, and I don't understand -
pg_stat_get_xact_tuples_returned() now looks at index stats, even though it
afaics continues to be used in pg_stat_xact_all_tables? Huh?


> +/* ----------
> + * PgStat_IndexStatus                        Per-index status within a 
> backend
> + *
> + * Many of the event counters are nontransactional, ie, we count events
> + * in committed and aborted transactions alike.  For these, we just count
> + * directly in the PgStat_IndexStatus.
> + * ----------
> + */

Which counters are transactional for indexes? None, no?

> diff --git a/src/test/recovery/t/029_stats_restart.pl 
> b/src/test/recovery/t/029_stats_restart.pl
> index 83d6647d32..8b0b597419 100644
> --- a/src/test/recovery/t/029_stats_restart.pl
> +++ b/src/test/recovery/t/029_stats_restart.pl
> @@ -43,8 +43,8 @@ my $sect = "initial";
>  is(have_stats('database', $dboid, 0), 't', "$sect: db stats do exist");
>  is(have_stats('function', $dboid, $funcoid),
>       't', "$sect: function stats do exist");
> -is(have_stats('relation', $dboid, $tableoid),
> -     't', "$sect: relation stats do exist");
> +is(have_stats('table', $dboid, $tableoid),
> +     't', "$sect: table stats do exist");

Think this should grow a test for an index too. There's not that much point in
the isolation case, because we don't have transactional stats, but here it
seems worth testing?

Greetings,

Andres Freund


Reply via email to