pgsql: Avoid unnecessary recursion to child tables in ALTER TABLE SET N

Поиск
Список
Период
Сортировка
От Tom Lane
Тема pgsql: Avoid unnecessary recursion to child tables in ALTER TABLE SET N
Дата
Msg-id E1kIbOC-0006CL-9l@gemulon.postgresql.org
обсуждение исходный текст
Список pgsql-committers
Avoid unnecessary recursion to child tables in ALTER TABLE SET NOT NULL.

If a partitioned table's column is already marked NOT NULL, there is
no need to examine its partitions, because we can rely on previous
DDL to have enforced that the child columns are NOT NULL as well.
(Unfortunately, the same cannot be said for traditional inheritance,
so for now we have to restrict the optimization to partitioned tables.)
Hence, we may skip recursing to child tables in this situation.

The reason this case is worth worrying about is that when pg_dump dumps
a partitioned table having a primary key, it will include the requisite
NOT NULL markings in the CREATE TABLE commands, and then add the
primary key as a separate step.  The primary key addition generates a
SET NOT NULL as a subcommand, just to be sure.  So the situation where
a SET NOT NULL is redundant does arise in the real world.

Skipping the recursion does more than just save a few cycles: it means
that a command such as "ALTER TABLE ONLY partition_parent ADD PRIMARY
KEY" will take locks only on the partition parent table, not on the
partitions.  It turns out that parallel pg_restore is effectively
assuming that that's true, and has little choice but to do so because
the dependencies listed for such a TOC entry don't include the
partitions.  pg_restore could thus issue this ALTER while data restores
on the partitions are still in progress.  Taking unnecessary locks on
the partitions not only hurts concurrency, but can lead to actual
deadlock failures, as reported by Domagoj Smoljanovic.

(A contributing factor in the deadlock is that TRUNCATE on a child
partition wants a non-exclusive lock on the parent.  This seems
likewise unnecessary, but the fix for it is more invasive so we
won't consider back-patching it.  Fortunately, getting rid of one
of these two poor behaviors is enough to remove the deadlock.)

Although support for partitioned primary keys came in with v11,
this patch is dependent on the SET NOT NULL refactoring done by
commit f4a3fdfbd, so we can only patch back to v12.

Patch by me; thanks to Alvaro Herrera and Amit Langote for review.

Discussion: https://postgr.es/m/VI1PR03MB31670CA1BD9625C3A8C5DD05EB230@VI1PR03MB3167.eurprd03.prod.outlook.com

Branch
------
master

Details
-------
https://git.postgresql.org/pg/commitdiff/e5fac1cb1941e4adbcb88206f914e2035e5cccf2

Modified Files
--------------
src/backend/commands/tablecmds.c | 45 +++++++++++++++++++++++++++++++++-------
1 file changed, 38 insertions(+), 7 deletions(-)


В списке pgsql-committers по дате отправления:

Предыдущее
От: Tom Lane
Дата:
Сообщение: pgsql: Fix bogus cache-invalidation logic in logical replication worker
Следующее
От: Peter Geoghegan
Дата:
Сообщение: pgsql: Fix amcheck child check pg_upgrade bug.