Received: from malur.postgresql.org ([217.196.149.56]) by arkaria.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1izq9R-0004ol-MM for pgsql-bugs@arkaria.postgresql.org; Thu, 06 Feb 2020 23:01:37 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.89) (envelope-from ) id 1izq9Q-0003Th-Ek for pgsql-bugs@arkaria.postgresql.org; Thu, 06 Feb 2020 23:01:36 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.2:ECDHE_RSA_AES_256_CBC_SHA1:256) (Exim 4.89) (envelope-from ) id 1izq9Q-0003TQ-2v for pgsql-bugs@lists.postgresql.org; Thu, 06 Feb 2020 23:01:36 +0000 Received: from mail-qt1-x842.google.com ([2607:f8b0:4864:20::842]) by makus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1izq9N-0008MK-MV for pgsql-bugs@lists.postgresql.org; Thu, 06 Feb 2020 23:01:34 +0000 Received: by mail-qt1-x842.google.com with SMTP id h12so482699qtu.1 for ; Thu, 06 Feb 2020 15:01:33 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=2ndquadrant-com.20150623.gappssmtp.com; s=20150623; h=date:from:to:cc:subject:message-id:mime-version:content-disposition :content-transfer-encoding:in-reply-to:user-agent; bh=pQLnbKiSEvz8JiHMg9MQ7JdtlyigPhr2PyNhgObrJrc=; b=CKY3QtYHOXk3M3sleYxlpGTxB2N/M4Fn9ZRfDSx/E6FHLfYpxhR27asrpqfD/c7N+I derJV0fUpsMJixbAzYJPaYT572tKd9YLMVnTJHiCpbalFXuJ7sYMIVXsvODEL7Xp9Vek xBqvJ1cUQxR8LUUOsiyz5NMNeqIG8XAVrIRTpg0m707EzMd54TUImS3GwFKcair5y11U 9RQkIRhqTE1xPK7AsN7TrSgfZn73MHfYqsrlcqvD0AnjTCAlQLchQHlcpf4YHAGCODGG RavnGmtiioGF9xxBdkaHuX9LrhxejXuiTO7a7ZShfWQWoU+WYZms+Fj0KD6FZX7QwK6a q5oQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:from:to:cc:subject:message-id:mime-version :content-disposition:content-transfer-encoding:in-reply-to :user-agent; bh=pQLnbKiSEvz8JiHMg9MQ7JdtlyigPhr2PyNhgObrJrc=; b=exqP+3rij61YavN0OBIYp0xf8LoCp0F6K5HR8+nBD5W2DMiuBF1x3R2IivWjJCbM3h MALi3arsTDYskZJSdJBXW+HxOYEPm+2LvIdUnqHx653/UjT+SBMC0OVlo6LbEiTi+QOv 39U7I85zGp7aHd0gNes0dWqMoYG18uBVE7AotGroc9rIzDVKXTrgDd3lpsILrGeEyW47 rsE9JbNFKFS4rApOn86/v9U+IMFeMN4s3EbVXwENLRRWISYkbE4P/tegiLtiR5WWK0AH xmP3acDRCWzDDJo8+Lulo2VRpe+Mys7tBAWH+2k2VnHcRiiK5dbZxxjx67PImRkJaO7I vJ8A== X-Gm-Message-State: APjAAAWCgF6ImpRrH9v0anY1ou2WrgwqL+r63yHBNvmCGtDUDRBR+h6e XIgBahQiNz+cdufWDoDdsVg6/FRwvuw= X-Google-Smtp-Source: APXvYqwLBunQA4TqpjD3uOjVey3NlfG9RpcyUw4pUMCyXQLSxbSdAHtbsQnkhc8TVzBtfiqudUgSBg== X-Received: by 2002:ac8:6697:: with SMTP id d23mr4853538qtp.235.1581030092542; Thu, 06 Feb 2020 15:01:32 -0800 (PST) Received: from nimloth.alvh.no-ip.org ([179.56.50.157]) by smtp.gmail.com with ESMTPSA id m27sm432478qta.21.2020.02.06.15.01.31 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 06 Feb 2020 15:01:31 -0800 (PST) Received: by nimloth.alvh.no-ip.org (Postfix, from userid 1000) id 4BBD3300807; Thu, 6 Feb 2020 20:01:29 -0300 (-03) Date: Thu, 6 Feb 2020 20:01:29 -0300 From: Alvaro Herrera To: Jehan-Guillaume de Rorthais Cc: pgsql-bugs@lists.postgresql.org Subject: Re: FK violation in partitioned table after truncating a referenced partition Message-ID: <20200206230129.GA9760@alvherre.pgsql> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: <20200206223015.GA32754@alvherre.pgsql> User-Agent: Mutt/1.10.1 (2018-07-13) List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Precedence: bulk On 2020-Feb-06, Alvaro Herrera wrote: > On 2020-Feb-06, Alvaro Herrera wrote: > > > I agree that patching heap_truncate_find_FKs is a reasonable way to fix. > > I propose a slightly different formulation: instead of the loop that you > > have, we can just use the second loop, and add more parent constraints > > to the list if any constraint we scan in turn has a parent constraint. > > So we don't repeat the whole thing, but only that second loop. > > Hmm, this doesn't actually work; I modified your test case and I see > that my code fails to do the right thing. Yeah, AFAICS both algorithms posted so far (yours and mine) are wrong. Maybe there's another way to fix it, but I think we're going to need the find_all_inheritors call you didn't want; here's a rough sketch of what I'm thinking: while (HeapTupleIsValid(tuple = systable_getnext(fkeyScan))) { Form_pg_constraint con = (Form_pg_constraint) GETSTRUCT(tuple); /* Not referencing one of our list of tables */ if (!list_member_oid(oids, con->confrelid)) continue; /* * If the constraint has a parent, climb up the partition hierarchy * all the way to the top. We need to process all the partitions * covered by the topmost constraint. */ while (OidIsValid(con->conparentid)) { scan2 = systable_beginscan(fkeyRel, ConstraintParentIndexId, true, NULL, 1, &key); tup2 = heap_copytuple(systable_getnext(scan2)); /* XXX leaks memory */ con = (Form_pg_constraint) GETSTRUCT(tup2); systable_endscan(scan2); } /* Add referencer to result, unless present in input list */ if (!list_member_oid(relationIds, con->conrelid)) result = lappend_oid(result, con->conrelid); if (conrelid is partitioned) { add each partition to result list; } } ENOTIME to complete it now, though ... also: I'm not sure about having heap_truncate_find_FKs() acquire the locks on partitions; but what happens if there's a concurrent detach? This is a larger can of worms than I imagined. Maybe a simpler solution is to say that you cannot truncate a partition; if you want that, truncate the topmost relation. No functionality seems lost with that restriction, or is it? And the semantics seem better defined anyway. (AFAICS this is implemented easily: if we see a non-invalid conparentid, raise an error). -- Álvaro Herrera https://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services