This can lead to deadlocks during parallel restore. Test case: create table bar (a int primary key, b int); create table baz (z int, a int references bar); create view foo as select a, b, sum(1) from bar group by a union all select z, a, 0 from baz;
I dumped this with: pg_dump -Fc -s -f test.dmp Then: while (dropdb rhaas; createdb; pg_restore -O -d rhaas -j3 test.dmp); do true; done This quickly fails for me with: pg_restore: [archiver (db)] Error while PROCESSING TOC: pg_restore: [archiver (db)] Error from TOC entry 2155; 2606 47822 FK CONSTRAINT baz_a_fkey rhaas pg_restore: [archiver (db)] could not execute query: ERROR: deadlock detected DETAIL: Process 81791 waits for AccessExclusiveLock on relation 47862 of database 47861; blocked by process 81789. Process 81789 waits for AccessShareLock on relation 47865 of database 47861; blocked by process 81791. HINT: See server log for query details. Command was: ALTER TABLE ONLY baz ADD CONSTRAINT baz_a_fkey FOREIGN KEY (a) REFERENCES bar(a); WARNING: errors ignored on restore: 2 The attached patch seems to fix it for me. Comments? -- Robert Haas EnterpriseDB: http://www.enterprisedb.com The Enterprise PostgreSQL Company
diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c index ded9135..0393153 100644 --- a/src/bin/pg_dump/pg_backup_archiver.c +++ b/src/bin/pg_dump/pg_backup_archiver.c @@ -4140,11 +4140,10 @@ identify_locking_dependencies(ArchiveHandle *AH, TocEntry *te) return; /* - * We assume the item requires exclusive lock on each TABLE DATA item - * listed among its dependencies. (This was originally a dependency on - * the TABLE, but fix_dependencies repointed it to the data item. Note - * that all the entry types we are interested in here are POST_DATA, so - * they will all have been changed this way.) + * We assume the item requires exclusive lock on each TABLE or TABLE DATA + * item listed among its dependencies. (fix_dependencies may have + * repointed TABLE dependencies at TABLE DATA items, but not in a + * schema-only dump.) */ lockids = (DumpId *) pg_malloc(te->nDeps * sizeof(DumpId)); nlockids = 0; @@ -4153,7 +4152,8 @@ identify_locking_dependencies(ArchiveHandle *AH, TocEntry *te) DumpId depid = te->dependencies[i]; if (depid <= AH->maxDumpId && AH->tocsByDumpId[depid] != NULL && - strcmp(AH->tocsByDumpId[depid]->desc, "TABLE DATA") == 0) + ((strcmp(AH->tocsByDumpId[depid]->desc, "TABLE DATA") == 0) || + strcmp(AH->tocsByDumpId[depid]->desc, "TABLE") == 0)) lockids[nlockids++] = depid; }
-- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers