Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                
Skip to content

Commit 4cfba53

Browse files
committed
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
1 parent 4fd69e4 commit 4cfba53

File tree

1 file changed

+54
-0
lines changed

1 file changed

+54
-0
lines changed

contrib/pg_upgrade/check.c

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ static void check_locale_and_encoding(ControlData *oldctrl,
2020
static bool equivalent_locale(int category, const char *loca, const char *locb);
2121
static bool equivalent_encoding(const char *chara, const char *charb);
2222
static void check_is_super_user(ClusterInfo *cluster);
23+
static void check_proper_datallowconn(ClusterInfo *cluster);
2324
static void check_for_prepared_transactions(ClusterInfo *cluster);
2425
static void check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster);
2526
static void check_for_reg_data_type_usage(ClusterInfo *cluster);
@@ -95,6 +96,7 @@ check_and_dump_old_cluster(bool live_check, char **sequence_script_file_name)
9596
* Check for various failure cases
9697
*/
9798
check_is_super_user(&old_cluster);
99+
check_proper_datallowconn(&old_cluster);
98100
check_for_prepared_transactions(&old_cluster);
99101
check_for_reg_data_type_usage(&old_cluster);
100102
check_for_isn_and_int8_passing_mismatch(&old_cluster);
@@ -629,6 +631,58 @@ create_script_for_cluster_analyze(char **analyze_script_file_name)
629631
}
630632

631633

634+
static void
635+
check_proper_datallowconn(ClusterInfo *cluster)
636+
{
637+
int dbnum;
638+
PGconn *conn_template1;
639+
PGresult *dbres;
640+
int ntups;
641+
int i_datname;
642+
int i_datallowconn;
643+
644+
prep_status("Checking database connection settings");
645+
646+
conn_template1 = connectToServer(cluster, "template1");
647+
648+
/* get database names */
649+
dbres = executeQueryOrDie(conn_template1,
650+
"SELECT datname, datallowconn "
651+
"FROM pg_catalog.pg_database");
652+
653+
i_datname = PQfnumber(dbres, "datname");
654+
i_datallowconn = PQfnumber(dbres, "datallowconn");
655+
656+
ntups = PQntuples(dbres);
657+
for (dbnum = 0; dbnum < ntups; dbnum++)
658+
{
659+
char *datname = PQgetvalue(dbres, dbnum, i_datname);
660+
char *datallowconn = PQgetvalue(dbres, dbnum, i_datallowconn);
661+
662+
if (strcmp(datname, "template0") == 0)
663+
{
664+
/* avoid restore failure when pg_dumpall tries to create template0 */
665+
if (strcmp(datallowconn, "t") == 0)
666+
pg_log(PG_FATAL, "template0 must not allow connections, "
667+
"i.e. its pg_database.datallowconn must be false\n");
668+
}
669+
else
670+
{
671+
/* avoid datallowconn == false databases from being skipped on restore */
672+
if (strcmp(datallowconn, "f") == 0)
673+
pg_log(PG_FATAL, "All non-template0 databases must allow connections, "
674+
"i.e. their pg_database.datallowconn must be true\n");
675+
}
676+
}
677+
678+
PQclear(dbres);
679+
680+
PQfinish(conn_template1);
681+
682+
check_ok();
683+
}
684+
685+
632686
/*
633687
* create_script_for_old_cluster_deletion()
634688
*

0 commit comments

Comments
 (0)