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

Reply via email to