appendStringInfo(buf, "; %sdropped stats:", label);
for (i = 0; i < ndropped; i++)
{
- appendStringInfo(buf, " %d/%u/%u",
+ uint64 objid =
+ ((uint64) dropped_stats[i].objid_hi) << 32 | dropped_stats[i].objid_lo;
+
+ appendStringInfo(buf, " %d/%u/%llu",
dropped_stats[i].kind,
dropped_stats[i].dboid,
- dropped_stats[i].objoid);
+ (unsigned long long) objid);
}
}
}
REVOKE EXECUTE ON FUNCTION pg_stat_reset_replication_slot(text) FROM public;
-REVOKE EXECUTE ON FUNCTION pg_stat_have_stats(text, oid, oid) FROM public;
+REVOKE EXECUTE ON FUNCTION pg_stat_have_stats(text, oid, int8) FROM public;
REVOKE EXECUTE ON FUNCTION pg_stat_reset_subscription_stats(oid) FROM public;
* GRANT system.
*/
void
-pgstat_reset(PgStat_Kind kind, Oid dboid, Oid objoid)
+pgstat_reset(PgStat_Kind kind, Oid dboid, uint64 objid)
{
const PgStat_KindInfo *kind_info = pgstat_get_kind_info(kind);
TimestampTz ts = GetCurrentTimestamp();
Assert(!pgstat_get_kind_info(kind)->fixed_amount);
/* reset the "single counter" */
- pgstat_reset_entry(kind, dboid, objoid, ts);
+ pgstat_reset_entry(kind, dboid, objid, ts);
if (!kind_info->accessed_across_databases)
pgstat_reset_database_timestamp(dboid, ts);
}
void *
-pgstat_fetch_entry(PgStat_Kind kind, Oid dboid, Oid objoid)
+pgstat_fetch_entry(PgStat_Kind kind, Oid dboid, uint64 objid)
{
PgStat_HashKey key;
PgStat_EntryRef *entry_ref;
key.kind = kind;
key.dboid = dboid;
- key.objoid = objoid;
+ key.objid = objid;
/* if we need to build a full snapshot, do so */
if (pgstat_fetch_consistency == PGSTAT_FETCH_CONSISTENCY_SNAPSHOT)
pgStatLocal.snapshot.mode = pgstat_fetch_consistency;
- entry_ref = pgstat_get_entry_ref(kind, dboid, objoid, false, NULL);
+ entry_ref = pgstat_get_entry_ref(kind, dboid, objid, false, NULL);
if (entry_ref == NULL || entry_ref->shared_entry->dropped)
{
}
bool
-pgstat_have_entry(PgStat_Kind kind, Oid dboid, Oid objoid)
+pgstat_have_entry(PgStat_Kind kind, Oid dboid, uint64 objid)
{
/* fixed-numbered stats always exist */
if (pgstat_get_kind_info(kind)->fixed_amount)
return true;
- return pgstat_get_entry_ref(kind, dboid, objoid, false, NULL) != NULL;
+ return pgstat_get_entry_ref(kind, dboid, objid, false, NULL) != NULL;
}
/*
* created, false otherwise.
*/
PgStat_EntryRef *
-pgstat_prep_pending_entry(PgStat_Kind kind, Oid dboid, Oid objoid, bool *created_entry)
+pgstat_prep_pending_entry(PgStat_Kind kind, Oid dboid, uint64 objid, bool *created_entry)
{
PgStat_EntryRef *entry_ref;
ALLOCSET_SMALL_SIZES);
}
- entry_ref = pgstat_get_entry_ref(kind, dboid, objoid,
+ entry_ref = pgstat_get_entry_ref(kind, dboid, objid,
true, created_entry);
if (entry_ref->pending == NULL)
* that it shouldn't be needed.
*/
PgStat_EntryRef *
-pgstat_fetch_pending_entry(PgStat_Kind kind, Oid dboid, Oid objoid)
+pgstat_fetch_pending_entry(PgStat_Kind kind, Oid dboid, uint64 objid)
{
PgStat_EntryRef *entry_ref;
- entry_ref = pgstat_get_entry_ref(kind, dboid, objoid, false, NULL);
+ entry_ref = pgstat_get_entry_ref(kind, dboid, objid, false, NULL);
if (entry_ref == NULL || entry_ref->pending == NULL)
return NULL;
*/
if (!pgstat_is_kind_valid(ps->key.kind))
{
- elog(WARNING, "found unknown stats entry %u/%u/%u",
- ps->key.kind, ps->key.dboid, ps->key.objoid);
+ elog(WARNING, "found unknown stats entry %u/%u/%llu",
+ ps->key.kind, ps->key.dboid,
+ (unsigned long long) ps->key.objid);
continue;
}
if (!pgstat_is_kind_valid(key.kind))
{
- elog(WARNING, "invalid stats kind for entry %u/%u/%u of type %c",
- key.kind, key.dboid, key.objoid, t);
+ elog(WARNING, "invalid stats kind for entry %u/%u/%llu of type %c",
+ key.kind, key.dboid,
+ (unsigned long long) key.objid, t);
goto error;
}
}
if (found)
{
dshash_release_lock(pgStatLocal.shared_hash, p);
- elog(WARNING, "found duplicate stats entry %u/%u/%u of type %c",
- key.kind, key.dboid, key.objoid, t);
+ elog(WARNING, "found duplicate stats entry %u/%u/%llu of type %c",
+ key.kind, key.dboid,
+ (unsigned long long) key.objid, t);
goto error;
}
pgstat_get_entry_data(key.kind, header),
pgstat_get_entry_len(key.kind)))
{
- elog(WARNING, "could not read data for entry %u/%u/%u of type %c",
- key.kind, key.dboid, key.objoid, t);
+ elog(WARNING, "could not read data for entry %u/%u/%llu of type %c",
+ key.kind, key.dboid,
+ (unsigned long long) key.objid, t);
goto error;
}
* isn't allowed to change at this point, we can assume that a slot exists
* at the offset.
*/
- if (!ReplicationSlotName(key->objoid, name))
- elog(ERROR, "could not find name for replication slot index %u",
- key->objoid);
+ if (!ReplicationSlotName(key->objid, name))
+ elog(ERROR, "could not find name for replication slot index %llu",
+ (unsigned long long) key->objid);
}
bool
key->kind = PGSTAT_KIND_REPLSLOT;
key->dboid = InvalidOid;
- key->objoid = idx;
+ key->objid = idx;
return true;
}
* if the entry is newly created, false otherwise.
*/
PgStat_EntryRef *
-pgstat_get_entry_ref(PgStat_Kind kind, Oid dboid, Oid objoid, bool create,
+pgstat_get_entry_ref(PgStat_Kind kind, Oid dboid, uint64 objid, bool create,
bool *created_entry)
{
- PgStat_HashKey key = {.kind = kind,.dboid = dboid,.objoid = objoid};
+ PgStat_HashKey key = {.kind = kind,.dboid = dboid,.objid = objid};
PgStatShared_HashEntry *shhashent;
PgStatShared_Common *shheader = NULL;
PgStat_EntryRef *entry_ref;
* Helper function to fetch and lock shared stats.
*/
PgStat_EntryRef *
-pgstat_get_entry_ref_locked(PgStat_Kind kind, Oid dboid, Oid objoid,
+pgstat_get_entry_ref_locked(PgStat_Kind kind, Oid dboid, uint64 objid,
bool nowait)
{
PgStat_EntryRef *entry_ref;
/* find shared table stats entry corresponding to the local entry */
- entry_ref = pgstat_get_entry_ref(kind, dboid, objoid, true, NULL);
+ entry_ref = pgstat_get_entry_ref(kind, dboid, objid, true, NULL);
/* lock the shared entry to protect the content, skip if failed */
if (!pgstat_lock_entry(entry_ref, nowait))
*/
if (shent->dropped)
elog(ERROR,
- "trying to drop stats entry already dropped: kind=%s dboid=%u objoid=%u refcount=%u",
+ "trying to drop stats entry already dropped: kind=%s dboid=%u objid=%llu refcount=%u",
pgstat_get_kind_info(shent->key.kind)->name,
- shent->key.dboid, shent->key.objoid,
+ shent->key.dboid,
+ (unsigned long long) shent->key.objid,
pg_atomic_read_u32(&shent->refcount));
shent->dropped = true;
* pgstat_gc_entry_refs().
*/
bool
-pgstat_drop_entry(PgStat_Kind kind, Oid dboid, Oid objoid)
+pgstat_drop_entry(PgStat_Kind kind, Oid dboid, uint64 objid)
{
- PgStat_HashKey key = {.kind = kind,.dboid = dboid,.objoid = objoid};
+ PgStat_HashKey key = {.kind = kind,.dboid = dboid,.objid = objid};
PgStatShared_HashEntry *shent;
bool freed = true;
* Reset one variable-numbered stats entry.
*/
void
-pgstat_reset_entry(PgStat_Kind kind, Oid dboid, Oid objoid, TimestampTz ts)
+pgstat_reset_entry(PgStat_Kind kind, Oid dboid, uint64 objid, TimestampTz ts)
{
PgStat_EntryRef *entry_ref;
Assert(!pgstat_get_kind_info(kind)->fixed_amount);
- entry_ref = pgstat_get_entry_ref(kind, dboid, objoid, false, NULL);
+ entry_ref = pgstat_get_entry_ref(kind, dboid, objid, false, NULL);
if (!entry_ref || entry_ref->shared_entry->dropped)
return;
PgStat_PendingDroppedStatsItem *pending =
dclist_container(PgStat_PendingDroppedStatsItem, node, iter.cur);
xl_xact_stats_item *it = &pending->item;
+ uint64 objid = ((uint64) it->objid_hi) << 32 | it->objid_lo;
if (isCommit && !pending->is_create)
{
* Transaction that dropped an object committed. Drop the stats
* too.
*/
- if (!pgstat_drop_entry(it->kind, it->dboid, it->objoid))
+ if (!pgstat_drop_entry(it->kind, it->dboid, objid))
not_freed_count++;
}
else if (!isCommit && pending->is_create)
* Transaction that created an object aborted. Drop the stats
* associated with the object.
*/
- if (!pgstat_drop_entry(it->kind, it->dboid, it->objoid))
+ if (!pgstat_drop_entry(it->kind, it->dboid, objid))
not_freed_count++;
}
PgStat_PendingDroppedStatsItem *pending =
dclist_container(PgStat_PendingDroppedStatsItem, node, iter.cur);
xl_xact_stats_item *it = &pending->item;
+ uint64 objid = ((uint64) it->objid_hi) << 32 | it->objid_lo;
dclist_delete_from(&xact_state->pending_drops, &pending->node);
* Subtransaction creating a new stats object aborted. Drop the
* stats object.
*/
- if (!pgstat_drop_entry(it->kind, it->dboid, it->objoid))
+ if (!pgstat_drop_entry(it->kind, it->dboid, objid))
not_freed_count++;
pfree(pending);
}
for (int i = 0; i < ndrops; i++)
{
xl_xact_stats_item *it = &items[i];
+ uint64 objid = ((uint64) it->objid_hi) << 32 | it->objid_lo;
- if (!pgstat_drop_entry(it->kind, it->dboid, it->objoid))
+ if (!pgstat_drop_entry(it->kind, it->dboid, objid))
not_freed_count++;
}
}
static void
-create_drop_transactional_internal(PgStat_Kind kind, Oid dboid, Oid objoid, bool is_create)
+create_drop_transactional_internal(PgStat_Kind kind, Oid dboid, uint64 objid, bool is_create)
{
int nest_level = GetCurrentTransactionNestLevel();
PgStat_SubXactStatus *xact_state;
drop->is_create = is_create;
drop->item.kind = kind;
drop->item.dboid = dboid;
- drop->item.objoid = objoid;
+ drop->item.objid_lo = (uint32) objid;
+ drop->item.objid_hi = (uint32) (objid >> 32);
dclist_push_tail(&xact_state->pending_drops, &drop->node);
}
* dropped.
*/
void
-pgstat_create_transactional(PgStat_Kind kind, Oid dboid, Oid objoid)
+pgstat_create_transactional(PgStat_Kind kind, Oid dboid, uint64 objid)
{
- if (pgstat_get_entry_ref(kind, dboid, objoid, false, NULL))
+ if (pgstat_get_entry_ref(kind, dboid, objid, false, NULL))
{
ereport(WARNING,
- errmsg("resetting existing statistics for kind %s, db=%u, oid=%u",
- (pgstat_get_kind_info(kind))->name, dboid, objoid));
+ errmsg("resetting existing statistics for kind %s, db=%u, oid=%llu",
+ (pgstat_get_kind_info(kind))->name, dboid,
+ (unsigned long long) objid));
- pgstat_reset(kind, dboid, objoid);
+ pgstat_reset(kind, dboid, objid);
}
- create_drop_transactional_internal(kind, dboid, objoid, /* create */ true);
+ create_drop_transactional_internal(kind, dboid, objid, /* create */ true);
}
/*
* alive.
*/
void
-pgstat_drop_transactional(PgStat_Kind kind, Oid dboid, Oid objoid)
+pgstat_drop_transactional(PgStat_Kind kind, Oid dboid, uint64 objid)
{
- create_drop_transactional_internal(kind, dboid, objoid, /* create */ false);
+ create_drop_transactional_internal(kind, dboid, objid, /* create */ false);
}
{
char *stats_type = text_to_cstring(PG_GETARG_TEXT_P(0));
Oid dboid = PG_GETARG_OID(1);
- Oid objoid = PG_GETARG_OID(2);
+ uint64 objid = PG_GETARG_INT64(2);
PgStat_Kind kind = pgstat_get_kind_from_str(stats_type);
- PG_RETURN_BOOL(pgstat_have_entry(kind, dboid, objoid));
+ PG_RETURN_BOOL(pgstat_have_entry(kind, dboid, objid));
}
{
int kind;
Oid dboid;
- Oid objoid;
+
+ /*
+ * This stores the value of PgStat_HashKey.objid as two uint32 as all the
+ * fields of xl_xact_xinfo should be multiples of size(int).
+ */
+ uint32 objid_lo;
+ uint32 objid_hi;
} xl_xact_stats_item;
typedef struct xl_xact_stats_items
/*
* Each page of XLOG file has a header like this:
*/
-#define XLOG_PAGE_MAGIC 0xD116 /* can be used as WAL version indicator */
+#define XLOG_PAGE_MAGIC 0xD117 /* can be used as WAL version indicator */
typedef struct XLogPageHeaderData
{
*/
/* yyyymmddN */
-#define CATALOG_VERSION_NO 202409172
+#define CATALOG_VERSION_NO 202409181
#endif
{ oid => '6230', descr => 'statistics: check if a stats object exists',
proname => 'pg_stat_have_stats', provolatile => 'v', proparallel => 'r',
- prorettype => 'bool', proargtypes => 'text oid oid',
+ prorettype => 'bool', proargtypes => 'text oid int8',
prosrc => 'pg_stat_have_stats' },
{ oid => '6231', descr => 'statistics: information about subscription stats',
* ------------------------------------------------------------
*/
-#define PGSTAT_FILE_FORMAT_ID 0x01A5BCAE
+#define PGSTAT_FILE_FORMAT_ID 0x01A5BCAF
typedef struct PgStat_ArchiverStats
{
extern void pgstat_force_next_flush(void);
extern void pgstat_reset_counters(void);
-extern void pgstat_reset(PgStat_Kind kind, Oid dboid, Oid objoid);
+extern void pgstat_reset(PgStat_Kind kind, Oid dboid, uint64 objid);
extern void pgstat_reset_of_kind(PgStat_Kind kind);
/* stats accessors */
/* helpers */
extern PgStat_Kind pgstat_get_kind_from_str(char *kind_str);
-extern bool pgstat_have_entry(PgStat_Kind kind, Oid dboid, Oid objoid);
+extern bool pgstat_have_entry(PgStat_Kind kind, Oid dboid, uint64 objid);
/*
{
PgStat_Kind kind; /* statistics entry kind */
Oid dboid; /* database ID. InvalidOid for shared objects. */
- Oid objoid; /* object ID, either table or function. */
+ uint64 objid; /* object ID (table, function, etc.), or
+ * identifier. */
} PgStat_HashKey;
/*
#endif
extern void pgstat_delete_pending_entry(PgStat_EntryRef *entry_ref);
-extern PgStat_EntryRef *pgstat_prep_pending_entry(PgStat_Kind kind, Oid dboid, Oid objoid, bool *created_entry);
-extern PgStat_EntryRef *pgstat_fetch_pending_entry(PgStat_Kind kind, Oid dboid, Oid objoid);
+extern PgStat_EntryRef *pgstat_prep_pending_entry(PgStat_Kind kind, Oid dboid,
+ uint64 objid,
+ bool *created_entry);
+extern PgStat_EntryRef *pgstat_fetch_pending_entry(PgStat_Kind kind,
+ Oid dboid, uint64 objid);
-extern void *pgstat_fetch_entry(PgStat_Kind kind, Oid dboid, Oid objoid);
+extern void *pgstat_fetch_entry(PgStat_Kind kind, Oid dboid, uint64 objid);
extern void pgstat_snapshot_fixed(PgStat_Kind kind);
extern void pgstat_attach_shmem(void);
extern void pgstat_detach_shmem(void);
-extern PgStat_EntryRef *pgstat_get_entry_ref(PgStat_Kind kind, Oid dboid, Oid objoid,
+extern PgStat_EntryRef *pgstat_get_entry_ref(PgStat_Kind kind, Oid dboid, uint64 objid,
bool create, bool *created_entry);
extern bool pgstat_lock_entry(PgStat_EntryRef *entry_ref, bool nowait);
extern bool pgstat_lock_entry_shared(PgStat_EntryRef *entry_ref, bool nowait);
extern void pgstat_unlock_entry(PgStat_EntryRef *entry_ref);
-extern bool pgstat_drop_entry(PgStat_Kind kind, Oid dboid, Oid objoid);
+extern bool pgstat_drop_entry(PgStat_Kind kind, Oid dboid, uint64 objid);
extern void pgstat_drop_all_entries(void);
-extern PgStat_EntryRef *pgstat_get_entry_ref_locked(PgStat_Kind kind, Oid dboid, Oid objoid,
+extern PgStat_EntryRef *pgstat_get_entry_ref_locked(PgStat_Kind kind, Oid dboid, uint64 objid,
bool nowait);
-extern void pgstat_reset_entry(PgStat_Kind kind, Oid dboid, Oid objoid, TimestampTz ts);
+extern void pgstat_reset_entry(PgStat_Kind kind, Oid dboid, uint64 objid, TimestampTz ts);
extern void pgstat_reset_entries_of_kind(PgStat_Kind kind, TimestampTz ts);
extern void pgstat_reset_matching_entries(bool (*do_reset) (PgStatShared_HashEntry *, Datum),
Datum match_data,
*/
extern PgStat_SubXactStatus *pgstat_get_xact_stack_level(int nest_level);
-extern void pgstat_drop_transactional(PgStat_Kind kind, Oid dboid, Oid objoid);
-extern void pgstat_create_transactional(PgStat_Kind kind, Oid dboid, Oid objoid);
+extern void pgstat_drop_transactional(PgStat_Kind kind, Oid dboid, uint64 objid);
+extern void pgstat_create_transactional(PgStat_Kind kind, Oid dboid, uint64 objid);
/*
};
/*
- * Compute stats entry idx from point name with a 4-byte hash.
+ * Compute stats entry idx from point name with an 8-byte hash.
*/
-#define PGSTAT_INJ_IDX(name) hash_bytes((const unsigned char *) name, strlen(name))
+#define PGSTAT_INJ_IDX(name) hash_bytes_extended((const unsigned char *) name, strlen(name), 0)
/*
* Kind ID reserved for statistics of injection points.
sub have_stats
{
- my ($kind, $dboid, $objoid) = @_;
+ my ($kind, $dboid, $objid) = @_;
return $node->safe_psql($connect_db,
- "SELECT pg_stat_have_stats('$kind', $dboid, $objoid)");
+ "SELECT pg_stat_have_stats('$kind', $dboid, $objid)");
}
sub overwrite_file
-- unknown stats kinds error out
SELECT pg_stat_have_stats('zaphod', 0, 0);
ERROR: invalid statistics kind: "zaphod"
--- db stats have objoid 0
+-- db stats have objid 0
SELECT pg_stat_have_stats('database', :dboid, 1);
pg_stat_have_stats
--------------------
SELECT pg_stat_have_stats('bgwriter', 0, 0);
-- unknown stats kinds error out
SELECT pg_stat_have_stats('zaphod', 0, 0);
--- db stats have objoid 0
+-- db stats have objid 0
SELECT pg_stat_have_stats('database', :dboid, 1);
SELECT pg_stat_have_stats('database', :dboid, 0);