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 1tv43F-00GjLX-Vz for pgsql-hackers@arkaria.postgresql.org; Thu, 20 Mar 2025 00:46:26 +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 1tv42F-00EQ7H-0t for pgsql-hackers@arkaria.postgresql.org; Thu, 20 Mar 2025 00:45:23 +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 1tv42E-00EQ3O-DL for pgsql-hackers@lists.postgresql.org; Thu, 20 Mar 2025 00:45:22 +0000 Received: from mail-pl1-x633.google.com ([2607:f8b0:4864:20::633]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1tv42B-0001sh-0k for pgsql-hackers@postgresql.org; Thu, 20 Mar 2025 00:45:21 +0000 Received: by mail-pl1-x633.google.com with SMTP id d9443c01a7336-223fd89d036so2355425ad.1 for ; Wed, 19 Mar 2025 17:45:18 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=leadboat.com; s=google; t=1742431517; x=1743036317; darn=postgresql.org; h=user-agent:in-reply-to:content-disposition:mime-version:references :message-id:subject:cc:to:from:date:from:to:cc:subject:date :message-id:reply-to; bh=U9NH0vcqXecAH/7DE8GVvOfQv+h+T1MMbaIGFwAGi4g=; b=XAlAfKDqU9M3oav9ndDbI0DYkL7qCxULe4gCdaevxU8ksWQXdfO1v67E/30vcj3MoE H0cScsavSLPJciqYN3lZ5n8ImmH7TS4VbYsGJbMnElffM4zz1eN+Cp2U/sJKbrof6HrO EayAsz1uPknVHddrzJje7ckdRwqcBqZFBSkQ8= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1742431517; x=1743036317; h=user-agent:in-reply-to:content-disposition:mime-version:references :message-id:subject:cc:to:from:date:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=U9NH0vcqXecAH/7DE8GVvOfQv+h+T1MMbaIGFwAGi4g=; b=GKMAYnDs5RDp4acGNTkKuaG2oS1wj9dtM+NDi3j1U6tDA/Z21m9C9kBD7pey4tFJy4 o3gzkAgSgTjMCjM4yR+t6F7AOgPD77AZuJYTwjxCR2/dgL/3/MJmRhXfnqMnPxcSeS4S V+nh6kwZ0affVb5FnLgkzsPg2yoCvEYhxO33T+iFshn59ogXUmACQvkvxY0fhcS4ZGax RqwlW3FMBonSPMugcPDMIkkMVKOV3ZypKd83xeTqEYp1U2OkZwQSudoIQ/N3UeGuKDm+ 5HqjecKHzujKyZ7BAIerhIiuniRQjstO1fK3HPn0z2+sd5BydRzENQKWfYwi64/KUS56 WUNQ== X-Forwarded-Encrypted: i=1; AJvYcCU3m1i0pfh2dclo9Z39uK76kstyGzVREu2sLWXEwbhsVN4IbfZhVGbmJxoN/naMdi3yoxPWUC+rUrqlwBKP@postgresql.org X-Gm-Message-State: AOJu0YwgyyjJd2nsd8h8SzV5ehFjPIYz66ECuQxqjZS7hbbzc4ms7Xgp aINjC7w6aq+P9OU+l60t8XNkS9nB4VCarFFLY43U7ViaLE+QvAd0ucbIWiR7QQ== X-Gm-Gg: ASbGncvZhwhYoUrOOg+WNE+3WK6JWjrg19UN6Gi2RiOU1nNsDQshfZcnQcj2pfiL21A xKIBSU/aLNPB+94+/xxdkQ9ZIWwNSk/f8Gh+LgOUU+gvbZ4LlyWu6D6dC9EU+HWL6vcG6WpfmOf +KCeuq0TZK7fvuBCqFGFlyCOl8jj8lOKifBZQBhljYG9GtT5xM70hS6S2FnN0uK6Ek42ouxE1tx m/qwASur10Bn1UMcFHXi/4NYrA+Sv6KDzJD8Z2B5rKaWH6DL6Dq1i8+HTUULI6h4IfrytfopH2J DFNQch/18wZ0cBVV43LosBz4WIdoqHrJaqmCydeB9Q== X-Google-Smtp-Source: AGHT+IG7JWbRZ4M2Zkmd1XwayaMMtQr+qHQeqT5mbR+eXZZhBSk6MFCj9AufNyo5VOe2nX1X5j14ew== X-Received: by 2002:a17:90b:1a8a:b0:2fa:e9b:33b3 with SMTP id 98e67ed59e1d1-301bde53a76mr5639015a91.6.1742431516818; Wed, 19 Mar 2025 17:45:16 -0700 (PDT) Received: from google.com ([2601:647:5600:80d0::31cd]) by smtp.gmail.com with ESMTPSA id 98e67ed59e1d1-301bf5d0955sm2390117a91.47.2025.03.19.17.45.15 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 19 Mar 2025 17:45:16 -0700 (PDT) Date: Wed, 19 Mar 2025 17:45:14 -0700 From: Noah Misch To: Andres Freund Cc: Thomas Munro , pgsql-hackers@postgresql.org Subject: Re: md.c vs elog.c vs smgrreleaseall() in barrier Message-ID: <20250320004514.95.nmisch@google.com> References: <3vae7l5ozvqtxmd7rr7zaeq3qkuipz365u3rtim5t5wdkr6f4g@vkgf2fogjirl> <4qtmksxdbbp3pb7dqmn6lnzzdv7ujnizmbqtfbwm7c25waavtk@i6iyjrhk5eh5> <20250319195553.ef.nmisch@google.com> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: User-Agent: Mutt/2.2.12 (2023-09-09) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On Wed, Mar 19, 2025 at 06:45:20PM -0400, Andres Freund wrote: > On 2025-03-19 12:55:53 -0700, Noah Misch wrote: > > On Mon, Mar 17, 2025 at 07:52:02PM -0400, Andres Freund wrote: > > > @@ -362,12 +397,16 @@ smgrreleaseall(void) > > > if (SMgrRelationHash == NULL) > > > return; > > > > > > + HOLD_INTERRUPTS(); > > > > Likely not important, but it's not clear to me why smgrdestroyall() and > > smgrreleaseall() get HOLD_INTERRUPTS(), as opposed to relying on the holds in > > smgrdestroy() and smgrrelease(). In contrast, smgrreleaserellocator() does > > rely on smgrrelease() for the hold. > > It didn't seem particularly safe to allow interrupts, which in turn could > change the list of open relations, while iterating over a linked list / a > hashtable. Fair. > > > @@ -434,6 +481,8 @@ smgrdosyncall(SMgrRelation *rels, int nrels) > > > if (nrels == 0) > > > return; > > > > > > + HOLD_INTERRUPTS(); > > > + > > > FlushRelationsAllBuffers(rels, nrels); > > > > FlushRelationsAllBuffers() isn't part of smgr or md.c, so it's unlikely to > > become sensitive to smgrrelease(). It may do a ton of I/O. Hence, I'd > > HOLD_INTERRUPTS() after FlushRelationsAllBuffers(), not before. > > Hm - we never would want to process interrupts while in > FlushRelationsAllBuffers() or such, would we? I'm ok with changing it, I > guess I just didn't see a reason not to use a wider scope. If we get a query cancel or fast shutdown, it's better for the user to abort the transaction rather than keep flushing. smgrDoPendingSyncs() calls here rather late in the pre-commit actions, so failing is still supposed to be fine. I think the code succeeds at making it fine to fail here. > I guess I am a bit paranoid because gave me flashbacks to issues around > smgrtruncate() failing after doing DropRelationBuffers(), that Thomas recently > fixed (and I had worked on a few years before). But of course > DropRelationBuffers() is way more dangerous than FlushRelationsAllBuffers(). Fair. > > > } > > > } > > > + > > > + RESUME_INTERRUPTS(); > > > } > > > > > > /* > > > @@ -471,6 +522,8 @@ smgrdounlinkall(SMgrRelation *rels, int nrels, bool isRedo) > > > if (nrels == 0) > > > return; > > > > > > + HOLD_INTERRUPTS(); > > > > I would move this below DropRelationsAllBuffers(), for reasons like > > FlushRelationsAllBuffers() above. > > I think that'd be unsafe. Once we dropped buffers from the buffer pool we > can't just continue without also unlinking the underlying relation, otherwise > an older view of the data later can be "revived from the dead" after an error, > causing all manner of corruption. > > I suspect it's always called with interrupts held already though. Ah, confirmed. If I put this assert at the top of smgrdounlinkall(), check-world passes: Assert(IsBinaryUpgrade || InRecovery || !INTERRUPTS_CAN_BE_PROCESSED()); > > > Subject: [PATCH v2 2/2] smgr: Make SMgrRelation initialization safer against > > > errors > > > > > > In case the smgr_open callback failed, the ->pincount field would not be > > > initialized and the relation would not be put onto the unpinned_relns list. > > > > > > This buglet was introduced in 21d9c3ee4ef7. As that commit is only in HEAD, no > > > need to backpatch. > > > > > > Discussion: https://postgr.es/m/3vae7l5ozvqtxmd7rr7zaeq3qkuipz365u3rtim5t5wdkr6f4g@vkgf2fogjirl > > > --- > > > src/backend/storage/smgr/smgr.c | 6 +++--- > > > 1 file changed, 3 insertions(+), 3 deletions(-) > > > > > > diff --git a/src/backend/storage/smgr/smgr.c b/src/backend/storage/smgr/smgr.c > > > index 53a09fe4aaa..24971304b85 100644 > > > --- a/src/backend/storage/smgr/smgr.c > > > +++ b/src/backend/storage/smgr/smgr.c > > > @@ -255,12 +255,12 @@ smgropen(RelFileLocator rlocator, ProcNumber backend) > > > reln->smgr_cached_nblocks[i] = InvalidBlockNumber; > > > reln->smgr_which = 0; /* we only have md.c at present */ > > > > > > - /* implementation-specific initialization */ > > > - smgrsw[reln->smgr_which].smgr_open(reln); > > > - > > > /* it is not pinned yet */ > > > reln->pincount = 0; > > > dlist_push_tail(&unpinned_relns, &reln->node); > > > + > > > + /* implementation-specific initialization */ > > > + smgrsw[reln->smgr_which].smgr_open(reln); > > > } > > > > I struggle to speculate about the merits of this, because mdopen() can't fail. > > If mdopen() started to do things that could fail, mdnblocks() would be > > reasonable in assuming those things are done. Hence, the long-term direction > > should be more like destroying the new smgr entry in the event of error. > > > > I would not make this change. I'd maybe add a comment that smgr_open > > callbacks currently aren't allowed to fail, since smgropen() isn't ready to > > clean up smgr-level state from a failed open. How do you see it? > > I see no disadvantage in the change - it seems strictly better to initialize > pincount earlier. I agree that it might be a good idea to explicitly handle > errors eventually, but that'd not be made harder by this change... Okay. I suppose if mdopen() gained the ability to fail and mdnblocks() also gained the ability to cure said failure, this change would make that okay.