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 1twLUt-00D8NF-UI for pgsql-general@arkaria.postgresql.org; Sun, 23 Mar 2025 13:36:15 +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 1twLUr-00GMDv-Q1 for pgsql-general@arkaria.postgresql.org; Sun, 23 Mar 2025 13:36:13 +0000 Received: from magus.postgresql.org ([2a02:c0:301:0:ffff::29]) by malur.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.94.2) (envelope-from ) id 1twLUr-00GMDn-C0 for pgsql-general@lists.postgresql.org; Sun, 23 Mar 2025 13:36:13 +0000 Received: from mail-lf1-x129.google.com ([2a00:1450:4864:20::129]) by magus.postgresql.org with esmtps (TLS1.3) tls TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (Exim 4.96) (envelope-from ) id 1twLUo-000g94-37 for pgsql-general@postgresql.org; Sun, 23 Mar 2025 13:36:13 +0000 Received: by mail-lf1-x129.google.com with SMTP id 2adb3069b0e04-54991d85f99so4862751e87.1 for ; Sun, 23 Mar 2025 06:36:10 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1742736970; x=1743341770; darn=postgresql.org; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=3Azhd63kDSsr3N9QVFm8cD6vA9KrV0Dhl2qec47L6Ws=; b=EUdwYsOZgj4NcEMf1Z9BzLxNZmRCFbYzVdbYV0uhF4k8ODvJDb3v8dZxTmBbIXu+YU 6oa2ixZK+2jKOnKhg8BfSNBWcRAS9jdJN8dumBw5c2A2iS0PQN4VuCLq2c1xJpXtTG66 Vd0H8l86wbZsBmdWQDdNja3WzswC5+DfNNT4o7UT6JgPYLPtWeNcebN2Swv2G33M8xEM /bla2bjHyhicnJGPdFoyh/0K39LIJsqylWTlSU6n0lx1P9XtKLsW1kYsi1Hp1rhpSXdY SuchOwaDAztUfhnGmymMRkbiv39sR7AWaBZLMluFsxLzVi/gl5ba4i+DxRbaSWtAKZpe l9tw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1742736970; x=1743341770; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=3Azhd63kDSsr3N9QVFm8cD6vA9KrV0Dhl2qec47L6Ws=; b=SsgykKVfKzNT8IUN3oFf44bwOpBQz6czbeA05cOIOqK0GAi+xP4ANdsqTZvQdBIBGH i1wrY7ty1ZMcfWAoEE+myBeg+JYZLi4v4GeZSWgg2YdXcs+ExJTa30UhH/O0SJaela1p TzqoINh1mWPl+4CHlfbM/HXnfvDXvYzjIZAVXD5iwlWJA4VgMaN5WOoQiiUGzLYonOqi 6hkfB/SlMIaqiPUtp51PiflcJvOMemBZ9lU1ww0t3XOBBT8fEnXsnFvRH9cbfNHF0Yld htDaoIxjvbCjeDzTLU9XeY+nvbrGDKYgOF4tc2XxE3qkg2McURY1JVnXu9pmZGyvp35X 79OQ== X-Gm-Message-State: AOJu0YyiNHDHAUwY9fvTyPqD9CPkzi5dGfe7zAafDITyNVEruDAOFfOJ KbJRrDVr8uJvOpNnQU/aOwjs1aj8kuryhzfpOx3SENfnALdsaXIdLzXMhwxLXZ9J6aO0ZVhPi2e RIt8rvCSHXZO2D93UBL1KeNuAgL0U/JZf X-Gm-Gg: ASbGncsNTakOhO8rWveBBPFOurm+/54xG+eSvTwQ0zPiyqM4J+jR+wNJsPbRRkg0dsd ihgIlgHvn9n+wGYhILpNRzcw9fc/X1ze+VZAbCRvbFNojTzEr8wwvzCPAkVOlmYb2TLEooY9KCB GDavIA1DR7foxEcuFBpNumpKYmK1HQt2MYmTluhLEtPFQWFFkSJ6PLBwn2dXA= X-Google-Smtp-Source: AGHT+IF15robGkjT1DHebSivAhiSJPfRLIB4CcxIj2IvfqNazi697cRoA4AwO9GFeCeXRvVFND7914SyLnH0jhC4gKI= X-Received: by 2002:a05:6512:68a:b0:549:9813:3e6b with SMTP id 2adb3069b0e04-54ad5f9283amr4217722e87.0.1742736969649; Sun, 23 Mar 2025 06:36:09 -0700 (PDT) MIME-Version: 1.0 References: <01020195b987abd3-a008b77d-8c63-4931-80a4-be36a351c8b2-000000@eu-west-1.amazonses.com> In-Reply-To: <01020195b987abd3-a008b77d-8c63-4931-80a4-be36a351c8b2-000000@eu-west-1.amazonses.com> From: David Rowley Date: Mon, 24 Mar 2025 02:35:58 +1300 X-Gm-Features: AQ5f1Jonup0VcCy-X6Yr1SqLP_NW3pZTNV8XCIsUC0a7MkeYHl4-nPRdqmRVYLw Message-ID: Subject: Re: Querying one partition in a function takes locks on all partitions To: Evgeny Morozov Cc: PostgreSQL General Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable List-Id: List-Help: List-Subscribe: List-Post: List-Owner: List-Archive: Archived-At: Precedence: bulk On Sat, 22 Mar 2025 at 05:27, Evgeny Morozov wrote: > select read_partition(1); -- This takes shared locks on entity_1 AND > entity_2 > > -- select count(*) from entity where part_id =3D 1; -- but this would onl= y > take a shared lock only on entity_1 > > If another session tries something that takes an exclusive lock on > another partition, like > > alter table entity_2 add column new_column text; Is this just an example command? You can't add a column to a partition directly. > I would expect that to be able to run concurrently, but it blocks due to > the shared lock on entity_2. (The way I originally found the problem was > the opposite: once one client took an exclusive lock on a partition many > others were blocked from reading from ANY partition.) > > This seems like quite the "gotcha", especially when the query plan for > the function call (logged via autoexplain) shows it only accessing one > partition (entity_1). Is this expected behavior? If so, is it documented > somewhere? It is expected behaviour and, unfortunately, not really documented anywhere outside of the source code. What's going on is that PostgreSQL is creating a generic plan for your query, that is, a plan that will work with any parameter value that you give to your function. When the generic plan is executed and the locks are taken for the relations mentioned in the query, and since the plan is generic, it includes all partitions that could match any possible parameter value you could pass. When the locks are taken, it's not yet known which partition will be needed as the partition pruning that occurs only does so after the locks are taken. There has been work done for PostgreSQL 18 which swaps the order of these operations and makes it so that the executor only obtains the locks on the partitions which will actually be scanned. Hopefully, we'll see that feature released with PostgreSQL 18 toward the end of 2025. As for the documentation, it might be worth adding a mention of this at the end of the following paragraph in [1]: "During initialization of the query plan. Partition pruning can be performed here for parameter values which are known during the initialization phase of execution. Partitions which are pruned during this stage will not show up in the query's EXPLAIN or EXPLAIN ANALYZE. It is possible to determine the number of partitions which were removed during this phase by observing the =E2=80=9CSubplans Removed=E2=80= =9D property in the EXPLAIN output." Perhaps something like. "It's important to note that any partitions removed by the partition pruning done at this time are still locked at the beginning of execution". David [1] https://www.postgresql.org/docs/17/ddl-partitioning.html