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

83 {
84  /* -- OLD -- */
85 
86  if (!live_check)
88 
89  /* Extract a list of databases and tables from the old cluster */
91 
93 
95 
96 
97  /*
98  * Check for various failure cases
99  */
106 
107  /*
108  * PG 16 increased the size of the 'aclitem' type, which breaks the
109  * on-disk format for existing data.
110  */
113 
114  /*
115  * PG 14 changed the function signature of encoding conversion functions.
116  * Conversions from older versions cannot be upgraded automatically
117  * because the user-defined functions used by the encoding conversions
118  * need to be changed to match the new signature.
119  */
122 
123  /*
124  * Pre-PG 14 allowed user defined postfix operators, which are not
125  * supported anymore. Verify there are none, iff applicable.
126  */
129 
130  /*
131  * PG 14 changed polymorphic functions from anyarray to
132  * anycompatiblearray.
133  */
136 
137  /*
138  * Pre-PG 12 allowed tables to be declared WITH OIDS, which is not
139  * supported anymore. Verify there are none, iff applicable.
140  */
143 
144  /*
145  * PG 12 changed the 'sql_identifier' type storage to be based on name,
146  * not varchar, which breaks on-disk format for existing data. So we need
147  * to prevent upgrade when used in user objects (tables, indexes, ...).
148  */
151 
152  /*
153  * Pre-PG 10 allowed tables with 'unknown' type columns and non WAL logged
154  * hash indexes
155  */
157  {
159  if (user_opts.check)
161  }
162 
163  /* 9.5 and below should not have roles starting with pg_ */
166 
170 
171  /* Pre-PG 9.4 had a different 'line' data type internal format */
174 
175  /*
176  * While not a check option, we do this now because this is the only time
177  * the old server is running.
178  */
179  if (!user_opts.check)
181 
182  if (!live_check)
183  stop_postmaster(false);
184 }
static void check_for_tables_with_oids(ClusterInfo *cluster)
Definition: check.c:1018
static void check_for_pg_role_prefix(ClusterInfo *cluster)
Definition: check.c:1272
static void check_for_composite_data_type_usage(ClusterInfo *cluster)
Definition: check.c:1098
static void check_is_install_user(ClusterInfo *cluster)
Definition: check.c:532
static void check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster)
Definition: check.c:710
static void check_for_user_defined_postfix_ops(ClusterInfo *cluster)
Definition: check.c:792
static void check_for_prepared_transactions(ClusterInfo *cluster)
Definition: check.c:675
static void check_proper_datallowconn(ClusterInfo *cluster)
Definition: check.c:590
static void check_for_aclitem_data_type_usage(ClusterInfo *cluster)
Definition: check.c:1214
static void check_for_user_defined_encoding_conversions(ClusterInfo *cluster)
Definition: check.c:1328
static void check_for_jsonb_9_4_usage(ClusterInfo *cluster)
Definition: check.c:1242
static void check_for_incompatible_polymorphics(ClusterInfo *cluster)
Definition: check.c:891
static void check_for_reg_data_type_usage(ClusterInfo *cluster)
Definition: check.c:1159
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:275
static pid_t start_postmaster(void)
Definition: pg_ctl.c:440
ClusterInfo old_cluster
Definition: pg_upgrade.c:63
void init_tablespaces(void)
Definition: tablespace.c:19
void old_11_check_for_sql_identifier_data_type_usage(ClusterInfo *cluster)
Definition: version.c: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:320
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:261
uint32 major_version
Definition: pg_upgrade.h:272
uint32 cat_ver
Definition: pg_upgrade.h:207
bool check
Definition: pg_upgrade.h:301

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

335 {
336  /* get/check pg_control data of servers */
337  get_control_data(&old_cluster, live_check);
338  get_control_data(&new_cluster, false);
340 
341  if (live_check && old_cluster.port == new_cluster.port)
342  pg_fatal("When checking a live server, "
343  "the old and new port numbers must be different.");
344 }
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:64
unsigned short port
Definition: pg_upgrade.h:271

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

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

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

static void check_for_aclitem_data_type_usage ( ClusterInfo cluster)
static

Definition at line 1214 of file check.c.

1215 {
1216  char output_path[MAXPGPATH];
1217 
1218  prep_status("Checking for incompatible \"aclitem\" data type in user tables");
1219 
1220  snprintf(output_path, sizeof(output_path), "tables_using_aclitem.txt");
1221 
1222  if (check_for_data_type_usage(cluster, "pg_catalog.aclitem", output_path))
1223  {
1224  pg_log(PG_REPORT, "fatal");
1225  pg_fatal("Your installation contains the \"aclitem\" data type in user tables.\n"
1226  "The internal format of \"aclitem\" changed in PostgreSQL version 16\n"
1227  "so this cluster cannot currently be upgraded. You can drop the\n"
1228  "problem columns and restart the upgrade. A list of the problem\n"
1229  "columns is in the file:\n"
1230  " %s", output_path);
1231  }
1232  else
1233  check_ok();
1234 }
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:248
#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 1098 of file check.c.

1099 {
1100  bool found;
1101  Oid firstUserOid;
1102  char output_path[MAXPGPATH];
1103  char *base_query;
1104 
1105  prep_status("Checking for system-defined composite types in user tables");
1106 
1107  snprintf(output_path, sizeof(output_path), "%s/%s",
1108  log_opts.basedir,
1109  "tables_using_composite.txt");
1110 
1111  /*
1112  * Look for composite types that were made during initdb *or* belong to
1113  * information_schema; that's important in case information_schema was
1114  * dropped and reloaded.
1115  *
1116  * The cutoff OID here should match the source cluster's value of
1117  * FirstNormalObjectId. We hardcode it rather than using that C #define
1118  * because, if that #define is ever changed, our own version's value is
1119  * NOT what to use. Eventually we may need a test on the source cluster's
1120  * version to select the correct value.
1121  */
1122  firstUserOid = 16384;
1123 
1124  base_query = psprintf("SELECT t.oid FROM pg_catalog.pg_type t "
1125  "LEFT JOIN pg_catalog.pg_namespace n ON t.typnamespace = n.oid "
1126  " WHERE typtype = 'c' AND (t.oid < %u OR nspname = 'information_schema')",
1127  firstUserOid);
1128 
1129  found = check_for_data_types_usage(cluster, base_query, output_path);
1130 
1131  free(base_query);
1132 
1133  if (found)
1134  {
1135  pg_log(PG_REPORT, "fatal");
1136  pg_fatal("Your installation contains system-defined composite type(s) in user tables.\n"
1137  "These type OIDs are not stable across PostgreSQL versions,\n"
1138  "so this cluster cannot currently be upgraded. You can\n"
1139  "drop the problem columns and restart the upgrade.\n"
1140  "A list of the problem columns is in the file:\n"
1141  " %s", output_path);
1142  }
1143  else
1144  check_ok();
1145 }
#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:289

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

892 {
893  PGresult *res;
894  FILE *script = NULL;
895  char output_path[MAXPGPATH];
896  PQExpBufferData old_polymorphics;
897 
898  prep_status("Checking for incompatible polymorphic functions");
899 
900  snprintf(output_path, sizeof(output_path), "%s/%s",
902  "incompatible_polymorphics.txt");
903 
904  /* The set of problematic functions varies a bit in different versions */
905  initPQExpBuffer(&old_polymorphics);
906 
907  appendPQExpBufferStr(&old_polymorphics,
908  "'array_append(anyarray,anyelement)'"
909  ", 'array_cat(anyarray,anyarray)'"
910  ", 'array_prepend(anyelement,anyarray)'");
911 
912  if (GET_MAJOR_VERSION(cluster->major_version) >= 903)
913  appendPQExpBufferStr(&old_polymorphics,
914  ", 'array_remove(anyarray,anyelement)'"
915  ", 'array_replace(anyarray,anyelement,anyelement)'");
916 
917  if (GET_MAJOR_VERSION(cluster->major_version) >= 905)
918  appendPQExpBufferStr(&old_polymorphics,
919  ", 'array_position(anyarray,anyelement)'"
920  ", 'array_position(anyarray,anyelement,integer)'"
921  ", 'array_positions(anyarray,anyelement)'"
922  ", 'width_bucket(anyelement,anyarray)'");
923 
924  for (int dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
925  {
926  bool db_used = false;
927  DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
928  PGconn *conn = connectToServer(cluster, active_db->db_name);
929  int ntups;
930  int i_objkind,
931  i_objname;
932 
933  /*
934  * The query below hardcodes FirstNormalObjectId as 16384 rather than
935  * interpolating that C #define into the query because, if that
936  * #define is ever changed, the cutoff we want to use is the value
937  * used by pre-version 14 servers, not that of some future version.
938  */
940  /* Aggregate transition functions */
941  "SELECT 'aggregate' AS objkind, p.oid::regprocedure::text AS objname "
942  "FROM pg_proc AS p "
943  "JOIN pg_aggregate AS a ON a.aggfnoid=p.oid "
944  "JOIN pg_proc AS transfn ON transfn.oid=a.aggtransfn "
945  "WHERE p.oid >= 16384 "
946  "AND a.aggtransfn = ANY(ARRAY[%s]::regprocedure[]) "
947  "AND a.aggtranstype = ANY(ARRAY['anyarray', 'anyelement']::regtype[]) "
948 
949  /* Aggregate final functions */
950  "UNION ALL "
951  "SELECT 'aggregate' AS objkind, p.oid::regprocedure::text AS objname "
952  "FROM pg_proc AS p "
953  "JOIN pg_aggregate AS a ON a.aggfnoid=p.oid "
954  "JOIN pg_proc AS finalfn ON finalfn.oid=a.aggfinalfn "
955  "WHERE p.oid >= 16384 "
956  "AND a.aggfinalfn = ANY(ARRAY[%s]::regprocedure[]) "
957  "AND a.aggtranstype = ANY(ARRAY['anyarray', 'anyelement']::regtype[]) "
958 
959  /* Operators */
960  "UNION ALL "
961  "SELECT 'operator' AS objkind, op.oid::regoperator::text AS objname "
962  "FROM pg_operator AS op "
963  "WHERE op.oid >= 16384 "
964  "AND oprcode = ANY(ARRAY[%s]::regprocedure[]) "
965  "AND oprleft = ANY(ARRAY['anyarray', 'anyelement']::regtype[]);",
966  old_polymorphics.data,
967  old_polymorphics.data,
968  old_polymorphics.data);
969 
970  ntups = PQntuples(res);
971 
972  i_objkind = PQfnumber(res, "objkind");
973  i_objname = PQfnumber(res, "objname");
974 
975  for (int rowno = 0; rowno < ntups; rowno++)
976  {
977  if (script == NULL &&
978  (script = fopen_priv(output_path, "w")) == NULL)
979  pg_fatal("could not open file \"%s\": %s",
980  output_path, strerror(errno));
981  if (!db_used)
982  {
983  fprintf(script, "In database: %s\n", active_db->db_name);
984  db_used = true;
985  }
986 
987  fprintf(script, " %s: %s\n",
988  PQgetvalue(res, rowno, i_objkind),
989  PQgetvalue(res, rowno, i_objname));
990  }
991 
992  PQclear(res);
993  PQfinish(conn);
994  }
995 
996  if (script)
997  {
998  fclose(script);
999  pg_log(PG_REPORT, "fatal");
1000  pg_fatal("Your installation contains user-defined objects that refer to internal\n"
1001  "polymorphic functions with arguments of type \"anyarray\" or \"anyelement\".\n"
1002  "These user-defined objects must be dropped before upgrading and restored\n"
1003  "afterwards, changing them to refer to the new corresponding functions with\n"
1004  "arguments of type \"anycompatiblearray\" and \"anycompatible\".\n"
1005  "A list of the problematic objects is in the file:\n"
1006  " %s", output_path);
1007  }
1008  else
1009  check_ok();
1010 
1011  termPQExpBuffer(&old_polymorphics);
1012 }
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4599
int PQntuples(const PGresult *res)
Definition: fe-exec.c:3314
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3709
int PQfnumber(const PGresult *res, const char *field_name)
Definition: fe-exec.c:3422
#define fopen_priv(path, mode)
Definition: pg_upgrade.h:390
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
char * db_name
Definition: pg_upgrade.h:175

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

711 {
712  int dbnum;
713  FILE *script = NULL;
714  char output_path[MAXPGPATH];
715 
716  prep_status("Checking for contrib/isn with bigint-passing mismatch");
717 
720  {
721  /* no mismatch */
722  check_ok();
723  return;
724  }
725 
726  snprintf(output_path, sizeof(output_path), "%s/%s",
728  "contrib_isn_and_int8_pass_by_value.txt");
729 
730  for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
731  {
732  PGresult *res;
733  bool db_used = false;
734  int ntups;
735  int rowno;
736  int i_nspname,
737  i_proname;
738  DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
739  PGconn *conn = connectToServer(cluster, active_db->db_name);
740 
741  /* Find any functions coming from contrib/isn */
743  "SELECT n.nspname, p.proname "
744  "FROM pg_catalog.pg_proc p, "
745  " pg_catalog.pg_namespace n "
746  "WHERE p.pronamespace = n.oid AND "
747  " p.probin = '$libdir/isn'");
748 
749  ntups = PQntuples(res);
750  i_nspname = PQfnumber(res, "nspname");
751  i_proname = PQfnumber(res, "proname");
752  for (rowno = 0; rowno < ntups; rowno++)
753  {
754  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
755  pg_fatal("could not open file \"%s\": %s",
756  output_path, strerror(errno));
757  if (!db_used)
758  {
759  fprintf(script, "In database: %s\n", active_db->db_name);
760  db_used = true;
761  }
762  fprintf(script, " %s.%s\n",
763  PQgetvalue(res, rowno, i_nspname),
764  PQgetvalue(res, rowno, i_proname));
765  }
766 
767  PQclear(res);
768 
769  PQfinish(conn);
770  }
771 
772  if (script)
773  {
774  fclose(script);
775  pg_log(PG_REPORT, "fatal");
776  pg_fatal("Your installation contains \"contrib/isn\" functions which rely on the\n"
777  "bigint data type. Your old and new clusters pass bigint values\n"
778  "differently so this cluster cannot currently be upgraded. You can\n"
779  "manually dump databases in the old cluster that use \"contrib/isn\"\n"
780  "facilities, drop them, perform the upgrade, and then restore them. A\n"
781  "list of the problem functions is in the file:\n"
782  " %s", output_path);
783  }
784  else
785  check_ok();
786 }
bool float8_pass_by_value
Definition: pg_upgrade.h:226

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

1243 {
1244  char output_path[MAXPGPATH];
1245 
1246  prep_status("Checking for incompatible \"jsonb\" data type");
1247 
1248  snprintf(output_path, sizeof(output_path), "%s/%s",
1249  log_opts.basedir,
1250  "tables_using_jsonb.txt");
1251 
1252  if (check_for_data_type_usage(cluster, "pg_catalog.jsonb", output_path))
1253  {
1254  pg_log(PG_REPORT, "fatal");
1255  pg_fatal("Your installation contains the \"jsonb\" data type in user tables.\n"
1256  "The internal format of \"jsonb\" changed during 9.4 beta so this\n"
1257  "cluster cannot currently be upgraded. You can\n"
1258  "drop the problem columns and restart the upgrade.\n"
1259  "A list of the problem columns is in the file:\n"
1260  " %s", output_path);
1261  }
1262  else
1263  check_ok();
1264 }

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

381 {
382  int tblnum;
383  char new_tablespace_dir[MAXPGPATH];
384 
385  prep_status("Checking for new cluster tablespace directories");
386 
387  for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
388  {
389  struct stat statbuf;
390 
391  snprintf(new_tablespace_dir, MAXPGPATH, "%s%s",
392  os_info.old_tablespaces[tblnum],
394 
395  if (stat(new_tablespace_dir, &statbuf) == 0 || errno != ENOENT)
396  pg_fatal("new cluster tablespace directory already exists: \"%s\"",
397  new_tablespace_dir);
398  }
399 
400  check_ok();
401 }
OSInfo os_info
Definition: pg_upgrade.c:65
const char * tablespace_suffix
Definition: pg_upgrade.h:275
int num_old_tablespaces
Definition: pg_upgrade.h:324
char ** old_tablespaces
Definition: pg_upgrade.h:323
#define stat
Definition: win32_port.h:292

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

1273 {
1274  PGresult *res;
1275  PGconn *conn = connectToServer(cluster, "template1");
1276  int ntups;
1277  int i_roloid;
1278  int i_rolname;
1279  FILE *script = NULL;
1280  char output_path[MAXPGPATH];
1281 
1282  prep_status("Checking for roles starting with \"pg_\"");
1283 
1284  snprintf(output_path, sizeof(output_path), "%s/%s",
1285  log_opts.basedir,
1286  "pg_role_prefix.txt");
1287 
1289  "SELECT oid AS roloid, rolname "
1290  "FROM pg_catalog.pg_roles "
1291  "WHERE rolname ~ '^pg_'");
1292 
1293  ntups = PQntuples(res);
1294  i_roloid = PQfnumber(res, "roloid");
1295  i_rolname = PQfnumber(res, "rolname");
1296  for (int rowno = 0; rowno < ntups; rowno++)
1297  {
1298  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
1299  pg_fatal("could not open file \"%s\": %s",
1300  output_path, strerror(errno));
1301  fprintf(script, "%s (oid=%s)\n",
1302  PQgetvalue(res, rowno, i_rolname),
1303  PQgetvalue(res, rowno, i_roloid));
1304  }
1305 
1306  PQclear(res);
1307 
1308  PQfinish(conn);
1309 
1310  if (script)
1311  {
1312  fclose(script);
1313  pg_log(PG_REPORT, "fatal");
1314  pg_fatal("Your installation contains roles starting with \"pg_\".\n"
1315  "\"pg_\" is a reserved prefix for system roles. The cluster\n"
1316  "cannot be upgraded until these roles are renamed.\n"
1317  "A list of roles starting with \"pg_\" is in the file:\n"
1318  " %s", output_path);
1319  }
1320  else
1321  check_ok();
1322 }

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

676 {
677  PGresult *res;
678  PGconn *conn = connectToServer(cluster, "template1");
679 
680  prep_status("Checking for prepared transactions");
681 
683  "SELECT * "
684  "FROM pg_catalog.pg_prepared_xacts");
685 
686  if (PQntuples(res) != 0)
687  {
688  if (cluster == &old_cluster)
689  pg_fatal("The source cluster contains prepared transactions");
690  else
691  pg_fatal("The target cluster contains prepared transactions");
692  }
693 
694  PQclear(res);
695 
696  PQfinish(conn);
697 
698  check_ok();
699 }

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

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

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

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

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

1329 {
1330  int dbnum;
1331  FILE *script = NULL;
1332  char output_path[MAXPGPATH];
1333 
1334  prep_status("Checking for user-defined encoding conversions");
1335 
1336  snprintf(output_path, sizeof(output_path), "%s/%s",
1337  log_opts.basedir,
1338  "encoding_conversions.txt");
1339 
1340  /* Find any user defined encoding conversions */
1341  for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
1342  {
1343  PGresult *res;
1344  bool db_used = false;
1345  int ntups;
1346  int rowno;
1347  int i_conoid,
1348  i_conname,
1349  i_nspname;
1350  DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
1351  PGconn *conn = connectToServer(cluster, active_db->db_name);
1352 
1353  /*
1354  * The query below hardcodes FirstNormalObjectId as 16384 rather than
1355  * interpolating that C #define into the query because, if that
1356  * #define is ever changed, the cutoff we want to use is the value
1357  * used by pre-version 14 servers, not that of some future version.
1358  */
1360  "SELECT c.oid as conoid, c.conname, n.nspname "
1361  "FROM pg_catalog.pg_conversion c, "
1362  " pg_catalog.pg_namespace n "
1363  "WHERE c.connamespace = n.oid AND "
1364  " c.oid >= 16384");
1365  ntups = PQntuples(res);
1366  i_conoid = PQfnumber(res, "conoid");
1367  i_conname = PQfnumber(res, "conname");
1368  i_nspname = PQfnumber(res, "nspname");
1369  for (rowno = 0; rowno < ntups; rowno++)
1370  {
1371  if (script == NULL &&
1372  (script = fopen_priv(output_path, "w")) == NULL)
1373  pg_fatal("could not open file \"%s\": %s",
1374  output_path, strerror(errno));
1375  if (!db_used)
1376  {
1377  fprintf(script, "In database: %s\n", active_db->db_name);
1378  db_used = true;
1379  }
1380  fprintf(script, " (oid=%s) %s.%s\n",
1381  PQgetvalue(res, rowno, i_conoid),
1382  PQgetvalue(res, rowno, i_nspname),
1383  PQgetvalue(res, rowno, i_conname));
1384  }
1385 
1386  PQclear(res);
1387 
1388  PQfinish(conn);
1389  }
1390 
1391  if (script)
1392  {
1393  fclose(script);
1394  pg_log(PG_REPORT, "fatal");
1395  pg_fatal("Your installation contains user-defined encoding conversions.\n"
1396  "The conversion function parameters changed in PostgreSQL version 14\n"
1397  "so this cluster cannot currently be upgraded. You can remove the\n"
1398  "encoding conversions in the old cluster and restart the upgrade.\n"
1399  "A list of user-defined encoding conversions is in the file:\n"
1400  " %s", output_path);
1401  }
1402  else
1403  check_ok();
1404 }

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

793 {
794  int dbnum;
795  FILE *script = NULL;
796  char output_path[MAXPGPATH];
797 
798  prep_status("Checking for user-defined postfix operators");
799 
800  snprintf(output_path, sizeof(output_path), "%s/%s",
802  "postfix_ops.txt");
803 
804  /* Find any user defined postfix operators */
805  for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
806  {
807  PGresult *res;
808  bool db_used = false;
809  int ntups;
810  int rowno;
811  int i_oproid,
812  i_oprnsp,
813  i_oprname,
814  i_typnsp,
815  i_typname;
816  DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
817  PGconn *conn = connectToServer(cluster, active_db->db_name);
818 
819  /*
820  * The query below hardcodes FirstNormalObjectId as 16384 rather than
821  * interpolating that C #define into the query because, if that
822  * #define is ever changed, the cutoff we want to use is the value
823  * used by pre-version 14 servers, not that of some future version.
824  */
826  "SELECT o.oid AS oproid, "
827  " n.nspname AS oprnsp, "
828  " o.oprname, "
829  " tn.nspname AS typnsp, "
830  " t.typname "
831  "FROM pg_catalog.pg_operator o, "
832  " pg_catalog.pg_namespace n, "
833  " pg_catalog.pg_type t, "
834  " pg_catalog.pg_namespace tn "
835  "WHERE o.oprnamespace = n.oid AND "
836  " o.oprleft = t.oid AND "
837  " t.typnamespace = tn.oid AND "
838  " o.oprright = 0 AND "
839  " o.oid >= 16384");
840  ntups = PQntuples(res);
841  i_oproid = PQfnumber(res, "oproid");
842  i_oprnsp = PQfnumber(res, "oprnsp");
843  i_oprname = PQfnumber(res, "oprname");
844  i_typnsp = PQfnumber(res, "typnsp");
845  i_typname = PQfnumber(res, "typname");
846  for (rowno = 0; rowno < ntups; rowno++)
847  {
848  if (script == NULL &&
849  (script = fopen_priv(output_path, "w")) == NULL)
850  pg_fatal("could not open file \"%s\": %s",
851  output_path, strerror(errno));
852  if (!db_used)
853  {
854  fprintf(script, "In database: %s\n", active_db->db_name);
855  db_used = true;
856  }
857  fprintf(script, " (oid=%s) %s.%s (%s.%s, NONE)\n",
858  PQgetvalue(res, rowno, i_oproid),
859  PQgetvalue(res, rowno, i_oprnsp),
860  PQgetvalue(res, rowno, i_oprname),
861  PQgetvalue(res, rowno, i_typnsp),
862  PQgetvalue(res, rowno, i_typname));
863  }
864 
865  PQclear(res);
866 
867  PQfinish(conn);
868  }
869 
870  if (script)
871  {
872  fclose(script);
873  pg_log(PG_REPORT, "fatal");
874  pg_fatal("Your installation contains user-defined postfix operators, which are not\n"
875  "supported anymore. Consider dropping the postfix operators and replacing\n"
876  "them with prefix operators or function calls.\n"
877  "A list of user-defined postfix operators is in the file:\n"
878  " %s", output_path);
879  }
880  else
881  check_ok();
882 }

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

533 {
534  PGresult *res;
535  PGconn *conn = connectToServer(cluster, "template1");
536 
537  prep_status("Checking database user is the install user");
538 
539  /* Can't use pg_authid because only superusers can view it. */
541  "SELECT rolsuper, oid "
542  "FROM pg_catalog.pg_roles "
543  "WHERE rolname = current_user "
544  "AND rolname !~ '^pg_'");
545 
546  /*
547  * We only allow the install user in the new cluster (see comment below)
548  * and we preserve pg_authid.oid, so this must be the install user in the
549  * old cluster too.
550  */
551  if (PQntuples(res) != 1 ||
552  atooid(PQgetvalue(res, 0, 1)) != BOOTSTRAP_SUPERUSERID)
553  pg_fatal("database user \"%s\" is not the install user",
554  os_info.user);
555 
556  PQclear(res);
557 
559  "SELECT COUNT(*) "
560  "FROM pg_catalog.pg_roles "
561  "WHERE rolname !~ '^pg_'");
562 
563  if (PQntuples(res) != 1)
564  pg_fatal("could not determine the number of users");
565 
566  /*
567  * We only allow the install user in the new cluster because other defined
568  * users might match users defined in the old cluster and generate an
569  * error during pg_dump restore.
570  */
571  if (cluster == &new_cluster && strcmp(PQgetvalue(res, 0, 0), "1") != 0)
572  pg_fatal("Only the install user can be defined in the new cluster.");
573 
574  PQclear(res);
575 
576  PQfinish(conn);
577 
578  check_ok();
579 }
#define atooid(x)
Definition: postgres_ext.h:42
char * user
Definition: pg_upgrade.h:321

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

void check_new_cluster ( void  )

Definition at line 188 of file check.c.

189 {
191 
193 
195 
196  switch (user_opts.transfer_mode)
197  {
198  case TRANSFER_MODE_CLONE:
200  break;
201  case TRANSFER_MODE_COPY:
202  break;
203  case TRANSFER_MODE_LINK:
204  check_hard_link();
205  break;
206  }
207 
209 
211 
213 }
static void check_new_cluster_is_empty(void)
Definition: check.c:348
static void check_for_new_tablespace_dir(ClusterInfo *new_cluster)
Definition: check.c:380
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:236
@ TRANSFER_MODE_LINK
Definition: pg_upgrade.h:237
@ TRANSFER_MODE_CLONE
Definition: pg_upgrade.h:235
transferMode transfer_mode
Definition: pg_upgrade.h:304

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

349 {
350  int dbnum;
351 
352  for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++)
353  {
354  int relnum;
355  RelInfoArr *rel_arr = &new_cluster.dbarr.dbs[dbnum].rel_arr;
356 
357  for (relnum = 0; relnum < rel_arr->nrels;
358  relnum++)
359  {
360  /* pg_largeobject and its index should be skipped */
361  if (strcmp(rel_arr->rels[relnum].nspname, "pg_catalog") != 0)
362  pg_fatal("New cluster database \"%s\" is not empty: found relation \"%s.%s\"",
363  new_cluster.dbarr.dbs[dbnum].db_name,
364  rel_arr->rels[relnum].nspname,
365  rel_arr->rels[relnum].relname);
366  }
367  }
368 }
DbInfoArr dbarr
Definition: pg_upgrade.h:263
DbInfo * dbs
Definition: pg_upgrade.h:195
RelInfoArr rel_arr
Definition: pg_upgrade.h:178
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 590 of file check.c.

591 {
592  int dbnum;
593  PGconn *conn_template1;
594  PGresult *dbres;
595  int ntups;
596  int i_datname;
597  int i_datallowconn;
598  FILE *script = NULL;
599  char output_path[MAXPGPATH];
600 
601  prep_status("Checking database connection settings");
602 
603  snprintf(output_path, sizeof(output_path), "%s/%s",
605  "databases_with_datallowconn_false.txt");
606 
607  conn_template1 = connectToServer(cluster, "template1");
608 
609  /* get database names */
610  dbres = executeQueryOrDie(conn_template1,
611  "SELECT datname, datallowconn "
612  "FROM pg_catalog.pg_database");
613 
614  i_datname = PQfnumber(dbres, "datname");
615  i_datallowconn = PQfnumber(dbres, "datallowconn");
616 
617  ntups = PQntuples(dbres);
618  for (dbnum = 0; dbnum < ntups; dbnum++)
619  {
620  char *datname = PQgetvalue(dbres, dbnum, i_datname);
621  char *datallowconn = PQgetvalue(dbres, dbnum, i_datallowconn);
622 
623  if (strcmp(datname, "template0") == 0)
624  {
625  /* avoid restore failure when pg_dumpall tries to create template0 */
626  if (strcmp(datallowconn, "t") == 0)
627  pg_fatal("template0 must not allow connections, "
628  "i.e. its pg_database.datallowconn must be false");
629  }
630  else
631  {
632  /*
633  * avoid datallowconn == false databases from being skipped on
634  * restore
635  */
636  if (strcmp(datallowconn, "f") == 0)
637  {
638  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
639  pg_fatal("could not open file \"%s\": %s",
640  output_path, strerror(errno));
641 
642  fprintf(script, "%s\n", datname);
643  }
644  }
645  }
646 
647  PQclear(dbres);
648 
649  PQfinish(conn_template1);
650 
651  if (script)
652  {
653  fclose(script);
654  pg_log(PG_REPORT, "fatal");
655  pg_fatal("All non-template0 databases must allow connections, i.e. their\n"
656  "pg_database.datallowconn must be true. Your installation contains\n"
657  "non-template0 databases with their pg_database.datallowconn set to\n"
658  "false. Consider allowing connection for all non-template0 databases\n"
659  "or drop the databases which do not allow connections. A list of\n"
660  "databases with the problem is in the file:\n"
661  " %s", output_path);
662  }
663  else
664  check_ok();
665 }
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 409 of file check.c.

410 {
411  FILE *script = NULL;
412  int tblnum;
413  char old_cluster_pgdata[MAXPGPATH],
414  new_cluster_pgdata[MAXPGPATH];
415 
416  *deletion_script_file_name = psprintf("%sdelete_old_cluster.%s",
418 
419  strlcpy(old_cluster_pgdata, old_cluster.pgdata, MAXPGPATH);
420  canonicalize_path(old_cluster_pgdata);
421 
422  strlcpy(new_cluster_pgdata, new_cluster.pgdata, MAXPGPATH);
423  canonicalize_path(new_cluster_pgdata);
424 
425  /* Some people put the new data directory inside the old one. */
426  if (path_is_prefix_of_path(old_cluster_pgdata, new_cluster_pgdata))
427  {
429  "\nWARNING: new data directory should not be inside the old data directory, i.e. %s", old_cluster_pgdata);
430 
431  /* Unlink file in case it is left over from a previous run. */
432  unlink(*deletion_script_file_name);
433  pg_free(*deletion_script_file_name);
434  *deletion_script_file_name = NULL;
435  return;
436  }
437 
438  /*
439  * Some users (oddly) create tablespaces inside the cluster data
440  * directory. We can't create a proper old cluster delete script in that
441  * case.
442  */
443  for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
444  {
445  char old_tablespace_dir[MAXPGPATH];
446 
447  strlcpy(old_tablespace_dir, os_info.old_tablespaces[tblnum], MAXPGPATH);
448  canonicalize_path(old_tablespace_dir);
449  if (path_is_prefix_of_path(old_cluster_pgdata, old_tablespace_dir))
450  {
451  /* reproduce warning from CREATE TABLESPACE that is in the log */
453  "\nWARNING: user-defined tablespace locations should not be inside the data directory, i.e. %s", old_tablespace_dir);
454 
455  /* Unlink file in case it is left over from a previous run. */
456  unlink(*deletion_script_file_name);
457  pg_free(*deletion_script_file_name);
458  *deletion_script_file_name = NULL;
459  return;
460  }
461  }
462 
463  prep_status("Creating script to delete old cluster");
464 
465  if ((script = fopen_priv(*deletion_script_file_name, "w")) == NULL)
466  pg_fatal("could not open file \"%s\": %s",
467  *deletion_script_file_name, strerror(errno));
468 
469 #ifndef WIN32
470  /* add shebang header */
471  fprintf(script, "#!/bin/sh\n\n");
472 #endif
473 
474  /* delete old cluster's default tablespace */
475  fprintf(script, RMDIR_CMD " %c%s%c\n", PATH_QUOTE,
477 
478  /* delete old cluster's alternate tablespaces */
479  for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
480  {
481  /*
482  * Do the old cluster's per-database directories share a directory
483  * with a new version-specific tablespace?
484  */
485  if (strlen(old_cluster.tablespace_suffix) == 0)
486  {
487  /* delete per-database directories */
488  int dbnum;
489 
490  fprintf(script, "\n");
491 
492  for (dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
493  fprintf(script, RMDIR_CMD " %c%s%c%u%c\n", PATH_QUOTE,
496  PATH_QUOTE);
497  }
498  else
499  {
500  char *suffix_path = pg_strdup(old_cluster.tablespace_suffix);
501 
502  /*
503  * Simply delete the tablespace directory, which might be ".old"
504  * or a version-specific subdirectory.
505  */
506  fprintf(script, RMDIR_CMD " %c%s%s%c\n", PATH_QUOTE,
508  fix_path_separator(suffix_path), PATH_QUOTE);
509  pfree(suffix_path);
510  }
511  }
512 
513  fclose(script);
514 
515 #ifndef WIN32
516  if (chmod(*deletion_script_file_name, S_IRWXU) != 0)
517  pg_fatal("could not add execute permission to file \"%s\": %s",
518  *deletion_script_file_name, strerror(errno));
519 #endif
520 
521  check_ok();
522 }
static char * fix_path_separator(char *path)
Definition: check.c:43
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:1456
#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:249
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:264
Oid db_oid
Definition: pg_upgrade.h:174
#define S_IRWXU
Definition: win32_port.h:306

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

◆ fix_path_separator()

static char* fix_path_separator ( char *  path)
static

Definition at line 43 of file check.c.

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

References pg_strdup().

Referenced by create_script_for_old_cluster_deletion().

◆ issue_warnings_and_set_wal_level()

void issue_warnings_and_set_wal_level ( void  )

Definition at line 236 of file check.c.

237 {
238  /*
239  * We unconditionally start/stop the new server because pg_resetwal -o set
240  * wal_level to 'minimum'. If the user is upgrading standby servers using
241  * the rsync instructions, they will need pg_upgrade to write its final
242  * WAL record showing wal_level as 'replica'.
243  */
245 
246  /* Reindex hash indexes for old < 10.0 */
249 
251 
252  stop_postmaster(false);
253 }
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 64 of file check.c.

65 {
66  if (user_opts.check && live_check)
67  {
69  "Performing Consistency Checks on Old Live Server\n"
70  "------------------------------------------------");
71  }
72  else
73  {
75  "Performing Consistency Checks\n"
76  "-----------------------------");
77  }
78 }

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

258 {
259  PQExpBufferData user_specification;
260 
261  initPQExpBuffer(&user_specification);
263  {
264  appendPQExpBufferStr(&user_specification, "-U ");
265  appendShellString(&user_specification, os_info.user);
266  appendPQExpBufferChar(&user_specification, ' ');
267  }
268 
270  "Optimizer statistics are not transferred by pg_upgrade.\n"
271  "Once you start the new server, consider running:\n"
272  " %s/vacuumdb %s--all --analyze-in-stages", new_cluster.bindir, user_specification.data);
273 
274  if (deletion_script_file_name)
276  "Running this script will delete the old cluster's data files:\n"
277  " %s",
278  deletion_script_file_name);
279  else
281  "Could not create a script to delete the old cluster's data files\n"
282  "because user-defined tablespaces or the new cluster's data directory\n"
283  "exist in the old cluster directory. The old cluster's contents must\n"
284  "be deleted manually.");
285 
286  termPQExpBuffer(&user_specification);
287 }
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:267
bool user_specified
Definition: pg_upgrade.h:322

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

218 {
219  if (user_opts.check)
220  {
221  pg_log(PG_REPORT, "\n*Clusters are compatible*");
222  /* stops new cluster */
223  stop_postmaster(false);
224 
226  exit(0);
227  }
228 
229  pg_log(PG_REPORT, "\n"
230  "If pg_upgrade fails after this point, you must re-initdb the\n"
231  "new cluster before continuing.");
232 }
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().