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_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 83 of file check.c.

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

84 {
85  /* -- OLD -- */
86 
87  if (!live_check)
89 
90  /* Extract a list of databases and tables from the old cluster */
92 
94 
96 
97 
98  /*
99  * Check for various failure cases
100  */
107 
108  /*
109  * PG 14 changed the function signature of encoding conversion functions.
110  * Conversions from older versions cannot be upgraded automatically
111  * because the user-defined functions used by the encoding conversions
112  * need to be changed to match the new signature.
113  */
116 
117  /*
118  * Pre-PG 14 allowed user defined postfix operators, which are not
119  * supported anymore. Verify there are none, iff applicable.
120  */
123 
124  /*
125  * Pre-PG 12 allowed tables to be declared WITH OIDS, which is not
126  * supported anymore. Verify there are none, iff applicable.
127  */
130 
131  /*
132  * PG 12 changed the 'sql_identifier' type storage to be based on name,
133  * not varchar, which breaks on-disk format for existing data. So we need
134  * to prevent upgrade when used in user objects (tables, indexes, ...).
135  */
138 
139  /*
140  * Pre-PG 10 allowed tables with 'unknown' type columns and non WAL logged
141  * hash indexes
142  */
144  {
146  if (user_opts.check)
148  }
149 
150  /* 9.5 and below should not have roles starting with pg_ */
153 
157 
158  /* Pre-PG 9.4 had a different 'line' data type internal format */
161 
162  /* Pre-PG 9.0 had no large object permissions */
165 
166  /*
167  * While not a check option, we do this now because this is the only time
168  * the old server is running.
169  */
170  if (!user_opts.check)
172 
173  if (!live_check)
174  stop_postmaster(false);
175 }
uint32 major_version
Definition: pg_upgrade.h:267
ControlData controldata
Definition: pg_upgrade.h:257
#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:334
static void check_for_reg_data_type_usage(ClusterInfo *cluster)
Definition: check.c:1117
static void check_for_prepared_transactions(ClusterInfo *cluster)
Definition: check.c:756
static void check_for_user_defined_postfix_ops(ClusterInfo *cluster)
Definition: check.c:876
static void check_proper_datallowconn(ClusterInfo *cluster)
Definition: check.c:695
static void check_for_pg_role_prefix(ClusterInfo *cluster)
Definition: check.c:1199
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:975
void generate_old_dump(void)
Definition: dump.c:16
static void check_is_install_user(ClusterInfo *cluster)
Definition: check.c:644
static void check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster)
Definition: check.c:791
UserOpts user_opts
Definition: option.c:30
uint32 cat_ver
Definition: pg_upgrade.h:202
void stop_postmaster(bool in_atexit)
Definition: server.c:330
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:124
bool check
Definition: pg_upgrade.h:290
static pgpid_t start_postmaster(void)
Definition: pg_ctl.c:443
static void check_for_jsonb_9_4_usage(ClusterInfo *cluster)
Definition: check.c:1171
void init_tablespaces(void)
Definition: tablespace.c:19
void old_9_3_check_for_line_data_type_usage(ClusterInfo *cluster)
Definition: version.c:268
static void check_for_composite_data_type_usage(ClusterInfo *cluster)
Definition: check.c:1058
static void check_for_user_defined_encoding_conversions(ClusterInfo *cluster)
Definition: check.c:1230
void old_11_check_for_sql_identifier_data_type_usage(ClusterInfo *cluster)
Definition: version.c:449
void old_9_6_check_for_unknown_data_type_usage(ClusterInfo *cluster)
Definition: version.c:306

◆ check_cluster_compatibility()

void check_cluster_compatibility ( bool  live_check)

Definition at line 325 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().

326 {
327  /* get/check pg_control data of servers */
328  get_control_data(&old_cluster, live_check);
329  get_control_data(&new_cluster, false);
331 
332  /* We read the real port number for PG >= 9.1 */
333  if (live_check && GET_MAJOR_VERSION(old_cluster.major_version) <= 900 &&
335  pg_fatal("When checking a pre-PG 9.1 live old server, "
336  "you must specify the old server's port number.\n");
337 
338  if (live_check && old_cluster.port == new_cluster.port)
339  pg_fatal("When checking a live server, "
340  "the old and new port numbers must be different.\n");
341 }
uint32 major_version
Definition: pg_upgrade.h:267
ControlData controldata
Definition: pg_upgrade.h:257
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:23
#define pg_fatal(...)
Definition: pg_rewind.h:37
unsigned short port
Definition: pg_upgrade.h:266
void check_control_data(ControlData *oldctrl, ControlData *newctrl)
Definition: controldata.c:633
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 283 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().

284 {
285  prep_status("Checking cluster versions");
286 
287  /* cluster versions should already have been obtained */
290 
291  /*
292  * We allow upgrades from/to the same major version for alpha/beta
293  * upgrades
294  */
295 
297  pg_fatal("This utility can only upgrade from PostgreSQL version 8.4 and later.\n");
298 
299  /* Only current PG version is supported as a target */
301  pg_fatal("This utility can only upgrade to PostgreSQL version %s.\n",
302  PG_MAJORVERSION);
303 
304  /*
305  * We can't allow downgrading because we use the target pg_dump, and
306  * pg_dump cannot operate on newer database versions, only current and
307  * older versions.
308  */
310  pg_fatal("This utility cannot be used to downgrade to older major PostgreSQL versions.\n");
311 
312  /* Ensure binaries match the designated data directories */
315  pg_fatal("Old cluster data and binary directories are from different major versions.\n");
318  pg_fatal("New cluster data and binary directories are from different major versions.\n");
319 
320  check_ok();
321 }
uint32 major_version
Definition: pg_upgrade.h:267
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:23
#define pg_fatal(...)
Definition: pg_rewind.h:37
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:1991
uint32 bin_version
Definition: pg_upgrade.h:269
#define Assert(condition)
Definition: c.h:804

◆ check_databases_are_compatible()

static void check_databases_are_compatible ( void  )
static

Definition at line 448 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().

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

◆ check_for_composite_data_type_usage()

static void check_for_composite_data_type_usage ( ClusterInfo cluster)
static

Definition at line 1058 of file check.c.

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

Referenced by check_and_dump_old_cluster().

1059 {
1060  bool found;
1061  Oid firstUserOid;
1062  char output_path[MAXPGPATH];
1063  char *base_query;
1064 
1065  prep_status("Checking for system-defined composite types in user tables");
1066 
1067  snprintf(output_path, sizeof(output_path), "tables_using_composite.txt");
1068 
1069  /*
1070  * Look for composite types that were made during initdb *or* belong to
1071  * information_schema; that's important in case information_schema was
1072  * dropped and reloaded.
1073  *
1074  * The cutoff OID here should match the source cluster's value of
1075  * FirstNormalObjectId. We hardcode it rather than using that C #define
1076  * because, if that #define is ever changed, our own version's value is
1077  * NOT what to use. Eventually we may need a test on the source cluster's
1078  * version to select the correct value.
1079  */
1080  firstUserOid = 16384;
1081 
1082  base_query = psprintf("SELECT t.oid FROM pg_catalog.pg_type t "
1083  "LEFT JOIN pg_catalog.pg_namespace n ON t.typnamespace = n.oid "
1084  " WHERE typtype = 'c' AND (t.oid < %u OR nspname = 'information_schema')",
1085  firstUserOid);
1086 
1087  found = check_for_data_types_usage(cluster, base_query, output_path);
1088 
1089  free(base_query);
1090 
1091  if (found)
1092  {
1093  pg_log(PG_REPORT, "fatal\n");
1094  pg_fatal("Your installation contains system-defined composite type(s) in user tables.\n"
1095  "These type OIDs are not stable across PostgreSQL versions,\n"
1096  "so this cluster cannot currently be upgraded. You can\n"
1097  "drop the problem columns and restart the upgrade.\n"
1098  "A list of the problem columns is in the file:\n"
1099  " %s\n\n", output_path);
1100  }
1101  else
1102  check_ok();
1103 }
bool check_for_data_types_usage(ClusterInfo *cluster, const char *base_query, const char *output_path)
Definition: version.c:113
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
#define pg_fatal(...)
Definition: pg_rewind.h:37
unsigned int Oid
Definition: postgres_ext.h:31
#define MAXPGPATH
void prep_status(const char *fmt,...) pg_attribute_printf(1
static void check_ok(void)
Definition: initdb.c:1991
#define free(a)
Definition: header.h:65
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
#define snprintf
Definition: port.h:216

◆ check_for_isn_and_int8_passing_mismatch()

static void check_for_isn_and_int8_passing_mismatch ( ClusterInfo cluster)
static

Definition at line 791 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().

792 {
793  int dbnum;
794  FILE *script = NULL;
795  bool found = false;
796  char output_path[MAXPGPATH];
797 
798  prep_status("Checking for contrib/isn with bigint-passing mismatch");
799 
802  {
803  /* no mismatch */
804  check_ok();
805  return;
806  }
807 
808  snprintf(output_path, sizeof(output_path),
809  "contrib_isn_and_int8_pass_by_value.txt");
810 
811  for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
812  {
813  PGresult *res;
814  bool db_used = false;
815  int ntups;
816  int rowno;
817  int i_nspname,
818  i_proname;
819  DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
820  PGconn *conn = connectToServer(cluster, active_db->db_name);
821 
822  /* Find any functions coming from contrib/isn */
823  res = executeQueryOrDie(conn,
824  "SELECT n.nspname, p.proname "
825  "FROM pg_catalog.pg_proc p, "
826  " pg_catalog.pg_namespace n "
827  "WHERE p.pronamespace = n.oid AND "
828  " p.probin = '$libdir/isn'");
829 
830  ntups = PQntuples(res);
831  i_nspname = PQfnumber(res, "nspname");
832  i_proname = PQfnumber(res, "proname");
833  for (rowno = 0; rowno < ntups; rowno++)
834  {
835  found = true;
836  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
837  pg_fatal("could not open file \"%s\": %s\n",
838  output_path, strerror(errno));
839  if (!db_used)
840  {
841  fprintf(script, "In database: %s\n", active_db->db_name);
842  db_used = true;
843  }
844  fprintf(script, " %s.%s\n",
845  PQgetvalue(res, rowno, i_nspname),
846  PQgetvalue(res, rowno, i_proname));
847  }
848 
849  PQclear(res);
850 
851  PQfinish(conn);
852  }
853 
854  if (script)
855  fclose(script);
856 
857  if (found)
858  {
859  pg_log(PG_REPORT, "fatal\n");
860  pg_fatal("Your installation contains \"contrib/isn\" functions which rely on the\n"
861  "bigint data type. Your old and new clusters pass bigint values\n"
862  "differently so this cluster cannot currently be upgraded. You can\n"
863  "manually dump databases in the old cluster that use \"contrib/isn\"\n"
864  "facilities, drop them, perform the upgrade, and then restore them. A\n"
865  "list of the problem functions is in the file:\n"
866  " %s\n\n", output_path);
867  }
868  else
869  check_ok();
870 }
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3561
ControlData controldata
Definition: pg_upgrade.h:257
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
#define pg_fatal(...)
Definition: pg_rewind.h:37
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4229
int PQntuples(const PGresult *res)
Definition: fe-exec.c:3167
#define fprintf
Definition: port.h:220
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:1991
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:3275
void PQclear(PGresult *res)
Definition: fe-exec.c:680
DbInfoArr dbarr
Definition: pg_upgrade.h:258
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
#define strerror
Definition: port.h:229
#define fopen_priv(path, mode)
Definition: pg_upgrade.h:378
char * db_name
Definition: pg_upgrade.h:179
DbInfo * dbs
Definition: pg_upgrade.h:190
#define snprintf
Definition: port.h:216
bool float8_pass_by_value
Definition: pg_upgrade.h:220

◆ check_for_jsonb_9_4_usage()

static void check_for_jsonb_9_4_usage ( ClusterInfo cluster)
static

Definition at line 1171 of file check.c.

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

Referenced by check_and_dump_old_cluster().

1172 {
1173  char output_path[MAXPGPATH];
1174 
1175  prep_status("Checking for incompatible \"jsonb\" data type");
1176 
1177  snprintf(output_path, sizeof(output_path), "tables_using_jsonb.txt");
1178 
1179  if (check_for_data_type_usage(cluster, "pg_catalog.jsonb", output_path))
1180  {
1181  pg_log(PG_REPORT, "fatal\n");
1182  pg_fatal("Your installation contains the \"jsonb\" data type in user tables.\n"
1183  "The internal format of \"jsonb\" changed during 9.4 beta so this\n"
1184  "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 }
#define pg_fatal(...)
Definition: pg_rewind.h:37
#define MAXPGPATH
void prep_status(const char *fmt,...) pg_attribute_printf(1
static void check_ok(void)
Definition: initdb.c:1991
bool check_for_data_type_usage(ClusterInfo *cluster, const char *typename, const char *output_path)
Definition: version.c:241
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
#define snprintf
Definition: port.h:216

◆ check_for_new_tablespace_dir()

static void check_for_new_tablespace_dir ( ClusterInfo new_cluster)
static

Definition at line 487 of file check.c.

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

Referenced by check_new_cluster().

488 {
489  int tblnum;
490  char new_tablespace_dir[MAXPGPATH];
491 
492  prep_status("Checking for new cluster tablespace directories");
493 
494  for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
495  {
496  struct stat statbuf;
497 
498  snprintf(new_tablespace_dir, MAXPGPATH, "%s%s",
499  os_info.old_tablespaces[tblnum],
500  new_cluster->tablespace_suffix);
501 
502  if (stat(new_tablespace_dir, &statbuf) == 0 || errno != ENOENT)
503  pg_fatal("new cluster tablespace directory already exists: \"%s\"\n",
504  new_tablespace_dir);
505  }
506 
507  check_ok();
508 }
#define pg_fatal(...)
Definition: pg_rewind.h:37
#define MAXPGPATH
void prep_status(const char *fmt,...) pg_attribute_printf(1
static void check_ok(void)
Definition: initdb.c:1991
char ** old_tablespaces
Definition: pg_upgrade.h:311
const char * tablespace_suffix
Definition: pg_upgrade.h:270
int num_old_tablespaces
Definition: pg_upgrade.h:312
OSInfo os_info
Definition: pg_upgrade.c:61
#define snprintf
Definition: port.h:216
#define stat
Definition: win32_port.h:275

◆ check_for_pg_role_prefix()

static void check_for_pg_role_prefix ( ClusterInfo cluster)
static

Definition at line 1199 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().

1200 {
1201  PGresult *res;
1202  PGconn *conn = connectToServer(cluster, "template1");
1203 
1204  prep_status("Checking for roles starting with \"pg_\"");
1205 
1206  res = executeQueryOrDie(conn,
1207  "SELECT * "
1208  "FROM pg_catalog.pg_roles "
1209  "WHERE rolname ~ '^pg_'");
1210 
1211  if (PQntuples(res) != 0)
1212  {
1213  if (cluster == &old_cluster)
1214  pg_fatal("The source cluster contains roles starting with \"pg_\"\n");
1215  else
1216  pg_fatal("The target cluster contains roles starting with \"pg_\"\n");
1217  }
1218 
1219  PQclear(res);
1220 
1221  PQfinish(conn);
1222 
1223  check_ok();
1224 }
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
#define pg_fatal(...)
Definition: pg_rewind.h:37
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4229
int PQntuples(const PGresult *res)
Definition: fe-exec.c:3167
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:1991
PGconn * connectToServer(ClusterInfo *cluster, const char *db_name)
Definition: server.c:27
void PQclear(PGresult *res)
Definition: fe-exec.c:680

◆ check_for_prepared_transactions()

static void check_for_prepared_transactions ( ClusterInfo cluster)
static

Definition at line 756 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().

757 {
758  PGresult *res;
759  PGconn *conn = connectToServer(cluster, "template1");
760 
761  prep_status("Checking for prepared transactions");
762 
763  res = executeQueryOrDie(conn,
764  "SELECT * "
765  "FROM pg_catalog.pg_prepared_xacts");
766 
767  if (PQntuples(res) != 0)
768  {
769  if (cluster == &old_cluster)
770  pg_fatal("The source cluster contains prepared transactions\n");
771  else
772  pg_fatal("The target cluster contains prepared transactions\n");
773  }
774 
775  PQclear(res);
776 
777  PQfinish(conn);
778 
779  check_ok();
780 }
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
#define pg_fatal(...)
Definition: pg_rewind.h:37
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4229
int PQntuples(const PGresult *res)
Definition: fe-exec.c:3167
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:1991
PGconn * connectToServer(ClusterInfo *cluster, const char *db_name)
Definition: server.c:27
void PQclear(PGresult *res)
Definition: fe-exec.c:680

◆ check_for_reg_data_type_usage()

static void check_for_reg_data_type_usage ( ClusterInfo cluster)
static

Definition at line 1117 of file check.c.

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

Referenced by check_and_dump_old_cluster().

1118 {
1119  bool found;
1120  char output_path[MAXPGPATH];
1121 
1122  prep_status("Checking for reg* data types in user tables");
1123 
1124  snprintf(output_path, sizeof(output_path), "tables_using_reg.txt");
1125 
1126  /*
1127  * Note: older servers will not have all of these reg* types, so we have
1128  * to write the query like this rather than depending on casts to regtype.
1129  */
1130  found = check_for_data_types_usage(cluster,
1131  "SELECT oid FROM pg_catalog.pg_type t "
1132  "WHERE t.typnamespace = "
1133  " (SELECT oid FROM pg_catalog.pg_namespace "
1134  " WHERE nspname = 'pg_catalog') "
1135  " AND t.typname IN ( "
1136  /* pg_class.oid is preserved, so 'regclass' is OK */
1137  " 'regcollation', "
1138  " 'regconfig', "
1139  " 'regdictionary', "
1140  " 'regnamespace', "
1141  " 'regoper', "
1142  " 'regoperator', "
1143  " 'regproc', "
1144  " 'regprocedure' "
1145  /* pg_authid.oid is preserved, so 'regrole' is OK */
1146  /* pg_type.oid is (mostly) preserved, so 'regtype' is OK */
1147  " )",
1148  output_path);
1149 
1150  if (found)
1151  {
1152  pg_log(PG_REPORT, "fatal\n");
1153  pg_fatal("Your installation contains one of the reg* data types in user tables.\n"
1154  "These data types reference system OIDs that are not preserved by\n"
1155  "pg_upgrade, so this cluster cannot currently be upgraded. You can\n"
1156  "drop the problem columns and restart the upgrade.\n"
1157  "A list of the problem columns is in the file:\n"
1158  " %s\n\n", output_path);
1159  }
1160  else
1161  check_ok();
1162 }
bool check_for_data_types_usage(ClusterInfo *cluster, const char *base_query, const char *output_path)
Definition: version.c:113
#define pg_fatal(...)
Definition: pg_rewind.h:37
#define MAXPGPATH
void prep_status(const char *fmt,...) pg_attribute_printf(1
static void check_ok(void)
Definition: initdb.c:1991
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
#define snprintf
Definition: port.h:216

◆ check_for_tables_with_oids()

static void check_for_tables_with_oids ( ClusterInfo cluster)
static

Definition at line 975 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().

976 {
977  int dbnum;
978  FILE *script = NULL;
979  bool found = false;
980  char output_path[MAXPGPATH];
981 
982  prep_status("Checking for tables WITH OIDS");
983 
984  snprintf(output_path, sizeof(output_path),
985  "tables_with_oids.txt");
986 
987  /* Find any tables declared WITH OIDS */
988  for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
989  {
990  PGresult *res;
991  bool db_used = false;
992  int ntups;
993  int rowno;
994  int i_nspname,
995  i_relname;
996  DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
997  PGconn *conn = connectToServer(cluster, active_db->db_name);
998 
999  res = executeQueryOrDie(conn,
1000  "SELECT n.nspname, c.relname "
1001  "FROM pg_catalog.pg_class c, "
1002  " pg_catalog.pg_namespace n "
1003  "WHERE c.relnamespace = n.oid AND "
1004  " c.relhasoids AND"
1005  " n.nspname NOT IN ('pg_catalog')");
1006 
1007  ntups = PQntuples(res);
1008  i_nspname = PQfnumber(res, "nspname");
1009  i_relname = PQfnumber(res, "relname");
1010  for (rowno = 0; rowno < ntups; rowno++)
1011  {
1012  found = true;
1013  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
1014  pg_fatal("could not open file \"%s\": %s\n",
1015  output_path, strerror(errno));
1016  if (!db_used)
1017  {
1018  fprintf(script, "In database: %s\n", active_db->db_name);
1019  db_used = true;
1020  }
1021  fprintf(script, " %s.%s\n",
1022  PQgetvalue(res, rowno, i_nspname),
1023  PQgetvalue(res, rowno, i_relname));
1024  }
1025 
1026  PQclear(res);
1027 
1028  PQfinish(conn);
1029  }
1030 
1031  if (script)
1032  fclose(script);
1033 
1034  if (found)
1035  {
1036  pg_log(PG_REPORT, "fatal\n");
1037  pg_fatal("Your installation contains tables declared WITH OIDS, which is not\n"
1038  "supported anymore. Consider removing the oid column using\n"
1039  " ALTER TABLE ... SET WITHOUT OIDS;\n"
1040  "A list of tables with the problem is in the file:\n"
1041  " %s\n\n", output_path);
1042  }
1043  else
1044  check_ok();
1045 }
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3561
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
#define pg_fatal(...)
Definition: pg_rewind.h:37
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4229
int PQntuples(const PGresult *res)
Definition: fe-exec.c:3167
#define fprintf
Definition: port.h:220
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:1991
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:3275
void PQclear(PGresult *res)
Definition: fe-exec.c:680
DbInfoArr dbarr
Definition: pg_upgrade.h:258
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
#define strerror
Definition: port.h:229
#define fopen_priv(path, mode)
Definition: pg_upgrade.h:378
char * db_name
Definition: pg_upgrade.h:179
DbInfo * dbs
Definition: pg_upgrade.h:190
#define snprintf
Definition: port.h:216

◆ check_for_user_defined_encoding_conversions()

static void check_for_user_defined_encoding_conversions ( ClusterInfo cluster)
static

Definition at line 1230 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().

1231 {
1232  int dbnum;
1233  FILE *script = NULL;
1234  bool found = false;
1235  char output_path[MAXPGPATH];
1236 
1237  prep_status("Checking for user-defined encoding conversions");
1238 
1239  snprintf(output_path, sizeof(output_path),
1240  "encoding_conversions.txt");
1241 
1242  /* Find any user defined encoding conversions */
1243  for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
1244  {
1245  PGresult *res;
1246  bool db_used = false;
1247  int ntups;
1248  int rowno;
1249  int i_conoid,
1250  i_conname,
1251  i_nspname;
1252  DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
1253  PGconn *conn = connectToServer(cluster, active_db->db_name);
1254 
1255  /*
1256  * The query below hardcodes FirstNormalObjectId as 16384 rather than
1257  * interpolating that C #define into the query because, if that
1258  * #define is ever changed, the cutoff we want to use is the value
1259  * used by pre-version 14 servers, not that of some future version.
1260  */
1261  res = executeQueryOrDie(conn,
1262  "SELECT c.oid as conoid, c.conname, n.nspname "
1263  "FROM pg_catalog.pg_conversion c, "
1264  " pg_catalog.pg_namespace n "
1265  "WHERE c.connamespace = n.oid AND "
1266  " c.oid >= 16384");
1267  ntups = PQntuples(res);
1268  i_conoid = PQfnumber(res, "conoid");
1269  i_conname = PQfnumber(res, "conname");
1270  i_nspname = PQfnumber(res, "nspname");
1271  for (rowno = 0; rowno < ntups; rowno++)
1272  {
1273  found = true;
1274  if (script == NULL &&
1275  (script = fopen_priv(output_path, "w")) == NULL)
1276  pg_fatal("could not open file \"%s\": %s\n",
1277  output_path, strerror(errno));
1278  if (!db_used)
1279  {
1280  fprintf(script, "In database: %s\n", active_db->db_name);
1281  db_used = true;
1282  }
1283  fprintf(script, " (oid=%s) %s.%s\n",
1284  PQgetvalue(res, rowno, i_conoid),
1285  PQgetvalue(res, rowno, i_nspname),
1286  PQgetvalue(res, rowno, i_conname));
1287  }
1288 
1289  PQclear(res);
1290 
1291  PQfinish(conn);
1292  }
1293 
1294  if (script)
1295  fclose(script);
1296 
1297  if (found)
1298  {
1299  pg_log(PG_REPORT, "fatal\n");
1300  pg_fatal("Your installation contains user-defined encoding conversions.\n"
1301  "The conversion function parameters changed in PostgreSQL version 14\n"
1302  "so this cluster cannot currently be upgraded. You can remove the\n"
1303  "encoding conversions in the old cluster and restart the upgrade.\n"
1304  "A list of user-defined encoding conversions is in the file:\n"
1305  " %s\n\n", output_path);
1306  }
1307  else
1308  check_ok();
1309 }
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3561
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
#define pg_fatal(...)
Definition: pg_rewind.h:37
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4229
int PQntuples(const PGresult *res)
Definition: fe-exec.c:3167
#define fprintf
Definition: port.h:220
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:1991
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:3275
void PQclear(PGresult *res)
Definition: fe-exec.c:680
DbInfoArr dbarr
Definition: pg_upgrade.h:258
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
#define strerror
Definition: port.h:229
#define fopen_priv(path, mode)
Definition: pg_upgrade.h:378
char * db_name
Definition: pg_upgrade.h:179
DbInfo * dbs
Definition: pg_upgrade.h:190
#define snprintf
Definition: port.h:216

◆ check_for_user_defined_postfix_ops()

static void check_for_user_defined_postfix_ops ( ClusterInfo cluster)
static

Definition at line 876 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().

877 {
878  int dbnum;
879  FILE *script = NULL;
880  bool found = false;
881  char output_path[MAXPGPATH];
882 
883  prep_status("Checking for user-defined postfix operators");
884 
885  snprintf(output_path, sizeof(output_path),
886  "postfix_ops.txt");
887 
888  /* Find any user defined postfix operators */
889  for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
890  {
891  PGresult *res;
892  bool db_used = false;
893  int ntups;
894  int rowno;
895  int i_oproid,
896  i_oprnsp,
897  i_oprname,
898  i_typnsp,
899  i_typname;
900  DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
901  PGconn *conn = connectToServer(cluster, active_db->db_name);
902 
903  /*
904  * The query below hardcodes FirstNormalObjectId as 16384 rather than
905  * interpolating that C #define into the query because, if that
906  * #define is ever changed, the cutoff we want to use is the value
907  * used by pre-version 14 servers, not that of some future version.
908  */
909  res = executeQueryOrDie(conn,
910  "SELECT o.oid AS oproid, "
911  " n.nspname AS oprnsp, "
912  " o.oprname, "
913  " tn.nspname AS typnsp, "
914  " t.typname "
915  "FROM pg_catalog.pg_operator o, "
916  " pg_catalog.pg_namespace n, "
917  " pg_catalog.pg_type t, "
918  " pg_catalog.pg_namespace tn "
919  "WHERE o.oprnamespace = n.oid AND "
920  " o.oprleft = t.oid AND "
921  " t.typnamespace = tn.oid AND "
922  " o.oprright = 0 AND "
923  " o.oid >= 16384");
924  ntups = PQntuples(res);
925  i_oproid = PQfnumber(res, "oproid");
926  i_oprnsp = PQfnumber(res, "oprnsp");
927  i_oprname = PQfnumber(res, "oprname");
928  i_typnsp = PQfnumber(res, "typnsp");
929  i_typname = PQfnumber(res, "typname");
930  for (rowno = 0; rowno < ntups; rowno++)
931  {
932  found = true;
933  if (script == NULL &&
934  (script = fopen_priv(output_path, "w")) == NULL)
935  pg_fatal("could not open file \"%s\": %s\n",
936  output_path, strerror(errno));
937  if (!db_used)
938  {
939  fprintf(script, "In database: %s\n", active_db->db_name);
940  db_used = true;
941  }
942  fprintf(script, " (oid=%s) %s.%s (%s.%s, NONE)\n",
943  PQgetvalue(res, rowno, i_oproid),
944  PQgetvalue(res, rowno, i_oprnsp),
945  PQgetvalue(res, rowno, i_oprname),
946  PQgetvalue(res, rowno, i_typnsp),
947  PQgetvalue(res, rowno, i_typname));
948  }
949 
950  PQclear(res);
951 
952  PQfinish(conn);
953  }
954 
955  if (script)
956  fclose(script);
957 
958  if (found)
959  {
960  pg_log(PG_REPORT, "fatal\n");
961  pg_fatal("Your installation contains user-defined postfix operators, which are not\n"
962  "supported anymore. Consider dropping the postfix operators and replacing\n"
963  "them with prefix operators or function calls.\n"
964  "A list of user-defined postfix operators is in the file:\n"
965  " %s\n\n", output_path);
966  }
967  else
968  check_ok();
969 }
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3561
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
#define pg_fatal(...)
Definition: pg_rewind.h:37
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4229
int PQntuples(const PGresult *res)
Definition: fe-exec.c:3167
#define fprintf
Definition: port.h:220
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:1991
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:3275
void PQclear(PGresult *res)
Definition: fe-exec.c:680
DbInfoArr dbarr
Definition: pg_upgrade.h:258
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
#define strerror
Definition: port.h:229
#define fopen_priv(path, mode)
Definition: pg_upgrade.h:378
char * db_name
Definition: pg_upgrade.h:179
DbInfo * dbs
Definition: pg_upgrade.h:190
#define snprintf
Definition: port.h:216

◆ check_is_install_user()

static void check_is_install_user ( ClusterInfo cluster)
static

Definition at line 644 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().

645 {
646  PGresult *res;
647  PGconn *conn = connectToServer(cluster, "template1");
648 
649  prep_status("Checking database user is the install user");
650 
651  /* Can't use pg_authid because only superusers can view it. */
652  res = executeQueryOrDie(conn,
653  "SELECT rolsuper, oid "
654  "FROM pg_catalog.pg_roles "
655  "WHERE rolname = current_user "
656  "AND rolname !~ '^pg_'");
657 
658  /*
659  * We only allow the install user in the new cluster (see comment below)
660  * and we preserve pg_authid.oid, so this must be the install user in the
661  * old cluster too.
662  */
663  if (PQntuples(res) != 1 ||
664  atooid(PQgetvalue(res, 0, 1)) != BOOTSTRAP_SUPERUSERID)
665  pg_fatal("database user \"%s\" is not the install user\n",
666  os_info.user);
667 
668  PQclear(res);
669 
670  res = executeQueryOrDie(conn,
671  "SELECT COUNT(*) "
672  "FROM pg_catalog.pg_roles "
673  "WHERE rolname !~ '^pg_'");
674 
675  if (PQntuples(res) != 1)
676  pg_fatal("could not determine the number of users\n");
677 
678  /*
679  * We only allow the install user in the new cluster because other defined
680  * users might match users defined in the old cluster and generate an
681  * error during pg_dump restore.
682  */
683  if (cluster == &new_cluster && atooid(PQgetvalue(res, 0, 0)) != 1)
684  pg_fatal("Only the install user can be defined in the new cluster.\n");
685 
686  PQclear(res);
687 
688  PQfinish(conn);
689 
690  check_ok();
691 }
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3561
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
#define pg_fatal(...)
Definition: pg_rewind.h:37
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4229
int PQntuples(const PGresult *res)
Definition: fe-exec.c:3167
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:1991
PGconn * connectToServer(ClusterInfo *cluster, const char *db_name)
Definition: server.c:27
void PQclear(PGresult *res)
Definition: fe-exec.c:680
OSInfo os_info
Definition: pg_upgrade.c:61
char * user
Definition: pg_upgrade.h:309

◆ check_locale_and_encoding()

static void check_locale_and_encoding ( DbInfo olddb,
DbInfo newdb 
)
static

Definition at line 351 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().

352 {
353  if (olddb->db_encoding != newdb->db_encoding)
354  pg_fatal("encodings for database \"%s\" do not match: old \"%s\", new \"%s\"\n",
355  olddb->db_name,
358  if (!equivalent_locale(LC_COLLATE, olddb->db_collate, newdb->db_collate))
359  pg_fatal("lc_collate values for database \"%s\" do not match: old \"%s\", new \"%s\"\n",
360  olddb->db_name, olddb->db_collate, newdb->db_collate);
361  if (!equivalent_locale(LC_CTYPE, olddb->db_ctype, newdb->db_ctype))
362  pg_fatal("lc_ctype values for database \"%s\" do not match: old \"%s\", new \"%s\"\n",
363  olddb->db_name, olddb->db_ctype, newdb->db_ctype);
364 }
#define pg_fatal(...)
Definition: pg_rewind.h:37
static bool equivalent_locale(int category, const char *loca, const char *locb)
Definition: check.c:378
char * db_ctype
Definition: pg_upgrade.h:183
const char * pg_encoding_to_char(int encoding)
Definition: encnames.c:588
int db_encoding
Definition: pg_upgrade.h:184
char * db_name
Definition: pg_upgrade.h:179
char * db_collate
Definition: pg_upgrade.h:182

◆ check_new_cluster()

void check_new_cluster ( void  )

Definition at line 179 of file check.c.

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

180 {
182 
185 
187 
188  switch (user_opts.transfer_mode)
189  {
190  case TRANSFER_MODE_CLONE:
192  break;
193  case TRANSFER_MODE_COPY:
194  break;
195  case TRANSFER_MODE_LINK:
196  check_hard_link();
197  break;
198  }
199 
201 
203 
205 }
void check_file_clone(void)
Definition: file.c:317
void check_hard_link(void)
Definition: file.c:359
static void check_databases_are_compatible(void)
Definition: check.c:448
void check_loadable_libraries(void)
Definition: function.c:180
static void check_for_prepared_transactions(ClusterInfo *cluster)
Definition: check.c:756
ClusterInfo new_cluster
Definition: pg_upgrade.c:59
static void check_for_new_tablespace_dir(ClusterInfo *new_cluster)
Definition: check.c:487
static void check_is_install_user(ClusterInfo *cluster)
Definition: check.c:644
transferMode transfer_mode
Definition: pg_upgrade.h:292
UserOpts user_opts
Definition: option.c:30
static void check_new_cluster_is_empty(void)
Definition: check.c:421
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 421 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().

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

◆ check_proper_datallowconn()

static void check_proper_datallowconn ( ClusterInfo cluster)
static

Definition at line 695 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().

696 {
697  int dbnum;
698  PGconn *conn_template1;
699  PGresult *dbres;
700  int ntups;
701  int i_datname;
702  int i_datallowconn;
703 
704  prep_status("Checking database connection settings");
705 
706  conn_template1 = connectToServer(cluster, "template1");
707 
708  /* get database names */
709  dbres = executeQueryOrDie(conn_template1,
710  "SELECT datname, datallowconn "
711  "FROM pg_catalog.pg_database");
712 
713  i_datname = PQfnumber(dbres, "datname");
714  i_datallowconn = PQfnumber(dbres, "datallowconn");
715 
716  ntups = PQntuples(dbres);
717  for (dbnum = 0; dbnum < ntups; dbnum++)
718  {
719  char *datname = PQgetvalue(dbres, dbnum, i_datname);
720  char *datallowconn = PQgetvalue(dbres, dbnum, i_datallowconn);
721 
722  if (strcmp(datname, "template0") == 0)
723  {
724  /* avoid restore failure when pg_dumpall tries to create template0 */
725  if (strcmp(datallowconn, "t") == 0)
726  pg_fatal("template0 must not allow connections, "
727  "i.e. its pg_database.datallowconn must be false\n");
728  }
729  else
730  {
731  /*
732  * avoid datallowconn == false databases from being skipped on
733  * restore
734  */
735  if (strcmp(datallowconn, "f") == 0)
736  pg_fatal("All non-template0 databases must allow connections, "
737  "i.e. their pg_database.datallowconn must be true\n");
738  }
739  }
740 
741  PQclear(dbres);
742 
743  PQfinish(conn_template1);
744 
745  check_ok();
746 }
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3561
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
#define pg_fatal(...)
Definition: pg_rewind.h:37
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4229
NameData datname
Definition: pg_database.h:35
int PQntuples(const PGresult *res)
Definition: fe-exec.c:3167
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:1991
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:3275
void PQclear(PGresult *res)
Definition: fe-exec.c:680

◆ create_script_for_old_cluster_deletion()

void create_script_for_old_cluster_deletion ( char **  deletion_script_file_name)

Definition at line 516 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().

517 {
518  FILE *script = NULL;
519  int tblnum;
520  char old_cluster_pgdata[MAXPGPATH],
521  new_cluster_pgdata[MAXPGPATH];
522 
523  *deletion_script_file_name = psprintf("%sdelete_old_cluster.%s",
525 
526  strlcpy(old_cluster_pgdata, old_cluster.pgdata, MAXPGPATH);
527  canonicalize_path(old_cluster_pgdata);
528 
529  strlcpy(new_cluster_pgdata, new_cluster.pgdata, MAXPGPATH);
530  canonicalize_path(new_cluster_pgdata);
531 
532  /* Some people put the new data directory inside the old one. */
533  if (path_is_prefix_of_path(old_cluster_pgdata, new_cluster_pgdata))
534  {
536  "\nWARNING: new data directory should not be inside the old data directory, e.g. %s\n", old_cluster_pgdata);
537 
538  /* Unlink file in case it is left over from a previous run. */
539  unlink(*deletion_script_file_name);
540  pg_free(*deletion_script_file_name);
541  *deletion_script_file_name = NULL;
542  return;
543  }
544 
545  /*
546  * Some users (oddly) create tablespaces inside the cluster data
547  * directory. We can't create a proper old cluster delete script in that
548  * case.
549  */
550  for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
551  {
552  char old_tablespace_dir[MAXPGPATH];
553 
554  strlcpy(old_tablespace_dir, os_info.old_tablespaces[tblnum], MAXPGPATH);
555  canonicalize_path(old_tablespace_dir);
556  if (path_is_prefix_of_path(old_cluster_pgdata, old_tablespace_dir))
557  {
558  /* reproduce warning from CREATE TABLESPACE that is in the log */
560  "\nWARNING: user-defined tablespace locations should not be inside the data directory, e.g. %s\n", old_tablespace_dir);
561 
562  /* Unlink file in case it is left over from a previous run. */
563  unlink(*deletion_script_file_name);
564  pg_free(*deletion_script_file_name);
565  *deletion_script_file_name = NULL;
566  return;
567  }
568  }
569 
570  prep_status("Creating script to delete old cluster");
571 
572  if ((script = fopen_priv(*deletion_script_file_name, "w")) == NULL)
573  pg_fatal("could not open file \"%s\": %s\n",
574  *deletion_script_file_name, strerror(errno));
575 
576 #ifndef WIN32
577  /* add shebang header */
578  fprintf(script, "#!/bin/sh\n\n");
579 #endif
580 
581  /* delete old cluster's default tablespace */
582  fprintf(script, RMDIR_CMD " %c%s%c\n", PATH_QUOTE,
584 
585  /* delete old cluster's alternate tablespaces */
586  for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
587  {
588  /*
589  * Do the old cluster's per-database directories share a directory
590  * with a new version-specific tablespace?
591  */
592  if (strlen(old_cluster.tablespace_suffix) == 0)
593  {
594  /* delete per-database directories */
595  int dbnum;
596 
597  fprintf(script, "\n");
598  /* remove PG_VERSION? */
600  fprintf(script, RM_CMD " %s%cPG_VERSION\n",
603 
604  for (dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
605  fprintf(script, RMDIR_CMD " %c%s%c%u%c\n", PATH_QUOTE,
608  PATH_QUOTE);
609  }
610  else
611  {
612  char *suffix_path = pg_strdup(old_cluster.tablespace_suffix);
613 
614  /*
615  * Simply delete the tablespace directory, which might be ".old"
616  * or a version-specific subdirectory.
617  */
618  fprintf(script, RMDIR_CMD " %c%s%s%c\n", PATH_QUOTE,
620  fix_path_separator(suffix_path), PATH_QUOTE);
621  pfree(suffix_path);
622  }
623  }
624 
625  fclose(script);
626 
627 #ifndef WIN32
628  if (chmod(*deletion_script_file_name, S_IRWXU) != 0)
629  pg_fatal("could not add execute permission to file \"%s\": %s\n",
630  *deletion_script_file_name, strerror(errno));
631 #endif
632 
633  check_ok();
634 }
uint32 major_version
Definition: pg_upgrade.h:267
bool path_is_prefix_of_path(const char *path1, const char *path2)
Definition: path.c:438
#define PATH_SEPARATOR
Definition: pg_upgrade.h:68
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
#define SCRIPT_EXT
Definition: pg_upgrade.h:73
#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:37
#define fprintf
Definition: port.h:220
Oid db_oid
Definition: pg_upgrade.h:178
ClusterInfo new_cluster
Definition: pg_upgrade.c:59
void pfree(void *pointer)
Definition: mcxt.c:1169
#define MAXPGPATH
#define RMDIR_CMD
Definition: pg_upgrade.h:71
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:1991
char ** old_tablespaces
Definition: pg_upgrade.h:311
const char * tablespace_suffix
Definition: pg_upgrade.h:270
DbInfoArr dbarr
Definition: pg_upgrade.h:258
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:229
void pg_free(void *ptr)
Definition: fe_memutils.c:105
#define SCRIPT_PREFIX
Definition: pg_upgrade.h:72
#define PATH_QUOTE
Definition: pg_upgrade.h:69
#define fopen_priv(path, mode)
Definition: pg_upgrade.h:378
char * pgdata
Definition: pg_upgrade.h:259
#define S_IRWXU
Definition: win32_port.h:289
int num_old_tablespaces
Definition: pg_upgrade.h:312
OSInfo os_info
Definition: pg_upgrade.c:61
DbInfo * dbs
Definition: pg_upgrade.h:190
#define RM_CMD
Definition: pg_upgrade.h:70
static char * fix_path_separator(char *path)
Definition: check.c:44

◆ equivalent_locale()

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

Definition at line 378 of file check.c.

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

Referenced by check_locale_and_encoding().

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

References pg_strdup().

Referenced by create_script_for_old_cluster_deletion().

45 {
46 #ifdef WIN32
47 
48  char *result;
49  char *c;
50 
51  result = pg_strdup(path);
52 
53  for (c = result; *c != '\0'; c++)
54  if (*c == '/')
55  *c = '\\';
56 
57  return result;
58 #else
59 
60  return path;
61 #endif
62 }
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 1319 of file check.c.

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

Referenced by equivalent_locale().

1320 {
1321  char *save;
1322  char *res;
1323 
1324  /* get the current setting, so we can restore it. */
1325  save = setlocale(category, NULL);
1326  if (!save)
1327  pg_fatal("failed to get the current locale\n");
1328 
1329  /* 'save' may be pointing at a modifiable scratch variable, so copy it. */
1330  save = pg_strdup(save);
1331 
1332  /* set the locale with setlocale, to see if it accepts it. */
1333  res = setlocale(category, locale);
1334 
1335  if (!res)
1336  pg_fatal("failed to get system locale name for \"%s\"\n", locale);
1337 
1338  res = pg_strdup(res);
1339 
1340  /* restore old value. */
1341  if (!setlocale(category, save))
1342  pg_fatal("failed to restore old locale \"%s\"\n", save);
1343 
1344  pg_free(save);
1345 
1346  return res;
1347 }
#define setlocale(a, b)
Definition: win32_port.h:436
#define pg_fatal(...)
Definition: pg_rewind.h:37
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:126

◆ issue_warnings_and_set_wal_level()

void issue_warnings_and_set_wal_level ( void  )

Definition at line 226 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().

227 {
228  /*
229  * We unconditionally start/stop the new server because pg_resetwal -o set
230  * wal_level to 'minimum'. If the user is upgrading standby servers using
231  * the rsync instructions, they will need pg_upgrade to write its final
232  * WAL record showing wal_level as 'replica'.
233  */
235 
236  /* Create dummy large object permissions for old < PG 9.0? */
239 
240  /* Reindex hash indexes for old < 10.0 */
243 
244  stop_postmaster(false);
245 }
uint32 major_version
Definition: pg_upgrade.h:267
#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:334
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:330
static pgpid_t start_postmaster(void)
Definition: pg_ctl.c:443

◆ output_check_banner()

void output_check_banner ( bool  live_check)

Definition at line 65 of file check.c.

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

Referenced by main().

66 {
67  if (user_opts.check && live_check)
68  {
70  "Performing Consistency Checks on Old Live Server\n"
71  "------------------------------------------------\n");
72  }
73  else
74  {
76  "Performing Consistency Checks\n"
77  "-----------------------------\n");
78  }
79 }
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:290

◆ output_completion_banner()

void output_completion_banner ( char *  deletion_script_file_name)

Definition at line 249 of file check.c.

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

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

◆ report_clusters_compatible()

void report_clusters_compatible ( void  )

Definition at line 209 of file check.c.

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

Referenced by main().

210 {
211  if (user_opts.check)
212  {
213  pg_log(PG_REPORT, "\n*Clusters are compatible*\n");
214  /* stops new cluster */
215  stop_postmaster(false);
216  exit(0);
217  }
218 
219  pg_log(PG_REPORT, "\n"
220  "If pg_upgrade fails after this point, you must re-initdb the\n"
221  "new cluster before continuing.\n");
222 }
UserOpts user_opts
Definition: option.c:30
void stop_postmaster(bool in_atexit)
Definition: server.c:330
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
bool check
Definition: pg_upgrade.h:290