summaryrefslogtreecommitdiff
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
commit321db71239cb45ed2f2d3113ff5745757a64581a (patch)
treec124944ddaf84c9cbc0226e80a5d794ae7b6e617
parent436f3560925620b623d4ea6cdd8f7b38a117b643 (diff)
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
-rw-r--r--contrib/pg_upgrade/check.c54
1 files changed, 54 insertions, 0 deletions
diff --git a/contrib/pg_upgrade/check.c b/contrib/pg_upgrade/check.c
index 1ca6366f5ba..82fbd230353 100644
--- a/contrib/pg_upgrade/check.c
+++ b/contrib/pg_upgrade/check.c
@@ -16,6 +16,7 @@ static void check_old_cluster_has_new_cluster_dbs(void);
static void check_locale_and_encoding(ControlData *oldctrl,
ControlData *newctrl);
static void check_is_super_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);
@@ -97,6 +98,7 @@ check_old_cluster(bool live_check,
* Check for various failure cases
*/
check_is_super_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);
@@ -580,6 +582,58 @@ check_is_super_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_log(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_log(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()
*