aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBruce Momjian <bruce@momjian.us>2015-05-16 00:10:03 -0400
committerBruce Momjian <bruce@momjian.us>2015-05-16 00:10:03 -0400
commitfb694d959c97c912b49ec47326e6a05a8c0da11d (patch)
tree28e40adf6414969fe7d2109cbf0122cfb3538fb6 /src
parent12cc299c65ba6124c7d459f2605404ad43909db3 (diff)
downloadpostgresql-fb694d959c97c912b49ec47326e6a05a8c0da11d.tar.gz
postgresql-fb694d959c97c912b49ec47326e6a05a8c0da11d.zip
pg_upgrade: only allow template0 to be non-connectable
This patch causes pg_upgrade to error out during its check phase if: (1) template0 is marked connectable or (2) any other database is marked non-connectable This is done because, in the first case, pg_upgrade would fail because the pg_dumpall --globals restore would fail, and in the second case, the database would not be restored, leading to data loss. Report by Matt Landry (1), Stephen Frost (2) Backpatch through 9.0
Diffstat (limited to 'src')
-rw-r--r--src/bin/pg_upgrade/check.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/src/bin/pg_upgrade/check.c b/src/bin/pg_upgrade/check.c
index be66b24cf20..99c66be7fb4 100644
--- a/src/bin/pg_upgrade/check.c
+++ b/src/bin/pg_upgrade/check.c
@@ -19,6 +19,7 @@ static void check_databases_are_compatible(void);
static void check_locale_and_encoding(DbInfo *olddb, DbInfo *newdb);
static bool equivalent_locale(int category, const char *loca, const char *locb);
static void check_is_install_user(ClusterInfo *cluster);
+static void check_proper_datallowconn(ClusterInfo *cluster);
static void check_for_prepared_transactions(ClusterInfo *cluster);
static void check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster);
static void check_for_reg_data_type_usage(ClusterInfo *cluster);
@@ -93,6 +94,7 @@ check_and_dump_old_cluster(bool live_check)
* Check for various failure cases
*/
check_is_install_user(&old_cluster);
+ check_proper_datallowconn(&old_cluster);
check_for_prepared_transactions(&old_cluster);
check_for_reg_data_type_usage(&old_cluster);
check_for_isn_and_int8_passing_mismatch(&old_cluster);
@@ -642,6 +644,58 @@ check_is_install_user(ClusterInfo *cluster)
}
+static void
+check_proper_datallowconn(ClusterInfo *cluster)
+{
+ int dbnum;
+ PGconn *conn_template1;
+ PGresult *dbres;
+ int ntups;
+ int i_datname;
+ int i_datallowconn;
+
+ prep_status("Checking database connection settings");
+
+ conn_template1 = connectToServer(cluster, "template1");
+
+ /* get database names */
+ dbres = executeQueryOrDie(conn_template1,
+ "SELECT datname, datallowconn "
+ "FROM pg_catalog.pg_database");
+
+ i_datname = PQfnumber(dbres, "datname");
+ i_datallowconn = PQfnumber(dbres, "datallowconn");
+
+ ntups = PQntuples(dbres);
+ for (dbnum = 0; dbnum < ntups; dbnum++)
+ {
+ char *datname = PQgetvalue(dbres, dbnum, i_datname);
+ char *datallowconn = PQgetvalue(dbres, dbnum, i_datallowconn);
+
+ if (strcmp(datname, "template0") == 0)
+ {
+ /* avoid restore failure when pg_dumpall tries to create template0 */
+ if (strcmp(datallowconn, "t") == 0)
+ pg_fatal("template0 must not allow connections, "
+ "i.e. its pg_database.datallowconn must be false\n");
+ }
+ else
+ {
+ /* avoid datallowconn == false databases from being skipped on restore */
+ if (strcmp(datallowconn, "f") == 0)
+ pg_fatal("All non-template0 databases must allow connections, "
+ "i.e. their pg_database.datallowconn must be true\n");
+ }
+ }
+
+ PQclear(dbres);
+
+ PQfinish(conn_template1);
+
+ check_ok();
+}
+
+
/*
* check_for_prepared_transactions()
*