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 1kB51g-0000gk-9w for pgsql-hackers@arkaria.postgresql.org; Wed, 26 Aug 2020 23:40:20 +0000 Received: from localhost ([127.0.0.1] helo=malur.postgresql.org) by malur.postgresql.org with esmtp (Exim 4.92) (envelope-from ) id 1kB51e-000408-U7 for pgsql-hackers@arkaria.postgresql.org; Wed, 26 Aug 2020 23:40:18 +0000 Received: from makus.postgresql.org ([2001:4800:3e1:1::229]) by malur.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim 4.92) (envelope-from ) id 1kB51e-000401-Ih for pgsql-hackers@lists.postgresql.org; Wed, 26 Aug 2020 23:40:18 +0000 Received: from mail-qv1-xf44.google.com ([2607:f8b0:4864:20::f44]) by makus.postgresql.org with esmtps (TLS1.3:ECDHE_RSA_AES_128_GCM_SHA256:128) (Exim 4.92) (envelope-from ) id 1kB51X-0006I3-Gg for pgsql-hackers@lists.postgresql.org; Wed, 26 Aug 2020 23:40:17 +0000 Received: by mail-qv1-xf44.google.com with SMTP id cs12so1861332qvb.2 for ; Wed, 26 Aug 2020 16:40:11 -0700 (PDT) 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=cvN3UwtznKV5U6FwSHxTDIHhbB618ly/8b/MA/MuW6E=; b=MDjYzOW2vd6ZjP78i7YNFlaVd3aye7tLdYVVAxNJFeUSQAEUW4fz9kIOLQngy4wQ89 t1HYq3+O9Vyw9XpmBeiCLzYoZsRLhl+nK/pxkBJHOjaD6AP6qzu/ZmjaZrGBjwl0NTkL W498hypP/aGPXw3Z9KypZgUnVPa+ELmCEcHP6cbLIWIwio0GXGC7htjHfBmHZmM/Icfh pdeXmSSTtKBap0UqblmfuaLUOp56nIEVQSUHitWjV29iInVs4IxyQPS1qCIS3wA53LUy Fxh3a3SlZd6Vc/Ud1LosLK44IIfRIZlrD7A9n+RBtO3OptDd9seg7bS/lNHtp95bPJWC AGHQ== 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=cvN3UwtznKV5U6FwSHxTDIHhbB618ly/8b/MA/MuW6E=; b=h1Dn3vkw16JW+K3ZU+X7J/F5tqnfe/qxWiaAjuidgxImNGEZSsNTmRvnexrR9IeuTM oHV8CIdN/+i9PVY4It1xnr73rYEzq2W8wQd4Sv5pGxeDDdj6z+wHw+r+txWomjgxjFlo Ss74hy/J7i/41eMLP/JB0LXuLGN9Peq7lMUBFPdAZ8PmN44AqdRNkxSTwD2A493IWVFP zAAyUg+Qt4sdKbnRPvQScBGsBfn4LE00xTaZmWdtLVeWTKQAcPrii26Umro0GH2CXG3z g7XtSVcg96c/egNipw02ug6fpsHDztK8deEZOG59ZqjPuLWGquiYyMgmkwEbNIn4Jtvl e9OQ== X-Gm-Message-State: AOAM530gXT4XAz4ChcnkbXG6LberCNYFq7LCPHleSw9IRUVKUlUL+X10 rz1fGEl/wEp5kRfR75Bp0qtYaw== X-Google-Smtp-Source: ABdhPJyHqp+tBaiAJZtHyWzIXPDYlqE+6QZCWP7+Eo8Uyvy/+pJC6GVvhTbM3je0zHQkf8KbEZWk9w== X-Received: by 2002:ad4:576c:: with SMTP id r12mr16562382qvx.232.1598485210408; Wed, 26 Aug 2020 16:40:10 -0700 (PDT) Received: from perhan.alvh.no-ip.org ([190.95.19.47]) by smtp.gmail.com with ESMTPSA id g184sm526967qkd.51.2020.08.26.16.40.09 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 26 Aug 2020 16:40:09 -0700 (PDT) Received: by perhan.alvh.no-ip.org (Postfix, from userid 1000) id BC6B52A19E4; Wed, 26 Aug 2020 19:40:07 -0400 (-04) Date: Wed, 26 Aug 2020 19:40:07 -0400 From: Alvaro Herrera To: Robert Haas Cc: Pg Hackers Subject: Re: ALTER TABLE .. DETACH PARTITION CONCURRENTLY Message-ID: <20200826234007.GA4584@alvherre.pgsql> MIME-Version: 1.0 Content-Type: text/plain; charset=iso-8859-1 Content-Disposition: inline Content-Transfer-Encoding: 8bit In-Reply-To: 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-Aug-04, Robert Haas wrote: > On Mon, Aug 3, 2020 at 7:49 PM Alvaro Herrera wrote: > > Why two transactions? The reason is that in order for this to work, we > > make a catalog change (mark it detached), and commit so that all > > concurrent transactions can see the change. A second transaction waits > > for anybody who holds any lock on the partitioned table and grabs Access > > Exclusive on the partition (which now no one cares about, if they're > > looking at the partitioned table), where the DDL action on the partition > > can be completed. > > Is there a more detailed theory of operation of this patch somewhere? > What exactly do you mean by marking it detached? Committing the change > makes it possible for all concurrent transactions to see the change, > but does not guarantee that they will. If you can't guarantee that, > then I'm not sure how you can guarantee that they will behave sanely. Sorry for the long delay. I haven't written up the theory of operation. I suppose it is complicated enough that it should be documented somewhere. To mark it detached means to set pg_inherits.inhdetached=true. That column name is a bit of a misnomer, since that column really means "is in the process of being detached"; the pg_inherits row goes away entirely once the detach process completes. This mark guarantees that everyone will see that row because the detaching session waits long enough after committing the first transaction and before deleting the pg_inherits row, until everyone else has moved on. The other point is that the partition directory code can be asked to include detached partitions, or not to. The executor does the former, and the planner does the latter. This allows a transient period during which the partition descriptor returned to planner and executor is different; this makes the situation equivalent to what would have happened if the partition was attached during the operation: in executor we would detect that there is an additional partition that was not seen by the planner, and we already know how to deal with that situation by your handling of the ATTACH code. > Even if you can, it's not clear what the sane behavior is: what > happens when a tuple gets routed to an ex-partition? What happens when > an ex-partition needs to be scanned? During the transient period, any transaction that obtained a partition descriptor before the inhdetached mark is committed should be able to get the tuple routing done successfully, but transactions using later snapshots should get their insertions rejected. Reads should behave in the same way. > What prevents problems if a partition is detached, possibly modified, > and then reattached, possibly with different partition bounds? This should not be a problem, because the partition needs to be fully detached before it can be attached again. And if the partition bounds are different, that won't be a problem, because the previous partition bounds won't be present in the pg_class row. Of course, the new partition bounds will be checked to the existing contents. There is one fly in the ointment though, which is that if you cancel the wait and then immediately do the ALTER TABLE DETACH FINALIZE without waiting for as long as the original execution would have waited, you might end up killing the partition ahead of time. One solution to this would be to cause the FINALIZE action to wait again at start. This would cause it to take even longer, but it would be safer. (If you don't want it to take longer, you can just not cancel it in the first place.) This is not a problem if the server crashes in between (which is the scenario I had in mind when doing the FINALIZE thing), because of course no transaction can continue to run across a crash. I'm going to see if I can get the new delay_execution module to help test this, to verify whether my claims are true. -- Álvaro Herrera https://www.2ndQuadrant.com/ PostgreSQL Development, 24x7 Support, Remote DBA, Training & Services