aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTom Lane <tgl@sss.pgh.pa.us>2023-01-03 17:56:37 -0500
committerTom Lane <tgl@sss.pgh.pa.us>2023-01-03 17:56:44 -0500
commit5f53b42cfd053a724fcbe0712a9d5716e576a3e6 (patch)
tree34bbc9ea111022775683c7f6ad5e900b1fc6f3bb /src
parentb23837dde48028f9e31983c765c32e3f42cb7ef2 (diff)
downloadpostgresql-5f53b42cfd053a724fcbe0712a9d5716e576a3e6.tar.gz
postgresql-5f53b42cfd053a724fcbe0712a9d5716e576a3e6.zip
During pg_dump startup, acquire table locks in batches.
Combine multiple LOCK TABLE commands to reduce the number of round trips to the server. This is particularly helpful when dumping from a remote server, but it seems useful even without that. In particular, shortening the time from seeing a table in pg_class to acquiring lock on it reduces the window for trouble from concurrent DDL. Aleksander Alekseev, reviewed by Fabrízio de Royes Mello, Gilles Darold, and Andres Freund Discussion: https://postgr.es/m/CAJ7c6TO4z1+OBa-R+fC8FnaUgbEWJUf2Kq=nRngTW5EXtKru2g@mail.gmail.com
Diffstat (limited to 'src')
-rw-r--r--src/bin/pg_dump/pg_dump.c36
1 files changed, 31 insertions, 5 deletions
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index 755d75ae4dc..30718dd7582 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -6470,6 +6470,8 @@ getTables(Archive *fout, int *numTables)
ExecuteSqlStatement(fout, query->data);
}
+ resetPQExpBuffer(query);
+
for (i = 0; i < ntups; i++)
{
tblinfo[i].dobj.objType = DO_TABLE;
@@ -6587,14 +6589,38 @@ getTables(Archive *fout, int *numTables)
(tblinfo[i].relkind == RELKIND_RELATION ||
tblinfo[i].relkind == RELKIND_PARTITIONED_TABLE))
{
- resetPQExpBuffer(query);
- appendPQExpBuffer(query,
- "LOCK TABLE %s IN ACCESS SHARE MODE",
- fmtQualifiedDumpable(&tblinfo[i]));
- ExecuteSqlStatement(fout, query->data);
+ /*
+ * Tables are locked in batches. When dumping from a remote
+ * server this can save a significant amount of time by reducing
+ * the number of round trips.
+ */
+ if (query->len == 0)
+ appendPQExpBuffer(query, "LOCK TABLE %s",
+ fmtQualifiedDumpable(&tblinfo[i]));
+ else
+ {
+ appendPQExpBuffer(query, ", %s",
+ fmtQualifiedDumpable(&tblinfo[i]));
+
+ /* Arbitrarily end a batch when query length reaches 100K. */
+ if (query->len >= 100000)
+ {
+ /* Lock another batch of tables. */
+ appendPQExpBufferStr(query, " IN ACCESS SHARE MODE");
+ ExecuteSqlStatement(fout, query->data);
+ resetPQExpBuffer(query);
+ }
+ }
}
}
+ if (query->len != 0)
+ {
+ /* Lock the tables in the last batch. */
+ appendPQExpBufferStr(query, " IN ACCESS SHARE MODE");
+ ExecuteSqlStatement(fout, query->data);
+ }
+
if (dopt->lockWaitTimeout)
{
ExecuteSqlStatement(fout, "SET statement_timeout = 0");