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 1skCdf-008euk-7Z for pgsql-hackers@arkaria.postgresql.org; Sat, 31 Aug 2024 01:10:51 +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 1skCdd-00EWRE-Cf for pgsql-hackers@arkaria.postgresql.org; Sat, 31 Aug 2024 01:10:49 +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 1skCdc-00EWR6-Vj for pgsql-hackers@lists.postgresql.org; Sat, 31 Aug 2024 01:10:49 +0000 Received: from mail-pl1-x635.google.com ([2607:f8b0:4864:20::635]) by makus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.94.2) (envelope-from ) id 1skCda-002GBa-OT for pgsql-hackers@postgresql.org; Sat, 31 Aug 2024 01:10:48 +0000 Received: by mail-pl1-x635.google.com with SMTP id d9443c01a7336-2053a0bd0a6so7722035ad.3 for ; Fri, 30 Aug 2024 18:10:46 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=leadboat.com; s=google; t=1725066646; x=1725671446; darn=postgresql.org; h=user-agent:in-reply-to:content-transfer-encoding :content-disposition:mime-version:references:message-id:subject:cc :to:from:date:from:to:cc:subject:date:message-id:reply-to; bh=GECVBuI8F+3uOu04u3KNwhL6kgr8+lpLYgifJW8hCTA=; b=DKkXS0zyJmMei9nPJ7n8W1hM0iNrZb3ENjqOURfHwJP74mObOYPcjFb5qsLi0PEyRg tBek4nm6eiCMGJ1XW2jQyncBDEdlpAR5zTouyfQec/U+E0gXrnbt1Ds0Mb/1Mea6s887 n6CgRem0uYgJrclgsn9o8OrDCKBGbSu4a/q/E= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1725066646; x=1725671446; h=user-agent:in-reply-to:content-transfer-encoding :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=GECVBuI8F+3uOu04u3KNwhL6kgr8+lpLYgifJW8hCTA=; b=YAoGFrlJ3yovAEfW23ijrQ3tOv6Mr4ziyXjRybHInenKsA0cd1bIuVPTis51cVM26m oSoqzdjbJupbXZ0P74zQmonVyVWki+3nZJ9n395w/worRgUaZn77dRuY8jfhLjb9SqIr UJbTOfD1qHoBSAYVgizytuQPZ3l9FyPa1DkaLLBQDZGU7YgWvSEV/RdIs1UbuuIQ21M5 +BiRQhbRkTwJKLlBKPs9dIC0jKeXNQJuhQiKsgXse8z638pJWcJhzqRpPjvNueq6S7A4 /Lqhk24FyteUPKfrJOx8JezO4LckNDFN6HhPAFkLDy0tDQaTV9tDsPSLXCHgnlgiD2d8 AOfQ== X-Forwarded-Encrypted: i=1; AJvYcCWQZar5SitOH9ARvsC4gXnbxumw3LlourYPYuWrNJy24cUEVtkPQC5MHHouJ1UO0T4hZb9n64y9Urmlg4Ch@postgresql.org X-Gm-Message-State: AOJu0Yw/wFUGelIFMozC5Kr/AGICF3B33VPZXKaRVns3cvLlzsXHj7Oy W+dJp47El0bBCdtsme/1Q0z5sEG7Dj/Hhr0I8+qYLOVCKGGtEy/Sev79oDRmSA== X-Google-Smtp-Source: AGHT+IGiV0hEd4MsGURG9HsRMBm9EyEIVz21TiAlLbTfbEkghD9MJxjpdXT22qRGe5Lg9g+xtBgghw== X-Received: by 2002:a17:902:e5ce:b0:202:35e0:deaf with SMTP id d9443c01a7336-2050c3b704amr73912945ad.39.1725066645778; Fri, 30 Aug 2024 18:10:45 -0700 (PDT) Received: from google.com ([2600:1702:a20:5750::48]) by smtp.gmail.com with ESMTPSA id d9443c01a7336-2052fe97a60sm15077585ad.190.2024.08.30.18.10.44 (version=TLS1_2 cipher=ECDHE-ECDSA-AES128-GCM-SHA256 bits=128/128); Fri, 30 Aug 2024 18:10:45 -0700 (PDT) Date: Fri, 30 Aug 2024 18:10:43 -0700 From: Noah Misch To: Nitin Motiani Cc: Heikki Linnakangas , Robert Haas , pgsql-hackers@postgresql.org, Tom Lane , Smolkin Grigory , Michael Paquier , Alexander Lakhin Subject: Re: race condition in pg_class Message-ID: <20240831011043.2b.nmisch@google.com> References: <20240621212842.98.nmisch@google.com> <20240628051353.a0.nmisch@google.com> <20240704220816.51.nmisch@google.com> <20240714174800.de.nmisch@google.com> <20240817040748.f8.nmisch@google.com> <63c27c17-0d8f-4ede-a624-3ee41d28b539@iki.fi> <20240822073200.4f.nmisch@google.com> MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline Content-Transfer-Encoding: 8bit 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 Thu, Aug 29, 2024 at 09:08:43PM +0530, Nitin Motiani wrote: > On Thu, Aug 29, 2024 at 8:11 PM Noah Misch wrote: > > On Tue, Aug 20, 2024 at 11:59:45AM +0300, Heikki Linnakangas wrote: > > > My order of preference is: 2, 1, 3. > > > > I kept tuple locking responsibility in heapam.c. That's simpler and better > > for modularity, but it does mean we release+acquire after any xmax wait. > > Before, we avoided that if the next genam.c scan found the same TID. (If the > > next scan finds the same TID, the xmax probably aborted.) I think DDL aborts > > are rare enough to justify simplifying as this version does. I don't expect > > anyone to notice the starvation outside of tests built to show it. (With > > previous versions, one can show it with a purpose-built test that commits > > instead of aborting, like the "001_pgbench_grant@9" test.) > > > > This move also loses the optimization of unpinning before XactLockTableWait(). > > heap_update() doesn't optimize that way, so that's fine. > > > > The move ended up more like (1), though I did do > > s/systable_inplace_update_scan/systable_inplace_update_begin/ like in (2). I > > felt that worked better than (2) to achieve lock release before > > CacheInvalidateHeapTuple(). Alternatives that could be fine: > > > From a consistency point of view, I find it cleaner if we can have all > the heap_inplace_lock and heap_inplace_unlock in the same set of > functions. So here those would be the systable_inplace_* functions. That will technically be the case after inplace160, and I could make it so here by inlining heap_inplace_unlock() into its heapam.c caller. Would that be cleaner or less clean? > > - In the cancel case, call both systable_inplace_update_cancel and > > systable_inplace_update_end. _finish or _cancel would own unlock, while > > _end would own systable_endscan(). > > > What happens to CacheInvalidateHeapTuple() in this approach? I think > it will still need to be brought to the genam.c layer if we are > releasing the lock in systable_inplace_update_finish. Cancel scenarios don't do invalidation. (Same under other alternatives.) > > - Hoist the CacheInvalidateHeapTuple() up to the genam.c layer. While > > tolerable now, this gets less attractive after the inplace160 patch from > > https://postgr.es/m/flat/20240523000548.58.nmisch@google.com > > > I skimmed through the inplace160 patch. It wasn't clear to me why this > becomes less attractive with the patch. I see there is a new > CacheInvalidateHeapTupleInPlace but that looks like it would be called > while holding the lock. And then there is an > AcceptInvalidationMessages which can perhaps be moved to the genam.c > layer too. Is the concern that one invalidation call will be in the > heapam layer and the other will be in the genam layer? That, or a critical section would start in heapam.c, then end in genam.c. Current call tree at inplace160 v4: genam.c:systable_inplace_update_finish heapam.c:heap_inplace_update PreInplace_Inval START_CRIT_SECTION BUFFER_LOCK_UNLOCK AtInplace_Inval END_CRIT_SECTION UnlockTuple AcceptInvalidationMessages If we hoisted all of invalidation up to the genam.c layer, a critical section that starts in heapam.c would end in genam.c: genam.c:systable_inplace_update_finish PreInplace_Inval heapam.c:heap_inplace_update START_CRIT_SECTION BUFFER_LOCK_UNLOCK AtInplace_Inval END_CRIT_SECTION UnlockTuple AcceptInvalidationMessages If we didn't accept splitting the critical section but did accept splitting invalidation responsibilities, one gets perhaps: genam.c:systable_inplace_update_finish PreInplace_Inval heapam.c:heap_inplace_update START_CRIT_SECTION BUFFER_LOCK_UNLOCK AtInplace_Inval END_CRIT_SECTION UnlockTuple AcceptInvalidationMessages That's how I ended up at inplace120 v9's design. > Also I have a small question from inplace120. > > I see that all the places we check resultRelInfo->ri_needLockTagTuple, > we can just call > IsInplaceUpdateRelation(resultRelInfo->ri_RelationDesc). Is there a > big advantage of storing a separate bool field? Also there is another No, not a big advantage. I felt it was more in line with the typical style of src/backend/executor. > write to ri_RelationDesc in CatalogOpenIndexes in > src/backlog/catalog/indexing.c. I think ri_needLockTagTuple needs to > be set there also to keep it consistent with ri_RelationDesc. Please > let me know if I am missing something about the usage of the new > field. Can you say more about consequences you found? Only the full executor reads the field, doing so when it fetches the most recent version of a row. CatalogOpenIndexes() callers lack the full executor's practice of fetching the most recent version of a row, so they couldn't benefit reading the field. I don't think any CatalogOpenIndexes() caller passes its ResultRelInfo to the full executor, and "typedef struct ResultRelInfo *CatalogIndexState" exists in part to keep it that way. Since CatalogOpenIndexes() skips ri_TrigDesc and other fields, I would expect other malfunctions if some caller tried. Thanks, nm