PostgreSQL Source Code  git master
check.c File Reference
#include "postgres_fe.h"
#include "catalog/pg_authid_d.h"
#include "fe_utils/string_utils.h"
#include "mb/pg_wchar.h"
#include "pg_upgrade.h"
Include dependency graph for check.c:

Go to the source code of this file.

Functions

static void check_new_cluster_is_empty (void)
 
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_tables_with_oids (ClusterInfo *cluster)
 
static void check_for_reg_data_type_usage (ClusterInfo *cluster)
 
static void check_for_jsonb_9_4_usage (ClusterInfo *cluster)
 
static void check_for_pg_role_prefix (ClusterInfo *cluster)
 
static char * get_canonical_locale_name (int category, const char *locale)
 
static char * fix_path_separator (char *path)
 
void output_check_banner (bool live_check)
 
void check_and_dump_old_cluster (bool live_check)
 
void check_new_cluster (void)
 
void report_clusters_compatible (void)
 
void issue_warnings_and_set_wal_level (void)
 
void output_completion_banner (char *analyze_script_file_name, char *deletion_script_file_name)
 
void check_cluster_versions (void)
 
void check_cluster_compatibility (bool live_check)
 
void create_script_for_cluster_analyze (char **analyze_script_file_name)
 
void create_script_for_old_cluster_deletion (char **deletion_script_file_name)
 

Function Documentation

◆ check_and_dump_old_cluster()

void check_and_dump_old_cluster ( bool  live_check)

Definition at line 79 of file check.c.

References ControlData::cat_ver, UserOpts::check, check_for_isn_and_int8_passing_mismatch(), check_for_jsonb_9_4_usage(), check_for_pg_role_prefix(), check_for_prepared_transactions(), check_for_reg_data_type_usage(), check_for_tables_with_oids(), check_is_install_user(), check_proper_datallowconn(), ClusterInfo::controldata, generate_old_dump(), get_db_and_rel_infos(), get_loadable_libraries(), GET_MAJOR_VERSION, init_tablespaces(), JSONB_FORMAT_CHANGE_CAT_VER, ClusterInfo::major_version, new_9_0_populate_pg_largeobject_metadata(), old_11_check_for_sql_identifier_data_type_usage(), old_9_3_check_for_line_data_type_usage(), old_9_6_check_for_unknown_data_type_usage(), old_9_6_invalidate_hash_indexes(), old_cluster, start_postmaster(), stop_postmaster(), and user_opts.

Referenced by main().

80 {
81  /* -- OLD -- */
82 
83  if (!live_check)
85 
86  /* Extract a list of databases and tables from the old cluster */
88 
90 
92 
93 
94  /*
95  * Check for various failure cases
96  */
102 
103  /*
104  * Pre-PG 12 allowed tables to be declared WITH OIDS, which is not
105  * supported anymore. Verify there are none, iff applicable.
106  */
109 
110  /*
111  * PG 12 changed the 'sql_identifier' type storage to be based on name,
112  * not varchar, which breaks on-disk format for existing data. So we need
113  * to prevent upgrade when used in user objects (tables, indexes, ...).
114  */
117 
118  /*
119  * Pre-PG 10 allowed tables with 'unknown' type columns and non WAL logged
120  * hash indexes
121  */
123  {
125  if (user_opts.check)
127  }
128 
129  /* 9.5 and below should not have roles starting with pg_ */
132 
136 
137  /* Pre-PG 9.4 had a different 'line' data type internal format */
140 
141  /* Pre-PG 9.0 had no large object permissions */
144 
145  /*
146  * While not a check option, we do this now because this is the only time
147  * the old server is running.
148  */
149  if (!user_opts.check)
151 
152  if (!live_check)
153  stop_postmaster(false);
154 }
uint32 major_version
Definition: pg_upgrade.h:269
ControlData controldata
Definition: pg_upgrade.h:259
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:23
void old_9_6_invalidate_hash_indexes(ClusterInfo *cluster, bool check_mode)
Definition: version.c:299
static void check_for_reg_data_type_usage(ClusterInfo *cluster)
Definition: check.c:989
static void check_for_prepared_transactions(ClusterInfo *cluster)
Definition: check.c:783
static void check_proper_datallowconn(ClusterInfo *cluster)
Definition: check.c:722
static void check_for_pg_role_prefix(ClusterInfo *cluster)
Definition: check.c:1183
void new_9_0_populate_pg_largeobject_metadata(ClusterInfo *cluster, bool check_mode)
Definition: version.c:22
ClusterInfo old_cluster
Definition: pg_upgrade.c:59
static void check_for_tables_with_oids(ClusterInfo *cluster)
Definition: check.c:904
void generate_old_dump(void)
Definition: dump.c:16
static void check_is_install_user(ClusterInfo *cluster)
Definition: check.c:671
static void check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster)
Definition: check.c:818
UserOpts user_opts
Definition: option.c:30
uint32 cat_ver
Definition: pg_upgrade.h:204
void stop_postmaster(bool in_atexit)
Definition: server.c:327
void get_loadable_libraries(void)
Definition: function.c:53
void get_db_and_rel_infos(ClusterInfo *cluster)
Definition: info.c:309
#define JSONB_FORMAT_CHANGE_CAT_VER
Definition: pg_upgrade.h:126
bool check
Definition: pg_upgrade.h:292
static pgpid_t start_postmaster(void)
Definition: pg_ctl.c:445
static void check_for_jsonb_9_4_usage(ClusterInfo *cluster)
Definition: check.c:1094
void init_tablespaces(void)
Definition: tablespace.c:19
void old_9_3_check_for_line_data_type_usage(ClusterInfo *cluster)
Definition: version.c:235
void old_11_check_for_sql_identifier_data_type_usage(ClusterInfo *cluster)
Definition: version.c:414
void old_9_6_check_for_unknown_data_type_usage(ClusterInfo *cluster)
Definition: version.c:272

◆ check_cluster_compatibility()

void check_cluster_compatibility ( bool  live_check)

Definition at line 299 of file check.c.

References check_control_data(), ClusterInfo::controldata, DEF_PGUPORT, get_control_data(), GET_MAJOR_VERSION, ClusterInfo::major_version, new_cluster, old_cluster, pg_fatal, and ClusterInfo::port.

Referenced by main().

300 {
301  /* get/check pg_control data of servers */
302  get_control_data(&old_cluster, live_check);
303  get_control_data(&new_cluster, false);
305 
306  /* We read the real port number for PG >= 9.1 */
307  if (live_check && GET_MAJOR_VERSION(old_cluster.major_version) < 901 &&
309  pg_fatal("When checking a pre-PG 9.1 live old server, "
310  "you must specify the old server's port number.\n");
311 
312  if (live_check && old_cluster.port == new_cluster.port)
313  pg_fatal("When checking a live server, "
314  "the old and new port numbers must be different.\n");
315 }
uint32 major_version
Definition: pg_upgrade.h:269
ControlData controldata
Definition: pg_upgrade.h:259
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:23
#define pg_fatal(...)
Definition: pg_rewind.h:43
unsigned short port
Definition: pg_upgrade.h:268
void check_control_data(ControlData *oldctrl, ControlData *newctrl)
Definition: controldata.c:619
ClusterInfo new_cluster
Definition: pg_upgrade.c:59
ClusterInfo old_cluster
Definition: pg_upgrade.c:59
#define DEF_PGUPORT
Definition: pg_upgrade.h:16
void get_control_data(ClusterInfo *cluster, bool live_check)
Definition: controldata.c:34

◆ check_cluster_versions()

void check_cluster_versions ( void  )

Definition at line 257 of file check.c.

References Assert, ClusterInfo::bin_version, check_ok(), GET_MAJOR_VERSION, ClusterInfo::major_version, new_cluster, old_cluster, pg_fatal, and prep_status().

Referenced by main().

258 {
259  prep_status("Checking cluster versions");
260 
261  /* cluster versions should already have been obtained */
264 
265  /*
266  * We allow upgrades from/to the same major version for alpha/beta
267  * upgrades
268  */
269 
271  pg_fatal("This utility can only upgrade from PostgreSQL version 8.4 and later.\n");
272 
273  /* Only current PG version is supported as a target */
275  pg_fatal("This utility can only upgrade to PostgreSQL version %s.\n",
276  PG_MAJORVERSION);
277 
278  /*
279  * We can't allow downgrading because we use the target pg_dump, and
280  * pg_dump cannot operate on newer database versions, only current and
281  * older versions.
282  */
284  pg_fatal("This utility cannot be used to downgrade to older major PostgreSQL versions.\n");
285 
286  /* Ensure binaries match the designated data directories */
289  pg_fatal("Old cluster data and binary directories are from different major versions.\n");
292  pg_fatal("New cluster data and binary directories are from different major versions.\n");
293 
294  check_ok();
295 }
uint32 major_version
Definition: pg_upgrade.h:269
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:23
#define pg_fatal(...)
Definition: pg_rewind.h:43
ClusterInfo new_cluster
Definition: pg_upgrade.c:59
void prep_status(const char *fmt,...) pg_attribute_printf(1
ClusterInfo old_cluster
Definition: pg_upgrade.c:59
static void check_ok(void)
Definition: initdb.c:2079
uint32 bin_version
Definition: pg_upgrade.h:271
#define Assert(condition)
Definition: c.h:733

◆ check_databases_are_compatible()

static void check_databases_are_compatible ( void  )
static

Definition at line 422 of file check.c.

References check_locale_and_encoding(), DbInfo::db_name, ClusterInfo::dbarr, DbInfoArr::dbs, DbInfoArr::ndbs, new_cluster, and old_cluster.

Referenced by check_new_cluster().

423 {
424  int newdbnum;
425  int olddbnum;
426  DbInfo *newdbinfo;
427  DbInfo *olddbinfo;
428 
429  for (newdbnum = 0; newdbnum < new_cluster.dbarr.ndbs; newdbnum++)
430  {
431  newdbinfo = &new_cluster.dbarr.dbs[newdbnum];
432 
433  /* Find the corresponding database in the old cluster */
434  for (olddbnum = 0; olddbnum < old_cluster.dbarr.ndbs; olddbnum++)
435  {
436  olddbinfo = &old_cluster.dbarr.dbs[olddbnum];
437  if (strcmp(newdbinfo->db_name, olddbinfo->db_name) == 0)
438  {
439  check_locale_and_encoding(olddbinfo, newdbinfo);
440  break;
441  }
442  }
443  }
444 }
ClusterInfo new_cluster
Definition: pg_upgrade.c:59
ClusterInfo old_cluster
Definition: pg_upgrade.c:59
DbInfoArr dbarr
Definition: pg_upgrade.h:260
char * db_name
Definition: pg_upgrade.h:181
DbInfo * dbs
Definition: pg_upgrade.h:192
static void check_locale_and_encoding(DbInfo *olddb, DbInfo *newdb)
Definition: check.c:325

◆ check_for_isn_and_int8_passing_mismatch()

static void check_for_isn_and_int8_passing_mismatch ( ClusterInfo cluster)
static

Definition at line 818 of file check.c.

References check_ok(), conn, connectToServer(), ClusterInfo::controldata, DbInfo::db_name, ClusterInfo::dbarr, DbInfoArr::dbs, executeQueryOrDie(), ControlData::float8_pass_by_value, fopen_priv, fprintf, MAXPGPATH, DbInfoArr::ndbs, new_cluster, old_cluster, pg_fatal, pg_log(), PG_REPORT, PQclear(), PQfinish(), PQfnumber(), PQgetvalue(), PQntuples(), prep_status(), snprintf, and strerror.

Referenced by check_and_dump_old_cluster().

819 {
820  int dbnum;
821  FILE *script = NULL;
822  bool found = false;
823  char output_path[MAXPGPATH];
824 
825  prep_status("Checking for contrib/isn with bigint-passing mismatch");
826 
829  {
830  /* no mismatch */
831  check_ok();
832  return;
833  }
834 
835  snprintf(output_path, sizeof(output_path),
836  "contrib_isn_and_int8_pass_by_value.txt");
837 
838  for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
839  {
840  PGresult *res;
841  bool db_used = false;
842  int ntups;
843  int rowno;
844  int i_nspname,
845  i_proname;
846  DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
847  PGconn *conn = connectToServer(cluster, active_db->db_name);
848 
849  /* Find any functions coming from contrib/isn */
850  res = executeQueryOrDie(conn,
851  "SELECT n.nspname, p.proname "
852  "FROM pg_catalog.pg_proc p, "
853  " pg_catalog.pg_namespace n "
854  "WHERE p.pronamespace = n.oid AND "
855  " p.probin = '$libdir/isn'");
856 
857  ntups = PQntuples(res);
858  i_nspname = PQfnumber(res, "nspname");
859  i_proname = PQfnumber(res, "proname");
860  for (rowno = 0; rowno < ntups; rowno++)
861  {
862  found = true;
863  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
864  pg_fatal("could not open file \"%s\": %s\n",
865  output_path, strerror(errno));
866  if (!db_used)
867  {
868  fprintf(script, "In database: %s\n", active_db->db_name);
869  db_used = true;
870  }
871  fprintf(script, " %s.%s\n",
872  PQgetvalue(res, rowno, i_nspname),
873  PQgetvalue(res, rowno, i_proname));
874  }
875 
876  PQclear(res);
877 
878  PQfinish(conn);
879  }
880 
881  if (script)
882  fclose(script);
883 
884  if (found)
885  {
886  pg_log(PG_REPORT, "fatal\n");
887  pg_fatal("Your installation contains \"contrib/isn\" functions which rely on the\n"
888  "bigint data type. Your old and new clusters pass bigint values\n"
889  "differently so this cluster cannot currently be upgraded. You can\n"
890  "manually upgrade databases that use \"contrib/isn\" facilities and remove\n"
891  "\"contrib/isn\" from the old cluster and restart the upgrade. A list of\n"
892  "the problem functions is in the file:\n"
893  " %s\n\n", output_path);
894  }
895  else
896  check_ok();
897 }
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3163
ControlData controldata
Definition: pg_upgrade.h:259
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
#define pg_fatal(...)
Definition: pg_rewind.h:43
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4119
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2769
#define fprintf
Definition: port.h:196
ClusterInfo new_cluster
Definition: pg_upgrade.c:59
PGconn * conn
Definition: streamutil.c:54
#define MAXPGPATH
void prep_status(const char *fmt,...) pg_attribute_printf(1
ClusterInfo old_cluster
Definition: pg_upgrade.c:59
static void check_ok(void)
Definition: initdb.c:2079
PGconn * connectToServer(ClusterInfo *cluster, const char *db_name)
Definition: server.c:27
int PQfnumber(const PGresult *res, const char *field_name)
Definition: fe-exec.c:2877
void PQclear(PGresult *res)
Definition: fe-exec.c:694
DbInfoArr dbarr
Definition: pg_upgrade.h:260
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
#define strerror
Definition: port.h:205
#define fopen_priv(path, mode)
Definition: pg_upgrade.h:382
char * db_name
Definition: pg_upgrade.h:181
DbInfo * dbs
Definition: pg_upgrade.h:192
#define snprintf
Definition: port.h:192
bool float8_pass_by_value
Definition: pg_upgrade.h:222

◆ check_for_jsonb_9_4_usage()

static void check_for_jsonb_9_4_usage ( ClusterInfo cluster)
static

Definition at line 1094 of file check.c.

References check_ok(), conn, connectToServer(), DbInfo::db_name, ClusterInfo::dbarr, DbInfoArr::dbs, executeQueryOrDie(), fopen_priv, fprintf, MAXPGPATH, DbInfoArr::ndbs, pg_fatal, pg_log(), PG_REPORT, PQclear(), PQfinish(), PQfnumber(), PQgetvalue(), PQntuples(), prep_status(), snprintf, and strerror.

Referenced by check_and_dump_old_cluster().

1095 {
1096  int dbnum;
1097  FILE *script = NULL;
1098  bool found = false;
1099  char output_path[MAXPGPATH];
1100 
1101  prep_status("Checking for incompatible \"jsonb\" data type");
1102 
1103  snprintf(output_path, sizeof(output_path), "tables_using_jsonb.txt");
1104 
1105  for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
1106  {
1107  PGresult *res;
1108  bool db_used = false;
1109  int ntups;
1110  int rowno;
1111  int i_nspname,
1112  i_relname,
1113  i_attname;
1114  DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
1115  PGconn *conn = connectToServer(cluster, active_db->db_name);
1116 
1117  /*
1118  * While several relkinds don't store any data, e.g. views, they can
1119  * be used to define data types of other columns, so we check all
1120  * relkinds.
1121  */
1122  res = executeQueryOrDie(conn,
1123  "SELECT n.nspname, c.relname, a.attname "
1124  "FROM pg_catalog.pg_class c, "
1125  " pg_catalog.pg_namespace n, "
1126  " pg_catalog.pg_attribute a "
1127  "WHERE c.oid = a.attrelid AND "
1128  " NOT a.attisdropped AND "
1129  " a.atttypid = 'pg_catalog.jsonb'::pg_catalog.regtype AND "
1130  " c.relnamespace = n.oid AND "
1131  /* exclude possible orphaned temp tables */
1132  " n.nspname !~ '^pg_temp_' AND "
1133  " n.nspname NOT IN ('pg_catalog', 'information_schema')");
1134 
1135  ntups = PQntuples(res);
1136  i_nspname = PQfnumber(res, "nspname");
1137  i_relname = PQfnumber(res, "relname");
1138  i_attname = PQfnumber(res, "attname");
1139  for (rowno = 0; rowno < ntups; rowno++)
1140  {
1141  found = true;
1142  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
1143  pg_fatal("could not open file \"%s\": %s\n",
1144  output_path, strerror(errno));
1145  if (!db_used)
1146  {
1147  fprintf(script, "In database: %s\n", active_db->db_name);
1148  db_used = true;
1149  }
1150  fprintf(script, " %s.%s.%s\n",
1151  PQgetvalue(res, rowno, i_nspname),
1152  PQgetvalue(res, rowno, i_relname),
1153  PQgetvalue(res, rowno, i_attname));
1154  }
1155 
1156  PQclear(res);
1157 
1158  PQfinish(conn);
1159  }
1160 
1161  if (script)
1162  fclose(script);
1163 
1164  if (found)
1165  {
1166  pg_log(PG_REPORT, "fatal\n");
1167  pg_fatal("Your installation contains the \"jsonb\" data type in user tables.\n"
1168  "The internal format of \"jsonb\" changed during 9.4 beta so this cluster cannot currently\n"
1169  "be upgraded. You can remove the problem tables and restart the upgrade. A list\n"
1170  "of the problem columns is in the file:\n"
1171  " %s\n\n", output_path);
1172  }
1173  else
1174  check_ok();
1175 }
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3163
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
#define pg_fatal(...)
Definition: pg_rewind.h:43
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4119
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2769
#define fprintf
Definition: port.h:196
PGconn * conn
Definition: streamutil.c:54
#define MAXPGPATH
void prep_status(const char *fmt,...) pg_attribute_printf(1
static void check_ok(void)
Definition: initdb.c:2079
PGconn * connectToServer(ClusterInfo *cluster, const char *db_name)
Definition: server.c:27
int PQfnumber(const PGresult *res, const char *field_name)
Definition: fe-exec.c:2877
void PQclear(PGresult *res)
Definition: fe-exec.c:694
DbInfoArr dbarr
Definition: pg_upgrade.h:260
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
#define strerror
Definition: port.h:205
#define fopen_priv(path, mode)
Definition: pg_upgrade.h:382
char * db_name
Definition: pg_upgrade.h:181
DbInfo * dbs
Definition: pg_upgrade.h:192
#define snprintf
Definition: port.h:192

◆ check_for_pg_role_prefix()

static void check_for_pg_role_prefix ( ClusterInfo cluster)
static

Definition at line 1183 of file check.c.

References check_ok(), conn, connectToServer(), executeQueryOrDie(), old_cluster, pg_fatal, PQclear(), PQfinish(), PQntuples(), and prep_status().

Referenced by check_and_dump_old_cluster().

1184 {
1185  PGresult *res;
1186  PGconn *conn = connectToServer(cluster, "template1");
1187 
1188  prep_status("Checking for roles starting with \"pg_\"");
1189 
1190  res = executeQueryOrDie(conn,
1191  "SELECT * "
1192  "FROM pg_catalog.pg_roles "
1193  "WHERE rolname ~ '^pg_'");
1194 
1195  if (PQntuples(res) != 0)
1196  {
1197  if (cluster == &old_cluster)
1198  pg_fatal("The source cluster contains roles starting with \"pg_\"\n");
1199  else
1200  pg_fatal("The target cluster contains roles starting with \"pg_\"\n");
1201  }
1202 
1203  PQclear(res);
1204 
1205  PQfinish(conn);
1206 
1207  check_ok();
1208 }
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
#define pg_fatal(...)
Definition: pg_rewind.h:43
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4119
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2769
PGconn * conn
Definition: streamutil.c:54
void prep_status(const char *fmt,...) pg_attribute_printf(1
ClusterInfo old_cluster
Definition: pg_upgrade.c:59
static void check_ok(void)
Definition: initdb.c:2079
PGconn * connectToServer(ClusterInfo *cluster, const char *db_name)
Definition: server.c:27
void PQclear(PGresult *res)
Definition: fe-exec.c:694

◆ check_for_prepared_transactions()

static void check_for_prepared_transactions ( ClusterInfo cluster)
static

Definition at line 783 of file check.c.

References check_ok(), conn, connectToServer(), executeQueryOrDie(), old_cluster, pg_fatal, PQclear(), PQfinish(), PQntuples(), and prep_status().

Referenced by check_and_dump_old_cluster(), and check_new_cluster().

784 {
785  PGresult *res;
786  PGconn *conn = connectToServer(cluster, "template1");
787 
788  prep_status("Checking for prepared transactions");
789 
790  res = executeQueryOrDie(conn,
791  "SELECT * "
792  "FROM pg_catalog.pg_prepared_xacts");
793 
794  if (PQntuples(res) != 0)
795  {
796  if (cluster == &old_cluster)
797  pg_fatal("The source cluster contains prepared transactions\n");
798  else
799  pg_fatal("The target cluster contains prepared transactions\n");
800  }
801 
802  PQclear(res);
803 
804  PQfinish(conn);
805 
806  check_ok();
807 }
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
#define pg_fatal(...)
Definition: pg_rewind.h:43
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4119
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2769
PGconn * conn
Definition: streamutil.c:54
void prep_status(const char *fmt,...) pg_attribute_printf(1
ClusterInfo old_cluster
Definition: pg_upgrade.c:59
static void check_ok(void)
Definition: initdb.c:2079
PGconn * connectToServer(ClusterInfo *cluster, const char *db_name)
Definition: server.c:27
void PQclear(PGresult *res)
Definition: fe-exec.c:694

◆ check_for_reg_data_type_usage()

static void check_for_reg_data_type_usage ( ClusterInfo cluster)
static

Definition at line 989 of file check.c.

References check_ok(), conn, connectToServer(), DbInfo::db_name, ClusterInfo::dbarr, DbInfoArr::dbs, executeQueryOrDie(), fopen_priv, fprintf, MAXPGPATH, DbInfoArr::ndbs, pg_fatal, pg_log(), PG_REPORT, PQclear(), PQfinish(), PQfnumber(), PQgetvalue(), PQntuples(), prep_status(), snprintf, and strerror.

Referenced by check_and_dump_old_cluster().

990 {
991  int dbnum;
992  FILE *script = NULL;
993  bool found = false;
994  char output_path[MAXPGPATH];
995 
996  prep_status("Checking for reg* data types in user tables");
997 
998  snprintf(output_path, sizeof(output_path), "tables_using_reg.txt");
999 
1000  for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
1001  {
1002  PGresult *res;
1003  bool db_used = false;
1004  int ntups;
1005  int rowno;
1006  int i_nspname,
1007  i_relname,
1008  i_attname;
1009  DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
1010  PGconn *conn = connectToServer(cluster, active_db->db_name);
1011 
1012  /*
1013  * While several relkinds don't store any data, e.g. views, they can
1014  * be used to define data types of other columns, so we check all
1015  * relkinds.
1016  */
1017  res = executeQueryOrDie(conn,
1018  "SELECT n.nspname, c.relname, a.attname "
1019  "FROM pg_catalog.pg_class c, "
1020  " pg_catalog.pg_namespace n, "
1021  " pg_catalog.pg_attribute a, "
1022  " pg_catalog.pg_type t "
1023  "WHERE c.oid = a.attrelid AND "
1024  " NOT a.attisdropped AND "
1025  " a.atttypid = t.oid AND "
1026  " t.typnamespace = "
1027  " (SELECT oid FROM pg_namespace "
1028  " WHERE nspname = 'pg_catalog') AND"
1029  " t.typname IN ( "
1030  /* regclass.oid is preserved, so 'regclass' is OK */
1031  " 'regconfig', "
1032  " 'regdictionary', "
1033  " 'regnamespace', "
1034  " 'regoper', "
1035  " 'regoperator', "
1036  " 'regproc', "
1037  " 'regprocedure' "
1038  /* regrole.oid is preserved, so 'regrole' is OK */
1039  /* regtype.oid is preserved, so 'regtype' is OK */
1040  " ) AND "
1041  " c.relnamespace = n.oid AND "
1042  " n.nspname NOT IN ('pg_catalog', 'information_schema')");
1043 
1044  ntups = PQntuples(res);
1045  i_nspname = PQfnumber(res, "nspname");
1046  i_relname = PQfnumber(res, "relname");
1047  i_attname = PQfnumber(res, "attname");
1048  for (rowno = 0; rowno < ntups; rowno++)
1049  {
1050  found = true;
1051  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
1052  pg_fatal("could not open file \"%s\": %s\n",
1053  output_path, strerror(errno));
1054  if (!db_used)
1055  {
1056  fprintf(script, "In database: %s\n", active_db->db_name);
1057  db_used = true;
1058  }
1059  fprintf(script, " %s.%s.%s\n",
1060  PQgetvalue(res, rowno, i_nspname),
1061  PQgetvalue(res, rowno, i_relname),
1062  PQgetvalue(res, rowno, i_attname));
1063  }
1064 
1065  PQclear(res);
1066 
1067  PQfinish(conn);
1068  }
1069 
1070  if (script)
1071  fclose(script);
1072 
1073  if (found)
1074  {
1075  pg_log(PG_REPORT, "fatal\n");
1076  pg_fatal("Your installation contains one of the reg* data types in user tables.\n"
1077  "These data types reference system OIDs that are not preserved by\n"
1078  "pg_upgrade, so this cluster cannot currently be upgraded. You can\n"
1079  "remove the problem tables and restart the upgrade. A list of the problem\n"
1080  "columns is in the file:\n"
1081  " %s\n\n", output_path);
1082  }
1083  else
1084  check_ok();
1085 }
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3163
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
#define pg_fatal(...)
Definition: pg_rewind.h:43
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4119
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2769
#define fprintf
Definition: port.h:196
PGconn * conn
Definition: streamutil.c:54
#define MAXPGPATH
void prep_status(const char *fmt,...) pg_attribute_printf(1
static void check_ok(void)
Definition: initdb.c:2079
PGconn * connectToServer(ClusterInfo *cluster, const char *db_name)
Definition: server.c:27
int PQfnumber(const PGresult *res, const char *field_name)
Definition: fe-exec.c:2877
void PQclear(PGresult *res)
Definition: fe-exec.c:694
DbInfoArr dbarr
Definition: pg_upgrade.h:260
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
#define strerror
Definition: port.h:205
#define fopen_priv(path, mode)
Definition: pg_upgrade.h:382
char * db_name
Definition: pg_upgrade.h:181
DbInfo * dbs
Definition: pg_upgrade.h:192
#define snprintf
Definition: port.h:192

◆ check_for_tables_with_oids()

static void check_for_tables_with_oids ( ClusterInfo cluster)
static

Definition at line 904 of file check.c.

References check_ok(), conn, connectToServer(), DbInfo::db_name, ClusterInfo::dbarr, DbInfoArr::dbs, executeQueryOrDie(), fopen_priv, fprintf, MAXPGPATH, DbInfoArr::ndbs, pg_fatal, pg_log(), PG_REPORT, PQclear(), PQfinish(), PQfnumber(), PQgetvalue(), PQntuples(), prep_status(), snprintf, and strerror.

Referenced by check_and_dump_old_cluster().

905 {
906  int dbnum;
907  FILE *script = NULL;
908  bool found = false;
909  char output_path[MAXPGPATH];
910 
911  prep_status("Checking for tables WITH OIDS");
912 
913  snprintf(output_path, sizeof(output_path),
914  "tables_with_oids.txt");
915 
916  /* Find any tables declared WITH OIDS */
917  for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
918  {
919  PGresult *res;
920  bool db_used = false;
921  int ntups;
922  int rowno;
923  int i_nspname,
924  i_relname;
925  DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
926  PGconn *conn = connectToServer(cluster, active_db->db_name);
927 
928  res = executeQueryOrDie(conn,
929  "SELECT n.nspname, c.relname "
930  "FROM pg_catalog.pg_class c, "
931  " pg_catalog.pg_namespace n "
932  "WHERE c.relnamespace = n.oid AND "
933  " c.relhasoids AND"
934  " n.nspname NOT IN ('pg_catalog')");
935 
936  ntups = PQntuples(res);
937  i_nspname = PQfnumber(res, "nspname");
938  i_relname = PQfnumber(res, "relname");
939  for (rowno = 0; rowno < ntups; rowno++)
940  {
941  found = true;
942  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
943  pg_fatal("could not open file \"%s\": %s\n",
944  output_path, strerror(errno));
945  if (!db_used)
946  {
947  fprintf(script, "In database: %s\n", active_db->db_name);
948  db_used = true;
949  }
950  fprintf(script, " %s.%s\n",
951  PQgetvalue(res, rowno, i_nspname),
952  PQgetvalue(res, rowno, i_relname));
953  }
954 
955  PQclear(res);
956 
957  PQfinish(conn);
958  }
959 
960  if (script)
961  fclose(script);
962 
963  if (found)
964  {
965  pg_log(PG_REPORT, "fatal\n");
966  pg_fatal("Your installation contains tables declared WITH OIDS, which is not supported\n"
967  "anymore. Consider removing the oid column using\n"
968  " ALTER TABLE ... SET WITHOUT OIDS;\n"
969  "A list of tables with the problem is in the file:\n"
970  " %s\n\n", output_path);
971  }
972  else
973  check_ok();
974 }
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3163
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
#define pg_fatal(...)
Definition: pg_rewind.h:43
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4119
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2769
#define fprintf
Definition: port.h:196
PGconn * conn
Definition: streamutil.c:54
#define MAXPGPATH
void prep_status(const char *fmt,...) pg_attribute_printf(1
static void check_ok(void)
Definition: initdb.c:2079
PGconn * connectToServer(ClusterInfo *cluster, const char *db_name)
Definition: server.c:27
int PQfnumber(const PGresult *res, const char *field_name)
Definition: fe-exec.c:2877
void PQclear(PGresult *res)
Definition: fe-exec.c:694
DbInfoArr dbarr
Definition: pg_upgrade.h:260
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
#define strerror
Definition: port.h:205
#define fopen_priv(path, mode)
Definition: pg_upgrade.h:382
char * db_name
Definition: pg_upgrade.h:181
DbInfo * dbs
Definition: pg_upgrade.h:192
#define snprintf
Definition: port.h:192

◆ check_is_install_user()

static void check_is_install_user ( ClusterInfo cluster)
static

Definition at line 671 of file check.c.

References atooid, check_ok(), conn, connectToServer(), executeQueryOrDie(), new_cluster, os_info, pg_fatal, PQclear(), PQfinish(), PQgetvalue(), PQntuples(), prep_status(), and OSInfo::user.

Referenced by check_and_dump_old_cluster(), and check_new_cluster().

672 {
673  PGresult *res;
674  PGconn *conn = connectToServer(cluster, "template1");
675 
676  prep_status("Checking database user is the install user");
677 
678  /* Can't use pg_authid because only superusers can view it. */
679  res = executeQueryOrDie(conn,
680  "SELECT rolsuper, oid "
681  "FROM pg_catalog.pg_roles "
682  "WHERE rolname = current_user "
683  "AND rolname !~ '^pg_'");
684 
685  /*
686  * We only allow the install user in the new cluster (see comment below)
687  * and we preserve pg_authid.oid, so this must be the install user in the
688  * old cluster too.
689  */
690  if (PQntuples(res) != 1 ||
691  atooid(PQgetvalue(res, 0, 1)) != BOOTSTRAP_SUPERUSERID)
692  pg_fatal("database user \"%s\" is not the install user\n",
693  os_info.user);
694 
695  PQclear(res);
696 
697  res = executeQueryOrDie(conn,
698  "SELECT COUNT(*) "
699  "FROM pg_catalog.pg_roles "
700  "WHERE rolname !~ '^pg_'");
701 
702  if (PQntuples(res) != 1)
703  pg_fatal("could not determine the number of users\n");
704 
705  /*
706  * We only allow the install user in the new cluster because other defined
707  * users might match users defined in the old cluster and generate an
708  * error during pg_dump restore.
709  */
710  if (cluster == &new_cluster && atooid(PQgetvalue(res, 0, 0)) != 1)
711  pg_fatal("Only the install user can be defined in the new cluster.\n");
712 
713  PQclear(res);
714 
715  PQfinish(conn);
716 
717  check_ok();
718 }
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3163
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
#define pg_fatal(...)
Definition: pg_rewind.h:43
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4119
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2769
ClusterInfo new_cluster
Definition: pg_upgrade.c:59
PGconn * conn
Definition: streamutil.c:54
void prep_status(const char *fmt,...) pg_attribute_printf(1
#define atooid(x)
Definition: postgres_ext.h:42
static void check_ok(void)
Definition: initdb.c:2079
PGconn * connectToServer(ClusterInfo *cluster, const char *db_name)
Definition: server.c:27
void PQclear(PGresult *res)
Definition: fe-exec.c:694
OSInfo os_info
Definition: pg_upgrade.c:61
char * user
Definition: pg_upgrade.h:311

◆ check_locale_and_encoding()

static void check_locale_and_encoding ( DbInfo olddb,
DbInfo newdb 
)
static

Definition at line 325 of file check.c.

References DbInfo::db_collate, DbInfo::db_ctype, DbInfo::db_encoding, DbInfo::db_name, equivalent_locale(), pg_encoding_to_char(), and pg_fatal.

Referenced by check_databases_are_compatible().

326 {
327  if (olddb->db_encoding != newdb->db_encoding)
328  pg_fatal("encodings for database \"%s\" do not match: old \"%s\", new \"%s\"\n",
329  olddb->db_name,
332  if (!equivalent_locale(LC_COLLATE, olddb->db_collate, newdb->db_collate))
333  pg_fatal("lc_collate values for database \"%s\" do not match: old \"%s\", new \"%s\"\n",
334  olddb->db_name, olddb->db_collate, newdb->db_collate);
335  if (!equivalent_locale(LC_CTYPE, olddb->db_ctype, newdb->db_ctype))
336  pg_fatal("lc_ctype values for database \"%s\" do not match: old \"%s\", new \"%s\"\n",
337  olddb->db_name, olddb->db_ctype, newdb->db_ctype);
338 }
#define pg_fatal(...)
Definition: pg_rewind.h:43
static bool equivalent_locale(int category, const char *loca, const char *locb)
Definition: check.c:352
char * db_ctype
Definition: pg_upgrade.h:185
const char * pg_encoding_to_char(int encoding)
Definition: encnames.c:607
int db_encoding
Definition: pg_upgrade.h:186
char * db_name
Definition: pg_upgrade.h:181
char * db_collate
Definition: pg_upgrade.h:184

◆ check_new_cluster()

void check_new_cluster ( void  )

Definition at line 158 of file check.c.

References check_databases_are_compatible(), check_file_clone(), check_for_prepared_transactions(), check_hard_link(), check_is_install_user(), check_loadable_libraries(), check_new_cluster_is_empty(), get_db_and_rel_infos(), new_cluster, UserOpts::transfer_mode, TRANSFER_MODE_CLONE, TRANSFER_MODE_COPY, TRANSFER_MODE_LINK, and user_opts.

Referenced by main().

159 {
161 
164 
166 
167  switch (user_opts.transfer_mode)
168  {
169  case TRANSFER_MODE_CLONE:
171  break;
172  case TRANSFER_MODE_COPY:
173  break;
174  case TRANSFER_MODE_LINK:
175  check_hard_link();
176  break;
177  }
178 
180 
182 }
void check_file_clone(void)
Definition: file.c:321
void check_hard_link(void)
Definition: file.c:363
static void check_databases_are_compatible(void)
Definition: check.c:422
void check_loadable_libraries(void)
Definition: function.c:180
static void check_for_prepared_transactions(ClusterInfo *cluster)
Definition: check.c:783
ClusterInfo new_cluster
Definition: pg_upgrade.c:59
static void check_is_install_user(ClusterInfo *cluster)
Definition: check.c:671
transferMode transfer_mode
Definition: pg_upgrade.h:294
UserOpts user_opts
Definition: option.c:30
static void check_new_cluster_is_empty(void)
Definition: check.c:395
void get_db_and_rel_infos(ClusterInfo *cluster)
Definition: info.c:309

◆ check_new_cluster_is_empty()

static void check_new_cluster_is_empty ( void  )
static

Definition at line 395 of file check.c.

References DbInfo::db_name, ClusterInfo::dbarr, DbInfoArr::dbs, DbInfoArr::ndbs, new_cluster, RelInfoArr::nrels, RelInfo::nspname, pg_fatal, DbInfo::rel_arr, RelInfo::relname, and RelInfoArr::rels.

Referenced by check_new_cluster().

396 {
397  int dbnum;
398 
399  for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++)
400  {
401  int relnum;
402  RelInfoArr *rel_arr = &new_cluster.dbarr.dbs[dbnum].rel_arr;
403 
404  for (relnum = 0; relnum < rel_arr->nrels;
405  relnum++)
406  {
407  /* pg_largeobject and its index should be skipped */
408  if (strcmp(rel_arr->rels[relnum].nspname, "pg_catalog") != 0)
409  pg_fatal("New cluster database \"%s\" is not empty: found relation \"%s.%s\"\n",
410  new_cluster.dbarr.dbs[dbnum].db_name,
411  rel_arr->rels[relnum].nspname,
412  rel_arr->rels[relnum].relname);
413  }
414  }
415 }
char * relname
Definition: pg_upgrade.h:136
#define pg_fatal(...)
Definition: pg_rewind.h:43
char * nspname
Definition: pg_upgrade.h:135
ClusterInfo new_cluster
Definition: pg_upgrade.c:59
RelInfo * rels
Definition: pg_upgrade.h:148
DbInfoArr dbarr
Definition: pg_upgrade.h:260
RelInfoArr rel_arr
Definition: pg_upgrade.h:187
char * db_name
Definition: pg_upgrade.h:181
DbInfo * dbs
Definition: pg_upgrade.h:192

◆ check_proper_datallowconn()

static void check_proper_datallowconn ( ClusterInfo cluster)
static

Definition at line 722 of file check.c.

References check_ok(), connectToServer(), datallowconn, datname, executeQueryOrDie(), pg_fatal, PQclear(), PQfinish(), PQfnumber(), PQgetvalue(), PQntuples(), and prep_status().

Referenced by check_and_dump_old_cluster().

723 {
724  int dbnum;
725  PGconn *conn_template1;
726  PGresult *dbres;
727  int ntups;
728  int i_datname;
729  int i_datallowconn;
730 
731  prep_status("Checking database connection settings");
732 
733  conn_template1 = connectToServer(cluster, "template1");
734 
735  /* get database names */
736  dbres = executeQueryOrDie(conn_template1,
737  "SELECT datname, datallowconn "
738  "FROM pg_catalog.pg_database");
739 
740  i_datname = PQfnumber(dbres, "datname");
741  i_datallowconn = PQfnumber(dbres, "datallowconn");
742 
743  ntups = PQntuples(dbres);
744  for (dbnum = 0; dbnum < ntups; dbnum++)
745  {
746  char *datname = PQgetvalue(dbres, dbnum, i_datname);
747  char *datallowconn = PQgetvalue(dbres, dbnum, i_datallowconn);
748 
749  if (strcmp(datname, "template0") == 0)
750  {
751  /* avoid restore failure when pg_dumpall tries to create template0 */
752  if (strcmp(datallowconn, "t") == 0)
753  pg_fatal("template0 must not allow connections, "
754  "i.e. its pg_database.datallowconn must be false\n");
755  }
756  else
757  {
758  /*
759  * avoid datallowconn == false databases from being skipped on
760  * restore
761  */
762  if (strcmp(datallowconn, "f") == 0)
763  pg_fatal("All non-template0 databases must allow connections, "
764  "i.e. their pg_database.datallowconn must be true\n");
765  }
766  }
767 
768  PQclear(dbres);
769 
770  PQfinish(conn_template1);
771 
772  check_ok();
773 }
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3163
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
#define pg_fatal(...)
Definition: pg_rewind.h:43
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4119
NameData datname
Definition: pg_database.h:35
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2769
bool datallowconn
Definition: pg_database.h:53
void prep_status(const char *fmt,...) pg_attribute_printf(1
static void check_ok(void)
Definition: initdb.c:2079
PGconn * connectToServer(ClusterInfo *cluster, const char *db_name)
Definition: server.c:27
int PQfnumber(const PGresult *res, const char *field_name)
Definition: fe-exec.c:2877
void PQclear(PGresult *res)
Definition: fe-exec.c:694

◆ create_script_for_cluster_analyze()

void create_script_for_cluster_analyze ( char **  analyze_script_file_name)

Definition at line 453 of file check.c.

References appendPQExpBufferChar(), appendPQExpBufferStr(), appendShellString(), ClusterInfo::bindir, check_ok(), PQExpBufferData::data, ECHO_BLANK, ECHO_QUOTE, fopen_priv, fprintf, GET_MAJOR_VERSION, initPQExpBuffer(), ClusterInfo::major_version, new_cluster, old_cluster, os_info, pg_fatal, prep_status(), psprintf(), S_IRWXU, SCRIPT_EXT, SCRIPT_PREFIX, strerror, termPQExpBuffer(), OSInfo::user, and OSInfo::user_specified.

Referenced by main().

454 {
455  FILE *script = NULL;
456  PQExpBufferData user_specification;
457 
458  prep_status("Creating script to analyze new cluster");
459 
460  initPQExpBuffer(&user_specification);
462  {
463  appendPQExpBufferStr(&user_specification, "-U ");
464  appendShellString(&user_specification, os_info.user);
465  appendPQExpBufferChar(&user_specification, ' ');
466  }
467 
468  *analyze_script_file_name = psprintf("%sanalyze_new_cluster.%s",
470 
471  if ((script = fopen_priv(*analyze_script_file_name, "w")) == NULL)
472  pg_fatal("could not open file \"%s\": %s\n",
473  *analyze_script_file_name, strerror(errno));
474 
475 #ifndef WIN32
476  /* add shebang header */
477  fprintf(script, "#!/bin/sh\n\n");
478 #else
479  /* suppress command echoing */
480  fprintf(script, "@echo off\n");
481 #endif
482 
483  fprintf(script, "echo %sThis script will generate minimal optimizer statistics rapidly%s\n",
485  fprintf(script, "echo %sso your system is usable, and then gather statistics twice more%s\n",
487  fprintf(script, "echo %swith increasing accuracy. When it is done, your system will%s\n",
489  fprintf(script, "echo %shave the default level of optimizer statistics.%s\n",
491  fprintf(script, "echo%s\n\n", ECHO_BLANK);
492 
493  fprintf(script, "echo %sIf you have used ALTER TABLE to modify the statistics target for%s\n",
495  fprintf(script, "echo %sany tables, you might want to remove them and restore them after%s\n",
497  fprintf(script, "echo %srunning this script because they will delay fast statistics generation.%s\n",
499  fprintf(script, "echo%s\n\n", ECHO_BLANK);
500 
501  fprintf(script, "echo %sIf you would like default statistics as quickly as possible, cancel%s\n",
503  fprintf(script, "echo %sthis script and run:%s\n",
505  fprintf(script, "echo %s \"%s/vacuumdb\" %s--all %s%s\n", ECHO_QUOTE,
506  new_cluster.bindir, user_specification.data,
507  /* Did we copy the free space files? */
509  "--analyze-only" : "--analyze", ECHO_QUOTE);
510  fprintf(script, "echo%s\n\n", ECHO_BLANK);
511 
512  fprintf(script, "\"%s/vacuumdb\" %s--all --analyze-in-stages\n",
513  new_cluster.bindir, user_specification.data);
514  /* Did we copy the free space files? */
516  fprintf(script, "\"%s/vacuumdb\" %s--all\n", new_cluster.bindir,
517  user_specification.data);
518 
519  fprintf(script, "echo%s\n\n", ECHO_BLANK);
520  fprintf(script, "echo %sDone%s\n",
522 
523  fclose(script);
524 
525 #ifndef WIN32
526  if (chmod(*analyze_script_file_name, S_IRWXU) != 0)
527  pg_fatal("could not add execute permission to file \"%s\": %s\n",
528  *analyze_script_file_name, strerror(errno));
529 #endif
530 
531  termPQExpBuffer(&user_specification);
532 
533  check_ok();
534 }
uint32 major_version
Definition: pg_upgrade.h:269
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:131
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
#define SCRIPT_EXT
Definition: pg_upgrade.h:74
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:23
#define pg_fatal(...)
Definition: pg_rewind.h:43
#define fprintf
Definition: port.h:196
bool user_specified
Definition: pg_upgrade.h:312
ClusterInfo new_cluster
Definition: pg_upgrade.c:59
void prep_status(const char *fmt,...) pg_attribute_printf(1
ClusterInfo old_cluster
Definition: pg_upgrade.c:59
static void check_ok(void)
Definition: initdb.c:2079
char * bindir
Definition: pg_upgrade.h:264
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:380
void appendShellString(PQExpBuffer buf, const char *str)
Definition: string_utils.c:429
#define strerror
Definition: port.h:205
#define ECHO_BLANK
Definition: pg_upgrade.h:76
#define SCRIPT_PREFIX
Definition: pg_upgrade.h:73
#define fopen_priv(path, mode)
Definition: pg_upgrade.h:382
#define S_IRWXU
Definition: win32_port.h:269
OSInfo os_info
Definition: pg_upgrade.c:61
#define ECHO_QUOTE
Definition: pg_upgrade.h:75
char * user
Definition: pg_upgrade.h:311
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:92

◆ create_script_for_old_cluster_deletion()

void create_script_for_old_cluster_deletion ( char **  deletion_script_file_name)

Definition at line 543 of file check.c.

References canonicalize_path(), check_ok(), DbInfo::db_oid, ClusterInfo::dbarr, DbInfoArr::dbs, fix_path_separator(), fopen_priv, fprintf, GET_MAJOR_VERSION, ClusterInfo::major_version, MAXPGPATH, DbInfoArr::ndbs, new_cluster, OSInfo::num_old_tablespaces, old_cluster, OSInfo::old_tablespaces, os_info, path_is_prefix_of_path(), PATH_QUOTE, PATH_SEPARATOR, pfree(), pg_fatal, pg_free(), pg_log(), pg_strdup(), PG_WARNING, ClusterInfo::pgdata, prep_status(), psprintf(), RM_CMD, RMDIR_CMD, S_IRWXU, SCRIPT_EXT, SCRIPT_PREFIX, strerror, strlcpy(), and ClusterInfo::tablespace_suffix.

Referenced by main().

544 {
545  FILE *script = NULL;
546  int tblnum;
547  char old_cluster_pgdata[MAXPGPATH],
548  new_cluster_pgdata[MAXPGPATH];
549 
550  *deletion_script_file_name = psprintf("%sdelete_old_cluster.%s",
552 
553  strlcpy(old_cluster_pgdata, old_cluster.pgdata, MAXPGPATH);
554  canonicalize_path(old_cluster_pgdata);
555 
556  strlcpy(new_cluster_pgdata, new_cluster.pgdata, MAXPGPATH);
557  canonicalize_path(new_cluster_pgdata);
558 
559  /* Some people put the new data directory inside the old one. */
560  if (path_is_prefix_of_path(old_cluster_pgdata, new_cluster_pgdata))
561  {
563  "\nWARNING: new data directory should not be inside the old data directory, e.g. %s\n", old_cluster_pgdata);
564 
565  /* Unlink file in case it is left over from a previous run. */
566  unlink(*deletion_script_file_name);
567  pg_free(*deletion_script_file_name);
568  *deletion_script_file_name = NULL;
569  return;
570  }
571 
572  /*
573  * Some users (oddly) create tablespaces inside the cluster data
574  * directory. We can't create a proper old cluster delete script in that
575  * case.
576  */
577  for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
578  {
579  char old_tablespace_dir[MAXPGPATH];
580 
581  strlcpy(old_tablespace_dir, os_info.old_tablespaces[tblnum], MAXPGPATH);
582  canonicalize_path(old_tablespace_dir);
583  if (path_is_prefix_of_path(old_cluster_pgdata, old_tablespace_dir))
584  {
585  /* reproduce warning from CREATE TABLESPACE that is in the log */
587  "\nWARNING: user-defined tablespace locations should not be inside the data directory, e.g. %s\n", old_tablespace_dir);
588 
589  /* Unlink file in case it is left over from a previous run. */
590  unlink(*deletion_script_file_name);
591  pg_free(*deletion_script_file_name);
592  *deletion_script_file_name = NULL;
593  return;
594  }
595  }
596 
597  prep_status("Creating script to delete old cluster");
598 
599  if ((script = fopen_priv(*deletion_script_file_name, "w")) == NULL)
600  pg_fatal("could not open file \"%s\": %s\n",
601  *deletion_script_file_name, strerror(errno));
602 
603 #ifndef WIN32
604  /* add shebang header */
605  fprintf(script, "#!/bin/sh\n\n");
606 #endif
607 
608  /* delete old cluster's default tablespace */
609  fprintf(script, RMDIR_CMD " %c%s%c\n", PATH_QUOTE,
611 
612  /* delete old cluster's alternate tablespaces */
613  for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
614  {
615  /*
616  * Do the old cluster's per-database directories share a directory
617  * with a new version-specific tablespace?
618  */
619  if (strlen(old_cluster.tablespace_suffix) == 0)
620  {
621  /* delete per-database directories */
622  int dbnum;
623 
624  fprintf(script, "\n");
625  /* remove PG_VERSION? */
627  fprintf(script, RM_CMD " %s%cPG_VERSION\n",
630 
631  for (dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
632  fprintf(script, RMDIR_CMD " %c%s%c%d%c\n", PATH_QUOTE,
635  PATH_QUOTE);
636  }
637  else
638  {
639  char *suffix_path = pg_strdup(old_cluster.tablespace_suffix);
640 
641  /*
642  * Simply delete the tablespace directory, which might be ".old"
643  * or a version-specific subdirectory.
644  */
645  fprintf(script, RMDIR_CMD " %c%s%s%c\n", PATH_QUOTE,
647  fix_path_separator(suffix_path), PATH_QUOTE);
648  pfree(suffix_path);
649  }
650  }
651 
652  fclose(script);
653 
654 #ifndef WIN32
655  if (chmod(*deletion_script_file_name, S_IRWXU) != 0)
656  pg_fatal("could not add execute permission to file \"%s\": %s\n",
657  *deletion_script_file_name, strerror(errno));
658 #endif
659 
660  check_ok();
661 }
uint32 major_version
Definition: pg_upgrade.h:269
bool path_is_prefix_of_path(const char *path1, const char *path2)
Definition: path.c:438
#define PATH_SEPARATOR
Definition: pg_upgrade.h:69
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
#define SCRIPT_EXT
Definition: pg_upgrade.h:74
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:23
void canonicalize_path(char *path)
Definition: path.c:254
#define pg_fatal(...)
Definition: pg_rewind.h:43
#define fprintf
Definition: port.h:196
Oid db_oid
Definition: pg_upgrade.h:180
ClusterInfo new_cluster
Definition: pg_upgrade.c:59
void pfree(void *pointer)
Definition: mcxt.c:1056
#define MAXPGPATH
#define RMDIR_CMD
Definition: pg_upgrade.h:72
void prep_status(const char *fmt,...) pg_attribute_printf(1
ClusterInfo old_cluster
Definition: pg_upgrade.c:59
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
static void check_ok(void)
Definition: initdb.c:2079
char ** old_tablespaces
Definition: pg_upgrade.h:313
const char * tablespace_suffix
Definition: pg_upgrade.h:272
DbInfoArr dbarr
Definition: pg_upgrade.h:260
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
#define strerror
Definition: port.h:205
void pg_free(void *ptr)
Definition: fe_memutils.c:105
#define SCRIPT_PREFIX
Definition: pg_upgrade.h:73
#define PATH_QUOTE
Definition: pg_upgrade.h:70
#define fopen_priv(path, mode)
Definition: pg_upgrade.h:382
char * pgdata
Definition: pg_upgrade.h:261
#define S_IRWXU
Definition: win32_port.h:269
int num_old_tablespaces
Definition: pg_upgrade.h:314
OSInfo os_info
Definition: pg_upgrade.c:61
DbInfo * dbs
Definition: pg_upgrade.h:192
#define RM_CMD
Definition: pg_upgrade.h:71
static char * fix_path_separator(char *path)
Definition: check.c:40

◆ equivalent_locale()

static bool equivalent_locale ( int  category,
const char *  loca,
const char *  locb 
)
static

Definition at line 352 of file check.c.

References get_canonical_locale_name(), pg_free(), pg_strcasecmp(), and pg_strncasecmp().

Referenced by check_locale_and_encoding().

353 {
354  const char *chara;
355  const char *charb;
356  char *canona;
357  char *canonb;
358  int lena;
359  int lenb;
360 
361  /*
362  * If the names are equal, the locales are equivalent. Checking this first
363  * avoids calling setlocale() in the common case that the names are equal.
364  * That's a good thing, if setlocale() is buggy, for example.
365  */
366  if (pg_strcasecmp(loca, locb) == 0)
367  return true;
368 
369  /*
370  * Not identical. Canonicalize both names, remove the encoding parts, and
371  * try again.
372  */
373  canona = get_canonical_locale_name(category, loca);
374  chara = strrchr(canona, '.');
375  lena = chara ? (chara - canona) : strlen(canona);
376 
377  canonb = get_canonical_locale_name(category, locb);
378  charb = strrchr(canonb, '.');
379  lenb = charb ? (charb - canonb) : strlen(canonb);
380 
381  if (lena == lenb && pg_strncasecmp(canona, canonb, lena) == 0)
382  {
383  pg_free(canona);
384  pg_free(canonb);
385  return true;
386  }
387 
388  pg_free(canona);
389  pg_free(canonb);
390  return false;
391 }
static char * get_canonical_locale_name(int category, const char *locale)
Definition: check.c:1218
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
int pg_strncasecmp(const char *s1, const char *s2, size_t n)
Definition: pgstrcasecmp.c:69
void pg_free(void *ptr)
Definition: fe_memutils.c:105

◆ fix_path_separator()

static char* fix_path_separator ( char *  path)
static

Definition at line 40 of file check.c.

References pg_strdup().

Referenced by create_script_for_old_cluster_deletion().

41 {
42 #ifdef WIN32
43 
44  char *result;
45  char *c;
46 
47  result = pg_strdup(path);
48 
49  for (c = result; *c != '\0'; c++)
50  if (*c == '/')
51  *c = '\\';
52 
53  return result;
54 #else
55 
56  return path;
57 #endif
58 }
char * c
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85

◆ get_canonical_locale_name()

static char * get_canonical_locale_name ( int  category,
const char *  locale 
)
static

Definition at line 1218 of file check.c.

References pg_fatal, pg_free(), pg_strdup(), and setlocale.

Referenced by equivalent_locale().

1219 {
1220  char *save;
1221  char *res;
1222 
1223  /* get the current setting, so we can restore it. */
1224  save = setlocale(category, NULL);
1225  if (!save)
1226  pg_fatal("failed to get the current locale\n");
1227 
1228  /* 'save' may be pointing at a modifiable scratch variable, so copy it. */
1229  save = pg_strdup(save);
1230 
1231  /* set the locale with setlocale, to see if it accepts it. */
1232  res = setlocale(category, locale);
1233 
1234  if (!res)
1235  pg_fatal("failed to get system locale name for \"%s\"\n", locale);
1236 
1237  res = pg_strdup(res);
1238 
1239  /* restore old value. */
1240  if (!setlocale(category, save))
1241  pg_fatal("failed to restore old locale \"%s\"\n", save);
1242 
1243  pg_free(save);
1244 
1245  return res;
1246 }
#define setlocale(a, b)
Definition: win32_port.h:408
#define pg_fatal(...)
Definition: pg_rewind.h:43
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
void pg_free(void *ptr)
Definition: fe_memutils.c:105
static char * locale
Definition: initdb.c:125

◆ issue_warnings_and_set_wal_level()

void issue_warnings_and_set_wal_level ( void  )

Definition at line 203 of file check.c.

References GET_MAJOR_VERSION, ClusterInfo::major_version, new_9_0_populate_pg_largeobject_metadata(), new_cluster, old_9_6_invalidate_hash_indexes(), old_cluster, start_postmaster(), and stop_postmaster().

Referenced by main().

204 {
205  /*
206  * We unconditionally start/stop the new server because pg_resetwal -o set
207  * wal_level to 'minimum'. If the user is upgrading standby servers using
208  * the rsync instructions, they will need pg_upgrade to write its final
209  * WAL record showing wal_level as 'replica'.
210  */
212 
213  /* Create dummy large object permissions for old < PG 9.0? */
216 
217  /* Reindex hash indexes for old < 10.0 */
220 
221  stop_postmaster(false);
222 }
uint32 major_version
Definition: pg_upgrade.h:269
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:23
void old_9_6_invalidate_hash_indexes(ClusterInfo *cluster, bool check_mode)
Definition: version.c:299
ClusterInfo new_cluster
Definition: pg_upgrade.c:59
void new_9_0_populate_pg_largeobject_metadata(ClusterInfo *cluster, bool check_mode)
Definition: version.c:22
ClusterInfo old_cluster
Definition: pg_upgrade.c:59
void stop_postmaster(bool in_atexit)
Definition: server.c:327
static pgpid_t start_postmaster(void)
Definition: pg_ctl.c:445

◆ output_check_banner()

void output_check_banner ( bool  live_check)

Definition at line 61 of file check.c.

References UserOpts::check, pg_log(), PG_REPORT, and user_opts.

Referenced by main().

62 {
63  if (user_opts.check && live_check)
64  {
66  "Performing Consistency Checks on Old Live Server\n"
67  "------------------------------------------------\n");
68  }
69  else
70  {
72  "Performing Consistency Checks\n"
73  "-----------------------------\n");
74  }
75 }
UserOpts user_opts
Definition: option.c:30
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
bool check
Definition: pg_upgrade.h:292

◆ output_completion_banner()

void output_completion_banner ( char *  analyze_script_file_name,
char *  deletion_script_file_name 
)

Definition at line 226 of file check.c.

References GET_MAJOR_VERSION, ClusterInfo::major_version, old_cluster, pg_log(), and PG_REPORT.

Referenced by main().

228 {
229  /* Did we copy the free space files? */
232  "Optimizer statistics are not transferred by pg_upgrade so,\n"
233  "once you start the new server, consider running:\n"
234  " %s\n\n", analyze_script_file_name);
235  else
237  "Optimizer statistics and free space information are not transferred\n"
238  "by pg_upgrade so, once you start the new server, consider running:\n"
239  " %s\n\n", analyze_script_file_name);
240 
241 
242  if (deletion_script_file_name)
244  "Running this script will delete the old cluster's data files:\n"
245  " %s\n",
246  deletion_script_file_name);
247  else
249  "Could not create a script to delete the old cluster's data files\n"
250  "because user-defined tablespaces or the new cluster's data directory\n"
251  "exist in the old cluster directory. The old cluster's contents must\n"
252  "be deleted manually.\n");
253 }
uint32 major_version
Definition: pg_upgrade.h:269
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:23
ClusterInfo old_cluster
Definition: pg_upgrade.c:59
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2

◆ report_clusters_compatible()

void report_clusters_compatible ( void  )

Definition at line 186 of file check.c.

References UserOpts::check, pg_log(), PG_REPORT, stop_postmaster(), and user_opts.

Referenced by main().

187 {
188  if (user_opts.check)
189  {
190  pg_log(PG_REPORT, "\n*Clusters are compatible*\n");
191  /* stops new cluster */
192  stop_postmaster(false);
193  exit(0);
194  }
195 
196  pg_log(PG_REPORT, "\n"
197  "If pg_upgrade fails after this point, you must re-initdb the\n"
198  "new cluster before continuing.\n");
199 }
UserOpts user_opts
Definition: option.c:30
void stop_postmaster(bool in_atexit)
Definition: server.c:327
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
bool check
Definition: pg_upgrade.h:292