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

Commit 31f5d3f

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 d0ddcf6 commit 31f5d3f

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);
@@ -96,6 +97,7 @@ check_and_dump_old_cluster(bool live_check, char **sequence_script_file_name)
9697
* Check for various failure cases
9798
*/
9899
check_is_super_user(&old_cluster);
100+
check_proper_datallowconn(&old_cluster);
99101
check_for_prepared_transactions(&old_cluster);
100102
check_for_reg_data_type_usage(&old_cluster);
101103
check_for_isn_and_int8_passing_mismatch(&old_cluster);
@@ -592,6 +594,58 @@ create_script_for_cluster_analyze(char **analyze_script_file_name)
592594
}
593595

594596

597+
static void
598+
check_proper_datallowconn(ClusterInfo *cluster)
599+
{
600+
int dbnum;
601+
PGconn *conn_template1;
602+
PGresult *dbres;
603+
int ntups;
604+
int i_datname;
605+
int i_datallowconn;
606+
607+
prep_status("Checking database connection settings");
608+
609+
conn_template1 = connectToServer(cluster, "template1");
610+
611+
/* get database names */
612+
dbres = executeQueryOrDie(conn_template1,
613+
"SELECT datname, datallowconn "
614+
"FROM pg_catalog.pg_database");
615+
616+
i_datname = PQfnumber(dbres, "datname");
617+
i_datallowconn = PQfnumber(dbres, "datallowconn");
618+
619+
ntups = PQntuples(dbres);
620+
for (dbnum = 0; dbnum < ntups; dbnum++)
621+
{
622+
char *datname = PQgetvalue(dbres, dbnum, i_datname);
623+
char *datallowconn = PQgetvalue(dbres, dbnum, i_datallowconn);
624+
625+
if (strcmp(datname, "template0") == 0)
626+
{
627+
/* avoid restore failure when pg_dumpall tries to create template0 */
628+
if (strcmp(datallowconn, "t") == 0)
629+
pg_fatal("template0 must not allow connections, "
630+
"i.e. its pg_database.datallowconn must be false\n");
631+
}
632+
else
633+
{
634+
/* avoid datallowconn == false databases from being skipped on restore */
635+
if (strcmp(datallowconn, "f") == 0)
636+
pg_fatal("All non-template0 databases must allow connections, "
637+
"i.e. their pg_database.datallowconn must be true\n");
638+
}
639+
}
640+
641+
PQclear(dbres);
642+
643+
PQfinish(conn_template1);
644+
645+
check_ok();
646+
}
647+
648+
595649
/*
596650
* create_script_for_old_cluster_deletion()
597651
*

0 commit comments

Comments
 (0)