using <literal>InjectionPointDetach</literal>.
</para>
- <para>
- An example can be found in
- <filename>src/test/modules/injection_points</filename> in the PostgreSQL
- source tree.
- </para>
-
<para>
Enabling injection points requires
<option>--enable-injection-points</option> with
OBJS = \
$(WIN32RES) \
injection_points.o \
- injection_stats.o \
- injection_stats_fixed.o \
regress_injection.o
EXTENSION = injection_points
DATA = injection_points--1.0.sql
reindex-concurrently-upsert-on-constraint \
reindex-concurrently-upsert-partitioned
-TAP_TESTS = 1
-
# The injection points are cluster-wide, so disable installcheck
NO_INSTALLCHECK = 1
AS 'MODULE_PATHNAME', 'injection_points_list'
LANGUAGE C STRICT VOLATILE PARALLEL RESTRICTED;
---
--- injection_points_stats_numcalls()
---
--- Reports statistics, if any, related to the given injection point.
---
-CREATE FUNCTION injection_points_stats_numcalls(IN point_name TEXT)
-RETURNS bigint
-AS 'MODULE_PATHNAME', 'injection_points_stats_numcalls'
-LANGUAGE C STRICT;
-
---
--- injection_points_stats_count()
---
--- Return the number of entries stored in the pgstats hash table.
---
-CREATE FUNCTION injection_points_stats_count()
-RETURNS bigint
-AS 'MODULE_PATHNAME', 'injection_points_stats_count'
-LANGUAGE C STRICT;
-
---
--- injection_points_stats_drop()
---
--- Drop all statistics of injection points.
---
-CREATE FUNCTION injection_points_stats_drop()
-RETURNS void
-AS 'MODULE_PATHNAME', 'injection_points_stats_drop'
-LANGUAGE C STRICT;
-
---
--- injection_points_stats_fixed()
---
--- Reports fixed-numbered statistics for injection points.
-CREATE FUNCTION injection_points_stats_fixed(OUT numattach int8,
- OUT numdetach int8,
- OUT numrun int8,
- OUT numcached int8,
- OUT numloaded int8)
-RETURNS record
-AS 'MODULE_PATHNAME', 'injection_points_stats_fixed'
-LANGUAGE C STRICT;
-
--
-- regress_injection.c functions
--
#include "fmgr.h"
#include "funcapi.h"
-#include "injection_stats.h"
#include "miscadmin.h"
#include "nodes/pg_list.h"
#include "nodes/value.h"
/* track if injection points attached in this process are linked to it */
static bool injection_point_local = false;
-/*
- * GUC variable
- *
- * This GUC is useful to control if statistics should be enabled or not
- * during a test with injection points, like for example if a test relies
- * on a callback run in a critical section where no allocation should happen.
- */
-bool inj_stats_enabled = false;
-
/* Shared memory init callbacks */
static shmem_request_hook_type prev_shmem_request_hook = NULL;
static shmem_startup_hook_type prev_shmem_startup_hook = NULL;
char *name = strVal(lfirst(lc));
(void) InjectionPointDetach(name);
-
- /* Remove stats entry */
- pgstat_drop_inj(name);
}
}
if (!injection_point_allowed(condition))
return;
- pgstat_report_inj(name);
-
if (argstr)
elog(ERROR, "error triggered for injection point %s (%s)",
name, argstr);
if (!injection_point_allowed(condition))
return;
- pgstat_report_inj(name);
-
if (argstr)
elog(NOTICE, "notice triggered for injection point %s (%s)",
name, argstr);
if (!injection_point_allowed(condition))
return;
- pgstat_report_inj(name);
-
/*
* Use the injection point name for this custom wait event. Note that
* this custom wait event name is not released, but we don't care much for
condition.pid = MyProcPid;
}
- pgstat_report_inj_fixed(1, 0, 0, 0, 0);
InjectionPointAttach(name, "injection_points", function, &condition,
sizeof(InjectionPointCondition));
MemoryContextSwitchTo(oldctx);
}
- /* Add entry for stats */
- pgstat_create_inj(name);
-
PG_RETURN_VOID();
}
private_data_size = VARSIZE_ANY_EXHDR(private_data);
}
- pgstat_report_inj_fixed(1, 0, 0, 0, 0);
if (private_data != NULL)
InjectionPointAttach(name, lib_name, function, VARDATA_ANY(private_data),
private_data_size);
if (inj_state == NULL)
injection_init_shmem();
- pgstat_report_inj_fixed(0, 0, 0, 0, 1);
INJECTION_POINT_LOAD(name);
PG_RETURN_VOID();
if (!PG_ARGISNULL(1))
arg = text_to_cstring(PG_GETARG_TEXT_PP(1));
- pgstat_report_inj_fixed(0, 0, 1, 0, 0);
INJECTION_POINT(name, arg);
PG_RETURN_VOID();
if (!PG_ARGISNULL(1))
arg = text_to_cstring(PG_GETARG_TEXT_PP(1));
- pgstat_report_inj_fixed(0, 0, 0, 1, 0);
INJECTION_POINT_CACHED(name, arg);
PG_RETURN_VOID();
{
char *name = text_to_cstring(PG_GETARG_TEXT_PP(0));
- pgstat_report_inj_fixed(0, 1, 0, 0, 0);
if (!InjectionPointDetach(name))
elog(ERROR, "could not detach injection point \"%s\"", name);
MemoryContextSwitchTo(oldctx);
}
- /* Remove stats entry */
- pgstat_drop_inj(name);
-
PG_RETURN_VOID();
}
#undef NUM_INJECTION_POINTS_LIST
}
-
void
_PG_init(void)
{
if (!process_shared_preload_libraries_in_progress)
return;
- DefineCustomBoolVariable("injection_points.stats",
- "Enables statistics for injection points.",
- NULL,
- &inj_stats_enabled,
- false,
- PGC_POSTMASTER,
- 0,
- NULL,
- NULL,
- NULL);
-
- MarkGUCPrefixReserved("injection_points");
-
/* Shared memory initialization */
prev_shmem_request_hook = shmem_request_hook;
shmem_request_hook = injection_shmem_request;
prev_shmem_startup_hook = shmem_startup_hook;
shmem_startup_hook = injection_shmem_startup;
-
- pgstat_register_inj();
- pgstat_register_inj_fixed();
}
+++ /dev/null
-/*--------------------------------------------------------------------------
- *
- * injection_stats.c
- * Code for statistics of injection points.
- *
- * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- * IDENTIFICATION
- * src/test/modules/injection_points/injection_stats.c
- *
- * -------------------------------------------------------------------------
- */
-
-#include "postgres.h"
-
-#include "fmgr.h"
-
-#include "common/hashfn.h"
-#include "injection_stats.h"
-#include "pgstat.h"
-#include "utils/builtins.h"
-#include "utils/pgstat_internal.h"
-
-/* Structures for statistics of injection points */
-typedef struct PgStat_StatInjEntry
-{
- PgStat_Counter numcalls; /* number of times point has been run */
-} PgStat_StatInjEntry;
-
-typedef struct PgStatShared_InjectionPoint
-{
- PgStatShared_Common header;
- PgStat_StatInjEntry stats;
-} PgStatShared_InjectionPoint;
-
-static bool injection_stats_flush_cb(PgStat_EntryRef *entry_ref, bool nowait);
-
-static const PgStat_KindInfo injection_stats = {
- .name = "injection_points",
- .fixed_amount = false, /* Bounded by the number of points */
- .write_to_file = true,
- .track_entry_count = true,
-
- /* Injection points are system-wide */
- .accessed_across_databases = true,
-
- .shared_size = sizeof(PgStatShared_InjectionPoint),
- .shared_data_off = offsetof(PgStatShared_InjectionPoint, stats),
- .shared_data_len = sizeof(((PgStatShared_InjectionPoint *) 0)->stats),
- .pending_size = sizeof(PgStat_StatInjEntry),
- .flush_pending_cb = injection_stats_flush_cb,
-};
-
-/*
- * Compute stats entry idx from point name with an 8-byte hash.
- */
-#define PGSTAT_INJ_IDX(name) hash_bytes_extended((const unsigned char *) name, strlen(name), 0)
-
-/*
- * Kind ID reserved for statistics of injection points.
- */
-#define PGSTAT_KIND_INJECTION 25
-
-/* Track if stats are loaded */
-static bool inj_stats_loaded = false;
-
-/*
- * Callback for stats handling
- */
-static bool
-injection_stats_flush_cb(PgStat_EntryRef *entry_ref, bool nowait)
-{
- PgStat_StatInjEntry *localent;
- PgStatShared_InjectionPoint *shfuncent;
-
- localent = (PgStat_StatInjEntry *) entry_ref->pending;
- shfuncent = (PgStatShared_InjectionPoint *) entry_ref->shared_stats;
-
- if (!pgstat_lock_entry(entry_ref, nowait))
- return false;
-
- shfuncent->stats.numcalls += localent->numcalls;
-
- pgstat_unlock_entry(entry_ref);
-
- return true;
-}
-
-/*
- * Support function for the SQL-callable pgstat* functions. Returns
- * a pointer to the injection point statistics struct.
- */
-static PgStat_StatInjEntry *
-pgstat_fetch_stat_injentry(const char *name)
-{
- PgStat_StatInjEntry *entry = NULL;
-
- if (!inj_stats_loaded || !inj_stats_enabled)
- return NULL;
-
- /* Compile the lookup key as a hash of the point name */
- entry = (PgStat_StatInjEntry *) pgstat_fetch_entry(PGSTAT_KIND_INJECTION,
- InvalidOid,
- PGSTAT_INJ_IDX(name));
- return entry;
-}
-
-/*
- * Workhorse to do the registration work, called in _PG_init().
- */
-void
-pgstat_register_inj(void)
-{
- pgstat_register_kind(PGSTAT_KIND_INJECTION, &injection_stats);
-
- /* mark stats as loaded */
- inj_stats_loaded = true;
-}
-
-/*
- * Report injection point creation.
- */
-void
-pgstat_create_inj(const char *name)
-{
- PgStat_EntryRef *entry_ref;
- PgStatShared_InjectionPoint *shstatent;
-
- /* leave if disabled */
- if (!inj_stats_loaded || !inj_stats_enabled)
- return;
-
- entry_ref = pgstat_prep_pending_entry(PGSTAT_KIND_INJECTION, InvalidOid,
- PGSTAT_INJ_IDX(name), NULL);
-
- shstatent = (PgStatShared_InjectionPoint *) entry_ref->shared_stats;
-
- /* initialize shared memory data */
- memset(&shstatent->stats, 0, sizeof(shstatent->stats));
-}
-
-/*
- * Report injection point drop.
- */
-void
-pgstat_drop_inj(const char *name)
-{
- /* leave if disabled */
- if (!inj_stats_loaded || !inj_stats_enabled)
- return;
-
- if (!pgstat_drop_entry(PGSTAT_KIND_INJECTION, InvalidOid,
- PGSTAT_INJ_IDX(name)))
- pgstat_request_entry_refs_gc();
-}
-
-/*
- * Report statistics for injection point.
- *
- * This is simple because the set of stats to report currently is simple:
- * track the number of times a point has been run.
- */
-void
-pgstat_report_inj(const char *name)
-{
- PgStat_EntryRef *entry_ref;
- PgStat_StatInjEntry *pending;
-
- /* leave if disabled */
- if (!inj_stats_loaded || !inj_stats_enabled)
- return;
-
- entry_ref = pgstat_prep_pending_entry(PGSTAT_KIND_INJECTION, InvalidOid,
- PGSTAT_INJ_IDX(name), NULL);
-
- pending = (PgStat_StatInjEntry *) entry_ref->pending;
-
- /* Update the injection point pending statistics */
- pending->numcalls++;
-}
-
-/*
- * SQL function returning the number of times an injection point
- * has been called.
- */
-PG_FUNCTION_INFO_V1(injection_points_stats_numcalls);
-Datum
-injection_points_stats_numcalls(PG_FUNCTION_ARGS)
-{
- char *name = text_to_cstring(PG_GETARG_TEXT_PP(0));
- PgStat_StatInjEntry *entry = pgstat_fetch_stat_injentry(name);
-
- if (entry == NULL)
- PG_RETURN_NULL();
-
- PG_RETURN_INT64(entry->numcalls);
-}
-
-/*
- * SQL function returning the number of entries allocated for injection
- * points in the shared hashtable of pgstats.
- */
-PG_FUNCTION_INFO_V1(injection_points_stats_count);
-Datum
-injection_points_stats_count(PG_FUNCTION_ARGS)
-{
- PG_RETURN_INT64(pgstat_get_entry_count(PGSTAT_KIND_INJECTION));
-}
-
-/* Only used by injection_points_stats_drop() */
-static bool
-match_inj_entries(PgStatShared_HashEntry *entry, Datum match_data)
-{
- return entry->key.kind == PGSTAT_KIND_INJECTION;
-}
-
-/*
- * SQL function that drops all injection point statistics.
- */
-PG_FUNCTION_INFO_V1(injection_points_stats_drop);
-Datum
-injection_points_stats_drop(PG_FUNCTION_ARGS)
-{
- pgstat_drop_matching_entries(match_inj_entries, 0);
-
- PG_RETURN_VOID();
-}
+++ /dev/null
-/*--------------------------------------------------------------------------
- *
- * injection_stats.h
- * Definitions for statistics of injection points.
- *
- * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- * IDENTIFICATION
- * src/test/modules/injection_points/injection_stats.h
- *
- * -------------------------------------------------------------------------
- */
-
-#ifndef INJECTION_STATS
-#define INJECTION_STATS
-
-/* GUC variable */
-extern bool inj_stats_enabled;
-
-/* injection_stats.c */
-extern void pgstat_register_inj(void);
-extern void pgstat_create_inj(const char *name);
-extern void pgstat_drop_inj(const char *name);
-extern void pgstat_report_inj(const char *name);
-
-/* injection_stats_fixed.c */
-extern void pgstat_register_inj_fixed(void);
-extern void pgstat_report_inj_fixed(uint32 numattach,
- uint32 numdetach,
- uint32 numrun,
- uint32 numcached,
- uint32 numloaded);
-
-#endif
+++ /dev/null
-/*--------------------------------------------------------------------------
- *
- * injection_stats_fixed.c
- * Code for fixed-numbered statistics of injection points.
- *
- * Portions Copyright (c) 1996-2025, PostgreSQL Global Development Group
- * Portions Copyright (c) 1994, Regents of the University of California
- *
- * IDENTIFICATION
- * src/test/modules/injection_points/injection_stats_fixed.c
- *
- * -------------------------------------------------------------------------
- */
-
-#include "postgres.h"
-
-#include "fmgr.h"
-
-#include "access/htup_details.h"
-#include "common/hashfn.h"
-#include "funcapi.h"
-#include "injection_stats.h"
-#include "pgstat.h"
-#include "utils/builtins.h"
-#include "utils/pgstat_internal.h"
-
-/* Structures for statistics of injection points, fixed-size */
-typedef struct PgStat_StatInjFixedEntry
-{
- PgStat_Counter numattach; /* number of points attached */
- PgStat_Counter numdetach; /* number of points detached */
- PgStat_Counter numrun; /* number of points run */
- PgStat_Counter numcached; /* number of points cached */
- PgStat_Counter numloaded; /* number of points loaded */
- TimestampTz stat_reset_timestamp;
-} PgStat_StatInjFixedEntry;
-
-typedef struct PgStatShared_InjectionPointFixed
-{
- LWLock lock; /* protects all the counters */
- uint32 changecount;
- PgStat_StatInjFixedEntry stats;
- PgStat_StatInjFixedEntry reset_offset;
-} PgStatShared_InjectionPointFixed;
-
-/* Callbacks for fixed-numbered stats */
-static void injection_stats_fixed_init_shmem_cb(void *stats);
-static void injection_stats_fixed_reset_all_cb(TimestampTz ts);
-static void injection_stats_fixed_snapshot_cb(void);
-
-static const PgStat_KindInfo injection_stats_fixed = {
- .name = "injection_points_fixed",
- .fixed_amount = true,
- .write_to_file = true,
-
- .shared_size = sizeof(PgStat_StatInjFixedEntry),
- .shared_data_off = offsetof(PgStatShared_InjectionPointFixed, stats),
- .shared_data_len = sizeof(((PgStatShared_InjectionPointFixed *) 0)->stats),
-
- .init_shmem_cb = injection_stats_fixed_init_shmem_cb,
- .reset_all_cb = injection_stats_fixed_reset_all_cb,
- .snapshot_cb = injection_stats_fixed_snapshot_cb,
-};
-
-/*
- * Kind ID reserved for statistics of injection points.
- */
-#define PGSTAT_KIND_INJECTION_FIXED 26
-
-/* Track if fixed-numbered stats are loaded */
-static bool inj_fixed_loaded = false;
-
-static void
-injection_stats_fixed_init_shmem_cb(void *stats)
-{
- PgStatShared_InjectionPointFixed *stats_shmem =
- (PgStatShared_InjectionPointFixed *) stats;
-
- LWLockInitialize(&stats_shmem->lock, LWTRANCHE_PGSTATS_DATA);
-}
-
-static void
-injection_stats_fixed_reset_all_cb(TimestampTz ts)
-{
- PgStatShared_InjectionPointFixed *stats_shmem =
- pgstat_get_custom_shmem_data(PGSTAT_KIND_INJECTION_FIXED);
-
- LWLockAcquire(&stats_shmem->lock, LW_EXCLUSIVE);
- pgstat_copy_changecounted_stats(&stats_shmem->reset_offset,
- &stats_shmem->stats,
- sizeof(stats_shmem->stats),
- &stats_shmem->changecount);
- stats_shmem->stats.stat_reset_timestamp = ts;
- LWLockRelease(&stats_shmem->lock);
-}
-
-static void
-injection_stats_fixed_snapshot_cb(void)
-{
- PgStatShared_InjectionPointFixed *stats_shmem =
- pgstat_get_custom_shmem_data(PGSTAT_KIND_INJECTION_FIXED);
- PgStat_StatInjFixedEntry *stat_snap =
- pgstat_get_custom_snapshot_data(PGSTAT_KIND_INJECTION_FIXED);
- PgStat_StatInjFixedEntry *reset_offset = &stats_shmem->reset_offset;
- PgStat_StatInjFixedEntry reset;
-
- pgstat_copy_changecounted_stats(stat_snap,
- &stats_shmem->stats,
- sizeof(stats_shmem->stats),
- &stats_shmem->changecount);
-
- LWLockAcquire(&stats_shmem->lock, LW_SHARED);
- memcpy(&reset, reset_offset, sizeof(stats_shmem->stats));
- LWLockRelease(&stats_shmem->lock);
-
- /* compensate by reset offsets */
-#define FIXED_COMP(fld) stat_snap->fld -= reset.fld;
- FIXED_COMP(numattach);
- FIXED_COMP(numdetach);
- FIXED_COMP(numrun);
- FIXED_COMP(numcached);
- FIXED_COMP(numloaded);
-#undef FIXED_COMP
-}
-
-/*
- * Workhorse to do the registration work, called in _PG_init().
- */
-void
-pgstat_register_inj_fixed(void)
-{
- pgstat_register_kind(PGSTAT_KIND_INJECTION_FIXED, &injection_stats_fixed);
-
- /* mark stats as loaded */
- inj_fixed_loaded = true;
-}
-
-/*
- * Report fixed number of statistics for an injection point.
- */
-void
-pgstat_report_inj_fixed(uint32 numattach,
- uint32 numdetach,
- uint32 numrun,
- uint32 numcached,
- uint32 numloaded)
-{
- PgStatShared_InjectionPointFixed *stats_shmem;
-
- /* leave if disabled */
- if (!inj_fixed_loaded || !inj_stats_enabled)
- return;
-
- stats_shmem = pgstat_get_custom_shmem_data(PGSTAT_KIND_INJECTION_FIXED);
-
- LWLockAcquire(&stats_shmem->lock, LW_EXCLUSIVE);
-
- pgstat_begin_changecount_write(&stats_shmem->changecount);
- stats_shmem->stats.numattach += numattach;
- stats_shmem->stats.numdetach += numdetach;
- stats_shmem->stats.numrun += numrun;
- stats_shmem->stats.numcached += numcached;
- stats_shmem->stats.numloaded += numloaded;
- pgstat_end_changecount_write(&stats_shmem->changecount);
-
- LWLockRelease(&stats_shmem->lock);
-}
-
-/*
- * SQL function returning fixed-numbered statistics for injection points.
- */
-PG_FUNCTION_INFO_V1(injection_points_stats_fixed);
-Datum
-injection_points_stats_fixed(PG_FUNCTION_ARGS)
-{
- TupleDesc tupdesc;
- Datum values[5] = {0};
- bool nulls[5] = {0};
- PgStat_StatInjFixedEntry *stats;
-
- if (!inj_fixed_loaded || !inj_stats_enabled)
- PG_RETURN_NULL();
-
- pgstat_snapshot_fixed(PGSTAT_KIND_INJECTION_FIXED);
- stats = pgstat_get_custom_snapshot_data(PGSTAT_KIND_INJECTION_FIXED);
-
- /* Initialise attributes information in the tuple descriptor */
- tupdesc = CreateTemplateTupleDesc(5);
- TupleDescInitEntry(tupdesc, (AttrNumber) 1, "numattach",
- INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 2, "numdetach",
- INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 3, "numrun",
- INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 4, "numcached",
- INT8OID, -1, 0);
- TupleDescInitEntry(tupdesc, (AttrNumber) 5, "numloaded",
- INT8OID, -1, 0);
- BlessTupleDesc(tupdesc);
-
- values[0] = Int64GetDatum(stats->numattach);
- values[1] = Int64GetDatum(stats->numdetach);
- values[2] = Int64GetDatum(stats->numrun);
- values[3] = Int64GetDatum(stats->numcached);
- values[4] = Int64GetDatum(stats->numloaded);
- nulls[0] = false;
- nulls[1] = false;
- nulls[2] = false;
- nulls[3] = false;
- nulls[4] = false;
-
- /* Returns the record as Datum */
- PG_RETURN_DATUM(HeapTupleGetDatum(heap_form_tuple(tupdesc, values, nulls)));
-}
injection_points_sources = files(
'injection_points.c',
- 'injection_stats.c',
- 'injection_stats_fixed.c',
'regress_injection.c',
)
# Some tests wait for all snapshots, so avoid parallel execution
'runningcheck-parallel': false,
},
- 'tap': {
- 'env': {
- 'enable_injection_points': get_option('injection_points') ? 'yes' : 'no',
- },
- 'tests': [
- 't/001_stats.pl',
- ],
- # The injection points are cluster-wide, so disable installcheck
- 'runningcheck': false,
- },
}
+++ /dev/null
-
-# Copyright (c) 2024-2025, PostgreSQL Global Development Group
-
-# Tests for Custom Cumulative Statistics.
-
-use strict;
-use warnings FATAL => 'all';
-use locale;
-
-use PostgreSQL::Test::Cluster;
-use PostgreSQL::Test::Utils;
-use Test::More;
-
-# Test persistency of statistics generated for injection points.
-if ($ENV{enable_injection_points} ne 'yes')
-{
- plan skip_all => 'Injection points not supported by this build';
-}
-
-# Node initialization
-my $node = PostgreSQL::Test::Cluster->new('master');
-$node->init;
-$node->append_conf(
- 'postgresql.conf', qq(
-shared_preload_libraries = 'injection_points'
-injection_points.stats = true
-));
-$node->start;
-$node->safe_psql('postgres', 'CREATE EXTENSION injection_points;');
-
-# This should count for two calls.
-$node->safe_psql('postgres',
- "SELECT injection_points_attach('stats-notice', 'notice');");
-$node->safe_psql('postgres', "SELECT injection_points_run('stats-notice');");
-$node->safe_psql('postgres', "SELECT injection_points_run('stats-notice');");
-my $numcalls = $node->safe_psql('postgres',
- "SELECT injection_points_stats_numcalls('stats-notice');");
-is($numcalls, '2', 'number of stats calls');
-my $entrycount =
- $node->safe_psql('postgres', "SELECT injection_points_stats_count();");
-is($entrycount, '1', 'number of entries');
-my $fixedstats = $node->safe_psql('postgres',
- "SELECT * FROM injection_points_stats_fixed();");
-is($fixedstats, '1|0|2|0|0', 'fixed stats after some calls');
-
-# Loading and caching.
-$node->safe_psql(
- 'postgres', "
-SELECT injection_points_load('stats-notice');
-SELECT injection_points_cached('stats-notice');
-");
-$fixedstats = $node->safe_psql('postgres',
- "SELECT * FROM injection_points_stats_fixed();");
-is($fixedstats, '1|0|2|1|1', 'fixed stats after loading and caching');
-
-# Restart the node cleanly, stats should still be around.
-$node->restart;
-$numcalls = $node->safe_psql('postgres',
- "SELECT injection_points_stats_numcalls('stats-notice');");
-is($numcalls, '3', 'number of stats after clean restart');
-$entrycount =
- $node->safe_psql('postgres', "SELECT injection_points_stats_count();");
-is($entrycount, '1', 'number of entries after clean restart');
-$fixedstats = $node->safe_psql('postgres',
- "SELECT * FROM injection_points_stats_fixed();");
-is($fixedstats, '1|0|2|1|1', 'fixed stats after clean restart');
-
-# On crash the stats are gone.
-$node->stop('immediate');
-$node->start;
-$numcalls = $node->safe_psql('postgres',
- "SELECT injection_points_stats_numcalls('stats-notice');");
-is($numcalls, '', 'number of stats after crash');
-$entrycount =
- $node->safe_psql('postgres', "SELECT injection_points_stats_count();");
-is($entrycount, '0', 'number of entries after crash');
-$fixedstats = $node->safe_psql('postgres',
- "SELECT * FROM injection_points_stats_fixed();");
-is($fixedstats, '0|0|0|0|0', 'fixed stats after crash');
-
-# On drop all stats are gone
-$node->safe_psql('postgres',
- "SELECT injection_points_attach('stats-notice', 'notice');");
-$node->safe_psql('postgres', "SELECT injection_points_run('stats-notice');");
-$node->safe_psql('postgres', "SELECT injection_points_run('stats-notice');");
-$numcalls = $node->safe_psql('postgres',
- "SELECT injection_points_stats_numcalls('stats-notice');");
-is($numcalls, '2', 'number of stats calls');
-$node->safe_psql('postgres', "SELECT injection_points_stats_drop();");
-$numcalls = $node->safe_psql('postgres',
- "SELECT injection_points_stats_numcalls('stats-notice');");
-is($numcalls, '', 'no stats after drop via SQL function');
-$entrycount =
- $node->safe_psql('postgres', "SELECT injection_points_stats_count();");
-is($entrycount, '0', 'number of entries after drop via SQL function');
-
-# Stop the server, disable the module, then restart. The server
-# should be able to come up.
-$node->stop;
-$node->adjust_conf('postgresql.conf', 'shared_preload_libraries', "''");
-$node->start;
-
-done_testing();
PgStatShared_Function
PgStatShared_HashEntry
PgStatShared_IO
-PgStatShared_InjectionPoint
-PgStatShared_InjectionPointFixed
PgStatShared_Relation
PgStatShared_ReplSlot
PgStatShared_SLRU
PgStat_SnapshotEntry
PgStat_StatDBEntry
PgStat_StatFuncEntry
-PgStat_StatInjEntry
-PgStat_StatInjFixedEntry
PgStat_StatReplSlotEntry
PgStat_StatSubEntry
PgStat_StatTabEntry