mirror of
https://git.postgresql.org/git/postgresql.git
synced 2025-02-23 19:39:53 +08:00
Refactor some code related to transaction-level statistics for relations
This commit refactors find_tabstat_entry() so as transaction counters
for inserted, updated and deleted tuples are included in the result
returned. If a shared entry is found for a relation, its result is now
a copy of the PgStat_TableStatus entry retrieved from shared memory.
This idea has been proposed by Andres Freund.
While on it, the following SQL functions, used in system views, are
refactored with macros, in the same spirit as 83a1a1b566
, reducing the
amount of code:
- pg_stat_get_xact_tuples_deleted()
- pg_stat_get_xact_tuples_inserted()
- pg_stat_get_xact_tuples_updated()
There is now only one caller of find_tabstat_entry() in the tree.
Author: Bertrand Drouvot
Discussion: https://postgr.es/m/b9e1f543-ee93-8168-d530-d961708ad9d3@gmail.com
This commit is contained in:
parent
06be01eb26
commit
bf01e1ba96
@ -478,20 +478,52 @@ pgstat_fetch_stat_tabentry_ext(bool shared, Oid reloid)
|
||||
* Find any existing PgStat_TableStatus entry for rel_id in the current
|
||||
* database. If not found, try finding from shared tables.
|
||||
*
|
||||
* If no entry found, return NULL, don't create a new one
|
||||
* If an entry is found, copy it and increment the copy's counters with their
|
||||
* subtransaction counterparts, then return the copy. The caller may need to
|
||||
* pfree() the copy.
|
||||
*
|
||||
* If no entry found, return NULL, don't create a new one.
|
||||
*/
|
||||
PgStat_TableStatus *
|
||||
find_tabstat_entry(Oid rel_id)
|
||||
{
|
||||
PgStat_EntryRef *entry_ref;
|
||||
PgStat_TableXactStatus *trans;
|
||||
PgStat_TableStatus *tabentry = NULL;
|
||||
PgStat_TableStatus *tablestatus = NULL;
|
||||
|
||||
entry_ref = pgstat_fetch_pending_entry(PGSTAT_KIND_RELATION, MyDatabaseId, rel_id);
|
||||
if (!entry_ref)
|
||||
{
|
||||
entry_ref = pgstat_fetch_pending_entry(PGSTAT_KIND_RELATION, InvalidOid, rel_id);
|
||||
if (!entry_ref)
|
||||
return tablestatus;
|
||||
}
|
||||
|
||||
if (entry_ref)
|
||||
return entry_ref->pending;
|
||||
return NULL;
|
||||
tabentry = (PgStat_TableStatus *) entry_ref->pending;
|
||||
tablestatus = palloc(sizeof(PgStat_TableStatus));
|
||||
*tablestatus = *tabentry;
|
||||
|
||||
/*
|
||||
* Reset tablestatus->trans in the copy of PgStat_TableStatus as it may
|
||||
* point to a shared memory area. Its data is saved below, so removing it
|
||||
* does not matter.
|
||||
*/
|
||||
tablestatus->trans = NULL;
|
||||
|
||||
/*
|
||||
* Live subtransaction counts are not included yet. This is not a hot
|
||||
* code path so reconcile tuples_inserted, tuples_updated and
|
||||
* tuples_deleted even if the caller may not be interested in this data.
|
||||
*/
|
||||
for (trans = tabentry->trans; trans != NULL; trans = trans->upper)
|
||||
{
|
||||
tablestatus->counts.tuples_inserted += trans->tuples_inserted;
|
||||
tablestatus->counts.tuples_updated += trans->tuples_updated;
|
||||
tablestatus->counts.tuples_deleted += trans->tuples_deleted;
|
||||
}
|
||||
|
||||
return tablestatus;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1588,68 +1588,14 @@ PG_STAT_GET_XACT_RELENTRY_INT64(blocks_fetched)
|
||||
/* pg_stat_get_xact_blocks_hit */
|
||||
PG_STAT_GET_XACT_RELENTRY_INT64(blocks_hit)
|
||||
|
||||
Datum
|
||||
pg_stat_get_xact_tuples_inserted(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Oid relid = PG_GETARG_OID(0);
|
||||
int64 result;
|
||||
PgStat_TableStatus *tabentry;
|
||||
PgStat_TableXactStatus *trans;
|
||||
/* pg_stat_get_xact_tuples_inserted */
|
||||
PG_STAT_GET_XACT_RELENTRY_INT64(tuples_inserted)
|
||||
|
||||
if ((tabentry = find_tabstat_entry(relid)) == NULL)
|
||||
result = 0;
|
||||
else
|
||||
{
|
||||
result = tabentry->counts.tuples_inserted;
|
||||
/* live subtransactions' counts aren't in tuples_inserted yet */
|
||||
for (trans = tabentry->trans; trans != NULL; trans = trans->upper)
|
||||
result += trans->tuples_inserted;
|
||||
}
|
||||
/* pg_stat_get_xact_tuples_updated */
|
||||
PG_STAT_GET_XACT_RELENTRY_INT64(tuples_updated)
|
||||
|
||||
PG_RETURN_INT64(result);
|
||||
}
|
||||
|
||||
Datum
|
||||
pg_stat_get_xact_tuples_updated(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Oid relid = PG_GETARG_OID(0);
|
||||
int64 result;
|
||||
PgStat_TableStatus *tabentry;
|
||||
PgStat_TableXactStatus *trans;
|
||||
|
||||
if ((tabentry = find_tabstat_entry(relid)) == NULL)
|
||||
result = 0;
|
||||
else
|
||||
{
|
||||
result = tabentry->counts.tuples_updated;
|
||||
/* live subtransactions' counts aren't in tuples_updated yet */
|
||||
for (trans = tabentry->trans; trans != NULL; trans = trans->upper)
|
||||
result += trans->tuples_updated;
|
||||
}
|
||||
|
||||
PG_RETURN_INT64(result);
|
||||
}
|
||||
|
||||
Datum
|
||||
pg_stat_get_xact_tuples_deleted(PG_FUNCTION_ARGS)
|
||||
{
|
||||
Oid relid = PG_GETARG_OID(0);
|
||||
int64 result;
|
||||
PgStat_TableStatus *tabentry;
|
||||
PgStat_TableXactStatus *trans;
|
||||
|
||||
if ((tabentry = find_tabstat_entry(relid)) == NULL)
|
||||
result = 0;
|
||||
else
|
||||
{
|
||||
result = tabentry->counts.tuples_deleted;
|
||||
/* live subtransactions' counts aren't in tuples_deleted yet */
|
||||
for (trans = tabentry->trans; trans != NULL; trans = trans->upper)
|
||||
result += trans->tuples_deleted;
|
||||
}
|
||||
|
||||
PG_RETURN_INT64(result);
|
||||
}
|
||||
/* pg_stat_get_xact_tuples_deleted */
|
||||
PG_STAT_GET_XACT_RELENTRY_INT64(tuples_deleted)
|
||||
|
||||
Datum
|
||||
pg_stat_get_xact_function_calls(PG_FUNCTION_ARGS)
|
||||
|
Loading…
Reference in New Issue
Block a user