Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1tcGCO-00GVcC-Fp for pgsql-hackers@arkaria.postgresql.org; Mon, 27 Jan 2025 03:54:09 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.94.2) (envelope-from ) id 1tcGCM-0095Hp-0o for pgsql-hackers@arkaria.postgresql.org; Mon, 27 Jan 2025 03:54:06 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1tcGCK-0095Ha-IF for pgsql-hackers@lists.postgresql.org; Mon, 27 Jan 2025 03:54:05 +0000 Received: from fhigh-b3-smtp.messagingengine.com ([202.12.124.154]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1tcGCG-001hxA-0p for pgsql-hackers@lists.postgresql.org; Mon, 27 Jan 2025 03:54:03 +0000 Received: from phl-compute-02.internal (phl-compute-02.phl.internal [10.202.2.42]) by mailfhigh.stl.internal (Postfix) with ESMTP id 41F8D2540113; Sun, 26 Jan 2025 22:53:58 -0500 (EST) Received: from phl-mailfrontend-02 ([10.202.2.163]) by phl-compute-02.internal (MEProxy); Sun, 26 Jan 2025 22:53:58 -0500 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=paquier.xyz; h= cc:cc:content-type:content-type:date:date:from:from:in-reply-to :in-reply-to:message-id:mime-version:references:reply-to:subject :subject:to:to; s=fm3; t=1737950038; x=1738036438; bh=URMTX+6Lgn yzHFlg9dWShf+JnuxgIidLzlia1ouB7E8=; b=cxxE84iWwVG1ezQqpECjLxCvaM V5iQZVX2gknzm5xhCTIS1eCmt5Tp5YWSAL1uNWD8QbQT1zyOwvpPEarkEBJubFUW eKS0jw3kfHINfPrPJhC9AW+K5A8D0wm2ID2EKzjEnNjYbR9Bex7Q8KRJG7eDFEAg 630UoswVtpidMgacruLr9uyfrWwuU/Oz1mwdn6UGTSWWv910znv/xQsjMnIC4OAN auA1Ia8jpZU4wt2qqWyqoE8ZfzpG3bal0hK1gpwBrqtfyWCkv2QrbUiYxpnh7zVC wyJbJ7P+4pqDIki57ZsHQ5mu7hpbv1ghGpnIks6Y2NBtW5UWIgfxNp9JlJEg== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-type:content-type:date:date :feedback-id:feedback-id:from:from:in-reply-to:in-reply-to :message-id:mime-version:references:reply-to:subject:subject:to :to:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s=fm3; t= 1737950038; x=1738036438; bh=URMTX+6LgnyzHFlg9dWShf+JnuxgIidLzli a1ouB7E8=; b=Zbto7EEozcoim7RJTISogkS9bFKn86gbO7BAPXZiAnd/HY9oZYs Y+gjTELm1iXhlGdWF3ICVpE8J1hoHITPipmiuDQ16e/LV+IBBEP9ToB6kLOh6e1d /vcPGb91h8FET6GKzuWUTSdXrEahAmxPcgvwiKfiMPBD01oAHgJYI9GGcKmYFyN0 WVFypBRTyUiXm5r6386lIvvAUhPLHyYOx6sG/jVhGVfQbuBOisvgLljDXthjdzVC r0YoW3SPzpmN4Wskhk5xt+Ij4CXw3HyQc6i2wlJj2rdf0K6LmGy7RSfK8n8KsNwQ fNVKcPJKjngCqgMmlCNhElYw4fqzNJoojFg== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefuddrudejgedguddvudehucetufdoteggodetrf dotffvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdggtfgfnhhsuhgsshgtrhhisggv pdfurfetoffkrfgpnffqhgenuceurghilhhouhhtmecufedttdenucesvcftvggtihhpih gvnhhtshculddquddttddmnegfrhhlucfvnfffucdljedtmdenucfjughrpeffhffvvefu kfhfgggtuggjsehgtderredttddvnecuhfhrohhmpefoihgthhgrvghlucfrrghquhhivg hruceomhhitghhrggvlhesphgrqhhuihgvrhdrgiihiieqnecuggftrfgrthhtvghrnhep teelieefudffhffhtdetleeggeegfffhkeeuveetiefgudduvedutefggeeivdejnecuve hluhhsthgvrhfuihiivgeptdenucfrrghrrghmpehmrghilhhfrhhomhepmhhitghhrggv lhesphgrqhhuihgvrhdrgiihiidpnhgspghrtghpthhtohepgedpmhhouggvpehsmhhtph houhhtpdhrtghpthhtoheplhhukhgrshesfhhithhtlhdrtghomhdprhgtphhtthhopehs rghmihhmshgvihhhsehgmhgrihhlrdgtohhmpdhrtghpthhtohepphhgshhqlhdqhhgrtg hkvghrsheslhhishhtshdrphhoshhtghhrvghsqhhlrdhorhhgpdhrtghpthhtohepmhgr rhhkohesphhgrghnrghlhiiivgdrtghomh X-ME-Proxy: Feedback-ID: i0fe9450f:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Sun, 26 Jan 2025 22:53:55 -0500 (EST) Date: Mon, 27 Jan 2025 12:53:36 +0900 From: Michael Paquier To: Lukas Fittl Cc: Sami Imseih , PostgreSQL Hackers , Marko M Subject: Re: [PATCH] Optionally record Plan IDs to track plan changes for a query Message-ID: References: MIME-Version: 1.0 Content-Type: multipart/signed; micalg=pgp-sha512; protocol="application/pgp-signature"; boundary="qbYvi8k4MAxxhY8+" Content-Disposition: inline In-Reply-To: List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --qbYvi8k4MAxxhY8+ Content-Type: multipart/mixed; boundary="/MfvyD7Cq4Lo0QAQ" Content-Disposition: inline --/MfvyD7Cq4Lo0QAQ Content-Type: text/plain; charset=us-ascii Content-Disposition: inline On Fri, Jan 24, 2025 at 01:59:00AM -0800, Lukas Fittl wrote: > Overall, I also do wonder if it wouldn't be better to have a callback > mechanism in the shared memory stats, so stats plugins can do extra work > when an entry gets dropped (like freeing the DSA memory for the plan text), > vs having to add all this extra logic to do it. Not sure about this part yet. I have looked at 0002 to begin with something and it is really useful on its own. Stats kinds calling this routine don't need to worry about the internals of dropping local references or doing a seqscan on the shared hash table. However, what you have sent lacks in flexibility to me, and the duplication with pgstat_drop_all_entries is annoying. This had better be merged in a single routine. Attached is an updated version that adds an optional "do_drop" callback in the function that does the seqscan on the dshash, to decide if an entry should be gone or not. This follows the same model as the "reset" part, where stats kind can push the matching function they want to work on the individual entries. We could add a pgstat_drop_entries_of_kind(), but I'm not feeling that this is strongly necessary with the basic interface in place. The changes in the module injection_points were not good. The SQL function was named "reset" but that's a drop operation. What do you think? -- Michael --/MfvyD7Cq4Lo0QAQ Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="v3-0002-Add-pgstat_drop_matching_entries.patch" Content-Transfer-Encoding: quoted-printable =46rom 48412fcfb708eb990136321686681e961626aabe Mon Sep 17 00:00:00 2001 =46rom: Lukas Fittl Date: Thu, 2 Jan 2025 10:46:30 -0800 Subject: [PATCH v3] Add pgstat_drop_matching_entries() This allows users of the cumulative statistics systems to drop all entries based on the decisions of a matching function, similar to how pgstat_reset_matching_entries() works. --- src/include/utils/pgstat_internal.h | 2 ++ src/backend/utils/activity/pgstat_shmem.c | 31 ++++++++++++++++++- .../injection_points--1.0.sql | 10 ++++++ .../injection_points/injection_stats.c | 19 ++++++++++++ .../modules/injection_points/t/001_stats.pl | 13 ++++++++ 5 files changed, 74 insertions(+), 1 deletion(-) diff --git a/src/include/utils/pgstat_internal.h b/src/include/utils/pgstat= _internal.h index a3d39d2b725..06dcea3f0dc 100644 --- a/src/include/utils/pgstat_internal.h +++ b/src/include/utils/pgstat_internal.h @@ -718,6 +718,8 @@ extern bool pgstat_lock_entry_shared(PgStat_EntryRef *e= ntry_ref, bool nowait); extern void pgstat_unlock_entry(PgStat_EntryRef *entry_ref); extern bool pgstat_drop_entry(PgStat_Kind kind, Oid dboid, uint64 objid); extern void pgstat_drop_all_entries(void); +extern void pgstat_drop_matching_entries(bool (*do_drop) (PgStatShared_Has= hEntry *, Datum), + Datum match_data); 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, uint64 objid, = TimestampTz ts); diff --git a/src/backend/utils/activity/pgstat_shmem.c b/src/backend/utils/= activity/pgstat_shmem.c index 342586397d6..770d62425c5 100644 --- a/src/backend/utils/activity/pgstat_shmem.c +++ b/src/backend/utils/activity/pgstat_shmem.c @@ -993,19 +993,39 @@ pgstat_drop_entry(PgStat_Kind kind, Oid dboid, uint64= objid) return freed; } =20 +/* + * Scan through the shared hashtable of stats, dropping statistics if + * approved by the optional do_drop() function. + */ void -pgstat_drop_all_entries(void) +pgstat_drop_matching_entries(bool (*do_drop) (PgStatShared_HashEntry *, Da= tum), + Datum match_data) { dshash_seq_status hstat; PgStatShared_HashEntry *ps; uint64 not_freed_count =3D 0; =20 + /* entries are removed, take an exclusive lock */ dshash_seq_init(&hstat, pgStatLocal.shared_hash, true); while ((ps =3D dshash_seq_next(&hstat)) !=3D NULL) { if (ps->dropped) continue; =20 + if (do_drop !=3D NULL && !do_drop(ps, match_data)) + continue; + + /* delete local reference */ + if (pgStatEntryRefHash) + { + PgStat_EntryRefHashEntry *lohashent =3D + pgstat_entry_ref_hash_lookup(pgStatEntryRefHash, ps->key); + + if (lohashent) + pgstat_release_entry_ref(lohashent->key, lohashent->entry_ref, + true); + } + if (!pgstat_drop_entry_internal(ps, &hstat)) not_freed_count++; } @@ -1015,6 +1035,15 @@ pgstat_drop_all_entries(void) pgstat_request_entry_refs_gc(); } =20 +/* + * Scan through the shared hashtable of stats and drop all entries. + */ +void +pgstat_drop_all_entries(void) +{ + pgstat_drop_matching_entries(NULL, 0); +} + static void shared_stat_reset_contents(PgStat_Kind kind, PgStatShared_Common *header, TimestampTz ts) diff --git a/src/test/modules/injection_points/injection_points--1.0.sql b/= src/test/modules/injection_points/injection_points--1.0.sql index c445bf64e62..5d83f08811b 100644 --- a/src/test/modules/injection_points/injection_points--1.0.sql +++ b/src/test/modules/injection_points/injection_points--1.0.sql @@ -85,6 +85,16 @@ RETURNS bigint AS 'MODULE_PATHNAME', 'injection_points_stats_numcalls' LANGUAGE C STRICT; =20 +-- +-- 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() -- diff --git a/src/test/modules/injection_points/injection_stats.c b/src/test= /modules/injection_points/injection_stats.c index 5db62bca66f..14903c629e0 100644 --- a/src/test/modules/injection_points/injection_stats.c +++ b/src/test/modules/injection_points/injection_stats.c @@ -197,3 +197,22 @@ injection_points_stats_numcalls(PG_FUNCTION_ARGS) =20 PG_RETURN_INT64(entry->numcalls); } + +/* Only used by injection_points_stats_drop() */ +static bool +match_inj_entries(PgStatShared_HashEntry *entry, Datum match_data) +{ + return entry->key.kind =3D=3D 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(); +} diff --git a/src/test/modules/injection_points/t/001_stats.pl b/src/test/mo= dules/injection_points/t/001_stats.pl index d4539fe8727..25de5fc46fe 100644 --- a/src/test/modules/injection_points/t/001_stats.pl +++ b/src/test/modules/injection_points/t/001_stats.pl @@ -69,6 +69,19 @@ $fixedstats =3D $node->safe_psql('postgres', "SELECT * FROM injection_points_stats_fixed();"); is($fixedstats, '0|0|0|0|0', 'fixed stats after crash'); =20 +# 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 =3D $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 =3D $node->safe_psql('postgres', + "SELECT injection_points_stats_numcalls('stats-notice');"); +is($numcalls, '', 'no stats after drop via SQL function'); + # Stop the server, disable the module, then restart. The server # should be able to come up. $node->stop; --=20 2.47.2 --/MfvyD7Cq4Lo0QAQ-- --qbYvi8k4MAxxhY8+ Content-Type: application/pgp-signature; name="signature.asc" -----BEGIN PGP SIGNATURE----- iQIzBAABCgAdFiEEG72nH6vTowiyblFKnvQgOdbyQH0FAmeXA0AACgkQnvQgOdby QH3iLA//Q2/FZzaMLo//bTYkUAx34/+FMogEBh8yL+4BoC0GtMxRf9bl9eQc6DWA 9O5Y6/7KzJudL5sAtA1XZA/Lp0UQW4GODcb59KteqNWfPhJAeJkNDOVmsjHmmoju tBt8g/6Ugj5h5/7eFzV1iZe3wRskDA5+KDFvTVPkau344qftw1VCIM28IiUMVZIp eBMChrYOOwW/LWfjIj1JBluazL1YK+lyxf05OOpoW+sn+8VinrugvxML/jSWn+J3 17J4azkw2PmD8iYHkx+3hpjHlrKcGYJKFKL/uDq3eL/XQVUe+tkxnu2d6iMSKapJ oDgfkMgnqEDUDFh1bEc80rL0BrZ0eclpcCbLQcN6gCoBA32B/ai4VD92p7DlByWM BLs+ogln7KCqINu5n0nhUs//co6mlzNuI/t2BYaRTMIM+9F/ZTXoULjgGoV52RXj WcojugTaIc16LvrYyfuFSvnuNjN6vBSMJj7VhLf808lVJXdcMFcf+cX/z+bgLBuh HhjErzB3WNgYBZ/durVjObqdYkdNLezbwiCvijnQ1qDEzsfdBTsULmzDXdGAHWNc zl1fayy6Z1cSwjg9pegx4xF1X4+TkSjeEym3f3Snwc/j2LJOR4hjQphx5uxT9Cx2 RpA+99TJYRUKrvQob39cKeqUE/RPPE3T+n18RLDoeaf0n+06Ypc= =WpJb -----END PGP SIGNATURE----- --qbYvi8k4MAxxhY8+--