diff --git a/src/bin/pg_dump/common.c b/src/bin/pg_dump/common.c
index 4d35ae5..06c8647 100644
--- a/src/bin/pg_dump/common.c
+++ b/src/bin/pg_dump/common.c
@@ -244,6 +244,9 @@ getSchemaData(Archive *fout, int *numTablesPtr)
 		write_msg(NULL, "reading rewrite rules\n");
 	getRules(fout, &numRules);
 
+	/* Do this last... */
+	unlockCatalogs(fout, tblinfo, numTables);
+
 	*numTablesPtr = numTables;
 	return tblinfo;
 }
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 4fabc1d..f5f382f 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -4797,6 +4797,18 @@ getTables(Archive *fout, int *numTables)
 		if (tblinfo[i].dobj.dump && tblinfo[i].relkind == RELKIND_RELATION)
 		{
 			resetPQExpBuffer(query);
+
+			/*
+			 * Lock the catalog for the objects first. This lock will
+			 * be released when we have all catalog information, leaving
+			 * the AccessShareLock to persist while we dump data (if any).
+			 */
+			if (fout->remoteVersion >= 90400)
+				appendPQExpBuffer(query,
+							  "SELECT pg_lock_catalog('%s');",
+							  fmtQualifiedId(fout->remoteVersion,
+										tblinfo[i].dobj.namespace->dobj.name,
+											 tblinfo[i].dobj.name));
 			appendPQExpBuffer(query,
 							  "LOCK TABLE %s IN ACCESS SHARE MODE",
 							  fmtQualifiedId(fout->remoteVersion,
@@ -4824,6 +4836,49 @@ getTables(Archive *fout, int *numTables)
 }
 
 /*
+ * unlockCatalogs
+ *
+ * Catalogs are locked for dumpable objects in getTables()
+ * unlockCatalogs() is called right at the end of catalog access
+ */
+void
+unlockCatalogs(Archive *fout, TableInfo tblinfo[], int numTables)
+{
+	PGresult   *res;
+	int			i;
+	PQExpBuffer query;
+
+	if (fout->remoteVersion < 90400)
+		return;
+
+	query = createPQExpBuffer();
+
+	for (i = 0; i < numTables; i++)
+	{
+		/*
+		 * Ensure this matches the list of objects locked in getTables()
+		 */
+		if (tblinfo[i].dobj.dump && tblinfo[i].relkind == RELKIND_RELATION)
+		{
+			resetPQExpBuffer(query);
+
+			/*
+			 * Unlock the catalog for the objects.
+			 */
+			appendPQExpBuffer(query,
+							  "SELECT pg_unlock_catalog('%s');",
+							  fmtQualifiedId(fout->remoteVersion,
+										tblinfo[i].dobj.namespace->dobj.name,
+											 tblinfo[i].dobj.name));
+			ExecuteSqlStatement(fout, query->data);
+		}
+	}
+
+	PQclear(res);
+
+	destroyPQExpBuffer(query);
+}
+/*
  * getOwnedSeqs
  *	  identify owned sequences and mark them as dumpable if owning table is
  *
diff --git a/src/bin/pg_dump/pg_dump.h b/src/bin/pg_dump/pg_dump.h
index c8dac35..e371d0a 100644
--- a/src/bin/pg_dump/pg_dump.h
+++ b/src/bin/pg_dump/pg_dump.h
@@ -553,6 +553,7 @@ extern OpfamilyInfo *getOpfamilies(Archive *fout, int *numOpfamilies);
 extern CollInfo *getCollations(Archive *fout, int *numCollations);
 extern ConvInfo *getConversions(Archive *fout, int *numConversions);
 extern TableInfo *getTables(Archive *fout, int *numTables);
+extern void unlockCatalogs(Archive *fout, TableInfo tblinfo[], int numTables);
 extern void getOwnedSeqs(Archive *fout, TableInfo tblinfo[], int numTables);
 extern InhInfo *getInherits(Archive *fout, int *numInherits);
 extern void getIndexes(Archive *fout, TableInfo tblinfo[], int numTables);
