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.96) (envelope-from ) id 1wAbxJ-0008KF-1k for pgsql-hackers@arkaria.postgresql.org; Wed, 08 Apr 2026 23:05:06 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1wAbxG-002Uiy-2F for pgsql-hackers@arkaria.postgresql.org; Wed, 08 Apr 2026 23:05:03 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96) (envelope-from ) id 1wAbxF-002Uiq-2l for pgsql-hackers@lists.postgresql.org; Wed, 08 Apr 2026 23:05:03 +0000 Received: from fout-a5-smtp.messagingengine.com ([103.168.172.148]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.98.2) (envelope-from ) id 1wAbxE-000000004Ik-177Q for pgsql-hackers@postgresql.org; Wed, 08 Apr 2026 23:05:01 +0000 Received: from phl-compute-06.internal (phl-compute-06.internal [10.202.2.46]) by mailfout.phl.internal (Postfix) with ESMTP id B9E07EC01AF; Wed, 8 Apr 2026 19:04:59 -0400 (EDT) Received: from phl-frontend-04 ([10.202.2.163]) by phl-compute-06.internal (MEProxy); Wed, 08 Apr 2026 19:04:59 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=anarazel.de; h= cc:cc:content-transfer-encoding:content-type:content-type:date :date:from:from:in-reply-to:message-id:mime-version:reply-to :subject:subject:to:to; s=fm2; t=1775689499; x=1775775899; bh=Tx +ltTVWiQ/CFru5pNuUL1Ftemqyz5vxM9GxBB0UPjM=; b=RWt/YlMAjcc3tsIXtI a6nBW/e698CCMTW2qRILqkGl2r0kwMWG6bBl9xH/BhnLLUpnu4NZt3w024EJ8LYa jpdfIECENp7sWkWtRXkEvX4eZ4DX6YqJmErasZIqJq66GH0GkRQACFHSQfFa315R hBYU4caiBPSKcYUmkRJJiz6X9KkwYRCu+lkyOADFF5M1oecm+zWwrL8b8QiJ6fYb ymUzGufI+jK3CirRAL5SA/+sLiRUY4DsGtgDgJx4g1fBaJd9NPqJMPchRLUy5AC5 JdlbronIPhqok3jo1jKSF2FXwnXWKTE7S13oIoaMKtYTAVxLLjznPj/hhSiOXR2v wX+w== DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:cc:content-transfer-encoding :content-type:content-type:date:date:feedback-id:feedback-id :from:from:in-reply-to:message-id:mime-version:reply-to:subject :subject:to:to:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm2; t=1775689499; x=1775775899; bh=Tx+ltTVWiQ/CFru5pNuUL1Ftemqy z5vxM9GxBB0UPjM=; b=U8si13olUPYxJIdNS0NPSURZQ6NwKARk7DmXgRbh/ds3 Vk5RbxdSMoYoHnB1VNsAyqOuveRBaD71nV9GSr2YqB762+Z/tY/60mbPgA5BNhFl bUJJSv5JsENAQ2E1upgQ2sA0eBnRGgKNSkEjH/05x2c75eaAhxI1YeyIhXOpo8Ef fzoOEtUPDo6mDYEPNXkRue6xrifWEunZLv9P8xKkxPyep8XSXHrBCn7uHwnvRD5I WwXzzKQyFBVssDY4OlyFmxlTyhCMrekzSzFZ2omrxKu6TzoD12C7LWduWVNY8F9w +rPLr72JXdGljfoz6S9M42REa00rdPRBqbYWcGtjow== X-ME-Sender: X-ME-Received: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeefhedrtddtgddvgeekgecutefuodetggdotefrod ftvfcurfhrohhfihhlvgemucfhrghsthforghilhdpuffrtefokffrpgfnqfghnecuuegr ihhlohhuthemuceftddtnecusecvtfgvtghiphhivghnthhsucdlqddutddtmdenucfjug hrpeffhffvvefukfggtggugfesmheksfertddtjeenucfhrhhomheptehnughrvghsucfh rhgvuhhnugcuoegrnhgurhgvshesrghnrghrrgiivghlrdguvgeqnecuggftrfgrthhtvg hrnhepuefguddvgfetheduiefffeevhfetveegjeeitefhveeluedtkeegteffteejfedv necuffhomhgrihhnpehpohhsthhgrhdrvghsnecuvehluhhsthgvrhfuihiivgeptdenuc frrghrrghmpehmrghilhhfrhhomheprghnughrvghssegrnhgrrhgriigvlhdruggvpdhn sggprhgtphhtthhopeelpdhmohguvgepshhmthhpohhuthdprhgtphhtthhopegshhgrrh grthhhrdhruhhpihhrvgguugihfhhorhhpohhsthhgrhgvshesghhmrghilhdrtghomhdp rhgtphhtthhopegvgigtlhhushhiohhnsehgmhgrihhlrdgtohhmpdhrtghpthhtohepnh grthhhrghnuggsohhsshgrrhhtsehgmhgrihhlrdgtohhmpdhrtghpthhtohepshgrmhhi mhhsvghihhesghhmrghilhdrtghomhdprhgtphhtthhopehsrghthigrnhgrrhhlrghpuh hrrghmsehgmhgrihhlrdgtohhmpdhrtghpthhtohepthhnughrfigrnhhgsehgmhgrihhl rdgtohhmpdhrtghpthhtohepphhgshhqlhdqhhgrtghkvghrshesphhoshhtghhrvghsqh hlrdhorhhgpdhrtghpthhtohepthhglhesshhsshdrphhghhdrphgrrdhushdprhgtphht thhopehrohgsseigiihilhhlrgdrnhgvth X-ME-Proxy: Feedback-ID: id4a34324:Fastmail Received: by mail.messagingengine.com (Postfix) with ESMTPA; Wed, 8 Apr 2026 19:04:59 -0400 (EDT) Date: Wed, 8 Apr 2026 19:04:58 -0400 From: Andres Freund To: pgsql-hackers@postgresql.org Cc: Nathan Bossart , Tom Lane , Alexander Lakhin , Sami Imseih , Bharath Rupireddy , Treat , satyanarlapuram@gmail.com, pgsql-hackers , tndrwang@gmail.com Subject: pgstat vs aset Message-ID: MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="lnp7xd5wzhcgco7x" Content-Disposition: inline Content-Transfer-Encoding: 8bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --lnp7xd5wzhcgco7x Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit Hi, In [1] I looked at pgstat memory usage after sort of a complaint by Nathan. The conversion of "PgStat Shared Ref" to slab seems like an improvement we obviously should make [2]. In the email I also showed how much CacheMemoryContext using a lot of memory after doing a database wide VACUUM (with ~100k tables), not very surprising. I didn't immediately look at the next few entries: ┌────────────────────────┬─────────────┬───────────────┬────────────┬─────────────┬────────────┐ │ name │ total_bytes │ total_nblocks │ free_bytes │ free_chunks │ used_bytes │ ├────────────────────────┼─────────────┼───────────────┼────────────┼─────────────┼────────────┤ │ CacheMemoryContext │ 168820784 │ 31 │ 2363064 │ 33 │ 166457720 │ │ PgStat Pending │ 27983872 │ 3419 │ 27846912 │ 112699 │ 136960 │ │ smgr relation table │ 16777216 │ 12 │ 2797592 │ 50 │ 13979624 │ │ MdSmgr │ 8388608 │ 11 │ 3475256 │ 1 │ 4913352 │ │ PgStat Shared Ref │ 5767344 │ 88 │ 19712 │ 352 │ 5747632 │ │ PgStat Shared Ref Hash │ 4195376 │ 2 │ 712 │ 0 │ 4194664 │ │ Relcache by OID │ 4194304 │ 10 │ 57448 │ 24 │ 4136856 │ │ TopMemoryContext │ 173264 │ 7 │ 32968 │ 79 │ 140296 │ └────────────────────────┴─────────────┴───────────────┴────────────┴─────────────┴────────────┘ When I did I was quite surprised to see "PgStat Pending" using so much, as it should all be freed after the stats have been submitted, a few seconds later at most. After a moment of worry about having introduced a leak, and adding the necessary columns to see more information, it's clear that all the memory was actually freed. It's just that we don't ever free aset blocks, even if all the constituent memory has been freed. So the overall context size doesn't shrink. That seems decidedly not great. I wonder how bad it would be to teach aset to recognize this situation. But I think for this use case we actually have a more fitting memory context type for this workload, i.e. GenerationContext. With that the size after the same vacuum is │ PgStat Pending │ 134144 │ 3 │ 133848 │ 0 │ 296 │ Seems like a fairly obvious change. My local experimental changes attached. Greetings, Andres Freund [1] https://postgr.es/m/fcvnawwq32mamvf66q5i3sk73xudxz5corqlgqljtocepspjps%40ypvl6yjzy5xk [2] It's a big enough saving that I'm kinda wondering about whether we should try to sneak it into 19. --lnp7xd5wzhcgco7x Content-Type: text/x-diff; charset=us-ascii Content-Disposition: attachment; filename="pgstat-memory.diff" diff --git i/src/backend/utils/activity/pgstat.c w/src/backend/utils/activity/pgstat.c index eb8ccbaa628..fbfa0e8fc3c 100644 --- i/src/backend/utils/activity/pgstat.c +++ w/src/backend/utils/activity/pgstat.c @@ -1300,10 +1300,19 @@ pgstat_prep_pending_entry(PgStat_Kind kind, Oid dboid, uint64 objid, bool *creat if (unlikely(!pgStatPendingContext)) { +#if 0 pgStatPendingContext = AllocSetContextCreate(TopMemoryContext, "PgStat Pending", ALLOCSET_SMALL_SIZES); +#else + pgStatPendingContext = + GenerationContextCreate(TopMemoryContext, + "PgStat Pending", + 1024, + 1024, + 128 * 1024); +#endif } entry_ref = pgstat_get_entry_ref(kind, dboid, objid, diff --git i/src/backend/utils/activity/pgstat_shmem.c w/src/backend/utils/activity/pgstat_shmem.c index b8f354c818a..df279665d62 100644 --- i/src/backend/utils/activity/pgstat_shmem.c +++ w/src/backend/utils/activity/pgstat_shmem.c @@ -1179,10 +1179,20 @@ static void pgstat_setup_memcxt(void) { if (unlikely(!pgStatSharedRefContext)) + { +#if 0 pgStatSharedRefContext = AllocSetContextCreate(TopMemoryContext, "PgStat Shared Ref", ALLOCSET_SMALL_SIZES); +#else + pgStatSharedRefContext = + SlabContextCreate(TopMemoryContext, + "PgStat Shared Ref", + 16*1024, + sizeof(PgStat_EntryRef)); +#endif + } if (unlikely(!pgStatEntryRefHashContext)) pgStatEntryRefHashContext = AllocSetContextCreate(TopMemoryContext, --lnp7xd5wzhcgco7x--