PostgreSQL Source Code  git master
check.c File Reference
#include "postgres_fe.h"
#include "catalog/pg_authid_d.h"
#include "catalog/pg_collation.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_user_defined_postfix_ops (ClusterInfo *cluster)
 
static void check_for_tables_with_oids (ClusterInfo *cluster)
 
static void check_for_composite_data_type_usage (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 void check_for_new_tablespace_dir (ClusterInfo *new_cluster)
 
static void check_for_user_defined_encoding_conversions (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 *deletion_script_file_name)
 
void check_cluster_versions (void)
 
void check_cluster_compatibility (bool live_check)
 
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 84 of file check.c.

85 {
86  /* -- OLD -- */
87 
88  if (!live_check)
90 
91  /* Extract a list of databases and tables from the old cluster */
93 
95 
97 
98 
99  /*
100  * Check for various failure cases
101  */
108 
109  /*
110  * PG 14 changed the function signature of encoding conversion functions.
111  * Conversions from older versions cannot be upgraded automatically
112  * because the user-defined functions used by the encoding conversions
113  * need to be changed to match the new signature.
114  */
117 
118  /*
119  * Pre-PG 14 allowed user defined postfix operators, which are not
120  * supported anymore. Verify there are none, iff applicable.
121  */
124 
125  /*
126  * Pre-PG 12 allowed tables to be declared WITH OIDS, which is not
127  * supported anymore. Verify there are none, iff applicable.
128  */
131 
132  /*
133  * PG 12 changed the 'sql_identifier' type storage to be based on name,
134  * not varchar, which breaks on-disk format for existing data. So we need
135  * to prevent upgrade when used in user objects (tables, indexes, ...).
136  */
139 
140  /*
141  * Pre-PG 10 allowed tables with 'unknown' type columns and non WAL logged
142  * hash indexes
143  */
145  {
147  if (user_opts.check)
149  }
150 
151  /* 9.5 and below should not have roles starting with pg_ */
154 
158 
159  /* Pre-PG 9.4 had a different 'line' data type internal format */
162 
163  /*
164  * While not a check option, we do this now because this is the only time
165  * the old server is running.
166  */
167  if (!user_opts.check)
169 
170  if (!live_check)
171  stop_postmaster(false);
172 }
static void check_for_tables_with_oids(ClusterInfo *cluster)
Definition: check.c:1003
static void check_for_pg_role_prefix(ClusterInfo *cluster)
Definition: check.c:1228
static void check_for_composite_data_type_usage(ClusterInfo *cluster)
Definition: check.c:1087
static void check_is_install_user(ClusterInfo *cluster)
Definition: check.c:635
static void check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster)
Definition: check.c:817
static void check_for_user_defined_postfix_ops(ClusterInfo *cluster)
Definition: check.c:903
static void check_for_prepared_transactions(ClusterInfo *cluster)
Definition: check.c:782
static void check_proper_datallowconn(ClusterInfo *cluster)
Definition: check.c:693
static void check_for_user_defined_encoding_conversions(ClusterInfo *cluster)
Definition: check.c:1259
static void check_for_jsonb_9_4_usage(ClusterInfo *cluster)
Definition: check.c:1200
static void check_for_reg_data_type_usage(ClusterInfo *cluster)
Definition: check.c:1146
void generate_old_dump(void)
Definition: dump.c:16
void get_loadable_libraries(void)
Definition: function.c:53
void get_db_and_rel_infos(ClusterInfo *cluster)
Definition: info.c:274
static pgpid_t start_postmaster(void)
Definition: pg_ctl.c:445
ClusterInfo old_cluster
Definition: pg_upgrade.c:63
void init_tablespaces(void)
Definition: tablespace.c:19
void old_11_check_for_sql_identifier_data_type_usage(ClusterInfo *cluster)
Definition: version.c:361
void old_9_3_check_for_line_data_type_usage(ClusterInfo *cluster)
Definition: version.c:180
void old_9_6_check_for_unknown_data_type_usage(ClusterInfo *cluster)
Definition: version.c:218
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:26
void stop_postmaster(bool in_atexit)
Definition: server.c:323
void old_9_6_invalidate_hash_indexes(ClusterInfo *cluster, bool check_mode)
Definition: version.c:246
#define JSONB_FORMAT_CHANGE_CAT_VER
Definition: pg_upgrade.h:124
UserOpts user_opts
Definition: option.c:29
ControlData controldata
Definition: pg_upgrade.h:253
uint32 major_version
Definition: pg_upgrade.h:263
uint32 cat_ver
Definition: pg_upgrade.h:197
bool check
Definition: pg_upgrade.h:291

References ControlData::cat_ver, UserOpts::check, check_for_composite_data_type_usage(), 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_for_user_defined_encoding_conversions(), check_for_user_defined_postfix_ops(), 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, 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().

◆ check_cluster_compatibility()

void check_cluster_compatibility ( bool  live_check)

Definition at line 320 of file check.c.

321 {
322  /* get/check pg_control data of servers */
323  get_control_data(&old_cluster, live_check);
324  get_control_data(&new_cluster, false);
326 
327  if (live_check && old_cluster.port == new_cluster.port)
328  pg_fatal("When checking a live server, "
329  "the old and new port numbers must be different.\n");
330 }
void get_control_data(ClusterInfo *cluster, bool live_check)
Definition: controldata.c:34
void check_control_data(ControlData *oldctrl, ControlData *newctrl)
Definition: controldata.c:648
#define pg_fatal(...)
ClusterInfo new_cluster
Definition: pg_upgrade.c:64
unsigned short port
Definition: pg_upgrade.h:262

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

Referenced by main().

◆ check_cluster_versions()

void check_cluster_versions ( void  )

Definition at line 278 of file check.c.

279 {
280  prep_status("Checking cluster versions");
281 
282  /* cluster versions should already have been obtained */
285 
286  /*
287  * We allow upgrades from/to the same major version for alpha/beta
288  * upgrades
289  */
290 
292  pg_fatal("This utility can only upgrade from PostgreSQL version 9.2 and later.\n");
293 
294  /* Only current PG version is supported as a target */
296  pg_fatal("This utility can only upgrade to PostgreSQL version %s.\n",
297  PG_MAJORVERSION);
298 
299  /*
300  * We can't allow downgrading because we use the target pg_dump, and
301  * pg_dump cannot operate on newer database versions, only current and
302  * older versions.
303  */
305  pg_fatal("This utility cannot be used to downgrade to older major PostgreSQL versions.\n");
306 
307  /* Ensure binaries match the designated data directories */
310  pg_fatal("Old cluster data and binary directories are from different major versions.\n");
313  pg_fatal("New cluster data and binary directories are from different major versions.\n");
314 
315  check_ok();
316 }
static void check_ok(void)
Definition: initdb.c:1908
Assert(fmt[strlen(fmt) - 1] !='\n')
void prep_status(const char *fmt,...) pg_attribute_printf(1
uint32 bin_version
Definition: pg_upgrade.h:265

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().

◆ check_databases_are_compatible()

static void check_databases_are_compatible ( void  )
static

Definition at line 449 of file check.c.

450 {
451  int newdbnum;
452  int olddbnum;
453  DbInfo *newdbinfo;
454  DbInfo *olddbinfo;
455 
456  for (newdbnum = 0; newdbnum < new_cluster.dbarr.ndbs; newdbnum++)
457  {
458  newdbinfo = &new_cluster.dbarr.dbs[newdbnum];
459 
460  /* Find the corresponding database in the old cluster */
461  for (olddbnum = 0; olddbnum < old_cluster.dbarr.ndbs; olddbnum++)
462  {
463  olddbinfo = &old_cluster.dbarr.dbs[olddbnum];
464  if (strcmp(newdbinfo->db_name, olddbinfo->db_name) == 0)
465  {
466  check_locale_and_encoding(olddbinfo, newdbinfo);
467  break;
468  }
469  }
470  }
471 }
static void check_locale_and_encoding(DbInfo *olddb, DbInfo *newdb)
Definition: check.c:340
DbInfoArr dbarr
Definition: pg_upgrade.h:254
DbInfo * dbs
Definition: pg_upgrade.h:185
char * db_name
Definition: pg_upgrade.h:172

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

Referenced by check_new_cluster().

◆ check_for_composite_data_type_usage()

static void check_for_composite_data_type_usage ( ClusterInfo cluster)
static

Definition at line 1087 of file check.c.

1088 {
1089  bool found;
1090  Oid firstUserOid;
1091  char output_path[MAXPGPATH];
1092  char *base_query;
1093 
1094  prep_status("Checking for system-defined composite types in user tables");
1095 
1096  snprintf(output_path, sizeof(output_path), "tables_using_composite.txt");
1097 
1098  /*
1099  * Look for composite types that were made during initdb *or* belong to
1100  * information_schema; that's important in case information_schema was
1101  * dropped and reloaded.
1102  *
1103  * The cutoff OID here should match the source cluster's value of
1104  * FirstNormalObjectId. We hardcode it rather than using that C #define
1105  * because, if that #define is ever changed, our own version's value is
1106  * NOT what to use. Eventually we may need a test on the source cluster's
1107  * version to select the correct value.
1108  */
1109  firstUserOid = 16384;
1110 
1111  base_query = psprintf("SELECT t.oid FROM pg_catalog.pg_type t "
1112  "LEFT JOIN pg_catalog.pg_namespace n ON t.typnamespace = n.oid "
1113  " WHERE typtype = 'c' AND (t.oid < %u OR nspname = 'information_schema')",
1114  firstUserOid);
1115 
1116  found = check_for_data_types_usage(cluster, base_query, output_path);
1117 
1118  free(base_query);
1119 
1120  if (found)
1121  {
1122  pg_log(PG_REPORT, "fatal\n");
1123  pg_fatal("Your installation contains system-defined composite type(s) in user tables.\n"
1124  "These type OIDs are not stable across PostgreSQL versions,\n"
1125  "so this cluster cannot currently be upgraded. You can\n"
1126  "drop the problem columns and restart the upgrade.\n"
1127  "A list of the problem columns is in the file:\n"
1128  " %s\n\n", output_path);
1129  }
1130  else
1131  check_ok();
1132 }
void cluster(ParseState *pstate, ClusterStmt *stmt, bool isTopLevel)
Definition: cluster.c:108
#define free(a)
Definition: header.h:65
#define MAXPGPATH
bool check_for_data_types_usage(ClusterInfo *cluster, const char *base_query, const char *output_path)
Definition: version.c:31
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
@ PG_REPORT
Definition: pg_upgrade.h:237
#define snprintf
Definition: port.h:225
unsigned int Oid
Definition: postgres_ext.h:31
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46

References check_for_data_types_usage(), check_ok(), cluster(), free, MAXPGPATH, pg_fatal, pg_log(), PG_REPORT, prep_status(), psprintf(), and snprintf.

Referenced by check_and_dump_old_cluster().

◆ check_for_isn_and_int8_passing_mismatch()

static void check_for_isn_and_int8_passing_mismatch ( ClusterInfo cluster)
static

Definition at line 817 of file check.c.

818 {
819  int dbnum;
820  FILE *script = NULL;
821  bool found = false;
822  char output_path[MAXPGPATH];
823 
824  prep_status("Checking for contrib/isn with bigint-passing mismatch");
825 
828  {
829  /* no mismatch */
830  check_ok();
831  return;
832  }
833 
834  snprintf(output_path, sizeof(output_path), "%s/%s",
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 */
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 dump databases in the old cluster that use \"contrib/isn\"\n"
891  "facilities, drop them, perform the upgrade, and then restore them. A\n"
892  "list of the problem functions is in the file:\n"
893  " %s\n\n", output_path);
894  }
895  else
896  check_ok();
897 }
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4261
void PQclear(PGresult *res)
Definition: fe-exec.c:718
int PQntuples(const PGresult *res)
Definition: fe-exec.c:3340
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3735
int PQfnumber(const PGresult *res, const char *field_name)
Definition: fe-exec.c:3448
LogOpts log_opts
Definition: util.c:17
#define fopen_priv(path, mode)
Definition: pg_upgrade.h:380
PGconn * connectToServer(ClusterInfo *cluster, const char *db_name)
Definition: server.c:28
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
#define strerror
Definition: port.h:238
#define fprintf
Definition: port.h:229
PGconn * conn
Definition: streamutil.c:54
bool float8_pass_by_value
Definition: pg_upgrade.h:216
char * basedir
Definition: pg_upgrade.h:279

References LogOpts::basedir, check_ok(), cluster(), conn, connectToServer(), ClusterInfo::controldata, DbInfo::db_name, executeQueryOrDie(), ControlData::float8_pass_by_value, fopen_priv, fprintf, log_opts, MAXPGPATH, new_cluster, old_cluster, pg_fatal, pg_log(), PG_REPORT, PQclear(), PQfinish(), PQfnumber(), PQgetvalue(), PQntuples(), prep_status(), res, snprintf, and strerror.

Referenced by check_and_dump_old_cluster().

◆ check_for_jsonb_9_4_usage()

static void check_for_jsonb_9_4_usage ( ClusterInfo cluster)
static

Definition at line 1200 of file check.c.

1201 {
1202  char output_path[MAXPGPATH];
1203 
1204  prep_status("Checking for incompatible \"jsonb\" data type");
1205 
1206  snprintf(output_path, sizeof(output_path), "tables_using_jsonb.txt");
1207 
1208  if (check_for_data_type_usage(cluster, "pg_catalog.jsonb", output_path))
1209  {
1210  pg_log(PG_REPORT, "fatal\n");
1211  pg_fatal("Your installation contains the \"jsonb\" data type in user tables.\n"
1212  "The internal format of \"jsonb\" changed during 9.4 beta so this\n"
1213  "cluster cannot currently be upgraded. You can\n"
1214  "drop the problem columns and restart the upgrade.\n"
1215  "A list of the problem columns is in the file:\n"
1216  " %s\n\n", output_path);
1217  }
1218  else
1219  check_ok();
1220 }
bool check_for_data_type_usage(ClusterInfo *cluster, const char *type_name, const char *output_path)
Definition: version.c:153

References check_for_data_type_usage(), check_ok(), cluster(), MAXPGPATH, pg_fatal, pg_log(), PG_REPORT, prep_status(), and snprintf.

Referenced by check_and_dump_old_cluster().

◆ check_for_new_tablespace_dir()

static void check_for_new_tablespace_dir ( ClusterInfo new_cluster)
static

Definition at line 483 of file check.c.

484 {
485  int tblnum;
486  char new_tablespace_dir[MAXPGPATH];
487 
488  prep_status("Checking for new cluster tablespace directories");
489 
490  for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
491  {
492  struct stat statbuf;
493 
494  snprintf(new_tablespace_dir, MAXPGPATH, "%s%s",
495  os_info.old_tablespaces[tblnum],
497 
498  if (stat(new_tablespace_dir, &statbuf) == 0 || errno != ENOENT)
499  pg_fatal("new cluster tablespace directory already exists: \"%s\"\n",
500  new_tablespace_dir);
501  }
502 
503  check_ok();
504 }
OSInfo os_info
Definition: pg_upgrade.c:65
const char * tablespace_suffix
Definition: pg_upgrade.h:266
int num_old_tablespaces
Definition: pg_upgrade.h:314
char ** old_tablespaces
Definition: pg_upgrade.h:313
#define stat
Definition: win32_port.h:283

References check_ok(), MAXPGPATH, new_cluster, OSInfo::num_old_tablespaces, OSInfo::old_tablespaces, os_info, pg_fatal, prep_status(), snprintf, stat, and ClusterInfo::tablespace_suffix.

Referenced by check_new_cluster().

◆ check_for_pg_role_prefix()

static void check_for_pg_role_prefix ( ClusterInfo cluster)
static

Definition at line 1228 of file check.c.

1229 {
1230  PGresult *res;
1231  PGconn *conn = connectToServer(cluster, "template1");
1232 
1233  prep_status("Checking for roles starting with \"pg_\"");
1234 
1236  "SELECT * "
1237  "FROM pg_catalog.pg_roles "
1238  "WHERE rolname ~ '^pg_'");
1239 
1240  if (PQntuples(res) != 0)
1241  {
1242  if (cluster == &old_cluster)
1243  pg_fatal("The source cluster contains roles starting with \"pg_\"\n");
1244  else
1245  pg_fatal("The target cluster contains roles starting with \"pg_\"\n");
1246  }
1247 
1248  PQclear(res);
1249 
1250  PQfinish(conn);
1251 
1252  check_ok();
1253 }

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

Referenced by check_and_dump_old_cluster().

◆ check_for_prepared_transactions()

static void check_for_prepared_transactions ( ClusterInfo cluster)
static

Definition at line 782 of file check.c.

783 {
784  PGresult *res;
785  PGconn *conn = connectToServer(cluster, "template1");
786 
787  prep_status("Checking for prepared transactions");
788 
790  "SELECT * "
791  "FROM pg_catalog.pg_prepared_xacts");
792 
793  if (PQntuples(res) != 0)
794  {
795  if (cluster == &old_cluster)
796  pg_fatal("The source cluster contains prepared transactions\n");
797  else
798  pg_fatal("The target cluster contains prepared transactions\n");
799  }
800 
801  PQclear(res);
802 
803  PQfinish(conn);
804 
805  check_ok();
806 }

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

Referenced by check_and_dump_old_cluster(), and check_new_cluster().

◆ check_for_reg_data_type_usage()

static void check_for_reg_data_type_usage ( ClusterInfo cluster)
static

Definition at line 1146 of file check.c.

1147 {
1148  bool found;
1149  char output_path[MAXPGPATH];
1150 
1151  prep_status("Checking for reg* data types in user tables");
1152 
1153  snprintf(output_path, sizeof(output_path), "tables_using_reg.txt");
1154 
1155  /*
1156  * Note: older servers will not have all of these reg* types, so we have
1157  * to write the query like this rather than depending on casts to regtype.
1158  */
1160  "SELECT oid FROM pg_catalog.pg_type t "
1161  "WHERE t.typnamespace = "
1162  " (SELECT oid FROM pg_catalog.pg_namespace "
1163  " WHERE nspname = 'pg_catalog') "
1164  " AND t.typname IN ( "
1165  /* pg_class.oid is preserved, so 'regclass' is OK */
1166  " 'regcollation', "
1167  " 'regconfig', "
1168  " 'regdictionary', "
1169  " 'regnamespace', "
1170  " 'regoper', "
1171  " 'regoperator', "
1172  " 'regproc', "
1173  " 'regprocedure' "
1174  /* pg_authid.oid is preserved, so 'regrole' is OK */
1175  /* pg_type.oid is (mostly) preserved, so 'regtype' is OK */
1176  " )",
1177  output_path);
1178 
1179  if (found)
1180  {
1181  pg_log(PG_REPORT, "fatal\n");
1182  pg_fatal("Your installation contains one of the reg* data types in user tables.\n"
1183  "These data types reference system OIDs that are not preserved by\n"
1184  "pg_upgrade, so this cluster cannot currently be upgraded. You can\n"
1185  "drop the problem columns and restart the upgrade.\n"
1186  "A list of the problem columns is in the file:\n"
1187  " %s\n\n", output_path);
1188  }
1189  else
1190  check_ok();
1191 }

References check_for_data_types_usage(), check_ok(), cluster(), MAXPGPATH, pg_fatal, pg_log(), PG_REPORT, prep_status(), and snprintf.

Referenced by check_and_dump_old_cluster().

◆ check_for_tables_with_oids()

static void check_for_tables_with_oids ( ClusterInfo cluster)
static

Definition at line 1003 of file check.c.

1004 {
1005  int dbnum;
1006  FILE *script = NULL;
1007  bool found = false;
1008  char output_path[MAXPGPATH];
1009 
1010  prep_status("Checking for tables WITH OIDS");
1011 
1012  snprintf(output_path, sizeof(output_path), "%s/%s",
1013  log_opts.basedir,
1014  "tables_with_oids.txt");
1015 
1016  /* Find any tables declared WITH OIDS */
1017  for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
1018  {
1019  PGresult *res;
1020  bool db_used = false;
1021  int ntups;
1022  int rowno;
1023  int i_nspname,
1024  i_relname;
1025  DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
1026  PGconn *conn = connectToServer(cluster, active_db->db_name);
1027 
1029  "SELECT n.nspname, c.relname "
1030  "FROM pg_catalog.pg_class c, "
1031  " pg_catalog.pg_namespace n "
1032  "WHERE c.relnamespace = n.oid AND "
1033  " c.relhasoids AND"
1034  " n.nspname NOT IN ('pg_catalog')");
1035 
1036  ntups = PQntuples(res);
1037  i_nspname = PQfnumber(res, "nspname");
1038  i_relname = PQfnumber(res, "relname");
1039  for (rowno = 0; rowno < ntups; rowno++)
1040  {
1041  found = true;
1042  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
1043  pg_fatal("could not open file \"%s\": %s\n",
1044  output_path, strerror(errno));
1045  if (!db_used)
1046  {
1047  fprintf(script, "In database: %s\n", active_db->db_name);
1048  db_used = true;
1049  }
1050  fprintf(script, " %s.%s\n",
1051  PQgetvalue(res, rowno, i_nspname),
1052  PQgetvalue(res, rowno, i_relname));
1053  }
1054 
1055  PQclear(res);
1056 
1057  PQfinish(conn);
1058  }
1059 
1060  if (script)
1061  fclose(script);
1062 
1063  if (found)
1064  {
1065  pg_log(PG_REPORT, "fatal\n");
1066  pg_fatal("Your installation contains tables declared WITH OIDS, which is not\n"
1067  "supported anymore. Consider removing the oid column using\n"
1068  " ALTER TABLE ... SET WITHOUT OIDS;\n"
1069  "A list of tables with the problem is in the file:\n"
1070  " %s\n\n", output_path);
1071  }
1072  else
1073  check_ok();
1074 }

References LogOpts::basedir, check_ok(), cluster(), conn, connectToServer(), DbInfo::db_name, executeQueryOrDie(), fopen_priv, fprintf, log_opts, MAXPGPATH, pg_fatal, pg_log(), PG_REPORT, PQclear(), PQfinish(), PQfnumber(), PQgetvalue(), PQntuples(), prep_status(), res, snprintf, and strerror.

Referenced by check_and_dump_old_cluster().

◆ check_for_user_defined_encoding_conversions()

static void check_for_user_defined_encoding_conversions ( ClusterInfo cluster)
static

Definition at line 1259 of file check.c.

1260 {
1261  int dbnum;
1262  FILE *script = NULL;
1263  bool found = false;
1264  char output_path[MAXPGPATH];
1265 
1266  prep_status("Checking for user-defined encoding conversions");
1267 
1268  snprintf(output_path, sizeof(output_path), "%s/%s",
1269  log_opts.basedir,
1270  "encoding_conversions.txt");
1271 
1272  /* Find any user defined encoding conversions */
1273  for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
1274  {
1275  PGresult *res;
1276  bool db_used = false;
1277  int ntups;
1278  int rowno;
1279  int i_conoid,
1280  i_conname,
1281  i_nspname;
1282  DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
1283  PGconn *conn = connectToServer(cluster, active_db->db_name);
1284 
1285  /*
1286  * The query below hardcodes FirstNormalObjectId as 16384 rather than
1287  * interpolating that C #define into the query because, if that
1288  * #define is ever changed, the cutoff we want to use is the value
1289  * used by pre-version 14 servers, not that of some future version.
1290  */
1292  "SELECT c.oid as conoid, c.conname, n.nspname "
1293  "FROM pg_catalog.pg_conversion c, "
1294  " pg_catalog.pg_namespace n "
1295  "WHERE c.connamespace = n.oid AND "
1296  " c.oid >= 16384");
1297  ntups = PQntuples(res);
1298  i_conoid = PQfnumber(res, "conoid");
1299  i_conname = PQfnumber(res, "conname");
1300  i_nspname = PQfnumber(res, "nspname");
1301  for (rowno = 0; rowno < ntups; rowno++)
1302  {
1303  found = true;
1304  if (script == NULL &&
1305  (script = fopen_priv(output_path, "w")) == NULL)
1306  pg_fatal("could not open file \"%s\": %s\n",
1307  output_path, strerror(errno));
1308  if (!db_used)
1309  {
1310  fprintf(script, "In database: %s\n", active_db->db_name);
1311  db_used = true;
1312  }
1313  fprintf(script, " (oid=%s) %s.%s\n",
1314  PQgetvalue(res, rowno, i_conoid),
1315  PQgetvalue(res, rowno, i_nspname),
1316  PQgetvalue(res, rowno, i_conname));
1317  }
1318 
1319  PQclear(res);
1320 
1321  PQfinish(conn);
1322  }
1323 
1324  if (script)
1325  fclose(script);
1326 
1327  if (found)
1328  {
1329  pg_log(PG_REPORT, "fatal\n");
1330  pg_fatal("Your installation contains user-defined encoding conversions.\n"
1331  "The conversion function parameters changed in PostgreSQL version 14\n"
1332  "so this cluster cannot currently be upgraded. You can remove the\n"
1333  "encoding conversions in the old cluster and restart the upgrade.\n"
1334  "A list of user-defined encoding conversions is in the file:\n"
1335  " %s\n\n", output_path);
1336  }
1337  else
1338  check_ok();
1339 }

References LogOpts::basedir, check_ok(), cluster(), conn, connectToServer(), DbInfo::db_name, executeQueryOrDie(), fopen_priv, fprintf, log_opts, MAXPGPATH, pg_fatal, pg_log(), PG_REPORT, PQclear(), PQfinish(), PQfnumber(), PQgetvalue(), PQntuples(), prep_status(), res, snprintf, and strerror.

Referenced by check_and_dump_old_cluster().

◆ check_for_user_defined_postfix_ops()

static void check_for_user_defined_postfix_ops ( ClusterInfo cluster)
static

Definition at line 903 of file check.c.

904 {
905  int dbnum;
906  FILE *script = NULL;
907  bool found = false;
908  char output_path[MAXPGPATH];
909 
910  prep_status("Checking for user-defined postfix operators");
911 
912  snprintf(output_path, sizeof(output_path), "%s/%s",
914  "postfix_ops.txt");
915 
916  /* Find any user defined postfix operators */
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_oproid,
924  i_oprnsp,
925  i_oprname,
926  i_typnsp,
927  i_typname;
928  DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
929  PGconn *conn = connectToServer(cluster, active_db->db_name);
930 
931  /*
932  * The query below hardcodes FirstNormalObjectId as 16384 rather than
933  * interpolating that C #define into the query because, if that
934  * #define is ever changed, the cutoff we want to use is the value
935  * used by pre-version 14 servers, not that of some future version.
936  */
938  "SELECT o.oid AS oproid, "
939  " n.nspname AS oprnsp, "
940  " o.oprname, "
941  " tn.nspname AS typnsp, "
942  " t.typname "
943  "FROM pg_catalog.pg_operator o, "
944  " pg_catalog.pg_namespace n, "
945  " pg_catalog.pg_type t, "
946  " pg_catalog.pg_namespace tn "
947  "WHERE o.oprnamespace = n.oid AND "
948  " o.oprleft = t.oid AND "
949  " t.typnamespace = tn.oid AND "
950  " o.oprright = 0 AND "
951  " o.oid >= 16384");
952  ntups = PQntuples(res);
953  i_oproid = PQfnumber(res, "oproid");
954  i_oprnsp = PQfnumber(res, "oprnsp");
955  i_oprname = PQfnumber(res, "oprname");
956  i_typnsp = PQfnumber(res, "typnsp");
957  i_typname = PQfnumber(res, "typname");
958  for (rowno = 0; rowno < ntups; rowno++)
959  {
960  found = true;
961  if (script == NULL &&
962  (script = fopen_priv(output_path, "w")) == NULL)
963  pg_fatal("could not open file \"%s\": %s\n",
964  output_path, strerror(errno));
965  if (!db_used)
966  {
967  fprintf(script, "In database: %s\n", active_db->db_name);
968  db_used = true;
969  }
970  fprintf(script, " (oid=%s) %s.%s (%s.%s, NONE)\n",
971  PQgetvalue(res, rowno, i_oproid),
972  PQgetvalue(res, rowno, i_oprnsp),
973  PQgetvalue(res, rowno, i_oprname),
974  PQgetvalue(res, rowno, i_typnsp),
975  PQgetvalue(res, rowno, i_typname));
976  }
977 
978  PQclear(res);
979 
980  PQfinish(conn);
981  }
982 
983  if (script)
984  fclose(script);
985 
986  if (found)
987  {
988  pg_log(PG_REPORT, "fatal\n");
989  pg_fatal("Your installation contains user-defined postfix operators, which are not\n"
990  "supported anymore. Consider dropping the postfix operators and replacing\n"
991  "them with prefix operators or function calls.\n"
992  "A list of user-defined postfix operators is in the file:\n"
993  " %s\n\n", output_path);
994  }
995  else
996  check_ok();
997 }

References LogOpts::basedir, check_ok(), cluster(), conn, connectToServer(), DbInfo::db_name, executeQueryOrDie(), fopen_priv, fprintf, log_opts, MAXPGPATH, pg_fatal, pg_log(), PG_REPORT, PQclear(), PQfinish(), PQfnumber(), PQgetvalue(), PQntuples(), prep_status(), res, snprintf, and strerror.

Referenced by check_and_dump_old_cluster().

◆ check_is_install_user()

static void check_is_install_user ( ClusterInfo cluster)
static

Definition at line 635 of file check.c.

636 {
637  PGresult *res;
638  PGconn *conn = connectToServer(cluster, "template1");
639 
640  prep_status("Checking database user is the install user");
641 
642  /* Can't use pg_authid because only superusers can view it. */
644  "SELECT rolsuper, oid "
645  "FROM pg_catalog.pg_roles "
646  "WHERE rolname = current_user "
647  "AND rolname !~ '^pg_'");
648 
649  /*
650  * We only allow the install user in the new cluster (see comment below)
651  * and we preserve pg_authid.oid, so this must be the install user in the
652  * old cluster too.
653  */
654  if (PQntuples(res) != 1 ||
655  atooid(PQgetvalue(res, 0, 1)) != BOOTSTRAP_SUPERUSERID)
656  pg_fatal("database user \"%s\" is not the install user\n",
657  os_info.user);
658 
659  PQclear(res);
660 
662  "SELECT COUNT(*) "
663  "FROM pg_catalog.pg_roles "
664  "WHERE rolname !~ '^pg_'");
665 
666  if (PQntuples(res) != 1)
667  pg_fatal("could not determine the number of users\n");
668 
669  /*
670  * We only allow the install user in the new cluster because other defined
671  * users might match users defined in the old cluster and generate an
672  * error during pg_dump restore.
673  */
674  if (cluster == &new_cluster && atooid(PQgetvalue(res, 0, 0)) != 1)
675  pg_fatal("Only the install user can be defined in the new cluster.\n");
676 
677  PQclear(res);
678 
679  PQfinish(conn);
680 
681  check_ok();
682 }
#define atooid(x)
Definition: postgres_ext.h:42
char * user
Definition: pg_upgrade.h:311

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

Referenced by check_and_dump_old_cluster(), and check_new_cluster().

◆ check_locale_and_encoding()

static void check_locale_and_encoding ( DbInfo olddb,
DbInfo newdb 
)
static

Definition at line 340 of file check.c.

341 {
342  if (olddb->db_encoding != newdb->db_encoding)
343  pg_fatal("encodings for database \"%s\" do not match: old \"%s\", new \"%s\"\n",
344  olddb->db_name,
347  if (!equivalent_locale(LC_COLLATE, olddb->db_collate, newdb->db_collate))
348  pg_fatal("lc_collate values for database \"%s\" do not match: old \"%s\", new \"%s\"\n",
349  olddb->db_name, olddb->db_collate, newdb->db_collate);
350  if (!equivalent_locale(LC_CTYPE, olddb->db_ctype, newdb->db_ctype))
351  pg_fatal("lc_ctype values for database \"%s\" do not match: old \"%s\", new \"%s\"\n",
352  olddb->db_name, olddb->db_ctype, newdb->db_ctype);
353  if (olddb->db_collprovider != newdb->db_collprovider)
354  pg_fatal("locale providers for database \"%s\" do not match: old \"%s\", new \"%s\"\n",
355  olddb->db_name,
356  collprovider_name(olddb->db_collprovider),
357  collprovider_name(newdb->db_collprovider));
358  if ((olddb->db_iculocale == NULL && newdb->db_iculocale != NULL) ||
359  (olddb->db_iculocale != NULL && newdb->db_iculocale == NULL) ||
360  (olddb->db_iculocale != NULL && newdb->db_iculocale != NULL && strcmp(olddb->db_iculocale, newdb->db_iculocale) != 0))
361  pg_fatal("ICU locale values for database \"%s\" do not match: old \"%s\", new \"%s\"\n",
362  olddb->db_name,
363  olddb->db_iculocale ? olddb->db_iculocale : "(null)",
364  newdb->db_iculocale ? newdb->db_iculocale : "(null)");
365 }
static bool equivalent_locale(int category, const char *loca, const char *locb)
Definition: check.c:379
const char * pg_encoding_to_char(int encoding)
Definition: encnames.c:588
char * db_iculocale
Definition: pg_upgrade.h:178
char db_collprovider
Definition: pg_upgrade.h:177
char * db_collate
Definition: pg_upgrade.h:175
int db_encoding
Definition: pg_upgrade.h:179
char * db_ctype
Definition: pg_upgrade.h:176

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

Referenced by check_databases_are_compatible().

◆ check_new_cluster()

void check_new_cluster ( void  )

Definition at line 176 of file check.c.

177 {
179 
182 
184 
185  switch (user_opts.transfer_mode)
186  {
187  case TRANSFER_MODE_CLONE:
189  break;
190  case TRANSFER_MODE_COPY:
191  break;
192  case TRANSFER_MODE_LINK:
193  check_hard_link();
194  break;
195  }
196 
198 
200 
202 }
static void check_databases_are_compatible(void)
Definition: check.c:449
static void check_new_cluster_is_empty(void)
Definition: check.c:422
static void check_for_new_tablespace_dir(ClusterInfo *new_cluster)
Definition: check.c:483
void check_file_clone(void)
Definition: file.c:317
void check_hard_link(void)
Definition: file.c:359
void check_loadable_libraries(void)
Definition: function.c:120
@ TRANSFER_MODE_COPY
Definition: pg_upgrade.h:226
@ TRANSFER_MODE_LINK
Definition: pg_upgrade.h:227
@ TRANSFER_MODE_CLONE
Definition: pg_upgrade.h:225
transferMode transfer_mode
Definition: pg_upgrade.h:294

References check_databases_are_compatible(), check_file_clone(), check_for_new_tablespace_dir(), 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().

◆ check_new_cluster_is_empty()

static void check_new_cluster_is_empty ( void  )
static

Definition at line 422 of file check.c.

423 {
424  int dbnum;
425 
426  for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++)
427  {
428  int relnum;
429  RelInfoArr *rel_arr = &new_cluster.dbarr.dbs[dbnum].rel_arr;
430 
431  for (relnum = 0; relnum < rel_arr->nrels;
432  relnum++)
433  {
434  /* pg_largeobject and its index should be skipped */
435  if (strcmp(rel_arr->rels[relnum].nspname, "pg_catalog") != 0)
436  pg_fatal("New cluster database \"%s\" is not empty: found relation \"%s.%s\"\n",
437  new_cluster.dbarr.dbs[dbnum].db_name,
438  rel_arr->rels[relnum].nspname,
439  rel_arr->rels[relnum].relname);
440  }
441  }
442 }
RelInfoArr rel_arr
Definition: pg_upgrade.h:180
RelInfo * rels
Definition: pg_upgrade.h:146
char * nspname
Definition: pg_upgrade.h:133
char * relname
Definition: pg_upgrade.h:134

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().

◆ check_proper_datallowconn()

static void check_proper_datallowconn ( ClusterInfo cluster)
static

Definition at line 693 of file check.c.

694 {
695  int dbnum;
696  PGconn *conn_template1;
697  PGresult *dbres;
698  int ntups;
699  int i_datname;
700  int i_datallowconn;
701  FILE *script = NULL;
702  char output_path[MAXPGPATH];
703  bool found = false;
704 
705  prep_status("Checking database connection settings");
706 
707  snprintf(output_path, sizeof(output_path), "%s/%s",
709  "databases_with_datallowconn_false.txt");
710 
711  conn_template1 = connectToServer(cluster, "template1");
712 
713  /* get database names */
714  dbres = executeQueryOrDie(conn_template1,
715  "SELECT datname, datallowconn "
716  "FROM pg_catalog.pg_database");
717 
718  i_datname = PQfnumber(dbres, "datname");
719  i_datallowconn = PQfnumber(dbres, "datallowconn");
720 
721  ntups = PQntuples(dbres);
722  for (dbnum = 0; dbnum < ntups; dbnum++)
723  {
724  char *datname = PQgetvalue(dbres, dbnum, i_datname);
725  char *datallowconn = PQgetvalue(dbres, dbnum, i_datallowconn);
726 
727  if (strcmp(datname, "template0") == 0)
728  {
729  /* avoid restore failure when pg_dumpall tries to create template0 */
730  if (strcmp(datallowconn, "t") == 0)
731  pg_fatal("template0 must not allow connections, "
732  "i.e. its pg_database.datallowconn must be false\n");
733  }
734  else
735  {
736  /*
737  * avoid datallowconn == false databases from being skipped on
738  * restore
739  */
740  if (strcmp(datallowconn, "f") == 0)
741  {
742  found = true;
743  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
744  pg_fatal("could not open file \"%s\": %s\n",
745  output_path, strerror(errno));
746 
747  fprintf(script, "%s\n", datname);
748  }
749  }
750  }
751 
752  PQclear(dbres);
753 
754  PQfinish(conn_template1);
755 
756  if (script)
757  fclose(script);
758 
759  if (found)
760  {
761  pg_log(PG_REPORT, "fatal\n");
762  pg_fatal("All non-template0 databases must allow connections, i.e. their\n"
763  "pg_database.datallowconn must be true. Your installation contains\n"
764  "non-template0 databases with their pg_database.datallowconn set to\n"
765  "false. Consider allowing connection for all non-template0 databases\n"
766  "or drop the databases which do not allow connections. A list of\n"
767  "databases with the problem is in the file:\n"
768  " %s\n\n", output_path);
769  }
770  else
771  check_ok();
772 }
NameData datname
Definition: pg_database.h:35
bool datallowconn
Definition: pg_database.h:50

References LogOpts::basedir, check_ok(), cluster(), connectToServer(), datallowconn, datname, executeQueryOrDie(), fopen_priv, fprintf, log_opts, MAXPGPATH, pg_fatal, pg_log(), PG_REPORT, PQclear(), PQfinish(), PQfnumber(), PQgetvalue(), PQntuples(), prep_status(), snprintf, and strerror.

Referenced by check_and_dump_old_cluster().

◆ create_script_for_old_cluster_deletion()

void create_script_for_old_cluster_deletion ( char **  deletion_script_file_name)

Definition at line 512 of file check.c.

513 {
514  FILE *script = NULL;
515  int tblnum;
516  char old_cluster_pgdata[MAXPGPATH],
517  new_cluster_pgdata[MAXPGPATH];
518 
519  *deletion_script_file_name = psprintf("%sdelete_old_cluster.%s",
521 
522  strlcpy(old_cluster_pgdata, old_cluster.pgdata, MAXPGPATH);
523  canonicalize_path(old_cluster_pgdata);
524 
525  strlcpy(new_cluster_pgdata, new_cluster.pgdata, MAXPGPATH);
526  canonicalize_path(new_cluster_pgdata);
527 
528  /* Some people put the new data directory inside the old one. */
529  if (path_is_prefix_of_path(old_cluster_pgdata, new_cluster_pgdata))
530  {
532  "\nWARNING: new data directory should not be inside the old data directory, e.g. %s\n", old_cluster_pgdata);
533 
534  /* Unlink file in case it is left over from a previous run. */
535  unlink(*deletion_script_file_name);
536  pg_free(*deletion_script_file_name);
537  *deletion_script_file_name = NULL;
538  return;
539  }
540 
541  /*
542  * Some users (oddly) create tablespaces inside the cluster data
543  * directory. We can't create a proper old cluster delete script in that
544  * case.
545  */
546  for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
547  {
548  char old_tablespace_dir[MAXPGPATH];
549 
550  strlcpy(old_tablespace_dir, os_info.old_tablespaces[tblnum], MAXPGPATH);
551  canonicalize_path(old_tablespace_dir);
552  if (path_is_prefix_of_path(old_cluster_pgdata, old_tablespace_dir))
553  {
554  /* reproduce warning from CREATE TABLESPACE that is in the log */
556  "\nWARNING: user-defined tablespace locations should not be inside the data directory, e.g. %s\n", old_tablespace_dir);
557 
558  /* Unlink file in case it is left over from a previous run. */
559  unlink(*deletion_script_file_name);
560  pg_free(*deletion_script_file_name);
561  *deletion_script_file_name = NULL;
562  return;
563  }
564  }
565 
566  prep_status("Creating script to delete old cluster");
567 
568  if ((script = fopen_priv(*deletion_script_file_name, "w")) == NULL)
569  pg_fatal("could not open file \"%s\": %s\n",
570  *deletion_script_file_name, strerror(errno));
571 
572 #ifndef WIN32
573  /* add shebang header */
574  fprintf(script, "#!/bin/sh\n\n");
575 #endif
576 
577  /* delete old cluster's default tablespace */
578  fprintf(script, RMDIR_CMD " %c%s%c\n", PATH_QUOTE,
580 
581  /* delete old cluster's alternate tablespaces */
582  for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
583  {
584  /*
585  * Do the old cluster's per-database directories share a directory
586  * with a new version-specific tablespace?
587  */
588  if (strlen(old_cluster.tablespace_suffix) == 0)
589  {
590  /* delete per-database directories */
591  int dbnum;
592 
593  fprintf(script, "\n");
594 
595  for (dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
596  fprintf(script, RMDIR_CMD " %c%s%c%u%c\n", PATH_QUOTE,
599  PATH_QUOTE);
600  }
601  else
602  {
603  char *suffix_path = pg_strdup(old_cluster.tablespace_suffix);
604 
605  /*
606  * Simply delete the tablespace directory, which might be ".old"
607  * or a version-specific subdirectory.
608  */
609  fprintf(script, RMDIR_CMD " %c%s%s%c\n", PATH_QUOTE,
611  fix_path_separator(suffix_path), PATH_QUOTE);
612  pfree(suffix_path);
613  }
614  }
615 
616  fclose(script);
617 
618 #ifndef WIN32
619  if (chmod(*deletion_script_file_name, S_IRWXU) != 0)
620  pg_fatal("could not add execute permission to file \"%s\": %s\n",
621  *deletion_script_file_name, strerror(errno));
622 #endif
623 
624  check_ok();
625 }
static char * fix_path_separator(char *path)
Definition: check.c:45
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
void pg_free(void *ptr)
Definition: fe_memutils.c:105
void pfree(void *pointer)
Definition: mcxt.c:1175
#define PATH_SEPARATOR
Definition: pg_upgrade.h:79
#define RMDIR_CMD
Definition: pg_upgrade.h:82
#define SCRIPT_EXT
Definition: pg_upgrade.h:84
#define SCRIPT_PREFIX
Definition: pg_upgrade.h:83
#define PATH_QUOTE
Definition: pg_upgrade.h:80
@ PG_WARNING
Definition: pg_upgrade.h:238
bool path_is_prefix_of_path(const char *path1, const char *path2)
Definition: path.c:559
void canonicalize_path(char *path)
Definition: path.c:264
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
char * pgdata
Definition: pg_upgrade.h:255
Oid db_oid
Definition: pg_upgrade.h:171
#define S_IRWXU
Definition: win32_port.h:297

References canonicalize_path(), check_ok(), DbInfo::db_oid, ClusterInfo::dbarr, DbInfoArr::dbs, fix_path_separator(), fopen_priv, fprintf, 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(), RMDIR_CMD, S_IRWXU, SCRIPT_EXT, SCRIPT_PREFIX, strerror, strlcpy(), and ClusterInfo::tablespace_suffix.

Referenced by main().

◆ equivalent_locale()

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

Definition at line 379 of file check.c.

380 {
381  const char *chara;
382  const char *charb;
383  char *canona;
384  char *canonb;
385  int lena;
386  int lenb;
387 
388  /*
389  * If the names are equal, the locales are equivalent. Checking this first
390  * avoids calling setlocale() in the common case that the names are equal.
391  * That's a good thing, if setlocale() is buggy, for example.
392  */
393  if (pg_strcasecmp(loca, locb) == 0)
394  return true;
395 
396  /*
397  * Not identical. Canonicalize both names, remove the encoding parts, and
398  * try again.
399  */
400  canona = get_canonical_locale_name(category, loca);
401  chara = strrchr(canona, '.');
402  lena = chara ? (chara - canona) : strlen(canona);
403 
404  canonb = get_canonical_locale_name(category, locb);
405  charb = strrchr(canonb, '.');
406  lenb = charb ? (charb - canonb) : strlen(canonb);
407 
408  if (lena == lenb && pg_strncasecmp(canona, canonb, lena) == 0)
409  {
410  pg_free(canona);
411  pg_free(canonb);
412  return true;
413  }
414 
415  pg_free(canona);
416  pg_free(canonb);
417  return false;
418 }
static char * get_canonical_locale_name(int category, const char *locale)
Definition: check.c:1349
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

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

Referenced by check_locale_and_encoding().

◆ fix_path_separator()

static char* fix_path_separator ( char *  path)
static

Definition at line 45 of file check.c.

46 {
47 #ifdef WIN32
48 
49  char *result;
50  char *c;
51 
52  result = pg_strdup(path);
53 
54  for (c = result; *c != '\0'; c++)
55  if (*c == '/')
56  *c = '\\';
57 
58  return result;
59 #else
60 
61  return path;
62 #endif
63 }
char * c

References pg_strdup().

Referenced by create_script_for_old_cluster_deletion().

◆ get_canonical_locale_name()

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

Definition at line 1349 of file check.c.

1350 {
1351  char *save;
1352  char *res;
1353 
1354  /* get the current setting, so we can restore it. */
1355  save = setlocale(category, NULL);
1356  if (!save)
1357  pg_fatal("failed to get the current locale\n");
1358 
1359  /* 'save' may be pointing at a modifiable scratch variable, so copy it. */
1360  save = pg_strdup(save);
1361 
1362  /* set the locale with setlocale, to see if it accepts it. */
1363  res = setlocale(category, locale);
1364 
1365  if (!res)
1366  pg_fatal("failed to get system locale name for \"%s\"\n", locale);
1367 
1368  res = pg_strdup(res);
1369 
1370  /* restore old value. */
1371  if (!setlocale(category, save))
1372  pg_fatal("failed to restore old locale \"%s\"\n", save);
1373 
1374  pg_free(save);
1375 
1376  return res;
1377 }
static char * locale
Definition: initdb.c:128
#define setlocale(a, b)
Definition: win32_port.h:446

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

Referenced by equivalent_locale().

◆ issue_warnings_and_set_wal_level()

void issue_warnings_and_set_wal_level ( void  )

Definition at line 223 of file check.c.

224 {
225  /*
226  * We unconditionally start/stop the new server because pg_resetwal -o set
227  * wal_level to 'minimum'. If the user is upgrading standby servers using
228  * the rsync instructions, they will need pg_upgrade to write its final
229  * WAL record showing wal_level as 'replica'.
230  */
232 
233  /* Reindex hash indexes for old < 10.0 */
236 
238 
239  stop_postmaster(false);
240 }
void report_extension_updates(ClusterInfo *cluster)
Definition: version.c:390

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

Referenced by main().

◆ output_check_banner()

void output_check_banner ( bool  live_check)

Definition at line 66 of file check.c.

67 {
68  if (user_opts.check && live_check)
69  {
71  "Performing Consistency Checks on Old Live Server\n"
72  "------------------------------------------------\n");
73  }
74  else
75  {
77  "Performing Consistency Checks\n"
78  "-----------------------------\n");
79  }
80 }

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

Referenced by main().

◆ output_completion_banner()

void output_completion_banner ( char *  deletion_script_file_name)

Definition at line 244 of file check.c.

245 {
246  PQExpBufferData user_specification;
247 
248  initPQExpBuffer(&user_specification);
250  {
251  appendPQExpBufferStr(&user_specification, "-U ");
252  appendShellString(&user_specification, os_info.user);
253  appendPQExpBufferChar(&user_specification, ' ');
254  }
255 
257  "Optimizer statistics are not transferred by pg_upgrade.\n"
258  "Once you start the new server, consider running:\n"
259  " %s/vacuumdb %s--all --analyze-in-stages\n\n", new_cluster.bindir, user_specification.data);
260 
261  if (deletion_script_file_name)
263  "Running this script will delete the old cluster's data files:\n"
264  " %s\n",
265  deletion_script_file_name);
266  else
268  "Could not create a script to delete the old cluster's data files\n"
269  "because user-defined tablespaces or the new cluster's data directory\n"
270  "exist in the old cluster directory. The old cluster's contents must\n"
271  "be deleted manually.\n");
272 
273  termPQExpBuffer(&user_specification);
274 }
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:92
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:380
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:131
void appendShellString(PQExpBuffer buf, const char *str)
Definition: string_utils.c:429
char * bindir
Definition: pg_upgrade.h:258
bool user_specified
Definition: pg_upgrade.h:312

References appendPQExpBufferChar(), appendPQExpBufferStr(), appendShellString(), ClusterInfo::bindir, PQExpBufferData::data, initPQExpBuffer(), new_cluster, os_info, pg_log(), PG_REPORT, termPQExpBuffer(), OSInfo::user, and OSInfo::user_specified.

Referenced by main().

◆ report_clusters_compatible()

void report_clusters_compatible ( void  )

Definition at line 206 of file check.c.

207 {
208  if (user_opts.check)
209  {
210  pg_log(PG_REPORT, "\n*Clusters are compatible*\n");
211  /* stops new cluster */
212  stop_postmaster(false);
213  exit(0);
214  }
215 
216  pg_log(PG_REPORT, "\n"
217  "If pg_upgrade fails after this point, you must re-initdb the\n"
218  "new cluster before continuing.\n");
219 }
exit(1)

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

Referenced by main().