1
0
mirror of https://github.com/postgres/postgres.git synced 2025-07-28 23:42:10 +03:00

Add a pg_dump option --lock-wait-timeout to allow failing the dump if unable

to acquire shared table locks within a specified amount of time.

David Gould
This commit is contained in:
Tom Lane
2008-07-20 18:43:30 +00:00
parent b133ceb77d
commit 673a30fbb2
2 changed files with 88 additions and 47 deletions

View File

@ -12,7 +12,7 @@
* by PostgreSQL
*
* IDENTIFICATION
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.496 2008/07/18 03:32:52 tgl Exp $
* $PostgreSQL: pgsql/src/bin/pg_dump/pg_dump.c,v 1.497 2008/07/20 18:43:30 tgl Exp $
*
*-------------------------------------------------------------------------
*/
@ -71,6 +71,7 @@ bool attrNames; /* put attr names into insert strings */
bool schemaOnly;
bool dataOnly;
bool aclsSkip;
const char *lockWaitTimeout;
/* subquery used to convert user ID (eg, datdba) to user name */
static const char *username_subquery;
@ -264,6 +265,7 @@ main(int argc, char **argv)
*/
{"disable-dollar-quoting", no_argument, &disable_dollar_quoting, 1},
{"disable-triggers", no_argument, &disable_triggers, 1},
{"lock-wait-timeout", required_argument, NULL, 2},
{"no-tablespaces", no_argument, &outputNoTablespaces, 1},
{"use-set-session-authorization", no_argument, &use_setsessauth, 1},
@ -279,6 +281,7 @@ main(int argc, char **argv)
strcpy(g_opaque_type, "opaque");
dataOnly = schemaOnly = dumpInserts = attrNames = false;
lockWaitTimeout = NULL;
progname = get_progname(argv[0]);
@ -437,6 +440,11 @@ main(int argc, char **argv)
/* This covers the long options equivalent to -X xxx. */
break;
case 2:
/* lock-wait-timeout */
lockWaitTimeout = optarg;
break;
default:
fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
exit(1);
@ -754,12 +762,13 @@ help(const char *progname)
printf(_(" %s [OPTION]... [DBNAME]\n"), progname);
printf(_("\nGeneral options:\n"));
printf(_(" -f, --file=FILENAME output file name\n"));
printf(_(" -F, --format=c|t|p output file format (custom, tar, plain text)\n"));
printf(_(" -v, --verbose verbose mode\n"));
printf(_(" -Z, --compress=0-9 compression level for compressed formats\n"));
printf(_(" --help show this help, then exit\n"));
printf(_(" --version output version information, then exit\n"));
printf(_(" -f, --file=FILENAME output file name\n"));
printf(_(" -F, --format=c|t|p output file format (custom, tar, plain text)\n"));
printf(_(" -v, --verbose verbose mode\n"));
printf(_(" -Z, --compress=0-9 compression level for compressed formats\n"));
printf(_(" --lock-wait-timeout=TIMEOUT fail after waiting TIMEOUT for a table lock\n"));
printf(_(" --help show this help, then exit\n"));
printf(_(" --version output version information, then exit\n"));
printf(_("\nOptions controlling the output content:\n"));
printf(_(" -a, --data-only dump only the data, not the schema\n"));
@ -2957,8 +2966,6 @@ getTables(int *numTables)
int ntups;
int i;
PQExpBuffer query = createPQExpBuffer();
PQExpBuffer delqry = createPQExpBuffer();
PQExpBuffer lockquery = createPQExpBuffer();
TableInfo *tblinfo;
int i_reltableoid;
int i_reloid;
@ -3192,6 +3199,21 @@ getTables(int *numTables)
i_reltablespace = PQfnumber(res, "reltablespace");
i_reloptions = PQfnumber(res, "reloptions");
if (lockWaitTimeout && g_fout->remoteVersion >= 70300)
{
/*
* Arrange to fail instead of waiting forever for a table lock.
*
* NB: this coding assumes that the only queries issued within
* the following loop are LOCK TABLEs; else the timeout may be
* undesirably applied to other things too.
*/
resetPQExpBuffer(query);
appendPQExpBuffer(query, "SET statement_timeout = ");
appendStringLiteralConn(query, lockWaitTimeout, g_conn);
do_sql_command(g_conn, query->data);
}
for (i = 0; i < ntups; i++)
{
tblinfo[i].dobj.objType = DO_TABLE;
@ -3246,12 +3268,12 @@ getTables(int *numTables)
*/
if (tblinfo[i].dobj.dump && tblinfo[i].relkind == RELKIND_RELATION)
{
resetPQExpBuffer(lockquery);
appendPQExpBuffer(lockquery,
resetPQExpBuffer(query);
appendPQExpBuffer(query,
"LOCK TABLE %s IN ACCESS SHARE MODE",
fmtQualifiedId(tblinfo[i].dobj.namespace->dobj.name,
tblinfo[i].dobj.name));
do_sql_command(g_conn, lockquery->data);
do_sql_command(g_conn, query->data);
}
/* Emit notice if join for owner failed */
@ -3260,6 +3282,11 @@ getTables(int *numTables)
tblinfo[i].dobj.name);
}
if (lockWaitTimeout && g_fout->remoteVersion >= 70300)
{
do_sql_command(g_conn, "SET statement_timeout = 0");
}
PQclear(res);
/*
@ -3292,8 +3319,6 @@ getTables(int *numTables)
}
destroyPQExpBuffer(query);
destroyPQExpBuffer(delqry);
destroyPQExpBuffer(lockquery);
return tblinfo;
}