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

@ -1,5 +1,5 @@
<!-- <!--
$PostgreSQL: pgsql/doc/src/sgml/ref/pg_dump.sgml,v 1.102 2008/04/13 03:49:21 tgl Exp $ $PostgreSQL: pgsql/doc/src/sgml/ref/pg_dump.sgml,v 1.103 2008/07/20 18:43:30 tgl Exp $
PostgreSQL documentation PostgreSQL documentation
--> -->
@ -415,23 +415,6 @@ PostgreSQL documentation
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><option>--no-tablespaces</option></term>
<listitem>
<para>
Do not output commands to select tablespaces.
With this option, all objects will be created in whichever
tablespace is the default during restore.
</para>
<para>
This option is only meaningful for the plain-text format. For
the archive formats, you can specify the option when you
call <command>pg_restore</command>.
</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><option>-s</option></term> <term><option>-s</option></term>
<term><option>--schema-only</option></term> <term><option>--schema-only</option></term>
@ -550,6 +533,18 @@ PostgreSQL documentation
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><option>-Z <replaceable class="parameter">0..9</replaceable></option></term>
<term><option>--compress=<replaceable class="parameter">0..9</replaceable></option></term>
<listitem>
<para>
Specify the compression level to use in archive formats that
support compression. (Currently only the custom archive
format supports compression.)
</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><option>--disable-dollar-quoting</></term> <term><option>--disable-dollar-quoting</></term>
<listitem> <listitem>
@ -587,6 +582,39 @@ PostgreSQL documentation
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><option>--lock-wait-timeout=<replaceable class="parameter">timeout</replaceable></option></term>
<listitem>
<para>
Do not wait forever to acquire shared table locks at the beginning of
the dump. Instead fail if unable to lock a table within the specified
<replaceable class="parameter">timeout</>. The timeout may be
specified in any of the formats accepted by <command>SET
statement_timeout</>. (Allowed values vary depending on the server
version you are dumping from, but an integer number of milliseconds
is accepted by all versions since 7.3. This option is ignored when
dumping from a pre-7.3 server.)
</para>
</listitem>
</varlistentry>
<varlistentry>
<term><option>--no-tablespaces</option></term>
<listitem>
<para>
Do not output commands to select tablespaces.
With this option, all objects will be created in whichever
tablespace is the default during restore.
</para>
<para>
This option is only meaningful for the plain-text format. For
the archive formats, you can specify the option when you
call <command>pg_restore</command>.
</para>
</listitem>
</varlistentry>
<varlistentry> <varlistentry>
<term><option>--use-set-session-authorization</></term> <term><option>--use-set-session-authorization</></term>
<listitem> <listitem>
@ -601,18 +629,6 @@ PostgreSQL documentation
</para> </para>
</listitem> </listitem>
</varlistentry> </varlistentry>
<varlistentry>
<term><option>-Z <replaceable class="parameter">0..9</replaceable></option></term>
<term><option>--compress=<replaceable class="parameter">0..9</replaceable></option></term>
<listitem>
<para>
Specify the compression level to use in archive formats that
support compression. (Currently only the custom archive
format supports compression.)
</para>
</listitem>
</varlistentry>
</variablelist> </variablelist>
</para> </para>

View File

@ -12,7 +12,7 @@
* by PostgreSQL * by PostgreSQL
* *
* IDENTIFICATION * 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 schemaOnly;
bool dataOnly; bool dataOnly;
bool aclsSkip; bool aclsSkip;
const char *lockWaitTimeout;
/* subquery used to convert user ID (eg, datdba) to user name */ /* subquery used to convert user ID (eg, datdba) to user name */
static const char *username_subquery; static const char *username_subquery;
@ -264,6 +265,7 @@ main(int argc, char **argv)
*/ */
{"disable-dollar-quoting", no_argument, &disable_dollar_quoting, 1}, {"disable-dollar-quoting", no_argument, &disable_dollar_quoting, 1},
{"disable-triggers", no_argument, &disable_triggers, 1}, {"disable-triggers", no_argument, &disable_triggers, 1},
{"lock-wait-timeout", required_argument, NULL, 2},
{"no-tablespaces", no_argument, &outputNoTablespaces, 1}, {"no-tablespaces", no_argument, &outputNoTablespaces, 1},
{"use-set-session-authorization", no_argument, &use_setsessauth, 1}, {"use-set-session-authorization", no_argument, &use_setsessauth, 1},
@ -279,6 +281,7 @@ main(int argc, char **argv)
strcpy(g_opaque_type, "opaque"); strcpy(g_opaque_type, "opaque");
dataOnly = schemaOnly = dumpInserts = attrNames = false; dataOnly = schemaOnly = dumpInserts = attrNames = false;
lockWaitTimeout = NULL;
progname = get_progname(argv[0]); progname = get_progname(argv[0]);
@ -437,6 +440,11 @@ main(int argc, char **argv)
/* This covers the long options equivalent to -X xxx. */ /* This covers the long options equivalent to -X xxx. */
break; break;
case 2:
/* lock-wait-timeout */
lockWaitTimeout = optarg;
break;
default: default:
fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname); fprintf(stderr, _("Try \"%s --help\" for more information.\n"), progname);
exit(1); exit(1);
@ -758,6 +766,7 @@ help(const char *progname)
printf(_(" -F, --format=c|t|p output file format (custom, tar, plain text)\n")); printf(_(" -F, --format=c|t|p output file format (custom, tar, plain text)\n"));
printf(_(" -v, --verbose verbose mode\n")); printf(_(" -v, --verbose verbose mode\n"));
printf(_(" -Z, --compress=0-9 compression level for compressed formats\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(_(" --help show this help, then exit\n"));
printf(_(" --version output version information, then exit\n")); printf(_(" --version output version information, then exit\n"));
@ -2957,8 +2966,6 @@ getTables(int *numTables)
int ntups; int ntups;
int i; int i;
PQExpBuffer query = createPQExpBuffer(); PQExpBuffer query = createPQExpBuffer();
PQExpBuffer delqry = createPQExpBuffer();
PQExpBuffer lockquery = createPQExpBuffer();
TableInfo *tblinfo; TableInfo *tblinfo;
int i_reltableoid; int i_reltableoid;
int i_reloid; int i_reloid;
@ -3192,6 +3199,21 @@ getTables(int *numTables)
i_reltablespace = PQfnumber(res, "reltablespace"); i_reltablespace = PQfnumber(res, "reltablespace");
i_reloptions = PQfnumber(res, "reloptions"); 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++) for (i = 0; i < ntups; i++)
{ {
tblinfo[i].dobj.objType = DO_TABLE; tblinfo[i].dobj.objType = DO_TABLE;
@ -3246,12 +3268,12 @@ getTables(int *numTables)
*/ */
if (tblinfo[i].dobj.dump && tblinfo[i].relkind == RELKIND_RELATION) if (tblinfo[i].dobj.dump && tblinfo[i].relkind == RELKIND_RELATION)
{ {
resetPQExpBuffer(lockquery); resetPQExpBuffer(query);
appendPQExpBuffer(lockquery, appendPQExpBuffer(query,
"LOCK TABLE %s IN ACCESS SHARE MODE", "LOCK TABLE %s IN ACCESS SHARE MODE",
fmtQualifiedId(tblinfo[i].dobj.namespace->dobj.name, fmtQualifiedId(tblinfo[i].dobj.namespace->dobj.name,
tblinfo[i].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 */ /* Emit notice if join for owner failed */
@ -3260,6 +3282,11 @@ getTables(int *numTables)
tblinfo[i].dobj.name); tblinfo[i].dobj.name);
} }
if (lockWaitTimeout && g_fout->remoteVersion >= 70300)
{
do_sql_command(g_conn, "SET statement_timeout = 0");
}
PQclear(res); PQclear(res);
/* /*
@ -3292,8 +3319,6 @@ getTables(int *numTables)
} }
destroyPQExpBuffer(query); destroyPQExpBuffer(query);
destroyPQExpBuffer(delqry);
destroyPQExpBuffer(lockquery);
return tblinfo; return tblinfo;
} }