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 1w4eV8-002PS5-0x for pgsql-hackers@arkaria.postgresql.org; Mon, 23 Mar 2026 12:35:22 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1w4eV5-00HWS2-26 for pgsql-hackers@arkaria.postgresql.org; Mon, 23 Mar 2026 12:35:20 +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.96) (envelope-from ) id 1w4eV5-00HWRu-1B for pgsql-hackers@lists.postgresql.org; Mon, 23 Mar 2026 12:35:19 +0000 Received: from mail-wm1-x331.google.com ([2a00:1450:4864:20::331]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.98.2) (envelope-from ) id 1w4eV3-00000000gM4-1ATU for pgsql-hackers@postgresql.org; Mon, 23 Mar 2026 12:35:19 +0000 Received: by mail-wm1-x331.google.com with SMTP id 5b1f17b1804b1-486fd5360d4so777715e9.1 for ; Mon, 23 Mar 2026 05:35:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1774269317; x=1774874117; darn=postgresql.org; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:user-agent:mime-version:date:message-id :from:to:cc:subject:date:message-id:reply-to; bh=OFqk9RCjHX2Cax/6/YFTIFwZN1SMogdTT7nfZeNIBjE=; b=A9r3jDYxOEkbIW/nAeKSVFrKP9RAnTYewVOMqeaizeeUY7Vj/wDxPvlTD7lS9gT449 oET4oNezB9OFQ9MDT2//yXR4dQQ/JWKBEigDn3135iPoE+76/r2bGCr/8GJ59Yblelg8 +5yhxtTJq7wi8TgNjJj1EdszfhVQiptWqumQigS8V4m3/063QjbwE9asrsDMgcRSOz3Z tpK6UKDVprsI6fNVbRUxW4LdRHjpC7lcYwrfKfBCEOks2keaTMgvaqlJIWGR7ebuTlKV iFq6CWFrLTciS6EFm8PL8SSH4dmKdZgEOwA3fpOWIdQFilaq8xXCZ5YKh2lhkQAuMN8K BIzw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1774269317; x=1774874117; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:user-agent:mime-version:date:message-id :x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=OFqk9RCjHX2Cax/6/YFTIFwZN1SMogdTT7nfZeNIBjE=; b=gzoG5Yi7ZmvMNbwC0zD1Tsh8qvIaMuOLeI3D4BH35xSU4cdPqnqm934sO/i2MYj9cj urkyxtN1P3VRLMQ7sRTrBzRagV9u1UTQ8f4bOYXmUTtnSUVf+7q/ldXRhQ6sBSm1Osvb b9k+wB3VDdHLe2wOvIMTWquPjcuH3JG+z0i/rLZApvJiHri8PvGYFyObIvK4mPLmYxXB Eu1uAnLcuMRbFGWAsYBD7HxFHcXelGsMV4nSgSE37ZBU0kwfscSKO646T5EDGUjWWY8s oBr1BTyA3C+4e8BR5dsooAdS2NTYZ5zzs75DHAe4YhkSL3SA+yyYkiudk4bgsrZivGXJ eZRQ== X-Gm-Message-State: AOJu0Yzya+jQjjsbNjzgCTwXgbAUA+SceKJ7WG9z8WCgrfpSoxdJjeQn tHKdFac0zlWxORtIyK3H1j/5wDsXpRI2x1jfuBhR/3ZlThUrTfYZWa6H X-Gm-Gg: ATEYQzzBiymA/CK2iZPQ4HlVns5knQnSPxcy2dB4vgnASY8hEhMtYW4QOmYr6I4R3yf 8FikkpdbNLOQcFbBmHtUhbLMEiIb+KdH2dyOPFMEwdcqPic7C1P5HaUOa3Jf+Hk1EuytGGFpUOU cJaad5UaFOpO8SVdshX4OUL5NeWt/76CdbSFlsJ4RlE9IUrr/EtxMLUNKUpvMnBZ8KXYIiLerHJ D6ozppphP3E3/gG9E2FYYzCR/+ts+HOj5yJuL1+4NMFzYD2ZPalKsz+qA756XrY+6VkpK7DxpUB TkxFubn85gjVHVBk6aT2p3+id4fpDgsvu49feZfxBt2dprWfQIElQSZFgRLc7OPxtvdpDTsErEH tvogZFEqK8CzoD2u9z46dFlaAWRfYB736iLCOFG+aBVaEXvxjCeozmrvzPXHhZZxSaZ/xG+G62N DN1KwVrd6Fx9bVbESbfCXKFvufog== X-Received: by 2002:a05:600c:4e8e:b0:485:3fd1:992c with SMTP id 5b1f17b1804b1-486fedaafc2mr159887185e9.1.1774269316501; Mon, 23 Mar 2026 05:35:16 -0700 (PDT) Received: from [172.31.5.233] ([147.161.235.32]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-48705135631sm202517955e9.15.2026.03.23.05.35.15 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Mon, 23 Mar 2026 05:35:16 -0700 (PDT) Message-ID: Date: Mon, 23 Mar 2026 13:35:14 +0100 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: Add pg_stat_vfdcache view for VFD cache statistics To: Jakub Wartak , KAZAR Ayoub Cc: Pg Hackers , "tomas@vondra.me" References: Content-Language: en-US From: David Geier In-Reply-To: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk Hi! On 23.03.2026 12:22, Jakub Wartak wrote: > On Sat, Mar 21, 2026 at 5:59 PM KAZAR Ayoub wrote: >> >> Hello hackers, >> >> This comes from Tomas's patch idea from his website[1], i thought this patch makes sense to have. >> >> PostgreSQL's virtual file descriptor (VFD) maintains a >> per-backend cache of open file descriptors, bounded by >> max_files_per_process (default 1000). When the cache is full, the >> least-recently-used entry is evicted so its OS fd is closed, so a new >> file can be opened. On the next access to that file, open() must be >> called again, incurring a syscall that a larger cache would have >> avoided. That's one use-case. The other one that I've recently come across is just knowing how many VFD cache entries there are in the first place. While the number of open files is bounded by max_files_per_process, the number of cache entries is unbounded. Large database can easily have hundreds of thousands of files due to our segmentation scheme. Workloads that access a big portion of these files can end up spending very considerable amounts of memory on the VFD cache. For example, with 100,000 VFD entries per backend * 80 bytes per VFD = ~7.6 MiB. With 1000 backends that almost 10 GiB just for VFD entries; assuming that each backend over time accumulates that many files. A production database I looked recently had ~300,000 files and many thousand backends. It spent close to 30 GiBs on VFD cache. I've looked at struct vfd and some simple changes to the struct would already cut memory consumption in half. I can look into that. Thoughts? >> A trivial example is with partitioned tables: a table with 1500 >> partitions requires even more than 1500 file descriptors per full scan (main >> fork, vm ...), which is more than the default limit, causing potential evictions and reopens. >> >> The problem is well-understood and the fix is straightforward: raise >> max_files_per_process. Tomas showed a 4-5x throughput >> improvement in [1] sometimes, on my end i see something less than that, depending on the query itself, but we get the idea. The question is what the kernel makes out of that, especially in aforementioned case where the number of total files and backends is large. In the Linux kernel each process that open some file gets its own struct file. sizeof(struct file) is ~200 bytes. Hence, increasing max_files_per_process can measurably impact memory consumption if changed lightheartedly. We should document that. But I guess in most cases it's rather about changing it from 1k to 2k, rather than changing it from 1k to 100k. >> AFAIK there is currently no way from inside PostgreSQL to know whether fd cache pressure is occurring. >> >> Implementation is trivial, because the VFD cache is strictly per-backend, the counters are also >> per-backend and require no shared memory or locking. Three macros (pgstat_count_vfd_hit/miss/eviction) update fields in PendingVfdCacheStats directly from fd.c. >> >> I find this a bit useful, I would love to hear about anyone's thoughts whether this is useful or not. > > Hi, > > My $0.02, for that for that to being useful it would need to allow viewing > global vfd cache picture (across all backends), not just from *current* backend. > Applicaiton wouldn't call this function anyway, because they would have to be > modified. +1 > In order to get that you technically should collect the hits/misses in local > pending pgstat io area (see e.g. pgstat_io or simpler pgstat_bgwriter/ > checkpointer) like you do already with PendingVfdCacheStats, but then copy them > to shared memory pgstat area (with some LWLock* protection) that would be > queryable. I would include here the sum of VFD cache entries across all backend and the total VFD cache size. -- David Geier