Skip to content

Commit bf01e1b

Browse files
committed
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 83a1a1b, 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
1 parent 06be01e commit bf01e1b

File tree

2 files changed

+42
-64
lines changed

2 files changed

+42
-64
lines changed

src/backend/utils/activity/pgstat_relation.c

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -478,20 +478,52 @@ pgstat_fetch_stat_tabentry_ext(bool shared, Oid reloid)
478478
* Find any existing PgStat_TableStatus entry for rel_id in the current
479479
* database. If not found, try finding from shared tables.
480480
*
481-
* If no entry found, return NULL, don't create a new one
481+
* If an entry is found, copy it and increment the copy's counters with their
482+
* subtransaction counterparts, then return the copy. The caller may need to
483+
* pfree() the copy.
484+
*
485+
* If no entry found, return NULL, don't create a new one.
482486
*/
483487
PgStat_TableStatus *
484488
find_tabstat_entry(Oid rel_id)
485489
{
486490
PgStat_EntryRef *entry_ref;
491+
PgStat_TableXactStatus *trans;
492+
PgStat_TableStatus *tabentry = NULL;
493+
PgStat_TableStatus *tablestatus = NULL;
487494

488495
entry_ref = pgstat_fetch_pending_entry(PGSTAT_KIND_RELATION, MyDatabaseId, rel_id);
489496
if (!entry_ref)
497+
{
490498
entry_ref = pgstat_fetch_pending_entry(PGSTAT_KIND_RELATION, InvalidOid, rel_id);
499+
if (!entry_ref)
500+
return tablestatus;
501+
}
502+
503+
tabentry = (PgStat_TableStatus *) entry_ref->pending;
504+
tablestatus = palloc(sizeof(PgStat_TableStatus));
505+
*tablestatus = *tabentry;
506+
507+
/*
508+
* Reset tablestatus->trans in the copy of PgStat_TableStatus as it may
509+
* point to a shared memory area. Its data is saved below, so removing it
510+
* does not matter.
511+
*/
512+
tablestatus->trans = NULL;
513+
514+
/*
515+
* Live subtransaction counts are not included yet. This is not a hot
516+
* code path so reconcile tuples_inserted, tuples_updated and
517+
* tuples_deleted even if the caller may not be interested in this data.
518+
*/
519+
for (trans = tabentry->trans; trans != NULL; trans = trans->upper)
520+
{
521+
tablestatus->counts.tuples_inserted += trans->tuples_inserted;
522+
tablestatus->counts.tuples_updated += trans->tuples_updated;
523+
tablestatus->counts.tuples_deleted += trans->tuples_deleted;
524+
}
491525

492-
if (entry_ref)
493-
return entry_ref->pending;
494-
return NULL;
526+
return tablestatus;
495527
}
496528

497529
/*

src/backend/utils/adt/pgstatfuncs.c

Lines changed: 6 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -1588,68 +1588,14 @@ PG_STAT_GET_XACT_RELENTRY_INT64(blocks_fetched)
15881588
/* pg_stat_get_xact_blocks_hit */
15891589
PG_STAT_GET_XACT_RELENTRY_INT64(blocks_hit)
15901590

1591-
Datum
1592-
pg_stat_get_xact_tuples_inserted(PG_FUNCTION_ARGS)
1593-
{
1594-
Oid relid = PG_GETARG_OID(0);
1595-
int64 result;
1596-
PgStat_TableStatus *tabentry;
1597-
PgStat_TableXactStatus *trans;
1591+
/* pg_stat_get_xact_tuples_inserted */
1592+
PG_STAT_GET_XACT_RELENTRY_INT64(tuples_inserted)
15981593

1599-
if ((tabentry = find_tabstat_entry(relid)) == NULL)
1600-
result = 0;
1601-
else
1602-
{
1603-
result = tabentry->counts.tuples_inserted;
1604-
/* live subtransactions' counts aren't in tuples_inserted yet */
1605-
for (trans = tabentry->trans; trans != NULL; trans = trans->upper)
1606-
result += trans->tuples_inserted;
1607-
}
1594+
/* pg_stat_get_xact_tuples_updated */
1595+
PG_STAT_GET_XACT_RELENTRY_INT64(tuples_updated)
16081596

1609-
PG_RETURN_INT64(result);
1610-
}
1611-
1612-
Datum
1613-
pg_stat_get_xact_tuples_updated(PG_FUNCTION_ARGS)
1614-
{
1615-
Oid relid = PG_GETARG_OID(0);
1616-
int64 result;
1617-
PgStat_TableStatus *tabentry;
1618-
PgStat_TableXactStatus *trans;
1619-
1620-
if ((tabentry = find_tabstat_entry(relid)) == NULL)
1621-
result = 0;
1622-
else
1623-
{
1624-
result = tabentry->counts.tuples_updated;
1625-
/* live subtransactions' counts aren't in tuples_updated yet */
1626-
for (trans = tabentry->trans; trans != NULL; trans = trans->upper)
1627-
result += trans->tuples_updated;
1628-
}
1629-
1630-
PG_RETURN_INT64(result);
1631-
}
1632-
1633-
Datum
1634-
pg_stat_get_xact_tuples_deleted(PG_FUNCTION_ARGS)
1635-
{
1636-
Oid relid = PG_GETARG_OID(0);
1637-
int64 result;
1638-
PgStat_TableStatus *tabentry;
1639-
PgStat_TableXactStatus *trans;
1640-
1641-
if ((tabentry = find_tabstat_entry(relid)) == NULL)
1642-
result = 0;
1643-
else
1644-
{
1645-
result = tabentry->counts.tuples_deleted;
1646-
/* live subtransactions' counts aren't in tuples_deleted yet */
1647-
for (trans = tabentry->trans; trans != NULL; trans = trans->upper)
1648-
result += trans->tuples_deleted;
1649-
}
1650-
1651-
PG_RETURN_INT64(result);
1652-
}
1597+
/* pg_stat_get_xact_tuples_deleted */
1598+
PG_STAT_GET_XACT_RELENTRY_INT64(tuples_deleted)
16531599

16541600
Datum
16551601
pg_stat_get_xact_function_calls(PG_FUNCTION_ARGS)

0 commit comments

Comments
 (0)