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 1vW9nn-00EHN5-0r for pgsql-hackers@arkaria.postgresql.org; Thu, 18 Dec 2025 08:56:04 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.96) (envelope-from ) id 1vW9nm-00159U-0i for pgsql-hackers@arkaria.postgresql.org; Thu, 18 Dec 2025 08:56: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 1vW9nl-00159M-2L for pgsql-hackers@lists.postgresql.org; Thu, 18 Dec 2025 08:56:02 +0000 Received: from mail-qt1-x829.google.com ([2607:f8b0:4864:20::829]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1vW9nk-001IWR-2A for pgsql-hackers@lists.postgresql.org; Thu, 18 Dec 2025 08:56:01 +0000 Received: by mail-qt1-x829.google.com with SMTP id d75a77b69052e-4ed82ee9e57so5714441cf.0 for ; Thu, 18 Dec 2025 00:56:00 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1766048159; x=1766652959; darn=lists.postgresql.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=yvtvZNkLdB5S7fbHtCh03+T8et975wi43LweeMhnX78=; b=Fha9f9eNFtyGGgVkwT2uhvVZlNj6uTlWFeL8Zio4v9H8xMPHIDp2b9qLG4SjPElkGY 1FxStn44E0tZS+g4pAncGnGPqOUbISFXyJ61GxChcPsnNKD8DjHpItInTkMEe9ypmBhT 2ox6yVPGWwJOKBbR8FQj9ptJFroypO/XNFvut8FjoXnewSQ0v4/RTPRlheCsuGVVgWP4 gp2efW7q/rMv5H0clT1Qiy+UuBuR5bZc4a5dCOtDlU4gZxKEdvlH6fgyPQIyAqXMyfw6 qcJArzaLXpZyI8A+DNxd36d3hlluLnU3Y2UBgdzXakb/bFp3de37Scy50KTrsc7N0uRs 23oA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1766048159; x=1766652959; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-gg:x-gm-message-state:from:to:cc:subject:date :message-id:reply-to; bh=yvtvZNkLdB5S7fbHtCh03+T8et975wi43LweeMhnX78=; b=HQUS8zzQSfeFukG/lo6tVfVRX9lA1R7sQBNfoqLZ8KgSEblUAmYcNqnRSW7FDdxrDi 1INNk1RneAdErr3yx9BOaVZ2NrIniF9nn1SEekvYZ533Cex4xEzlMc436GDB6WuH4GuW EE5nRvReOrLNL2F9bQjUyQR2s5HaT/wiMCzP3+JwYNn2DUFYMhm8GQ6QJ+tKViWmxVWp E1NgU8c8YNba3wkM4dX5Zd5Juw3Ub81NXQ1oGvLwWaFqkPZ60cZYEYt9GTL94rt733VG vVuSMQG1F3x0trdt/Nk37WgiKF7FOaQYFFCowx/oqm0c5TsF0/xmyCBWWbAjIJvuQiey nFSQ== X-Forwarded-Encrypted: i=1; AJvYcCVK48+7MWMm4XjAHxEbXZK3Gbi5tGS3PJdn40VyFzrvcIi60r2NFDYeEBdHb8lO3779X0cLrtZOQSp0Tu28@lists.postgresql.org X-Gm-Message-State: AOJu0YwhsnMamnn41uJJ6LqygMzWKQwJuBnzLBELxA97GK699rXKwcPU tsODQ7oRlOW4pkATyl50AVQ2l6rZCzth3CjLRicDzoxFn2XqKsaKzw9z5CvUvqFi1UuBcfBymvf 3+gaAuXgQreqcZv4XNOXN4asEROLMUyU= X-Gm-Gg: AY/fxX4kmTPWbthMGGv3aCY92XToW0j/eMYayqzPCmjdenQyMQyhF4Hn+JXM8eLWUnh k4xw6VKK9SaCCh4GAzWD7YvThVeAhOpu2Vw2KrI/R2U9DUlha0K8y0gSgkbnIRsW5z/bIjUvbAL gb63x+MJFeLAmyD6tLAk0zAI4LzO2Z7/bTQz4DZNzbTXaNuBFwUNmA8mdkb1XacVpC5nuX9qY1K GT7lbCN3+YzdInUZ1Ri/1bPN19PY3cgh3gD9CxUSgy9PVbZnGOn9YfUKDkZB01vWhkqHKERJk/h VsFem0pI X-Google-Smtp-Source: AGHT+IEOGYiStnvtWT40AKzIo6DGDMEIU70RVmW6AEERfDX8thwfcc+l+b7cr7S6ru0vsDpfnsLywQE2QHtM6wlORD4= X-Received: by 2002:a05:622a:4c1b:b0:4ee:4128:beb7 with SMTP id d75a77b69052e-4f1d0604eb6mr289036911cf.69.1766048158734; Thu, 18 Dec 2025 00:55:58 -0800 (PST) MIME-Version: 1.0 References: <2wk7jo4m4qwh5sn33pfgerdjfujebbccsmmlownybddbh6nawl@mdyyqpqzxjek> In-Reply-To: From: Kirill Reshke Date: Thu, 18 Dec 2025 13:55:46 +0500 X-Gm-Features: AQt7F2ruSZf2Hpj5U4WSKtBXecx_6hAbwkvmKXKQM8u9Sop_-I3mekbmbTvtAcQ Message-ID: Subject: Re: eliminate xl_heap_visible to reduce WAL (and eventually set VM on-access) To: Melanie Plageman Cc: Andres Freund , Robert Haas , Andrey Borodin , PostgreSQL Hackers , Heikki Linnakangas , Chao Li Content-Type: text/plain; charset="UTF-8" List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On Thu, 18 Dec 2025 at 05:30, Melanie Plageman wrote: > > > in v27-0005. This patch changes code which is not exercised in > > tests[0]. I spent some time understanding the conditions when we > > entered this. There is a comment about non-finished relation > > extension, but I got no success trying to reproduce this. I ended up > > modifying code to lose PageSetAllVisible in proper places and running > > vacuum. Looks like everything works as expected. I will spend some > > more time on this, maybe I will be successful in writing an > > injection-point-based TAP test which hits this... > > Based on the coverage report link you provided, that code is changed > by v27 0007, not 0005. 0005 is about moving an assertion out of > lazy_scan_prune(). 0007 changes lazy_scan_new_or_empty() (the code in > question). > > Regarding 0007, it looks like what is uncovered (the orange bits in > the coverage report are uncovered, I assume) is empty pages _without_ > PD_ALL_VISIBLE set. I don't see anywhere where PageSetAllVisible() is > called except vacuum and COPY FREEZE. Sure, I meant 0007. > If I was trying to guess how empty pages with PD_ALL_VISIBLE set are > getting vacuumed, I would think it is due to SKIP_PAGES_THRESHOLD > causing us to vacuum an all-frozen empty page. Yes, vacuum (disable_page_skipping); > Then the question is, why wouldn't we have coverage of the empty page > first being set all-visible/all-frozen? It can't be COPY FREEZE > because the page is empty. And it can't be vacuum, because then we > would have coverage. It's very mysterious. > > It would be good to have coverage for this case. I don't think you'll > need an injection point for the main case of "empty page not yet set > all-visible is vacuumed for the first time" (unless I'm > misunderstanding something). > > I'm not sure how you'll test the "vacuuming an empty, previously > uninitialized page" case described in this comment, though. > > * It's possible that another backend has extended the heap, > * initialized the page, and then failed to WAL-log the page due > * to an ERROR. Since heap extension is not WAL-logged, recovery > * might try to replay our record setting the page all-visible and > * find that the page isn't initialized, which will cause a PANIC. > * To prevent that, check whether the page has been previously > * WAL-logged, and if not, do that now. > > You'd want to force an error during relation extension and then vacuum > the page. I don't know if you need an injection point to force the > error -- depends on what kind of error, I think. I did small archeology and this "if (PageIsEmpty(page)) { if (!PageIsAllVisible(page)) { .... }}" code originates back to 608195a3a365. Comment about not WAL-logged relation extension is from a6370fd9ed3d, and I don't think we need to think about this case. I am currently inclined to think that we cannot see an empty page that has PD_ALL_VISIBLE not-set. This is because when we make a page empty, we are in a critical section, and we WAL-log everything we do, so our changes should not be half-made. Maybe as of 608195a3a365, there was a case with empry-page-without-PD_ALL_VISIBLE, but I dont think this happens on HEAD. > So that I know for attribution, did you review 0003-0005? yes, but I did not have any valuable review points for them. Also, after the whole set is committed, we should then never experience discrepancy between PD_ALL_VISIBLE and VM bits? Because they will be set in a single WAL record. The only cases when heap and VM disagrees on all-visibility then are corruption, pg_visibilitymap_truncate and old data (data before v19+ upgrade?) If my understanding is correct, should we add document this? -- Best regards, Kirill Reshke