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_incompatible_polymorphics (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_aclitem_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 86 of file check.c.

87 {
88  /* -- OLD -- */
89 
90  if (!live_check)
92 
93  /* Extract a list of databases and tables from the old cluster */
95 
97 
99 
100 
101  /*
102  * Check for various failure cases
103  */
110 
111  /*
112  * PG 16 increased the size of the 'aclitem' type, which breaks the on-disk
113  * format for existing data.
114  */
117 
118  /*
119  * PG 14 changed the function signature of encoding conversion functions.
120  * Conversions from older versions cannot be upgraded automatically
121  * because the user-defined functions used by the encoding conversions
122  * need to be changed to match the new signature.
123  */
126 
127  /*
128  * Pre-PG 14 allowed user defined postfix operators, which are not
129  * supported anymore. Verify there are none, iff applicable.
130  */
133 
134  /*
135  * PG 14 changed polymorphic functions from anyarray to
136  * anycompatiblearray.
137  */
140 
141  /*
142  * Pre-PG 12 allowed tables to be declared WITH OIDS, which is not
143  * supported anymore. Verify there are none, iff applicable.
144  */
147 
148  /*
149  * PG 12 changed the 'sql_identifier' type storage to be based on name,
150  * not varchar, which breaks on-disk format for existing data. So we need
151  * to prevent upgrade when used in user objects (tables, indexes, ...).
152  */
155 
156  /*
157  * Pre-PG 10 allowed tables with 'unknown' type columns and non WAL logged
158  * hash indexes
159  */
161  {
163  if (user_opts.check)
165  }
166 
167  /* 9.5 and below should not have roles starting with pg_ */
170 
174 
175  /* Pre-PG 9.4 had a different 'line' data type internal format */
178 
179  /*
180  * While not a check option, we do this now because this is the only time
181  * the old server is running.
182  */
183  if (!user_opts.check)
185 
186  if (!live_check)
187  stop_postmaster(false);
188 }
static void check_for_tables_with_oids(ClusterInfo *cluster)
Definition: check.c:1140
static void check_for_pg_role_prefix(ClusterInfo *cluster)
Definition: check.c:1394
static void check_for_composite_data_type_usage(ClusterInfo *cluster)
Definition: check.c:1220
static void check_is_install_user(ClusterInfo *cluster)
Definition: check.c:654
static void check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster)
Definition: check.c:832
static void check_for_user_defined_postfix_ops(ClusterInfo *cluster)
Definition: check.c:914
static void check_for_prepared_transactions(ClusterInfo *cluster)
Definition: check.c:797
static void check_proper_datallowconn(ClusterInfo *cluster)
Definition: check.c:712
static void check_for_aclitem_data_type_usage(ClusterInfo *cluster)
Definition: check.c:1336
static void check_for_user_defined_encoding_conversions(ClusterInfo *cluster)
Definition: check.c:1450
static void check_for_jsonb_9_4_usage(ClusterInfo *cluster)
Definition: check.c:1364
static void check_for_incompatible_polymorphics(ClusterInfo *cluster)
Definition: check.c:1013
static void check_for_reg_data_type_usage(ClusterInfo *cluster)
Definition: check.c:1281
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 pid_t start_postmaster(void)
Definition: pg_ctl.c:440
ClusterInfo old_cluster
Definition: pg_upgrade.c:62
void init_tablespaces(void)
Definition: tablespace.c:19
void old_11_check_for_sql_identifier_data_type_usage(ClusterInfo *cluster)
Definition: version.c:365
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:220
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:27
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:250
#define JSONB_FORMAT_CHANGE_CAT_VER
Definition: pg_upgrade.h:127
UserOpts user_opts
Definition: option.c:29
ControlData controldata
Definition: pg_upgrade.h:254
uint32 major_version
Definition: pg_upgrade.h:264
uint32 cat_ver
Definition: pg_upgrade.h:200
bool check
Definition: pg_upgrade.h:293

References ControlData::cat_ver, UserOpts::check, check_for_aclitem_data_type_usage(), check_for_composite_data_type_usage(), check_for_incompatible_polymorphics(), 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 339 of file check.c.

340 {
341  /* get/check pg_control data of servers */
342  get_control_data(&old_cluster, live_check);
343  get_control_data(&new_cluster, false);
345 
346  if (live_check && old_cluster.port == new_cluster.port)
347  pg_fatal("When checking a live server, "
348  "the old and new port numbers must be different.");
349 }
void get_control_data(ClusterInfo *cluster, bool live_check)
Definition: controldata.c:36
void check_control_data(ControlData *oldctrl, ControlData *newctrl)
Definition: controldata.c:655
#define pg_fatal(...)
ClusterInfo new_cluster
Definition: pg_upgrade.c:63
unsigned short port
Definition: pg_upgrade.h:263

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

297 {
298  prep_status("Checking cluster versions");
299 
300  /* cluster versions should already have been obtained */
303 
304  /*
305  * We allow upgrades from/to the same major version for alpha/beta
306  * upgrades
307  */
308 
310  pg_fatal("This utility can only upgrade from PostgreSQL version %s and later.",
311  "9.2");
312 
313  /* Only current PG version is supported as a target */
315  pg_fatal("This utility can only upgrade to PostgreSQL version %s.",
316  PG_MAJORVERSION);
317 
318  /*
319  * We can't allow downgrading because we use the target pg_dump, and
320  * pg_dump cannot operate on newer database versions, only current and
321  * older versions.
322  */
324  pg_fatal("This utility cannot be used to downgrade to older major PostgreSQL versions.");
325 
326  /* Ensure binaries match the designated data directories */
329  pg_fatal("Old cluster data and binary directories are from different major versions.");
332  pg_fatal("New cluster data and binary directories are from different major versions.");
333 
334  check_ok();
335 }
static void check_ok(void)
Definition: initdb.c:1823
Assert(fmt[strlen(fmt) - 1] !='\n')
void prep_status(const char *fmt,...) pg_attribute_printf(1
uint32 bin_version
Definition: pg_upgrade.h:266

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

469 {
470  int newdbnum;
471  int olddbnum;
472  DbInfo *newdbinfo;
473  DbInfo *olddbinfo;
474 
475  for (newdbnum = 0; newdbnum < new_cluster.dbarr.ndbs; newdbnum++)
476  {
477  newdbinfo = &new_cluster.dbarr.dbs[newdbnum];
478 
479  /* Find the corresponding database in the old cluster */
480  for (olddbnum = 0; olddbnum < old_cluster.dbarr.ndbs; olddbnum++)
481  {
482  olddbinfo = &old_cluster.dbarr.dbs[olddbnum];
483  if (strcmp(newdbinfo->db_name, olddbinfo->db_name) == 0)
484  {
485  check_locale_and_encoding(olddbinfo, newdbinfo);
486  break;
487  }
488  }
489  }
490 }
static void check_locale_and_encoding(DbInfo *olddb, DbInfo *newdb)
Definition: check.c:359
DbInfoArr dbarr
Definition: pg_upgrade.h:255
DbInfo * dbs
Definition: pg_upgrade.h:188
char * db_name
Definition: pg_upgrade.h:175

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

static void check_for_aclitem_data_type_usage ( ClusterInfo cluster)
static

Definition at line 1336 of file check.c.

1337 {
1338  char output_path[MAXPGPATH];
1339 
1340  prep_status("Checking for incompatible aclitem data type in user tables");
1341 
1342  snprintf(output_path, sizeof(output_path), "tables_using_aclitem.txt");
1343 
1344  if (check_for_data_type_usage(cluster, "pg_catalog.aclitem", output_path))
1345  {
1346  pg_log(PG_REPORT, "fatal");
1347  pg_fatal("Your installation contains the \"aclitem\" data type in user tables.\n"
1348  "The internal format of \"aclitem\" changed in PostgreSQL version 16\n"
1349  "so this cluster cannot currently be upgraded. You can drop the\n"
1350  "problem columns and restart the upgrade. A list of the problem\n"
1351  "columns is in the file:\n"
1352  " %s", output_path);
1353  }
1354  else
1355  check_ok();
1356 }
void cluster(ParseState *pstate, ClusterStmt *stmt, bool isTopLevel)
Definition: cluster.c:111
#define MAXPGPATH
bool check_for_data_type_usage(ClusterInfo *cluster, const char *type_name, const char *output_path)
Definition: version.c:153
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
@ PG_REPORT
Definition: pg_upgrade.h:241
#define snprintf
Definition: port.h:238

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

static void check_for_composite_data_type_usage ( ClusterInfo cluster)
static

Definition at line 1220 of file check.c.

1221 {
1222  bool found;
1223  Oid firstUserOid;
1224  char output_path[MAXPGPATH];
1225  char *base_query;
1226 
1227  prep_status("Checking for system-defined composite types in user tables");
1228 
1229  snprintf(output_path, sizeof(output_path), "%s/%s",
1230  log_opts.basedir,
1231  "tables_using_composite.txt");
1232 
1233  /*
1234  * Look for composite types that were made during initdb *or* belong to
1235  * information_schema; that's important in case information_schema was
1236  * dropped and reloaded.
1237  *
1238  * The cutoff OID here should match the source cluster's value of
1239  * FirstNormalObjectId. We hardcode it rather than using that C #define
1240  * because, if that #define is ever changed, our own version's value is
1241  * NOT what to use. Eventually we may need a test on the source cluster's
1242  * version to select the correct value.
1243  */
1244  firstUserOid = 16384;
1245 
1246  base_query = psprintf("SELECT t.oid FROM pg_catalog.pg_type t "
1247  "LEFT JOIN pg_catalog.pg_namespace n ON t.typnamespace = n.oid "
1248  " WHERE typtype = 'c' AND (t.oid < %u OR nspname = 'information_schema')",
1249  firstUserOid);
1250 
1251  found = check_for_data_types_usage(cluster, base_query, output_path);
1252 
1253  free(base_query);
1254 
1255  if (found)
1256  {
1257  pg_log(PG_REPORT, "fatal");
1258  pg_fatal("Your installation contains system-defined composite type(s) in user tables.\n"
1259  "These type OIDs are not stable across PostgreSQL versions,\n"
1260  "so this cluster cannot currently be upgraded. You can\n"
1261  "drop the problem columns and restart the upgrade.\n"
1262  "A list of the problem columns is in the file:\n"
1263  " %s", output_path);
1264  }
1265  else
1266  check_ok();
1267 }
#define free(a)
Definition: header.h:65
bool check_for_data_types_usage(ClusterInfo *cluster, const char *base_query, const char *output_path)
Definition: version.c:31
LogOpts log_opts
Definition: util.c:17
unsigned int Oid
Definition: postgres_ext.h:31
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
char * basedir
Definition: pg_upgrade.h:281

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

Referenced by check_and_dump_old_cluster().

◆ check_for_incompatible_polymorphics()

static void check_for_incompatible_polymorphics ( ClusterInfo cluster)
static

Definition at line 1013 of file check.c.

1014 {
1015  PGresult *res;
1016  FILE *script = NULL;
1017  char output_path[MAXPGPATH];
1018  PQExpBufferData old_polymorphics;
1019 
1020  prep_status("Checking for incompatible polymorphic functions");
1021 
1022  snprintf(output_path, sizeof(output_path), "%s/%s",
1023  log_opts.basedir,
1024  "incompatible_polymorphics.txt");
1025 
1026  /* The set of problematic functions varies a bit in different versions */
1027  initPQExpBuffer(&old_polymorphics);
1028 
1029  appendPQExpBufferStr(&old_polymorphics,
1030  "'array_append(anyarray,anyelement)'"
1031  ", 'array_cat(anyarray,anyarray)'"
1032  ", 'array_prepend(anyelement,anyarray)'");
1033 
1034  if (GET_MAJOR_VERSION(cluster->major_version) >= 903)
1035  appendPQExpBufferStr(&old_polymorphics,
1036  ", 'array_remove(anyarray,anyelement)'"
1037  ", 'array_replace(anyarray,anyelement,anyelement)'");
1038 
1039  if (GET_MAJOR_VERSION(cluster->major_version) >= 905)
1040  appendPQExpBufferStr(&old_polymorphics,
1041  ", 'array_position(anyarray,anyelement)'"
1042  ", 'array_position(anyarray,anyelement,integer)'"
1043  ", 'array_positions(anyarray,anyelement)'"
1044  ", 'width_bucket(anyelement,anyarray)'");
1045 
1046  for (int dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
1047  {
1048  bool db_used = false;
1049  DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
1050  PGconn *conn = connectToServer(cluster, active_db->db_name);
1051  int ntups;
1052  int i_objkind,
1053  i_objname;
1054 
1055  /*
1056  * The query below hardcodes FirstNormalObjectId as 16384 rather than
1057  * interpolating that C #define into the query because, if that
1058  * #define is ever changed, the cutoff we want to use is the value
1059  * used by pre-version 14 servers, not that of some future version.
1060  */
1062  /* Aggregate transition functions */
1063  "SELECT 'aggregate' AS objkind, p.oid::regprocedure::text AS objname "
1064  "FROM pg_proc AS p "
1065  "JOIN pg_aggregate AS a ON a.aggfnoid=p.oid "
1066  "JOIN pg_proc AS transfn ON transfn.oid=a.aggtransfn "
1067  "WHERE p.oid >= 16384 "
1068  "AND a.aggtransfn = ANY(ARRAY[%s]::regprocedure[]) "
1069  "AND a.aggtranstype = ANY(ARRAY['anyarray', 'anyelement']::regtype[]) "
1070 
1071  /* Aggregate final functions */
1072  "UNION ALL "
1073  "SELECT 'aggregate' AS objkind, p.oid::regprocedure::text AS objname "
1074  "FROM pg_proc AS p "
1075  "JOIN pg_aggregate AS a ON a.aggfnoid=p.oid "
1076  "JOIN pg_proc AS finalfn ON finalfn.oid=a.aggfinalfn "
1077  "WHERE p.oid >= 16384 "
1078  "AND a.aggfinalfn = ANY(ARRAY[%s]::regprocedure[]) "
1079  "AND a.aggtranstype = ANY(ARRAY['anyarray', 'anyelement']::regtype[]) "
1080 
1081  /* Operators */
1082  "UNION ALL "
1083  "SELECT 'operator' AS objkind, op.oid::regoperator::text AS objname "
1084  "FROM pg_operator AS op "
1085  "WHERE op.oid >= 16384 "
1086  "AND oprcode = ANY(ARRAY[%s]::regprocedure[]) "
1087  "AND oprleft = ANY(ARRAY['anyarray', 'anyelement']::regtype[]);",
1088  old_polymorphics.data,
1089  old_polymorphics.data,
1090  old_polymorphics.data);
1091 
1092  ntups = PQntuples(res);
1093 
1094  i_objkind = PQfnumber(res, "objkind");
1095  i_objname = PQfnumber(res, "objname");
1096 
1097  for (int rowno = 0; rowno < ntups; rowno++)
1098  {
1099  if (script == NULL &&
1100  (script = fopen_priv(output_path, "w")) == NULL)
1101  pg_fatal("could not open file \"%s\": %s",
1102  output_path, strerror(errno));
1103  if (!db_used)
1104  {
1105  fprintf(script, "In database: %s\n", active_db->db_name);
1106  db_used = true;
1107  }
1108 
1109  fprintf(script, " %s: %s\n",
1110  PQgetvalue(res, rowno, i_objkind),
1111  PQgetvalue(res, rowno, i_objname));
1112  }
1113 
1114  PQclear(res);
1115  PQfinish(conn);
1116  }
1117 
1118  if (script)
1119  {
1120  fclose(script);
1121  pg_log(PG_REPORT, "fatal");
1122  pg_fatal("Your installation contains user-defined objects that refer to internal\n"
1123  "polymorphic functions with arguments of type \"anyarray\" or \"anyelement\".\n"
1124  "These user-defined objects must be dropped before upgrading and restored\n"
1125  "afterwards, changing them to refer to the new corresponding functions with\n"
1126  "arguments of type \"anycompatiblearray\" and \"anycompatible\".\n"
1127  "A list of the problematic objects is in the file:\n"
1128  " %s", output_path);
1129  }
1130  else
1131  check_ok();
1132 
1133  termPQExpBuffer(&old_polymorphics);
1134 }
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4130
int PQntuples(const PGresult *res)
Definition: fe-exec.c:3310
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3705
int PQfnumber(const PGresult *res, const char *field_name)
Definition: fe-exec.c:3418
#define fopen_priv(path, mode)
Definition: pg_upgrade.h:382
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:251
#define fprintf
Definition: port.h:242
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:90
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:367
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:129
PGconn * conn
Definition: streamutil.c:54

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

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

833 {
834  int dbnum;
835  FILE *script = NULL;
836  char output_path[MAXPGPATH];
837 
838  prep_status("Checking for contrib/isn with bigint-passing mismatch");
839 
842  {
843  /* no mismatch */
844  check_ok();
845  return;
846  }
847 
848  snprintf(output_path, sizeof(output_path), "%s/%s",
850  "contrib_isn_and_int8_pass_by_value.txt");
851 
852  for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
853  {
854  PGresult *res;
855  bool db_used = false;
856  int ntups;
857  int rowno;
858  int i_nspname,
859  i_proname;
860  DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
861  PGconn *conn = connectToServer(cluster, active_db->db_name);
862 
863  /* Find any functions coming from contrib/isn */
865  "SELECT n.nspname, p.proname "
866  "FROM pg_catalog.pg_proc p, "
867  " pg_catalog.pg_namespace n "
868  "WHERE p.pronamespace = n.oid AND "
869  " p.probin = '$libdir/isn'");
870 
871  ntups = PQntuples(res);
872  i_nspname = PQfnumber(res, "nspname");
873  i_proname = PQfnumber(res, "proname");
874  for (rowno = 0; rowno < ntups; rowno++)
875  {
876  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
877  pg_fatal("could not open file \"%s\": %s",
878  output_path, strerror(errno));
879  if (!db_used)
880  {
881  fprintf(script, "In database: %s\n", active_db->db_name);
882  db_used = true;
883  }
884  fprintf(script, " %s.%s\n",
885  PQgetvalue(res, rowno, i_nspname),
886  PQgetvalue(res, rowno, i_proname));
887  }
888 
889  PQclear(res);
890 
891  PQfinish(conn);
892  }
893 
894  if (script)
895  {
896  fclose(script);
897  pg_log(PG_REPORT, "fatal");
898  pg_fatal("Your installation contains \"contrib/isn\" functions which rely on the\n"
899  "bigint data type. Your old and new clusters pass bigint values\n"
900  "differently so this cluster cannot currently be upgraded. You can\n"
901  "manually dump databases in the old cluster that use \"contrib/isn\"\n"
902  "facilities, drop them, perform the upgrade, and then restore them. A\n"
903  "list of the problem functions is in the file:\n"
904  " %s", output_path);
905  }
906  else
907  check_ok();
908 }
bool float8_pass_by_value
Definition: pg_upgrade.h:219

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

1365 {
1366  char output_path[MAXPGPATH];
1367 
1368  prep_status("Checking for incompatible \"jsonb\" data type");
1369 
1370  snprintf(output_path, sizeof(output_path), "%s/%s",
1371  log_opts.basedir,
1372  "tables_using_jsonb.txt");
1373 
1374  if (check_for_data_type_usage(cluster, "pg_catalog.jsonb", output_path))
1375  {
1376  pg_log(PG_REPORT, "fatal");
1377  pg_fatal("Your installation contains the \"jsonb\" data type in user tables.\n"
1378  "The internal format of \"jsonb\" changed during 9.4 beta so this\n"
1379  "cluster cannot currently be upgraded. You can\n"
1380  "drop the problem columns and restart the upgrade.\n"
1381  "A list of the problem columns is in the file:\n"
1382  " %s", output_path);
1383  }
1384  else
1385  check_ok();
1386 }

References LogOpts::basedir, check_for_data_type_usage(), check_ok(), cluster(), log_opts, 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 502 of file check.c.

503 {
504  int tblnum;
505  char new_tablespace_dir[MAXPGPATH];
506 
507  prep_status("Checking for new cluster tablespace directories");
508 
509  for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
510  {
511  struct stat statbuf;
512 
513  snprintf(new_tablespace_dir, MAXPGPATH, "%s%s",
514  os_info.old_tablespaces[tblnum],
516 
517  if (stat(new_tablespace_dir, &statbuf) == 0 || errno != ENOENT)
518  pg_fatal("new cluster tablespace directory already exists: \"%s\"",
519  new_tablespace_dir);
520  }
521 
522  check_ok();
523 }
OSInfo os_info
Definition: pg_upgrade.c:64
const char * tablespace_suffix
Definition: pg_upgrade.h:267
int num_old_tablespaces
Definition: pg_upgrade.h:316
char ** old_tablespaces
Definition: pg_upgrade.h:315
#define stat
Definition: win32_port.h:286

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

1395 {
1396  PGresult *res;
1397  PGconn *conn = connectToServer(cluster, "template1");
1398  int ntups;
1399  int i_roloid;
1400  int i_rolname;
1401  FILE *script = NULL;
1402  char output_path[MAXPGPATH];
1403 
1404  prep_status("Checking for roles starting with \"pg_\"");
1405 
1406  snprintf(output_path, sizeof(output_path), "%s/%s",
1407  log_opts.basedir,
1408  "pg_role_prefix.txt");
1409 
1411  "SELECT oid AS roloid, rolname "
1412  "FROM pg_catalog.pg_roles "
1413  "WHERE rolname ~ '^pg_'");
1414 
1415  ntups = PQntuples(res);
1416  i_roloid = PQfnumber(res, "roloid");
1417  i_rolname = PQfnumber(res, "rolname");
1418  for (int rowno = 0; rowno < ntups; rowno++)
1419  {
1420  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
1421  pg_fatal("could not open file \"%s\": %s",
1422  output_path, strerror(errno));
1423  fprintf(script, "%s (oid=%s)\n",
1424  PQgetvalue(res, rowno, i_rolname),
1425  PQgetvalue(res, rowno, i_roloid));
1426  }
1427 
1428  PQclear(res);
1429 
1430  PQfinish(conn);
1431 
1432  if (script)
1433  {
1434  fclose(script);
1435  pg_log(PG_REPORT, "fatal");
1436  pg_fatal("Your installation contains roles starting with \"pg_\".\n"
1437  "\"pg_\" is a reserved prefix for system roles, the cluster\n"
1438  "cannot be upgraded until these roles are renamed.\n"
1439  "A list of roles starting with \"pg_\" is in the file:\n"
1440  " %s", output_path);
1441  }
1442  else
1443  check_ok();
1444 }

References LogOpts::basedir, check_ok(), cluster(), conn, connectToServer(), 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_prepared_transactions()

static void check_for_prepared_transactions ( ClusterInfo cluster)
static

Definition at line 797 of file check.c.

798 {
799  PGresult *res;
800  PGconn *conn = connectToServer(cluster, "template1");
801 
802  prep_status("Checking for prepared transactions");
803 
805  "SELECT * "
806  "FROM pg_catalog.pg_prepared_xacts");
807 
808  if (PQntuples(res) != 0)
809  {
810  if (cluster == &old_cluster)
811  pg_fatal("The source cluster contains prepared transactions");
812  else
813  pg_fatal("The target cluster contains prepared transactions");
814  }
815 
816  PQclear(res);
817 
818  PQfinish(conn);
819 
820  check_ok();
821 }

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

1282 {
1283  bool found;
1284  char output_path[MAXPGPATH];
1285 
1286  prep_status("Checking for reg* data types in user tables");
1287 
1288  snprintf(output_path, sizeof(output_path), "%s/%s",
1289  log_opts.basedir,
1290  "tables_using_reg.txt");
1291 
1292  /*
1293  * Note: older servers will not have all of these reg* types, so we have
1294  * to write the query like this rather than depending on casts to regtype.
1295  */
1297  "SELECT oid FROM pg_catalog.pg_type t "
1298  "WHERE t.typnamespace = "
1299  " (SELECT oid FROM pg_catalog.pg_namespace "
1300  " WHERE nspname = 'pg_catalog') "
1301  " AND t.typname IN ( "
1302  /* pg_class.oid is preserved, so 'regclass' is OK */
1303  " 'regcollation', "
1304  " 'regconfig', "
1305  " 'regdictionary', "
1306  " 'regnamespace', "
1307  " 'regoper', "
1308  " 'regoperator', "
1309  " 'regproc', "
1310  " 'regprocedure' "
1311  /* pg_authid.oid is preserved, so 'regrole' is OK */
1312  /* pg_type.oid is (mostly) preserved, so 'regtype' is OK */
1313  " )",
1314  output_path);
1315 
1316  if (found)
1317  {
1318  pg_log(PG_REPORT, "fatal");
1319  pg_fatal("Your installation contains one of the reg* data types in user tables.\n"
1320  "These data types reference system OIDs that are not preserved by\n"
1321  "pg_upgrade, so this cluster cannot currently be upgraded. You can\n"
1322  "drop the problem columns and restart the upgrade.\n"
1323  "A list of the problem columns is in the file:\n"
1324  " %s", output_path);
1325  }
1326  else
1327  check_ok();
1328 }

References LogOpts::basedir, check_for_data_types_usage(), check_ok(), cluster(), log_opts, 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 1140 of file check.c.

1141 {
1142  int dbnum;
1143  FILE *script = NULL;
1144  char output_path[MAXPGPATH];
1145 
1146  prep_status("Checking for tables WITH OIDS");
1147 
1148  snprintf(output_path, sizeof(output_path), "%s/%s",
1149  log_opts.basedir,
1150  "tables_with_oids.txt");
1151 
1152  /* Find any tables declared WITH OIDS */
1153  for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
1154  {
1155  PGresult *res;
1156  bool db_used = false;
1157  int ntups;
1158  int rowno;
1159  int i_nspname,
1160  i_relname;
1161  DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
1162  PGconn *conn = connectToServer(cluster, active_db->db_name);
1163 
1165  "SELECT n.nspname, c.relname "
1166  "FROM pg_catalog.pg_class c, "
1167  " pg_catalog.pg_namespace n "
1168  "WHERE c.relnamespace = n.oid AND "
1169  " c.relhasoids AND"
1170  " n.nspname NOT IN ('pg_catalog')");
1171 
1172  ntups = PQntuples(res);
1173  i_nspname = PQfnumber(res, "nspname");
1174  i_relname = PQfnumber(res, "relname");
1175  for (rowno = 0; rowno < ntups; rowno++)
1176  {
1177  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
1178  pg_fatal("could not open file \"%s\": %s",
1179  output_path, strerror(errno));
1180  if (!db_used)
1181  {
1182  fprintf(script, "In database: %s\n", active_db->db_name);
1183  db_used = true;
1184  }
1185  fprintf(script, " %s.%s\n",
1186  PQgetvalue(res, rowno, i_nspname),
1187  PQgetvalue(res, rowno, i_relname));
1188  }
1189 
1190  PQclear(res);
1191 
1192  PQfinish(conn);
1193  }
1194 
1195  if (script)
1196  {
1197  fclose(script);
1198  pg_log(PG_REPORT, "fatal");
1199  pg_fatal("Your installation contains tables declared WITH OIDS, which is not\n"
1200  "supported anymore. Consider removing the oid column using\n"
1201  " ALTER TABLE ... SET WITHOUT OIDS;\n"
1202  "A list of tables with the problem is in the file:\n"
1203  " %s", output_path);
1204  }
1205  else
1206  check_ok();
1207 }

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

1451 {
1452  int dbnum;
1453  FILE *script = NULL;
1454  char output_path[MAXPGPATH];
1455 
1456  prep_status("Checking for user-defined encoding conversions");
1457 
1458  snprintf(output_path, sizeof(output_path), "%s/%s",
1459  log_opts.basedir,
1460  "encoding_conversions.txt");
1461 
1462  /* Find any user defined encoding conversions */
1463  for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
1464  {
1465  PGresult *res;
1466  bool db_used = false;
1467  int ntups;
1468  int rowno;
1469  int i_conoid,
1470  i_conname,
1471  i_nspname;
1472  DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
1473  PGconn *conn = connectToServer(cluster, active_db->db_name);
1474 
1475  /*
1476  * The query below hardcodes FirstNormalObjectId as 16384 rather than
1477  * interpolating that C #define into the query because, if that
1478  * #define is ever changed, the cutoff we want to use is the value
1479  * used by pre-version 14 servers, not that of some future version.
1480  */
1482  "SELECT c.oid as conoid, c.conname, n.nspname "
1483  "FROM pg_catalog.pg_conversion c, "
1484  " pg_catalog.pg_namespace n "
1485  "WHERE c.connamespace = n.oid AND "
1486  " c.oid >= 16384");
1487  ntups = PQntuples(res);
1488  i_conoid = PQfnumber(res, "conoid");
1489  i_conname = PQfnumber(res, "conname");
1490  i_nspname = PQfnumber(res, "nspname");
1491  for (rowno = 0; rowno < ntups; rowno++)
1492  {
1493  if (script == NULL &&
1494  (script = fopen_priv(output_path, "w")) == NULL)
1495  pg_fatal("could not open file \"%s\": %s",
1496  output_path, strerror(errno));
1497  if (!db_used)
1498  {
1499  fprintf(script, "In database: %s\n", active_db->db_name);
1500  db_used = true;
1501  }
1502  fprintf(script, " (oid=%s) %s.%s\n",
1503  PQgetvalue(res, rowno, i_conoid),
1504  PQgetvalue(res, rowno, i_nspname),
1505  PQgetvalue(res, rowno, i_conname));
1506  }
1507 
1508  PQclear(res);
1509 
1510  PQfinish(conn);
1511  }
1512 
1513  if (script)
1514  {
1515  fclose(script);
1516  pg_log(PG_REPORT, "fatal");
1517  pg_fatal("Your installation contains user-defined encoding conversions.\n"
1518  "The conversion function parameters changed in PostgreSQL version 14\n"
1519  "so this cluster cannot currently be upgraded. You can remove the\n"
1520  "encoding conversions in the old cluster and restart the upgrade.\n"
1521  "A list of user-defined encoding conversions is in the file:\n"
1522  " %s", output_path);
1523  }
1524  else
1525  check_ok();
1526 }

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

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

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

655 {
656  PGresult *res;
657  PGconn *conn = connectToServer(cluster, "template1");
658 
659  prep_status("Checking database user is the install user");
660 
661  /* Can't use pg_authid because only superusers can view it. */
663  "SELECT rolsuper, oid "
664  "FROM pg_catalog.pg_roles "
665  "WHERE rolname = current_user "
666  "AND rolname !~ '^pg_'");
667 
668  /*
669  * We only allow the install user in the new cluster (see comment below)
670  * and we preserve pg_authid.oid, so this must be the install user in the
671  * old cluster too.
672  */
673  if (PQntuples(res) != 1 ||
674  atooid(PQgetvalue(res, 0, 1)) != BOOTSTRAP_SUPERUSERID)
675  pg_fatal("database user \"%s\" is not the install user",
676  os_info.user);
677 
678  PQclear(res);
679 
681  "SELECT COUNT(*) "
682  "FROM pg_catalog.pg_roles "
683  "WHERE rolname !~ '^pg_'");
684 
685  if (PQntuples(res) != 1)
686  pg_fatal("could not determine the number of users");
687 
688  /*
689  * We only allow the install user in the new cluster because other defined
690  * users might match users defined in the old cluster and generate an
691  * error during pg_dump restore.
692  */
693  if (cluster == &new_cluster && atooid(PQgetvalue(res, 0, 0)) != 1)
694  pg_fatal("Only the install user can be defined in the new cluster.");
695 
696  PQclear(res);
697 
698  PQfinish(conn);
699 
700  check_ok();
701 }
#define atooid(x)
Definition: postgres_ext.h:42
char * user
Definition: pg_upgrade.h:313

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

360 {
361  if (olddb->db_encoding != newdb->db_encoding)
362  pg_fatal("encodings for database \"%s\" do not match: old \"%s\", new \"%s\"",
363  olddb->db_name,
366  if (!equivalent_locale(LC_COLLATE, olddb->db_collate, newdb->db_collate))
367  pg_fatal("lc_collate values for database \"%s\" do not match: old \"%s\", new \"%s\"",
368  olddb->db_name, olddb->db_collate, newdb->db_collate);
369  if (!equivalent_locale(LC_CTYPE, olddb->db_ctype, newdb->db_ctype))
370  pg_fatal("lc_ctype values for database \"%s\" do not match: old \"%s\", new \"%s\"",
371  olddb->db_name, olddb->db_ctype, newdb->db_ctype);
372  if (olddb->db_collprovider != newdb->db_collprovider)
373  pg_fatal("locale providers for database \"%s\" do not match: old \"%s\", new \"%s\"",
374  olddb->db_name,
375  collprovider_name(olddb->db_collprovider),
376  collprovider_name(newdb->db_collprovider));
377  if ((olddb->db_iculocale == NULL && newdb->db_iculocale != NULL) ||
378  (olddb->db_iculocale != NULL && newdb->db_iculocale == NULL) ||
379  (olddb->db_iculocale != NULL && newdb->db_iculocale != NULL && strcmp(olddb->db_iculocale, newdb->db_iculocale) != 0))
380  pg_fatal("ICU locale values for database \"%s\" do not match: old \"%s\", new \"%s\"",
381  olddb->db_name,
382  olddb->db_iculocale ? olddb->db_iculocale : "(null)",
383  newdb->db_iculocale ? newdb->db_iculocale : "(null)");
384 }
static bool equivalent_locale(int category, const char *loca, const char *locb)
Definition: check.c:398
const char * pg_encoding_to_char(int encoding)
Definition: encnames.c:588
char * db_iculocale
Definition: pg_upgrade.h:181
char db_collprovider
Definition: pg_upgrade.h:180
char * db_collate
Definition: pg_upgrade.h:178
int db_encoding
Definition: pg_upgrade.h:182
char * db_ctype
Definition: pg_upgrade.h:179

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

193 {
195 
198 
200 
201  switch (user_opts.transfer_mode)
202  {
203  case TRANSFER_MODE_CLONE:
205  break;
206  case TRANSFER_MODE_COPY:
207  break;
208  case TRANSFER_MODE_LINK:
209  check_hard_link();
210  break;
211  }
212 
214 
216 
218 }
static void check_databases_are_compatible(void)
Definition: check.c:468
static void check_new_cluster_is_empty(void)
Definition: check.c:441
static void check_for_new_tablespace_dir(ClusterInfo *new_cluster)
Definition: check.c:502
void check_file_clone(void)
Definition: file.c:320
void check_hard_link(void)
Definition: file.c:362
void check_loadable_libraries(void)
Definition: function.c:120
@ TRANSFER_MODE_COPY
Definition: pg_upgrade.h:229
@ TRANSFER_MODE_LINK
Definition: pg_upgrade.h:230
@ TRANSFER_MODE_CLONE
Definition: pg_upgrade.h:228
transferMode transfer_mode
Definition: pg_upgrade.h:296

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

442 {
443  int dbnum;
444 
445  for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++)
446  {
447  int relnum;
448  RelInfoArr *rel_arr = &new_cluster.dbarr.dbs[dbnum].rel_arr;
449 
450  for (relnum = 0; relnum < rel_arr->nrels;
451  relnum++)
452  {
453  /* pg_largeobject and its index should be skipped */
454  if (strcmp(rel_arr->rels[relnum].nspname, "pg_catalog") != 0)
455  pg_fatal("New cluster database \"%s\" is not empty: found relation \"%s.%s\"",
456  new_cluster.dbarr.dbs[dbnum].db_name,
457  rel_arr->rels[relnum].nspname,
458  rel_arr->rels[relnum].relname);
459  }
460  }
461 }
RelInfoArr rel_arr
Definition: pg_upgrade.h:183
RelInfo * rels
Definition: pg_upgrade.h:149
char * nspname
Definition: pg_upgrade.h:136
char * relname
Definition: pg_upgrade.h:137

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

713 {
714  int dbnum;
715  PGconn *conn_template1;
716  PGresult *dbres;
717  int ntups;
718  int i_datname;
719  int i_datallowconn;
720  FILE *script = NULL;
721  char output_path[MAXPGPATH];
722 
723  prep_status("Checking database connection settings");
724 
725  snprintf(output_path, sizeof(output_path), "%s/%s",
727  "databases_with_datallowconn_false.txt");
728 
729  conn_template1 = connectToServer(cluster, "template1");
730 
731  /* get database names */
732  dbres = executeQueryOrDie(conn_template1,
733  "SELECT datname, datallowconn "
734  "FROM pg_catalog.pg_database");
735 
736  i_datname = PQfnumber(dbres, "datname");
737  i_datallowconn = PQfnumber(dbres, "datallowconn");
738 
739  ntups = PQntuples(dbres);
740  for (dbnum = 0; dbnum < ntups; dbnum++)
741  {
742  char *datname = PQgetvalue(dbres, dbnum, i_datname);
743  char *datallowconn = PQgetvalue(dbres, dbnum, i_datallowconn);
744 
745  if (strcmp(datname, "template0") == 0)
746  {
747  /* avoid restore failure when pg_dumpall tries to create template0 */
748  if (strcmp(datallowconn, "t") == 0)
749  pg_fatal("template0 must not allow connections, "
750  "i.e. its pg_database.datallowconn must be false");
751  }
752  else
753  {
754  /*
755  * avoid datallowconn == false databases from being skipped on
756  * restore
757  */
758  if (strcmp(datallowconn, "f") == 0)
759  {
760  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
761  pg_fatal("could not open file \"%s\": %s",
762  output_path, strerror(errno));
763 
764  fprintf(script, "%s\n", datname);
765  }
766  }
767  }
768 
769  PQclear(dbres);
770 
771  PQfinish(conn_template1);
772 
773  if (script)
774  {
775  fclose(script);
776  pg_log(PG_REPORT, "fatal");
777  pg_fatal("All non-template0 databases must allow connections, i.e. their\n"
778  "pg_database.datallowconn must be true. Your installation contains\n"
779  "non-template0 databases with their pg_database.datallowconn set to\n"
780  "false. Consider allowing connection for all non-template0 databases\n"
781  "or drop the databases which do not allow connections. A list of\n"
782  "databases with the problem is in the file:\n"
783  " %s", output_path);
784  }
785  else
786  check_ok();
787 }
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 531 of file check.c.

532 {
533  FILE *script = NULL;
534  int tblnum;
535  char old_cluster_pgdata[MAXPGPATH],
536  new_cluster_pgdata[MAXPGPATH];
537 
538  *deletion_script_file_name = psprintf("%sdelete_old_cluster.%s",
540 
541  strlcpy(old_cluster_pgdata, old_cluster.pgdata, MAXPGPATH);
542  canonicalize_path(old_cluster_pgdata);
543 
544  strlcpy(new_cluster_pgdata, new_cluster.pgdata, MAXPGPATH);
545  canonicalize_path(new_cluster_pgdata);
546 
547  /* Some people put the new data directory inside the old one. */
548  if (path_is_prefix_of_path(old_cluster_pgdata, new_cluster_pgdata))
549  {
551  "\nWARNING: new data directory should not be inside the old data directory, i.e. %s", old_cluster_pgdata);
552 
553  /* Unlink file in case it is left over from a previous run. */
554  unlink(*deletion_script_file_name);
555  pg_free(*deletion_script_file_name);
556  *deletion_script_file_name = NULL;
557  return;
558  }
559 
560  /*
561  * Some users (oddly) create tablespaces inside the cluster data
562  * directory. We can't create a proper old cluster delete script in that
563  * case.
564  */
565  for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
566  {
567  char old_tablespace_dir[MAXPGPATH];
568 
569  strlcpy(old_tablespace_dir, os_info.old_tablespaces[tblnum], MAXPGPATH);
570  canonicalize_path(old_tablespace_dir);
571  if (path_is_prefix_of_path(old_cluster_pgdata, old_tablespace_dir))
572  {
573  /* reproduce warning from CREATE TABLESPACE that is in the log */
575  "\nWARNING: user-defined tablespace locations should not be inside the data directory, i.e. %s", old_tablespace_dir);
576 
577  /* Unlink file in case it is left over from a previous run. */
578  unlink(*deletion_script_file_name);
579  pg_free(*deletion_script_file_name);
580  *deletion_script_file_name = NULL;
581  return;
582  }
583  }
584 
585  prep_status("Creating script to delete old cluster");
586 
587  if ((script = fopen_priv(*deletion_script_file_name, "w")) == NULL)
588  pg_fatal("could not open file \"%s\": %s",
589  *deletion_script_file_name, strerror(errno));
590 
591 #ifndef WIN32
592  /* add shebang header */
593  fprintf(script, "#!/bin/sh\n\n");
594 #endif
595 
596  /* delete old cluster's default tablespace */
597  fprintf(script, RMDIR_CMD " %c%s%c\n", PATH_QUOTE,
599 
600  /* delete old cluster's alternate tablespaces */
601  for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
602  {
603  /*
604  * Do the old cluster's per-database directories share a directory
605  * with a new version-specific tablespace?
606  */
607  if (strlen(old_cluster.tablespace_suffix) == 0)
608  {
609  /* delete per-database directories */
610  int dbnum;
611 
612  fprintf(script, "\n");
613 
614  for (dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
615  fprintf(script, RMDIR_CMD " %c%s%c%u%c\n", PATH_QUOTE,
618  PATH_QUOTE);
619  }
620  else
621  {
622  char *suffix_path = pg_strdup(old_cluster.tablespace_suffix);
623 
624  /*
625  * Simply delete the tablespace directory, which might be ".old"
626  * or a version-specific subdirectory.
627  */
628  fprintf(script, RMDIR_CMD " %c%s%s%c\n", PATH_QUOTE,
630  fix_path_separator(suffix_path), PATH_QUOTE);
631  pfree(suffix_path);
632  }
633  }
634 
635  fclose(script);
636 
637 #ifndef WIN32
638  if (chmod(*deletion_script_file_name, S_IRWXU) != 0)
639  pg_fatal("could not add execute permission to file \"%s\": %s",
640  *deletion_script_file_name, strerror(errno));
641 #endif
642 
643  check_ok();
644 }
static char * fix_path_separator(char *path)
Definition: check.c:47
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:1436
#define PATH_SEPARATOR
Definition: pg_upgrade.h:82
#define RMDIR_CMD
Definition: pg_upgrade.h:85
#define SCRIPT_EXT
Definition: pg_upgrade.h:87
#define SCRIPT_PREFIX
Definition: pg_upgrade.h:86
#define PATH_QUOTE
Definition: pg_upgrade.h:83
@ PG_WARNING
Definition: pg_upgrade.h:242
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:256
Oid db_oid
Definition: pg_upgrade.h:174
#define S_IRWXU
Definition: win32_port.h:300

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

399 {
400  const char *chara;
401  const char *charb;
402  char *canona;
403  char *canonb;
404  int lena;
405  int lenb;
406 
407  /*
408  * If the names are equal, the locales are equivalent. Checking this first
409  * avoids calling setlocale() in the common case that the names are equal.
410  * That's a good thing, if setlocale() is buggy, for example.
411  */
412  if (pg_strcasecmp(loca, locb) == 0)
413  return true;
414 
415  /*
416  * Not identical. Canonicalize both names, remove the encoding parts, and
417  * try again.
418  */
419  canona = get_canonical_locale_name(category, loca);
420  chara = strrchr(canona, '.');
421  lena = chara ? (chara - canona) : strlen(canona);
422 
423  canonb = get_canonical_locale_name(category, locb);
424  charb = strrchr(canonb, '.');
425  lenb = charb ? (charb - canonb) : strlen(canonb);
426 
427  if (lena == lenb && pg_strncasecmp(canona, canonb, lena) == 0)
428  {
429  pg_free(canona);
430  pg_free(canonb);
431  return true;
432  }
433 
434  pg_free(canona);
435  pg_free(canonb);
436  return false;
437 }
static char * get_canonical_locale_name(int category, const char *locale)
Definition: check.c:1536
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 47 of file check.c.

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

1537 {
1538  char *save;
1539  char *res;
1540 
1541  /* get the current setting, so we can restore it. */
1542  save = setlocale(category, NULL);
1543  if (!save)
1544  pg_fatal("failed to get the current locale");
1545 
1546  /* 'save' may be pointing at a modifiable scratch variable, so copy it. */
1547  save = pg_strdup(save);
1548 
1549  /* set the locale with setlocale, to see if it accepts it. */
1550  res = setlocale(category, locale);
1551 
1552  if (!res)
1553  pg_fatal("failed to get system locale name for \"%s\"", locale);
1554 
1555  res = pg_strdup(res);
1556 
1557  /* restore old value. */
1558  if (!setlocale(category, save))
1559  pg_fatal("failed to restore old locale \"%s\"", save);
1560 
1561  pg_free(save);
1562 
1563  return res;
1564 }
static char * locale
Definition: initdb.c:129
#define setlocale(a, b)
Definition: win32_port.h:464

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

242 {
243  /*
244  * We unconditionally start/stop the new server because pg_resetwal -o set
245  * wal_level to 'minimum'. If the user is upgrading standby servers using
246  * the rsync instructions, they will need pg_upgrade to write its final
247  * WAL record showing wal_level as 'replica'.
248  */
250 
251  /* Reindex hash indexes for old < 10.0 */
254 
256 
257  stop_postmaster(false);
258 }
void report_extension_updates(ClusterInfo *cluster)
Definition: version.c:396

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

69 {
70  if (user_opts.check && live_check)
71  {
73  "Performing Consistency Checks on Old Live Server\n"
74  "------------------------------------------------");
75  }
76  else
77  {
79  "Performing Consistency Checks\n"
80  "-----------------------------");
81  }
82 }

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

263 {
264  PQExpBufferData user_specification;
265 
266  initPQExpBuffer(&user_specification);
268  {
269  appendPQExpBufferStr(&user_specification, "-U ");
270  appendShellString(&user_specification, os_info.user);
271  appendPQExpBufferChar(&user_specification, ' ');
272  }
273 
275  "Optimizer statistics are not transferred by pg_upgrade.\n"
276  "Once you start the new server, consider running:\n"
277  " %s/vacuumdb %s--all --analyze-in-stages", new_cluster.bindir, user_specification.data);
278 
279  if (deletion_script_file_name)
281  "Running this script will delete the old cluster's data files:\n"
282  " %s",
283  deletion_script_file_name);
284  else
286  "Could not create a script to delete the old cluster's data files\n"
287  "because user-defined tablespaces or the new cluster's data directory\n"
288  "exist in the old cluster directory. The old cluster's contents must\n"
289  "be deleted manually.");
290 
291  termPQExpBuffer(&user_specification);
292 }
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:378
void appendShellString(PQExpBuffer buf, const char *str)
Definition: string_utils.c:429
char * bindir
Definition: pg_upgrade.h:259
bool user_specified
Definition: pg_upgrade.h:314

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

223 {
224  if (user_opts.check)
225  {
226  pg_log(PG_REPORT, "\n*Clusters are compatible*");
227  /* stops new cluster */
228  stop_postmaster(false);
229 
231  exit(0);
232  }
233 
234  pg_log(PG_REPORT, "\n"
235  "If pg_upgrade fails after this point, you must re-initdb the\n"
236  "new cluster before continuing.");
237 }
exit(1)
void cleanup_output_dirs(void)
Definition: util.c:63

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

Referenced by main().