Remove pg_dump/pg_dumpall support for dumping from pre-9.2 servers.

Per discussion, we'll limit support for old servers to those branches
that can still be built easily on modern platforms, which as of now
is 9.2 and up.  Remove over a thousand lines of code dedicated to
dumping from older server versions.  (As in previous changes of
this sort, we aren't removing pg_restore's ability to read older
archive files ... though it's fair to wonder how that might be
tested nowadays.)  This cleans up some dead code left behind by
commit 989596152.

Discussion: https://postgr.es/m/2923349.1634942313@sss.pgh.pa.us
This commit is contained in:
Tom Lane 2021-12-14 17:09:07 -05:00
parent a2ff18e89f
commit 30e7c175b8
5 changed files with 417 additions and 1761 deletions

View File

@ -398,16 +398,6 @@ PostgreSQL documentation
different worker jobs wouldn't be guaranteed to see the same data in
each connection, which could lead to an inconsistent backup.
</para>
<para>
If you want to run a parallel dump of a pre-9.2 server, you need to make sure that the
database content doesn't change from between the time the leader connects to the
database until the last worker job has connected to the database. The easiest way to
do this is to halt any data modifying processes (DDL and DML) accessing the database
before starting the backup. You also need to specify the
<option>--no-synchronized-snapshots</option> parameter when running
<command>pg_dump -j</command> against a pre-9.2 <productname>PostgreSQL</productname>
server.
</para>
</listitem>
</varlistentry>
@ -945,9 +935,10 @@ PostgreSQL documentation
<term><option>--no-synchronized-snapshots</option></term>
<listitem>
<para>
This option allows running <command>pg_dump -j</command> against a pre-9.2
server, see the documentation of the <option>-j</option> parameter
for more details.
This option allows running <command>pg_dump -j</command> against a
pre-v10 standby server, at the cost of possibly producing an
inconsistent dump. See the documentation of the <option>-j</option>
parameter for more details.
</para>
</listitem>
</varlistentry>
@ -1381,7 +1372,7 @@ CREATE DATABASE foo WITH TEMPLATE template0;
<productname>PostgreSQL</productname> server versions newer than
<application>pg_dump</application>'s version. <application>pg_dump</application> can also
dump from <productname>PostgreSQL</productname> servers older than its own version.
(Currently, servers back to version 8.0 are supported.)
(Currently, servers back to version 9.2 are supported.)
However, <application>pg_dump</application> cannot dump from
<productname>PostgreSQL</productname> servers newer than its own major version;
it will refuse to even try, rather than risk making an invalid dump.

View File

@ -227,10 +227,6 @@ buildACLCommands(const char *name, const char *subname, const char *nspname,
appendPQExpBuffer(firstsql, "%s FROM ", name);
if (grantee->len == 0)
appendPQExpBufferStr(firstsql, "PUBLIC;\n");
else if (strncmp(grantee->data, "group ",
strlen("group ")) == 0)
appendPQExpBuffer(firstsql, "GROUP %s;\n",
fmtId(grantee->data + strlen("group ")));
else
appendPQExpBuffer(firstsql, "%s;\n",
fmtId(grantee->data));
@ -247,14 +243,9 @@ buildACLCommands(const char *name, const char *subname, const char *nspname,
* public privileges are added in new versions: the REVOKE ALL will revoke
* them, leading to behavior different from what the old version had,
* which is generally not what's wanted. So add back default privs if the
* source database is too old to have had that particular priv.
* source database is too old to have had that particular priv. (As of
* right now, no such cases exist in supported versions.)
*/
if (remoteVersion < 80200 && strcmp(type, "DATABASE") == 0)
{
/* database CONNECT priv didn't exist before 8.2 */
appendPQExpBuffer(firstsql, "%sGRANT CONNECT ON %s %s TO PUBLIC;\n",
prefix, type, name);
}
/*
* Scan individual ACL items to be granted.
@ -306,10 +297,6 @@ buildACLCommands(const char *name, const char *subname, const char *nspname,
appendPQExpBuffer(thissql, "%s TO ", name);
if (grantee->len == 0)
appendPQExpBufferStr(thissql, "PUBLIC;\n");
else if (strncmp(grantee->data, "group ",
strlen("group ")) == 0)
appendPQExpBuffer(thissql, "GROUP %s;\n",
fmtId(grantee->data + strlen("group ")));
else
appendPQExpBuffer(thissql, "%s;\n", fmtId(grantee->data));
}
@ -322,10 +309,6 @@ buildACLCommands(const char *name, const char *subname, const char *nspname,
appendPQExpBuffer(thissql, "%s TO ", name);
if (grantee->len == 0)
appendPQExpBufferStr(thissql, "PUBLIC");
else if (strncmp(grantee->data, "group ",
strlen("group ")) == 0)
appendPQExpBuffer(thissql, "GROUP %s",
fmtId(grantee->data + strlen("group ")));
else
appendPQExpBufferStr(thissql, fmtId(grantee->data));
appendPQExpBufferStr(thissql, " WITH GRANT OPTION;\n");
@ -420,16 +403,12 @@ buildDefaultACLCommands(const char *type, const char *nspname,
/*
* This will parse an aclitem string, having the general form
* username=privilegecodes/grantor
* or
* group groupname=privilegecodes/grantor
* (the "group" case occurs only with servers before 8.1).
*
* Returns true on success, false on parse error. On success, the components
* of the string are returned in the PQExpBuffer parameters.
*
* The returned grantee string will be the dequoted username or groupname
* (preceded with "group " in the latter case). Note that a grant to PUBLIC
* is represented by an empty grantee string. The returned grantor is the
* The returned grantee string will be the dequoted username, or an empty
* string in the case of a grant to PUBLIC. The returned grantor is the
* dequoted grantor name. Privilege characters are translated to GRANT/REVOKE
* comma-separated privileges lists. If "privswgo" is non-NULL, the result is
* separate lists for privileges with grant option ("privswgo") and without
@ -522,8 +501,7 @@ do { \
{
CONVERT_PRIV('d', "DELETE");
CONVERT_PRIV('t', "TRIGGER");
if (remoteVersion >= 80400)
CONVERT_PRIV('D', "TRUNCATE");
CONVERT_PRIV('D', "TRUNCATE");
}
}

View File

@ -904,13 +904,10 @@ restore_toc_entry(ArchiveHandle *AH, TocEntry *te, bool is_parallel)
StartTransaction(&AH->public);
/*
* If the server version is >= 8.4, make sure we issue
* TRUNCATE with ONLY so that child tables are not
* wiped.
* Issue TRUNCATE with ONLY so that child tables are
* not wiped.
*/
ahprintf(AH, "TRUNCATE TABLE %s%s;\n\n",
(PQserverVersion(AH->connection) >= 80400 ?
"ONLY " : ""),
ahprintf(AH, "TRUNCATE TABLE ONLY %s;\n\n",
fmtQualifiedId(te->namespace, te->tag));
}

File diff suppressed because it is too large Load Diff

View File

@ -36,7 +36,6 @@ static void help(void);
static void dropRoles(PGconn *conn);
static void dumpRoles(PGconn *conn);
static void dumpRoleMembership(PGconn *conn);
static void dumpGroups(PGconn *conn);
static void dropTablespaces(PGconn *conn);
static void dumpTablespaces(PGconn *conn);
static void dropDBs(PGconn *conn);
@ -440,8 +439,7 @@ main(int argc, char *argv[])
/*
* If there was a database specified on the command line, use that,
* otherwise try to connect to database "postgres", and failing that
* "template1". "postgres" is the preferred choice for 8.1 and later
* servers, but it usually will not exist on older ones.
* "template1".
*/
if (pgdb)
{
@ -517,7 +515,7 @@ main(int argc, char *argv[])
std_strings = "off";
/* Set the role if requested */
if (use_role && server_version >= 80100)
if (use_role)
{
PQExpBuffer query = createPQExpBuffer();
@ -527,7 +525,7 @@ main(int argc, char *argv[])
}
/* Force quoting of all identifiers if requested. */
if (quote_all_identifiers && server_version >= 90100)
if (quote_all_identifiers)
executeCommand(conn, "SET quote_all_identifiers = true");
fprintf(OPF, "--\n-- PostgreSQL database cluster dump\n--\n\n");
@ -581,11 +579,8 @@ main(int argc, char *argv[])
/* Dump roles (users) */
dumpRoles(conn);
/* Dump role memberships --- need different method for pre-8.1 */
if (server_version >= 80100)
dumpRoleMembership(conn);
else
dumpGroups(conn);
/* Dump role memberships */
dumpRoleMembership(conn);
}
/* Dump tablespaces */
@ -698,19 +693,11 @@ dropRoles(PGconn *conn)
"FROM %s "
"WHERE rolname !~ '^pg_' "
"ORDER BY 1", role_catalog);
else if (server_version >= 80100)
else
printfPQExpBuffer(buf,
"SELECT rolname "
"FROM %s "
"ORDER BY 1", role_catalog);
else
printfPQExpBuffer(buf,
"SELECT usename as rolname "
"FROM pg_shadow "
"UNION "
"SELECT groname as rolname "
"FROM pg_group "
"ORDER BY 1");
res = executeQuery(conn, buf->data);
@ -782,7 +769,7 @@ dumpRoles(PGconn *conn)
"rolname = current_user AS is_current_user "
"FROM %s "
"ORDER BY 2", role_catalog, role_catalog);
else if (server_version >= 90100)
else
printfPQExpBuffer(buf,
"SELECT oid, rolname, rolsuper, rolinherit, "
"rolcreaterole, rolcreatedb, "
@ -793,62 +780,6 @@ dumpRoles(PGconn *conn)
"rolname = current_user AS is_current_user "
"FROM %s "
"ORDER BY 2", role_catalog, role_catalog);
else if (server_version >= 80200)
printfPQExpBuffer(buf,
"SELECT oid, rolname, rolsuper, rolinherit, "
"rolcreaterole, rolcreatedb, "
"rolcanlogin, rolconnlimit, rolpassword, "
"rolvaliduntil, false as rolreplication, "
"false as rolbypassrls, "
"pg_catalog.shobj_description(oid, '%s') as rolcomment, "
"rolname = current_user AS is_current_user "
"FROM %s "
"ORDER BY 2", role_catalog, role_catalog);
else if (server_version >= 80100)
printfPQExpBuffer(buf,
"SELECT oid, rolname, rolsuper, rolinherit, "
"rolcreaterole, rolcreatedb, "
"rolcanlogin, rolconnlimit, rolpassword, "
"rolvaliduntil, false as rolreplication, "
"false as rolbypassrls, "
"null as rolcomment, "
"rolname = current_user AS is_current_user "
"FROM %s "
"ORDER BY 2", role_catalog);
else
printfPQExpBuffer(buf,
"SELECT 0 as oid, usename as rolname, "
"usesuper as rolsuper, "
"true as rolinherit, "
"usesuper as rolcreaterole, "
"usecreatedb as rolcreatedb, "
"true as rolcanlogin, "
"-1 as rolconnlimit, "
"passwd as rolpassword, "
"valuntil as rolvaliduntil, "
"false as rolreplication, "
"false as rolbypassrls, "
"null as rolcomment, "
"usename = current_user AS is_current_user "
"FROM pg_shadow "
"UNION ALL "
"SELECT 0 as oid, groname as rolname, "
"false as rolsuper, "
"true as rolinherit, "
"false as rolcreaterole, "
"false as rolcreatedb, "
"false as rolcanlogin, "
"-1 as rolconnlimit, "
"null::text as rolpassword, "
"null::timestamptz as rolvaliduntil, "
"false as rolreplication, "
"false as rolbypassrls, "
"null as rolcomment, "
"false AS is_current_user "
"FROM pg_group "
"WHERE NOT EXISTS (SELECT 1 FROM pg_shadow "
" WHERE usename = groname) "
"ORDER BY 2");
res = executeQuery(conn, buf->data);
@ -967,7 +898,7 @@ dumpRoles(PGconn *conn)
appendPQExpBufferStr(buf, ";\n");
}
if (!no_security_labels && server_version >= 90200)
if (!no_security_labels)
buildShSecLabels(conn, "pg_authid", auth_oid,
"ROLE", rolename,
buf);
@ -980,6 +911,9 @@ dumpRoles(PGconn *conn)
* We do it this way because config settings for roles could mention the
* names of other roles.
*/
if (PQntuples(res) > 0)
fprintf(OPF, "\n--\n-- User Configurations\n--\n");
for (i = 0; i < PQntuples(res); i++)
dumpUserConfig(conn, PQgetvalue(res, i, i_rolname));
@ -992,7 +926,7 @@ dumpRoles(PGconn *conn)
/*
* Dump role memberships. This code is used for 8.1 and later servers.
* Dump role memberships.
*
* Note: we expect dumpRoles already created all the roles, but there is
* no membership yet.
@ -1049,75 +983,6 @@ dumpRoleMembership(PGconn *conn)
fprintf(OPF, "\n\n");
}
/*
* Dump group memberships from a pre-8.1 server. It's annoying that we
* can't share any useful amount of code with the post-8.1 case, but
* the catalog representations are too different.
*
* Note: we expect dumpRoles already created all the roles, but there is
* no membership yet.
*/
static void
dumpGroups(PGconn *conn)
{
PQExpBuffer buf = createPQExpBuffer();
PGresult *res;
int i;
res = executeQuery(conn,
"SELECT groname, grolist FROM pg_group ORDER BY 1");
if (PQntuples(res) > 0)
fprintf(OPF, "--\n-- Role memberships\n--\n\n");
for (i = 0; i < PQntuples(res); i++)
{
char *groname = PQgetvalue(res, i, 0);
char *grolist = PQgetvalue(res, i, 1);
PGresult *res2;
int j;
/*
* Array representation is {1,2,3} ... convert to (1,2,3)
*/
if (strlen(grolist) < 3)
continue;
grolist = pg_strdup(grolist);
grolist[0] = '(';
grolist[strlen(grolist) - 1] = ')';
printfPQExpBuffer(buf,
"SELECT usename FROM pg_shadow "
"WHERE usesysid IN %s ORDER BY 1",
grolist);
free(grolist);
res2 = executeQuery(conn, buf->data);
for (j = 0; j < PQntuples(res2); j++)
{
char *usename = PQgetvalue(res2, j, 0);
/*
* Don't try to grant a role to itself; can happen if old
* installation has identically named user and group.
*/
if (strcmp(groname, usename) == 0)
continue;
fprintf(OPF, "GRANT %s", fmtId(groname));
fprintf(OPF, " TO %s;\n", fmtId(usename));
}
PQclear(res2);
}
PQclear(res);
destroyPQExpBuffer(buf);
fprintf(OPF, "\n\n");
}
/*
* Drop tablespaces.
@ -1167,41 +1032,15 @@ dumpTablespaces(PGconn *conn)
* Get all tablespaces except built-in ones (which we assume are named
* pg_xxx)
*/
if (server_version >= 90200)
res = executeQuery(conn, "SELECT oid, spcname, "
"pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
"pg_catalog.pg_tablespace_location(oid), "
"spcacl, acldefault('t', spcowner) AS acldefault, "
"array_to_string(spcoptions, ', '),"
"pg_catalog.shobj_description(oid, 'pg_tablespace') "
"FROM pg_catalog.pg_tablespace "
"WHERE spcname !~ '^pg_' "
"ORDER BY 1");
else if (server_version >= 90000)
res = executeQuery(conn, "SELECT oid, spcname, "
"pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
"spclocation, spcacl, NULL AS acldefault, "
"array_to_string(spcoptions, ', '),"
"pg_catalog.shobj_description(oid, 'pg_tablespace') "
"FROM pg_catalog.pg_tablespace "
"WHERE spcname !~ '^pg_' "
"ORDER BY 1");
else if (server_version >= 80200)
res = executeQuery(conn, "SELECT oid, spcname, "
"pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
"spclocation, spcacl, NULL AS acldefault, null, "
"pg_catalog.shobj_description(oid, 'pg_tablespace') "
"FROM pg_catalog.pg_tablespace "
"WHERE spcname !~ '^pg_' "
"ORDER BY 1");
else
res = executeQuery(conn, "SELECT oid, spcname, "
"pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
"spclocation, spcacl, NULL AS acldefault, "
"null, null "
"FROM pg_catalog.pg_tablespace "
"WHERE spcname !~ '^pg_' "
"ORDER BY 1");
res = executeQuery(conn, "SELECT oid, spcname, "
"pg_catalog.pg_get_userbyid(spcowner) AS spcowner, "
"pg_catalog.pg_tablespace_location(oid), "
"spcacl, acldefault('t', spcowner) AS acldefault, "
"array_to_string(spcoptions, ', '),"
"pg_catalog.shobj_description(oid, 'pg_tablespace') "
"FROM pg_catalog.pg_tablespace "
"WHERE spcname !~ '^pg_' "
"ORDER BY 1");
if (PQntuples(res) > 0)
fprintf(OPF, "--\n-- Tablespaces\n--\n\n");
@ -1253,7 +1092,7 @@ dumpTablespaces(PGconn *conn)
appendPQExpBufferStr(buf, ";\n");
}
if (!no_security_labels && server_version >= 90200)
if (!no_security_labels)
buildShSecLabels(conn, "pg_tablespace", spcoid,
"TABLESPACE", spcname,
buf);
@ -1323,52 +1162,31 @@ static void
dumpUserConfig(PGconn *conn, const char *username)
{
PQExpBuffer buf = createPQExpBuffer();
int count = 1;
bool first = true;
PGresult *res;
for (;;)
printfPQExpBuffer(buf, "SELECT unnest(setconfig) FROM pg_db_role_setting "
"WHERE setdatabase = 0 AND setrole = "
"(SELECT oid FROM %s WHERE rolname = ",
role_catalog);
appendStringLiteralConn(buf, username, conn);
appendPQExpBufferChar(buf, ')');
res = executeQuery(conn, buf->data);
if (PQntuples(res) > 0)
fprintf(OPF, "\n--\n-- User Config \"%s\"\n--\n\n", username);
for (int i = 0; i < PQntuples(res); i++)
{
PGresult *res;
if (server_version >= 90000)
printfPQExpBuffer(buf, "SELECT setconfig[%d] FROM pg_db_role_setting WHERE "
"setdatabase = 0 AND setrole = "
"(SELECT oid FROM %s WHERE rolname = ", count, role_catalog);
else if (server_version >= 80100)
printfPQExpBuffer(buf, "SELECT rolconfig[%d] FROM %s WHERE rolname = ", count, role_catalog);
else
printfPQExpBuffer(buf, "SELECT useconfig[%d] FROM pg_shadow WHERE usename = ", count);
appendStringLiteralConn(buf, username, conn);
if (server_version >= 90000)
appendPQExpBufferChar(buf, ')');
res = executeQuery(conn, buf->data);
if (PQntuples(res) == 1 &&
!PQgetisnull(res, 0, 0))
{
/* comment at section start, only if needed */
if (first)
{
fprintf(OPF, "--\n-- User Configurations\n--\n\n");
first = false;
}
fprintf(OPF, "--\n-- User Config \"%s\"\n--\n\n", username);
resetPQExpBuffer(buf);
makeAlterConfigCommand(conn, PQgetvalue(res, 0, 0),
"ROLE", username, NULL, NULL,
buf);
fprintf(OPF, "%s", buf->data);
PQclear(res);
count++;
}
else
{
PQclear(res);
break;
}
resetPQExpBuffer(buf);
makeAlterConfigCommand(conn, PQgetvalue(res, i, 0),
"ROLE", username, NULL, NULL,
buf);
fprintf(OPF, "%s", buf->data);
}
PQclear(res);
destroyPQExpBuffer(buf);
}
@ -1775,11 +1593,11 @@ connectDatabase(const char *dbname, const char *connection_string,
my_version = PG_VERSION_NUM;
/*
* We allow the server to be back to 8.4, and up to any minor release of
* We allow the server to be back to 9.2, and up to any minor release of
* our own major version. (See also version check in pg_dump.c.)
*/
if (my_version != server_version
&& (server_version < 80400 ||
&& (server_version < 90200 ||
(server_version / 100) > (my_version / 100)))
{
pg_log_error("server version: %s; %s version: %s",