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 1tuzWD-00FC8V-DQ for pgsql-hackers@arkaria.postgresql.org; Wed, 19 Mar 2025 19:56:01 +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 1tuzWC-00At1M-40 for pgsql-hackers@arkaria.postgresql.org; Wed, 19 Mar 2025 19:56:00 +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.94.2) (envelope-from ) id 1tuzWB-00Asrh-EZ for pgsql-hackers@lists.postgresql.org; Wed, 19 Mar 2025 19:55:59 +0000 Received: from mail-pl1-x62a.google.com ([2607:f8b0:4864:20::62a]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1tuzW9-003rD1-0j for pgsql-hackers@postgresql.org; Wed, 19 Mar 2025 19:55:58 +0000 Received: by mail-pl1-x62a.google.com with SMTP id d9443c01a7336-223594b3c6dso163358345ad.2 for ; Wed, 19 Mar 2025 12:55:57 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=leadboat.com; s=google; t=1742414156; x=1743018956; 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=qjyR88s9vBR0z1fugQSuErnXrqT8dmQBuGyb50VaZvE=; b=abR0N13bUmvJzAxVyU+shcv6lIKZrYsWfBI8/Tw3w1T6yANfgyilhx+Z11A0EMegPv uV6KxTlu6JGSA8c9WoHYA2GX+4KD0y31EXEVyfmp5GPOdTxlM27dRaIDoAPztRWIFTZF UI4AE2hORSoCC41JWTRC1Shog/onwAQOONssE= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1742414156; x=1743018956; 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=qjyR88s9vBR0z1fugQSuErnXrqT8dmQBuGyb50VaZvE=; b=Jf1A5lCnFb9rpd9SRcyjkoDiX167+yuWUK12PDPTCeIundXSjgEukGoBpr3mQN4kjH b3dchUkpFOceKiUwrwzXNxgWDdgVwL0R8ek1SMdb2V7IBV+g+wfFX3gSCXEfu9neQq+d WslYIpAmMvBykkI7RCSZ5ukCoVadIz9lfOjguBsVprHRVk/LVMMH7mH2mFAx9Eh1J59C GDkZZd7//VodQ+3tclMWvRvuFR6YaAz7OC7lRv5xqfw/A0XLRc/9omhM2uNLWHrcos4o l2Etfzi/1f7ZlgRiumwL6fevJoH/hpK5WZ3AGJdbt/l02BuCraN6D/Q4gE3ESHbPJnkN +BGQ== X-Forwarded-Encrypted: i=1; AJvYcCVD6aNGTEkrhPGCQBw5AkjqPYCxW4iPwCDP/EmnhGcs+hqfo0ZcAHPrA0yfW5RAf4OH2SKz1bfUbRvdJI00@postgresql.org X-Gm-Message-State: AOJu0YyHQXSPLwS4qoza6JrI0SvMxUOENm9QwLDVj+9hWGRXIyc3c4jj H9iiNXROi3BU3G1MJBdtqgWtOgADEpz1PKMt1UtBLVRQHqagyWg0XUtYzlolzA== X-Gm-Gg: ASbGncugJk7NdBodRdtJxMHz0y0RO8p0yH7qcuX5SkkZfuOtOlFJwJ1j7c5OaHPJEYV CXi9HGWtZGp6/E5N7Ab0vSAIz9l1K3MA126lTNg6wv0Fb9VouRNAkGL+vHjMk8ntjEHQwr+fxZh 8Wg54EzmnTUcRFr00vAf+fAlB53x677RFTD+ZQ3Hdn2EA4r6YRNkqiHFn/7hOj8Ro2hj/oAPtLS NxmYKAD9X6g8wm05iAKPHaaEj7rA7DkoR25/176rL1yEyTh8MEJOOj92jRL+AEosbz4bdBrFcwA /pWyKUe8vzHnx6zXyiYCzqkwNU5Fh9mT3deT52drfQ== X-Google-Smtp-Source: AGHT+IHfiC++TPzspNXVcGUQGYCw3vZNYMVjXNTNLbuauHo3HQ9V24U4sDP0BtKUVpYdTQy5iZ04VA== X-Received: by 2002:a05:6a00:3990:b0:736:64b7:f104 with SMTP id d2e1a72fcca58-7376d5e2792mr4654981b3a.5.1742414156077; Wed, 19 Mar 2025 12:55:56 -0700 (PDT) Received: from google.com ([2601:647:5600:80d0::31cd]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-7371169593csm12084524b3a.128.2025.03.19.12.55.55 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Wed, 19 Mar 2025 12:55:55 -0700 (PDT) Date: Wed, 19 Mar 2025 12:55:53 -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: <20250319195553.ef.nmisch@google.com> References: <3vae7l5ozvqtxmd7rr7zaeq3qkuipz365u3rtim5t5wdkr6f4g@vkgf2fogjirl> <4qtmksxdbbp3pb7dqmn6lnzzdv7ujnizmbqtfbwm7c25waavtk@i6iyjrhk5eh5> 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 Mon, Mar 17, 2025 at 07:52:02PM -0400, Andres Freund wrote: > Here's a proposed patch for this. It turns out that the bug might already be > reachable, even without defining FDDEBUG. There's a debug ereport() in > register_dirty_segment() - but it's hard to reach in practice. > > I don't really know whether that means we ought to backpatch or not - which > makes me want to be conservative and not backpatch. Non-backpatch sounds fine. > Subject: [PATCH v2 1/2] smgr: Hold interrupts in most smgr functions > It seems better to put the HOLD_INTERRUPTS()/RESUME_INTERRUPTS() in smgr.c, > instead of trying to push them down to md.c where possible: For one, every > smgr implementation would be vulnerable, for another, a good bit of smgr.c > code itself is affected too. I'm fine with putting it in smgr.c. Academically, I don't see every smgr implementation being vulnerable for most smgr entry points. For example, the upthread backtrace happens because mdclose() undoes the fd-opening work of mdnblocks(). Another smgr implementation could make its smgr_close callback a no-op. smgrrelease() doesn't destroy anything important at the smgr level; it is mdclose() that destroys state that md.c still needs. > @@ -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. > + > hash_seq_init(&status, SMgrRelationHash); > > while ((reln = (SMgrRelation) hash_seq_search(&status)) != NULL) > { > smgrrelease(reln); > } > + > + RESUME_INTERRUPTS(); > } > > /* > @@ -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. > > /* > @@ -449,6 +498,8 @@ smgrdosyncall(SMgrRelation *rels, int nrels) > smgrsw[which].smgr_immedsync(rels[i], forknum); Long-term, someone might change this to hold interrupts once per immedsync with a CFI between immedsync calls. That would be safe. It's not this change's job, though. I'm mentioning it for the archives. > } > } > + > + 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. > 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?