Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1lLwGU-0004q6-Od for pgsql-hackers@arkaria.postgresql.org; Mon, 15 Mar 2021 23:04:46 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1lLwGT-0000Qt-LH for pgsql-hackers@arkaria.postgresql.org; Mon, 15 Mar 2021 23:04:45 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1lLwGT-0000QT-DR for pgsql-hackers@lists.postgresql.org; Mon, 15 Mar 2021 23:04:45 +0000 Received: from out3-smtp.messagingengine.com ([66.111.4.27]) by magus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1lLwGR-0002vJ-72 for pgsql-hackers@lists.postgresql.org; Mon, 15 Mar 2021 23:04:45 +0000 Received: from compute2.internal (compute2.nyi.internal [10.202.2.42]) by mailout.nyi.internal (Postfix) with ESMTP id D299A5C015E; Mon, 15 Mar 2021 19:04:40 -0400 (EDT) Received: from mailfrontend2 ([10.202.2.163]) by compute2.internal (MEProxy); Mon, 15 Mar 2021 19:04:40 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d= messagingengine.com; h=cc:content-transfer-encoding:content-type :date:from:in-reply-to:message-id:mime-version:subject:to :x-me-proxy:x-me-proxy:x-me-sender:x-me-sender:x-sasl-enc; s= fm2; bh=7ovHS69sAuyj7qFUpO4k4YtoPnQOaRr2AtMtUNr8oAU=; b=PWsImAUY ZQk9JsgxyryLmhE8qfZs0X/tU8JA5G2lYMfyAjdNlQMjM/FFXjwsu33q7q7A8QPt A3dq3nFZ5EdeWwgdLuHPpYZ4yDx6USEGa8qnDoj8SiOfEyRAqPv/BBmJEc1xG2n4 yozNqbGYPxKED74ddlqlflEgg6MBw+ktsYbw3zmReEUs67Be7S4msAxzNYEtQSQ1 AOttxs4K+1A6RbSiumaoJ9NBGxR+PwhsZX9midbqMSrI4Ttt9+7iBs3O21ttfyhl 7hqr1kLoatvn/5mC66mynJqnpMg7/ObK++beD89m7FXLlac7OGGRcfwebMI3P9RK Cf6I4BNsMSncMA== X-ME-Sender: X-ME-Proxy-Cause: gggruggvucftvghtrhhoucdtuddrgeduledrudefuddgtdegucetufdoteggodetrfdotf fvucfrrhhofhhilhgvmecuhfgrshhtofgrihhlpdfqfgfvpdfurfetoffkrfgpnffqhgen uceurghilhhouhhtmecufedttdenucesvcftvggtihhpihgvnhhtshculddquddttddmne cujfgurhepfffhvffukfggtggugfgjfgesmhekreertderudenucfhrhhomheptehlvhgr rhhoucfjvghrrhgvrhgruceorghlvhhhvghrrhgvsegrlhhvhhdrnhhoqdhiphdrohhrgh eqnecuggftrfgrthhtvghrnheptdelgeeuffeujedthfefveeludfgtdffhffgveeiieev tdekvedvveevfefgheejnecuffhomhgrihhnpegrtghtshhofhhgohhrugdrtghomhenuc fkphepudeltddrleehrdduledrleehnecuvehluhhsthgvrhfuihiivgeptdenucfrrghr rghmpehmrghilhhfrhhomheprghlvhhhvghrrhgvsegrlhhvhhdrnhhoqdhiphdrohhrgh X-ME-Proxy: Received: from perhan.alvh.no-ip.org (unknown [190.95.19.95]) by mail.messagingengine.com (Postfix) with ESMTPA id 46CE31080063; Mon, 15 Mar 2021 19:04:40 -0400 (EDT) Received: by perhan.alvh.no-ip.org (Postfix, from userid 1000) id A84F12A0AE1; Mon, 15 Mar 2021 20:04:37 -0300 (-03) Date: Mon, 15 Mar 2021 20:04:37 -0300 From: Alvaro Herrera To: Justin Pryzby Cc: Amit Langote , pgsql-hackers@lists.postgresql.org Subject: Re: ALTER TABLE .. DETACH PARTITION CONCURRENTLY Message-ID: <20210315230437.GA20801@alvherre.pgsql> MIME-Version: 1.0 Content-Type: multipart/mixed; boundary="M9NhX3UHpAaciwkO" Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <20210226203236.GA30377@alvherre.pgsql> User-Agent: Mutt/1.10.1 (2018-07-13) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk --M9NhX3UHpAaciwkO Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit On 2021-Feb-26, Alvaro Herrera wrote: > Hmm, but if we take this approach, then we're still vulnerable to the > problem that somebody can do DETACH CONCURRENTLY and cancel the wait (or > crash the server), then mess up the state before doing DETACH FINALIZE: > when they cancel the wait, the lock will be released. > > I think the right fix is to disallow any action on a partition which is > pending detach other than DETACH FINALIZE. (Didn't do that here.) Here's a fixup patch to do it that way. I tried running the commands you showed and one of them immediately dies with the new error message; I can't cause the bogus constraint to show up anymore. I'll clean this up for a real submission tomorrow. -- Álvaro Herrera 39°49'30"S 73°17'W "The Gord often wonders why people threaten never to come back after they've been told never to return" (www.actsofgord.com) --M9NhX3UHpAaciwkO Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="dont.notpatch" diff --git a/src/backend/catalog/pg_inherits.c b/src/backend/catalog/pg_inherits.c index 3fd0880ca0..83093f9730 100644 --- a/src/backend/catalog/pg_inherits.c +++ b/src/backend/catalog/pg_inherits.c @@ -535,3 +535,39 @@ DeleteInheritsTuple(Oid inhrelid, Oid inhparent, bool detached, return found; } + +bool +PartitionHasPendingDetach(Oid partoid) +{ + Relation catalogRelation; + ScanKeyData key; + SysScanDesc scan; + HeapTuple inheritsTuple; + + /* + * Find pg_inherits entries by inhrelid. + */ + catalogRelation = table_open(InheritsRelationId, RowExclusiveLock); + ScanKeyInit(&key, + Anum_pg_inherits_inhrelid, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(partoid)); + scan = systable_beginscan(catalogRelation, InheritsRelidSeqnoIndexId, + true, NULL, 1, &key); + + while (HeapTupleIsValid(inheritsTuple = systable_getnext(scan))) + { + bool detached; + + detached = ((Form_pg_inherits) GETSTRUCT(inheritsTuple))->inhdetached; + + /* Done */ + systable_endscan(scan); + table_close(catalogRelation, RowExclusiveLock); + + return detached; + } + + elog(ERROR, "relation %u is not a partition", partoid); + return false; /* keep compiler quiet */ +} diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 5986b4dd56..5074c0ff2b 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -17106,6 +17106,8 @@ ATExecDetachPartition(List **wqueue, AlteredTableInfo *tab, Relation rel, */ partRel = table_openrv(name, concurrent ? ShareLock : AccessExclusiveLock); + if (PartitionHasPendingDetach(RelationGetRelid(partRel))) + elog(ERROR, "hey, don't!"); /* * Check inheritance conditions and either delete the pg_inherits row diff --git a/src/include/catalog/pg_inherits.h b/src/include/catalog/pg_inherits.h index 155596907c..19243ea9e4 100644 --- a/src/include/catalog/pg_inherits.h +++ b/src/include/catalog/pg_inherits.h @@ -61,5 +61,6 @@ extern void StoreSingleInheritance(Oid relationId, Oid parentOid, int32 seqNumber); extern bool DeleteInheritsTuple(Oid inhrelid, Oid inhparent, bool allow_detached, const char *childname); +extern bool PartitionHasPendingDetach(Oid partoid); #endif /* PG_INHERITS_H */ --M9NhX3UHpAaciwkO--