PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
check.c File Reference
#include "postgres_fe.h"
#include "catalog/pg_authid.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_reg_data_type_usage (ClusterInfo *cluster)
 
static void check_for_jsonb_9_4_usage (ClusterInfo *cluster)
 
static void check_for_pg_role_prefix (ClusterInfo *cluster)
 
static char * get_canonical_locale_name (int category, const char *locale)
 
static char * fix_path_separator (char *path)
 
void output_check_banner (bool live_check)
 
void check_and_dump_old_cluster (bool live_check)
 
void check_new_cluster (void)
 
void report_clusters_compatible (void)
 
void issue_warnings (void)
 
void output_completion_banner (char *analyze_script_file_name, char *deletion_script_file_name)
 
void check_cluster_versions (void)
 
void check_cluster_compatibility (bool live_check)
 
void create_script_for_cluster_analyze (char **analyze_script_file_name)
 
void create_script_for_old_cluster_deletion (char **deletion_script_file_name)
 

Function Documentation

void check_and_dump_old_cluster ( bool  live_check)

Definition at line 77 of file check.c.

References ControlData::cat_ver, UserOpts::check, check_for_isn_and_int8_passing_mismatch(), check_for_jsonb_9_4_usage(), check_for_pg_role_prefix(), check_for_prepared_transactions(), check_for_reg_data_type_usage(), check_is_install_user(), check_proper_datallowconn(), ClusterInfo::controldata, generate_old_dump(), get_db_and_rel_infos(), get_loadable_libraries(), GET_MAJOR_VERSION, init_tablespaces(), JSONB_FORMAT_CHANGE_CAT_VER, ClusterInfo::major_version, new_9_0_populate_pg_largeobject_metadata(), old_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().

78 {
79  /* -- OLD -- */
80 
81  if (!live_check)
83 
84  /* Extract a list of databases and tables from the old cluster */
86 
88 
90 
91 
92  /*
93  * Check for various failure cases
94  */
100 
101  /*
102  * Pre-PG 10 allowed tables with 'unknown' type columns and non WAL logged
103  * hash indexes
104  */
106  {
108  if (user_opts.check)
110  }
111 
112  /* 9.5 and below should not have roles starting with pg_ */
115 
119 
120  /* Pre-PG 9.4 had a different 'line' data type internal format */
123 
124  /* Pre-PG 9.0 had no large object permissions */
127 
128  /*
129  * While not a check option, we do this now because this is the only time
130  * the old server is running.
131  */
132  if (!user_opts.check)
134 
135  if (!live_check)
136  stop_postmaster(false);
137 }
uint32 major_version
Definition: pg_upgrade.h:272
ControlData controldata
Definition: pg_upgrade.h:262
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:29
void old_9_6_invalidate_hash_indexes(ClusterInfo *cluster, bool check_mode)
Definition: version.c:297
static void check_for_reg_data_type_usage(ClusterInfo *cluster)
Definition: check.c:884
static void check_for_prepared_transactions(ClusterInfo *cluster)
Definition: check.c:759
void stop_postmaster(bool fast)
Definition: server.c:308
static void check_proper_datallowconn(ClusterInfo *cluster)
Definition: check.c:698
static void check_for_pg_role_prefix(ClusterInfo *cluster)
Definition: check.c:1070
void new_9_0_populate_pg_largeobject_metadata(ClusterInfo *cluster, bool check_mode)
Definition: version.c:25
ClusterInfo old_cluster
Definition: pg_upgrade.c:56
void generate_old_dump(void)
Definition: dump.c:18
static void check_is_install_user(ClusterInfo *cluster)
Definition: check.c:647
static void check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster)
Definition: check.c:790
UserOpts user_opts
Definition: option.c:29
uint32 cat_ver
Definition: pg_upgrade.h:208
void get_loadable_libraries(void)
Definition: function.c:49
void get_db_and_rel_infos(ClusterInfo *cluster)
Definition: info.c:311
#define JSONB_FORMAT_CHANGE_CAT_VER
Definition: pg_upgrade.h:131
bool check
Definition: pg_upgrade.h:295
static pgpid_t start_postmaster(void)
Definition: pg_ctl.c:428
static void check_for_jsonb_9_4_usage(ClusterInfo *cluster)
Definition: check.c:981
void init_tablespaces(void)
Definition: tablespace.c:19
void old_9_3_check_for_line_data_type_usage(ClusterInfo *cluster)
Definition: version.c:111
void old_9_6_check_for_unknown_data_type_usage(ClusterInfo *cluster)
Definition: version.c:208
void check_cluster_compatibility ( bool  live_check)

Definition at line 271 of file check.c.

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

Referenced by main().

272 {
273  /* get/check pg_control data of servers */
274  get_control_data(&old_cluster, live_check);
275  get_control_data(&new_cluster, false);
277 
278  /* Is it 9.0 but without tablespace directories? */
281  pg_fatal("This utility can only upgrade to PostgreSQL version 9.0 after 2010-01-11\n"
282  "because of backend API changes made during development.\n");
283 
284  /* We read the real port number for PG >= 9.1 */
285  if (live_check && GET_MAJOR_VERSION(old_cluster.major_version) < 901 &&
287  pg_fatal("When checking a pre-PG 9.1 live old server, "
288  "you must specify the old server's port number.\n");
289 
290  if (live_check && old_cluster.port == new_cluster.port)
291  pg_fatal("When checking a live server, "
292  "the old and new port numbers must be different.\n");
293 }
uint32 major_version
Definition: pg_upgrade.h:272
ControlData controldata
Definition: pg_upgrade.h:262
#define TABLE_SPACE_SUBDIRS_CAT_VER
Definition: pg_upgrade.h:101
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:29
unsigned short port
Definition: pg_upgrade.h:271
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
void check_control_data(ControlData *oldctrl, ControlData *newctrl)
Definition: controldata.c:549
ClusterInfo new_cluster
Definition: pg_upgrade.c:56
ClusterInfo old_cluster
Definition: pg_upgrade.c:56
uint32 cat_ver
Definition: pg_upgrade.h:208
#define DEF_PGUPORT
Definition: pg_upgrade.h:16
void get_control_data(ClusterInfo *cluster, bool live_check)
Definition: controldata.c:34
void check_cluster_versions ( void  )

Definition at line 229 of file check.c.

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

Referenced by main().

230 {
231  prep_status("Checking cluster versions");
232 
233  /* get old and new cluster versions */
236 
237  /*
238  * We allow upgrades from/to the same major version for alpha/beta
239  * upgrades
240  */
241 
243  pg_fatal("This utility can only upgrade from PostgreSQL version 8.4 and later.\n");
244 
245  /* Only current PG version is supported as a target */
247  pg_fatal("This utility can only upgrade to PostgreSQL version %s.\n",
248  PG_MAJORVERSION);
249 
250  /*
251  * We can't allow downgrading because we use the target pg_dump, and
252  * pg_dump cannot operate on newer database versions, only current and
253  * older versions.
254  */
256  pg_fatal("This utility cannot be used to downgrade to older major PostgreSQL versions.\n");
257 
258  /* Ensure binaries match the designated data directories */
261  pg_fatal("Old cluster data and binary directories are from different major versions.\n");
264  pg_fatal("New cluster data and binary directories are from different major versions.\n");
265 
266  check_ok();
267 }
uint32 get_major_server_version(ClusterInfo *cluster)
Definition: server.c:155
uint32 major_version
Definition: pg_upgrade.h:272
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:29
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
ClusterInfo new_cluster
Definition: pg_upgrade.c:56
void prep_status(const char *fmt,...) pg_attribute_printf(1
ClusterInfo old_cluster
Definition: pg_upgrade.c:56
static void check_ok(void)
Definition: initdb.c:2008
uint32 bin_version
Definition: pg_upgrade.h:274
static void check_databases_are_compatible ( void  )
static

Definition at line 398 of file check.c.

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

Referenced by check_new_cluster().

399 {
400  int newdbnum;
401  int olddbnum;
402  DbInfo *newdbinfo;
403  DbInfo *olddbinfo;
404 
405  for (newdbnum = 0; newdbnum < new_cluster.dbarr.ndbs; newdbnum++)
406  {
407  newdbinfo = &new_cluster.dbarr.dbs[newdbnum];
408 
409  /* Find the corresponding database in the old cluster */
410  for (olddbnum = 0; olddbnum < old_cluster.dbarr.ndbs; olddbnum++)
411  {
412  olddbinfo = &old_cluster.dbarr.dbs[olddbnum];
413  if (strcmp(newdbinfo->db_name, olddbinfo->db_name) == 0)
414  {
415  check_locale_and_encoding(olddbinfo, newdbinfo);
416  break;
417  }
418  }
419  }
420 }
ClusterInfo new_cluster
Definition: pg_upgrade.c:56
ClusterInfo old_cluster
Definition: pg_upgrade.c:56
DbInfoArr dbarr
Definition: pg_upgrade.h:263
char * db_name
Definition: pg_upgrade.h:185
DbInfo * dbs
Definition: pg_upgrade.h:196
static void check_locale_and_encoding(DbInfo *olddb, DbInfo *newdb)
Definition: check.c:303
static void check_for_isn_and_int8_passing_mismatch ( ClusterInfo cluster)
static

Definition at line 790 of file check.c.

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

Referenced by check_and_dump_old_cluster().

791 {
792  int dbnum;
793  FILE *script = NULL;
794  bool found = false;
795  char output_path[MAXPGPATH];
796 
797  prep_status("Checking for contrib/isn with bigint-passing mismatch");
798 
801  {
802  /* no mismatch */
803  check_ok();
804  return;
805  }
806 
807  snprintf(output_path, sizeof(output_path),
808  "contrib_isn_and_int8_pass_by_value.txt");
809 
810  for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
811  {
812  PGresult *res;
813  bool db_used = false;
814  int ntups;
815  int rowno;
816  int i_nspname,
817  i_proname;
818  DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
819  PGconn *conn = connectToServer(cluster, active_db->db_name);
820 
821  /* Find any functions coming from contrib/isn */
822  res = executeQueryOrDie(conn,
823  "SELECT n.nspname, p.proname "
824  "FROM pg_catalog.pg_proc p, "
825  " pg_catalog.pg_namespace n "
826  "WHERE p.pronamespace = n.oid AND "
827  " p.probin = '$libdir/isn'");
828 
829  ntups = PQntuples(res);
830  i_nspname = PQfnumber(res, "nspname");
831  i_proname = PQfnumber(res, "proname");
832  for (rowno = 0; rowno < ntups; rowno++)
833  {
834  found = true;
835  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
836  pg_fatal("could not open file \"%s\": %s\n",
837  output_path, strerror(errno));
838  if (!db_used)
839  {
840  fprintf(script, "Database: %s\n", active_db->db_name);
841  db_used = true;
842  }
843  fprintf(script, " %s.%s\n",
844  PQgetvalue(res, rowno, i_nspname),
845  PQgetvalue(res, rowno, i_proname));
846  }
847 
848  PQclear(res);
849 
850  PQfinish(conn);
851  }
852 
853  if (script)
854  fclose(script);
855 
856  if (found)
857  {
858  pg_log(PG_REPORT, "fatal\n");
859  pg_fatal("Your installation contains \"contrib/isn\" functions which rely on the\n"
860  "bigint data type. Your old and new clusters pass bigint values\n"
861  "differently so this cluster cannot currently be upgraded. You can\n"
862  "manually upgrade databases that use \"contrib/isn\" facilities and remove\n"
863  "\"contrib/isn\" from the old cluster and restart the upgrade. A list of\n"
864  "the problem functions is in the file:\n"
865  " %s\n\n", output_path);
866  }
867  else
868  check_ok();
869 }
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3067
ControlData controldata
Definition: pg_upgrade.h:262
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3521
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2673
FILE * fopen_priv(const char *path, const char *mode)
Definition: file.c:321
ClusterInfo new_cluster
Definition: pg_upgrade.c:56
PGconn * conn
Definition: streamutil.c:42
#define MAXPGPATH
void prep_status(const char *fmt,...) pg_attribute_printf(1
ClusterInfo old_cluster
Definition: pg_upgrade.c:56
void pg_log(eLogType type, const char *fmt,...)
Definition: logging.c:69
static void check_ok(void)
Definition: initdb.c:2008
PGconn * connectToServer(ClusterInfo *cluster, const char *db_name)
Definition: server.c:27
int PQfnumber(const PGresult *res, const char *field_name)
Definition: fe-exec.c:2781
void PQclear(PGresult *res)
Definition: fe-exec.c:650
DbInfoArr dbarr
Definition: pg_upgrade.h:263
#define NULL
Definition: c.h:229
const char * strerror(int errnum)
Definition: strerror.c:19
char * db_name
Definition: pg_upgrade.h:185
DbInfo * dbs
Definition: pg_upgrade.h:196
bool float8_pass_by_value
Definition: pg_upgrade.h:226
static void check_for_jsonb_9_4_usage ( ClusterInfo cluster)
static

Definition at line 981 of file check.c.

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

Referenced by check_and_dump_old_cluster().

982 {
983  int dbnum;
984  FILE *script = NULL;
985  bool found = false;
986  char output_path[MAXPGPATH];
987 
988  prep_status("Checking for JSONB user data types");
989 
990  snprintf(output_path, sizeof(output_path), "tables_using_jsonb.txt");
991 
992  for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
993  {
994  PGresult *res;
995  bool db_used = false;
996  int ntups;
997  int rowno;
998  int i_nspname,
999  i_relname,
1000  i_attname;
1001  DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
1002  PGconn *conn = connectToServer(cluster, active_db->db_name);
1003 
1004  /*
1005  * While several relkinds don't store any data, e.g. views, they can
1006  * be used to define data types of other columns, so we check all
1007  * relkinds.
1008  */
1009  res = executeQueryOrDie(conn,
1010  "SELECT n.nspname, c.relname, a.attname "
1011  "FROM pg_catalog.pg_class c, "
1012  " pg_catalog.pg_namespace n, "
1013  " pg_catalog.pg_attribute a "
1014  "WHERE c.oid = a.attrelid AND "
1015  " NOT a.attisdropped AND "
1016  " a.atttypid = 'pg_catalog.jsonb'::pg_catalog.regtype AND "
1017  " c.relnamespace = n.oid AND "
1018  /* exclude possible orphaned temp tables */
1019  " n.nspname !~ '^pg_temp_' AND "
1020  " n.nspname NOT IN ('pg_catalog', 'information_schema')");
1021 
1022  ntups = PQntuples(res);
1023  i_nspname = PQfnumber(res, "nspname");
1024  i_relname = PQfnumber(res, "relname");
1025  i_attname = PQfnumber(res, "attname");
1026  for (rowno = 0; rowno < ntups; rowno++)
1027  {
1028  found = true;
1029  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
1030  pg_fatal("could not open file \"%s\": %s\n",
1031  output_path, strerror(errno));
1032  if (!db_used)
1033  {
1034  fprintf(script, "Database: %s\n", active_db->db_name);
1035  db_used = true;
1036  }
1037  fprintf(script, " %s.%s.%s\n",
1038  PQgetvalue(res, rowno, i_nspname),
1039  PQgetvalue(res, rowno, i_relname),
1040  PQgetvalue(res, rowno, i_attname));
1041  }
1042 
1043  PQclear(res);
1044 
1045  PQfinish(conn);
1046  }
1047 
1048  if (script)
1049  fclose(script);
1050 
1051  if (found)
1052  {
1053  pg_log(PG_REPORT, "fatal\n");
1054  pg_fatal("Your installation contains one of the JSONB data types in user tables.\n"
1055  "The internal format of JSONB changed during 9.4 beta so this cluster cannot currently\n"
1056  "be upgraded. You can remove the problem tables and restart the upgrade. A list\n"
1057  "of the problem columns is in the file:\n"
1058  " %s\n\n", output_path);
1059  }
1060  else
1061  check_ok();
1062 }
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3067
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3521
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2673
FILE * fopen_priv(const char *path, const char *mode)
Definition: file.c:321
PGconn * conn
Definition: streamutil.c:42
#define MAXPGPATH
void prep_status(const char *fmt,...) pg_attribute_printf(1
void pg_log(eLogType type, const char *fmt,...)
Definition: logging.c:69
static void check_ok(void)
Definition: initdb.c:2008
PGconn * connectToServer(ClusterInfo *cluster, const char *db_name)
Definition: server.c:27
int PQfnumber(const PGresult *res, const char *field_name)
Definition: fe-exec.c:2781
void PQclear(PGresult *res)
Definition: fe-exec.c:650
DbInfoArr dbarr
Definition: pg_upgrade.h:263
#define NULL
Definition: c.h:229
const char * strerror(int errnum)
Definition: strerror.c:19
char * db_name
Definition: pg_upgrade.h:185
DbInfo * dbs
Definition: pg_upgrade.h:196
static void check_for_pg_role_prefix ( ClusterInfo cluster)
static

Definition at line 1070 of file check.c.

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

Referenced by check_and_dump_old_cluster().

1071 {
1072  PGresult *res;
1073  PGconn *conn = connectToServer(cluster, "template1");
1074 
1075  prep_status("Checking for roles starting with 'pg_'");
1076 
1077  res = executeQueryOrDie(conn,
1078  "SELECT * "
1079  "FROM pg_catalog.pg_roles "
1080  "WHERE rolname ~ '^pg_'");
1081 
1082  if (PQntuples(res) != 0)
1083  pg_fatal("The %s cluster contains roles starting with 'pg_'\n",
1084  CLUSTER_NAME(cluster));
1085 
1086  PQclear(res);
1087 
1088  PQfinish(conn);
1089 
1090  check_ok();
1091 }
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3521
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2673
PGconn * conn
Definition: streamutil.c:42
#define CLUSTER_NAME(cluster)
Definition: pg_upgrade.h:97
void prep_status(const char *fmt,...) pg_attribute_printf(1
static void check_ok(void)
Definition: initdb.c:2008
PGconn * connectToServer(ClusterInfo *cluster, const char *db_name)
Definition: server.c:27
void PQclear(PGresult *res)
Definition: fe-exec.c:650
static void check_for_prepared_transactions ( ClusterInfo cluster)
static

Definition at line 759 of file check.c.

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

Referenced by check_and_dump_old_cluster(), and check_new_cluster().

760 {
761  PGresult *res;
762  PGconn *conn = connectToServer(cluster, "template1");
763 
764  prep_status("Checking for prepared transactions");
765 
766  res = executeQueryOrDie(conn,
767  "SELECT * "
768  "FROM pg_catalog.pg_prepared_xacts");
769 
770  if (PQntuples(res) != 0)
771  pg_fatal("The %s cluster contains prepared transactions\n",
772  CLUSTER_NAME(cluster));
773 
774  PQclear(res);
775 
776  PQfinish(conn);
777 
778  check_ok();
779 }
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3521
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2673
PGconn * conn
Definition: streamutil.c:42
#define CLUSTER_NAME(cluster)
Definition: pg_upgrade.h:97
void prep_status(const char *fmt,...) pg_attribute_printf(1
static void check_ok(void)
Definition: initdb.c:2008
PGconn * connectToServer(ClusterInfo *cluster, const char *db_name)
Definition: server.c:27
void PQclear(PGresult *res)
Definition: fe-exec.c:650
static void check_for_reg_data_type_usage ( ClusterInfo cluster)
static

Definition at line 884 of file check.c.

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

Referenced by check_and_dump_old_cluster().

885 {
886  int dbnum;
887  FILE *script = NULL;
888  bool found = false;
889  char output_path[MAXPGPATH];
890 
891  prep_status("Checking for reg* system OID user data types");
892 
893  snprintf(output_path, sizeof(output_path), "tables_using_reg.txt");
894 
895  for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
896  {
897  PGresult *res;
898  bool db_used = false;
899  int ntups;
900  int rowno;
901  int i_nspname,
902  i_relname,
903  i_attname;
904  DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
905  PGconn *conn = connectToServer(cluster, active_db->db_name);
906 
907  /*
908  * While several relkinds don't store any data, e.g. views, they can
909  * be used to define data types of other columns, so we check all
910  * relkinds.
911  */
912  res = executeQueryOrDie(conn,
913  "SELECT n.nspname, c.relname, a.attname "
914  "FROM pg_catalog.pg_class c, "
915  " pg_catalog.pg_namespace n, "
916  " pg_catalog.pg_attribute a "
917  "WHERE c.oid = a.attrelid AND "
918  " NOT a.attisdropped AND "
919  " a.atttypid IN ( "
920  " 'pg_catalog.regproc'::pg_catalog.regtype, "
921  " 'pg_catalog.regprocedure'::pg_catalog.regtype, "
922  " 'pg_catalog.regoper'::pg_catalog.regtype, "
923  " 'pg_catalog.regoperator'::pg_catalog.regtype, "
924  /* regclass.oid is preserved, so 'regclass' is OK */
925  /* regtype.oid is preserved, so 'regtype' is OK */
926  " 'pg_catalog.regconfig'::pg_catalog.regtype, "
927  " 'pg_catalog.regdictionary'::pg_catalog.regtype) AND "
928  " c.relnamespace = n.oid AND "
929  " n.nspname NOT IN ('pg_catalog', 'information_schema')");
930 
931  ntups = PQntuples(res);
932  i_nspname = PQfnumber(res, "nspname");
933  i_relname = PQfnumber(res, "relname");
934  i_attname = PQfnumber(res, "attname");
935  for (rowno = 0; rowno < ntups; rowno++)
936  {
937  found = true;
938  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
939  pg_fatal("could not open file \"%s\": %s\n",
940  output_path, strerror(errno));
941  if (!db_used)
942  {
943  fprintf(script, "Database: %s\n", active_db->db_name);
944  db_used = true;
945  }
946  fprintf(script, " %s.%s.%s\n",
947  PQgetvalue(res, rowno, i_nspname),
948  PQgetvalue(res, rowno, i_relname),
949  PQgetvalue(res, rowno, i_attname));
950  }
951 
952  PQclear(res);
953 
954  PQfinish(conn);
955  }
956 
957  if (script)
958  fclose(script);
959 
960  if (found)
961  {
962  pg_log(PG_REPORT, "fatal\n");
963  pg_fatal("Your installation contains one of the reg* data types in user tables.\n"
964  "These data types reference system OIDs that are not preserved by\n"
965  "pg_upgrade, so this cluster cannot currently be upgraded. You can\n"
966  "remove the problem tables and restart the upgrade. A list of the problem\n"
967  "columns is in the file:\n"
968  " %s\n\n", output_path);
969  }
970  else
971  check_ok();
972 }
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3067
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3521
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2673
FILE * fopen_priv(const char *path, const char *mode)
Definition: file.c:321
PGconn * conn
Definition: streamutil.c:42
#define MAXPGPATH
void prep_status(const char *fmt,...) pg_attribute_printf(1
void pg_log(eLogType type, const char *fmt,...)
Definition: logging.c:69
static void check_ok(void)
Definition: initdb.c:2008
PGconn * connectToServer(ClusterInfo *cluster, const char *db_name)
Definition: server.c:27
int PQfnumber(const PGresult *res, const char *field_name)
Definition: fe-exec.c:2781
void PQclear(PGresult *res)
Definition: fe-exec.c:650
DbInfoArr dbarr
Definition: pg_upgrade.h:263
#define NULL
Definition: c.h:229
const char * strerror(int errnum)
Definition: strerror.c:19
char * db_name
Definition: pg_upgrade.h:185
DbInfo * dbs
Definition: pg_upgrade.h:196
static void check_is_install_user ( ClusterInfo cluster)
static

Definition at line 647 of file check.c.

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

Referenced by check_and_dump_old_cluster(), and check_new_cluster().

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

Definition at line 303 of file check.c.

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

Referenced by check_databases_are_compatible().

304 {
305  if (olddb->db_encoding != newdb->db_encoding)
306  pg_fatal("encodings for database \"%s\" do not match: old \"%s\", new \"%s\"\n",
307  olddb->db_name,
310  if (!equivalent_locale(LC_COLLATE, olddb->db_collate, newdb->db_collate))
311  pg_fatal("lc_collate values for database \"%s\" do not match: old \"%s\", new \"%s\"\n",
312  olddb->db_name, olddb->db_collate, newdb->db_collate);
313  if (!equivalent_locale(LC_CTYPE, olddb->db_ctype, newdb->db_ctype))
314  pg_fatal("lc_ctype values for database \"%s\" do not match: old \"%s\", new \"%s\"\n",
315  olddb->db_name, olddb->db_ctype, newdb->db_ctype);
316 }
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
static bool equivalent_locale(int category, const char *loca, const char *locb)
Definition: check.c:330
char * db_ctype
Definition: pg_upgrade.h:189
const char * pg_encoding_to_char(int encoding)
Definition: encnames.c:607
int db_encoding
Definition: pg_upgrade.h:190
char * db_name
Definition: pg_upgrade.h:185
char * db_collate
Definition: pg_upgrade.h:188
void check_new_cluster ( void  )

Definition at line 141 of file check.c.

References check_databases_are_compatible(), 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_LINK, and user_opts.

Referenced by main().

142 {
144 
147 
149 
151  check_hard_link();
152 
154 
156 }
void check_hard_link(void)
Definition: file.c:282
static void check_databases_are_compatible(void)
Definition: check.c:398
void check_loadable_libraries(void)
Definition: function.c:203
static void check_for_prepared_transactions(ClusterInfo *cluster)
Definition: check.c:759
ClusterInfo new_cluster
Definition: pg_upgrade.c:56
static void check_is_install_user(ClusterInfo *cluster)
Definition: check.c:647
transferMode transfer_mode
Definition: pg_upgrade.h:297
UserOpts user_opts
Definition: option.c:29
static void check_new_cluster_is_empty(void)
Definition: check.c:373
void get_db_and_rel_infos(ClusterInfo *cluster)
Definition: info.c:311
static void check_new_cluster_is_empty ( void  )
static

Definition at line 373 of file check.c.

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

Referenced by check_new_cluster().

374 {
375  int dbnum;
376 
377  for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++)
378  {
379  int relnum;
380  RelInfoArr *rel_arr = &new_cluster.dbarr.dbs[dbnum].rel_arr;
381 
382  for (relnum = 0; relnum < rel_arr->nrels;
383  relnum++)
384  {
385  /* pg_largeobject and its index should be skipped */
386  if (strcmp(rel_arr->rels[relnum].nspname, "pg_catalog") != 0)
387  pg_fatal("New cluster database \"%s\" is not empty\n",
388  new_cluster.dbarr.dbs[dbnum].db_name);
389  }
390  }
391 }
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
char * nspname
Definition: pg_upgrade.h:139
ClusterInfo new_cluster
Definition: pg_upgrade.c:56
RelInfo * rels
Definition: pg_upgrade.h:152
DbInfoArr dbarr
Definition: pg_upgrade.h:263
RelInfoArr rel_arr
Definition: pg_upgrade.h:191
char * db_name
Definition: pg_upgrade.h:185
DbInfo * dbs
Definition: pg_upgrade.h:196
static void check_proper_datallowconn ( ClusterInfo cluster)
static

Definition at line 698 of file check.c.

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

Referenced by check_and_dump_old_cluster().

699 {
700  int dbnum;
701  PGconn *conn_template1;
702  PGresult *dbres;
703  int ntups;
704  int i_datname;
705  int i_datallowconn;
706 
707  prep_status("Checking database connection settings");
708 
709  conn_template1 = connectToServer(cluster, "template1");
710 
711  /* get database names */
712  dbres = executeQueryOrDie(conn_template1,
713  "SELECT datname, datallowconn "
714  "FROM pg_catalog.pg_database");
715 
716  i_datname = PQfnumber(dbres, "datname");
717  i_datallowconn = PQfnumber(dbres, "datallowconn");
718 
719  ntups = PQntuples(dbres);
720  for (dbnum = 0; dbnum < ntups; dbnum++)
721  {
722  char *datname = PQgetvalue(dbres, dbnum, i_datname);
723  char *datallowconn = PQgetvalue(dbres, dbnum, i_datallowconn);
724 
725  if (strcmp(datname, "template0") == 0)
726  {
727  /* avoid restore failure when pg_dumpall tries to create template0 */
728  if (strcmp(datallowconn, "t") == 0)
729  pg_fatal("template0 must not allow connections, "
730  "i.e. its pg_database.datallowconn must be false\n");
731  }
732  else
733  {
734  /*
735  * avoid datallowconn == false databases from being skipped on
736  * restore
737  */
738  if (strcmp(datallowconn, "f") == 0)
739  pg_fatal("All non-template0 databases must allow connections, "
740  "i.e. their pg_database.datallowconn must be true\n");
741  }
742  }
743 
744  PQclear(dbres);
745 
746  PQfinish(conn_template1);
747 
748  check_ok();
749 }
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3067
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3521
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2673
void prep_status(const char *fmt,...) pg_attribute_printf(1
static void check_ok(void)
Definition: initdb.c:2008
PGconn * connectToServer(ClusterInfo *cluster, const char *db_name)
Definition: server.c:27
int PQfnumber(const PGresult *res, const char *field_name)
Definition: fe-exec.c:2781
void PQclear(PGresult *res)
Definition: fe-exec.c:650
void create_script_for_cluster_analyze ( char **  analyze_script_file_name)

Definition at line 429 of file check.c.

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

Referenced by main().

430 {
431  FILE *script = NULL;
432  PQExpBufferData user_specification;
433 
434  prep_status("Creating script to analyze new cluster");
435 
436  initPQExpBuffer(&user_specification);
438  {
439  appendPQExpBufferStr(&user_specification, "-U ");
440  appendShellString(&user_specification, os_info.user);
441  appendPQExpBufferChar(&user_specification, ' ');
442  }
443 
444  *analyze_script_file_name = psprintf("%sanalyze_new_cluster.%s",
446 
447  if ((script = fopen_priv(*analyze_script_file_name, "w")) == NULL)
448  pg_fatal("could not open file \"%s\": %s\n",
449  *analyze_script_file_name, strerror(errno));
450 
451 #ifndef WIN32
452  /* add shebang header */
453  fprintf(script, "#!/bin/sh\n\n");
454 #else
455  /* suppress command echoing */
456  fprintf(script, "@echo off\n");
457 #endif
458 
459  fprintf(script, "echo %sThis script will generate minimal optimizer statistics rapidly%s\n",
461  fprintf(script, "echo %sso your system is usable, and then gather statistics twice more%s\n",
463  fprintf(script, "echo %swith increasing accuracy. When it is done, your system will%s\n",
465  fprintf(script, "echo %shave the default level of optimizer statistics.%s\n",
467  fprintf(script, "echo%s\n\n", ECHO_BLANK);
468 
469  fprintf(script, "echo %sIf you have used ALTER TABLE to modify the statistics target for%s\n",
471  fprintf(script, "echo %sany tables, you might want to remove them and restore them after%s\n",
473  fprintf(script, "echo %srunning this script because they will delay fast statistics generation.%s\n",
475  fprintf(script, "echo%s\n\n", ECHO_BLANK);
476 
477  fprintf(script, "echo %sIf you would like default statistics as quickly as possible, cancel%s\n",
479  fprintf(script, "echo %sthis script and run:%s\n",
481  fprintf(script, "echo %s \"%s/vacuumdb\" %s--all %s%s\n", ECHO_QUOTE,
482  new_cluster.bindir, user_specification.data,
483  /* Did we copy the free space files? */
485  "--analyze-only" : "--analyze", ECHO_QUOTE);
486  fprintf(script, "echo%s\n\n", ECHO_BLANK);
487 
488  fprintf(script, "\"%s/vacuumdb\" %s--all --analyze-in-stages\n",
489  new_cluster.bindir, user_specification.data);
490  /* Did we copy the free space files? */
492  fprintf(script, "\"%s/vacuumdb\" %s--all\n", new_cluster.bindir,
493  user_specification.data);
494 
495  fprintf(script, "echo%s\n\n", ECHO_BLANK);
496  fprintf(script, "echo %sDone%s\n",
498 
499  fclose(script);
500 
501 #ifndef WIN32
502  if (chmod(*analyze_script_file_name, S_IRWXU) != 0)
503  pg_fatal("could not add execute permission to file \"%s\": %s\n",
504  *analyze_script_file_name, strerror(errno));
505 #endif
506 
507  termPQExpBuffer(&user_specification);
508 
509  check_ok();
510 }
uint32 major_version
Definition: pg_upgrade.h:272
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:385
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
#define SCRIPT_EXT
Definition: pg_upgrade.h:80
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:29
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
FILE * fopen_priv(const char *path, const char *mode)
Definition: file.c:321
bool user_specified
Definition: pg_upgrade.h:310
ClusterInfo new_cluster
Definition: pg_upgrade.c:56
void prep_status(const char *fmt,...) pg_attribute_printf(1
ClusterInfo old_cluster
Definition: pg_upgrade.c:56
static void check_ok(void)
Definition: initdb.c:2008
char * bindir
Definition: pg_upgrade.h:267
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:396
void appendShellString(PQExpBuffer buf, const char *str)
Definition: string_utils.c:434
#define NULL
Definition: c.h:229
#define ECHO_BLANK
Definition: pg_upgrade.h:82
#define SCRIPT_PREFIX
Definition: pg_upgrade.h:79
const char * strerror(int errnum)
Definition: strerror.c:19
OSInfo os_info
Definition: pg_upgrade.c:58
#define ECHO_QUOTE
Definition: pg_upgrade.h:81
char * user
Definition: pg_upgrade.h:309
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
void create_script_for_old_cluster_deletion ( char **  deletion_script_file_name)

Definition at line 519 of file check.c.

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

Referenced by main().

520 {
521  FILE *script = NULL;
522  int tblnum;
523  char old_cluster_pgdata[MAXPGPATH],
524  new_cluster_pgdata[MAXPGPATH];
525 
526  *deletion_script_file_name = psprintf("%sdelete_old_cluster.%s",
528 
529  strlcpy(old_cluster_pgdata, old_cluster.pgdata, MAXPGPATH);
530  canonicalize_path(old_cluster_pgdata);
531 
532  strlcpy(new_cluster_pgdata, new_cluster.pgdata, MAXPGPATH);
533  canonicalize_path(new_cluster_pgdata);
534 
535  /* Some people put the new data directory inside the old one. */
536  if (path_is_prefix_of_path(old_cluster_pgdata, new_cluster_pgdata))
537  {
539  "\nWARNING: new data directory should not be inside the old data directory, e.g. %s\n", old_cluster_pgdata);
540 
541  /* Unlink file in case it is left over from a previous run. */
542  unlink(*deletion_script_file_name);
543  pg_free(*deletion_script_file_name);
544  *deletion_script_file_name = NULL;
545  return;
546  }
547 
548  /*
549  * Some users (oddly) create tablespaces inside the cluster data
550  * directory. We can't create a proper old cluster delete script in that
551  * case.
552  */
553  for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
554  {
555  char old_tablespace_dir[MAXPGPATH];
556 
557  strlcpy(old_tablespace_dir, os_info.old_tablespaces[tblnum], MAXPGPATH);
558  canonicalize_path(old_tablespace_dir);
559  if (path_is_prefix_of_path(old_cluster_pgdata, old_tablespace_dir))
560  {
561  /* reproduce warning from CREATE TABLESPACE that is in the log */
563  "\nWARNING: user-defined tablespace locations should not be inside the data directory, e.g. %s\n", old_tablespace_dir);
564 
565  /* Unlink file in case it is left over from a previous run. */
566  unlink(*deletion_script_file_name);
567  pg_free(*deletion_script_file_name);
568  *deletion_script_file_name = NULL;
569  return;
570  }
571  }
572 
573  prep_status("Creating script to delete old cluster");
574 
575  if ((script = fopen_priv(*deletion_script_file_name, "w")) == NULL)
576  pg_fatal("could not open file \"%s\": %s\n",
577  *deletion_script_file_name, strerror(errno));
578 
579 #ifndef WIN32
580  /* add shebang header */
581  fprintf(script, "#!/bin/sh\n\n");
582 #endif
583 
584  /* delete old cluster's default tablespace */
585  fprintf(script, RMDIR_CMD " %c%s%c\n", PATH_QUOTE,
587 
588  /* delete old cluster's alternate tablespaces */
589  for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
590  {
591  /*
592  * Do the old cluster's per-database directories share a directory
593  * with a new version-specific tablespace?
594  */
595  if (strlen(old_cluster.tablespace_suffix) == 0)
596  {
597  /* delete per-database directories */
598  int dbnum;
599 
600  fprintf(script, "\n");
601  /* remove PG_VERSION? */
603  fprintf(script, RM_CMD " %s%cPG_VERSION\n",
606 
607  for (dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
608  fprintf(script, RMDIR_CMD " %c%s%c%d%c\n", PATH_QUOTE,
611  PATH_QUOTE);
612  }
613  else
614  {
615  char *suffix_path = pg_strdup(old_cluster.tablespace_suffix);
616 
617  /*
618  * Simply delete the tablespace directory, which might be ".old"
619  * or a version-specific subdirectory.
620  */
621  fprintf(script, RMDIR_CMD " %c%s%s%c\n", PATH_QUOTE,
623  fix_path_separator(suffix_path), PATH_QUOTE);
624  pfree(suffix_path);
625  }
626  }
627 
628  fclose(script);
629 
630 #ifndef WIN32
631  if (chmod(*deletion_script_file_name, S_IRWXU) != 0)
632  pg_fatal("could not add execute permission to file \"%s\": %s\n",
633  *deletion_script_file_name, strerror(errno));
634 #endif
635 
636  check_ok();
637 }
uint32 major_version
Definition: pg_upgrade.h:272
bool path_is_prefix_of_path(const char *path1, const char *path2)
Definition: path.c:438
#define PATH_SEPARATOR
Definition: pg_upgrade.h:75
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
#define SCRIPT_EXT
Definition: pg_upgrade.h:80
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:29
void canonicalize_path(char *path)
Definition: path.c:254
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
FILE * fopen_priv(const char *path, const char *mode)
Definition: file.c:321
Oid db_oid
Definition: pg_upgrade.h:184
ClusterInfo new_cluster
Definition: pg_upgrade.c:56
void pfree(void *pointer)
Definition: mcxt.c:950
#define MAXPGPATH
#define RMDIR_CMD
Definition: pg_upgrade.h:78
void prep_status(const char *fmt,...) pg_attribute_printf(1
ClusterInfo old_cluster
Definition: pg_upgrade.c:56
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
void pg_log(eLogType type, const char *fmt,...)
Definition: logging.c:69
static void check_ok(void)
Definition: initdb.c:2008
int unlink(const char *filename)
char ** old_tablespaces
Definition: pg_upgrade.h:311
const char * tablespace_suffix
Definition: pg_upgrade.h:275
DbInfoArr dbarr
Definition: pg_upgrade.h:263
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
#define NULL
Definition: c.h:229
void pg_free(void *ptr)
Definition: fe_memutils.c:105
#define SCRIPT_PREFIX
Definition: pg_upgrade.h:79
#define PATH_QUOTE
Definition: pg_upgrade.h:76
char * pgdata
Definition: pg_upgrade.h:264
int num_old_tablespaces
Definition: pg_upgrade.h:312
const char * strerror(int errnum)
Definition: strerror.c:19
OSInfo os_info
Definition: pg_upgrade.c:58
DbInfo * dbs
Definition: pg_upgrade.h:196
#define RM_CMD
Definition: pg_upgrade.h:77
static char * fix_path_separator(char *path)
Definition: check.c:40
static bool equivalent_locale ( int  category,
const char *  loca,
const char *  locb 
)
static

Definition at line 330 of file check.c.

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

Referenced by check_locale_and_encoding().

331 {
332  const char *chara;
333  const char *charb;
334  char *canona;
335  char *canonb;
336  int lena;
337  int lenb;
338 
339  /*
340  * If the names are equal, the locales are equivalent. Checking this first
341  * avoids calling setlocale() in the common case that the names are equal.
342  * That's a good thing, if setlocale() is buggy, for example.
343  */
344  if (pg_strcasecmp(loca, locb) == 0)
345  return true;
346 
347  /*
348  * Not identical. Canonicalize both names, remove the encoding parts, and
349  * try again.
350  */
351  canona = get_canonical_locale_name(category, loca);
352  chara = strrchr(canona, '.');
353  lena = chara ? (chara - canona) : strlen(canona);
354 
355  canonb = get_canonical_locale_name(category, locb);
356  charb = strrchr(canonb, '.');
357  lenb = charb ? (charb - canonb) : strlen(canonb);
358 
359  if (lena == lenb && pg_strncasecmp(canona, canonb, lena) == 0)
360  {
361  pg_free(canona);
362  pg_free(canonb);
363  return true;
364  }
365 
366  pg_free(canona);
367  pg_free(canonb);
368  return false;
369 }
static char * get_canonical_locale_name(int category, const char *locale)
Definition: check.c:1101
int pg_strcasecmp(const char *s1, const char *s2)
Definition: pgstrcasecmp.c:36
int pg_strncasecmp(const char *s1, const char *s2, size_t n)
Definition: pgstrcasecmp.c:69
void pg_free(void *ptr)
Definition: fe_memutils.c:105
static char* fix_path_separator ( char *  path)
static

Definition at line 40 of file check.c.

References pg_strdup(), and result.

Referenced by create_script_for_old_cluster_deletion().

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

Definition at line 1101 of file check.c.

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

Referenced by equivalent_locale().

1102 {
1103  char *save;
1104  char *res;
1105 
1106  /* get the current setting, so we can restore it. */
1107  save = setlocale(category, NULL);
1108  if (!save)
1109  pg_fatal("failed to get the current locale\n");
1110 
1111  /* 'save' may be pointing at a modifiable scratch variable, so copy it. */
1112  save = pg_strdup(save);
1113 
1114  /* set the locale with setlocale, to see if it accepts it. */
1115  res = setlocale(category, locale);
1116 
1117  if (!res)
1118  pg_fatal("failed to get system locale name for \"%s\"\n", locale);
1119 
1120  res = pg_strdup(res);
1121 
1122  /* restore old value. */
1123  if (!setlocale(category, save))
1124  pg_fatal("failed to restore old locale \"%s\"\n", save);
1125 
1126  pg_free(save);
1127 
1128  return res;
1129 }
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
#define NULL
Definition: c.h:229
void pg_free(void *ptr)
Definition: fe_memutils.c:105
static char * locale
Definition: initdb.c:123
void issue_warnings ( void  )

Definition at line 177 of file check.c.

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

Referenced by main().

178 {
179  /* Create dummy large object permissions for old < PG 9.0? */
181  {
184  stop_postmaster(false);
185  }
186 
187  /* Reindex hash indexes for old < 10.0 */
189  {
192  stop_postmaster(false);
193  }
194 }
uint32 major_version
Definition: pg_upgrade.h:272
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:29
void old_9_6_invalidate_hash_indexes(ClusterInfo *cluster, bool check_mode)
Definition: version.c:297
void stop_postmaster(bool fast)
Definition: server.c:308
ClusterInfo new_cluster
Definition: pg_upgrade.c:56
void new_9_0_populate_pg_largeobject_metadata(ClusterInfo *cluster, bool check_mode)
Definition: version.c:25
ClusterInfo old_cluster
Definition: pg_upgrade.c:56
static pgpid_t start_postmaster(void)
Definition: pg_ctl.c:428
void output_check_banner ( bool  live_check)

Definition at line 61 of file check.c.

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

Referenced by main().

62 {
63  if (user_opts.check && live_check)
64  {
65  pg_log(PG_REPORT, "Performing Consistency Checks on Old Live Server\n");
66  pg_log(PG_REPORT, "------------------------------------------------\n");
67  }
68  else
69  {
70  pg_log(PG_REPORT, "Performing Consistency Checks\n");
71  pg_log(PG_REPORT, "-----------------------------\n");
72  }
73 }
void pg_log(eLogType type, const char *fmt,...)
Definition: logging.c:69
UserOpts user_opts
Definition: option.c:29
bool check
Definition: pg_upgrade.h:295
void output_completion_banner ( char *  analyze_script_file_name,
char *  deletion_script_file_name 
)

Definition at line 198 of file check.c.

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

Referenced by main().

200 {
201  /* Did we copy the free space files? */
204  "Optimizer statistics are not transferred by pg_upgrade so,\n"
205  "once you start the new server, consider running:\n"
206  " %s\n\n", analyze_script_file_name);
207  else
209  "Optimizer statistics and free space information are not transferred\n"
210  "by pg_upgrade so, once you start the new server, consider running:\n"
211  " %s\n\n", analyze_script_file_name);
212 
213 
214  if (deletion_script_file_name)
216  "Running this script will delete the old cluster's data files:\n"
217  " %s\n",
218  deletion_script_file_name);
219  else
221  "Could not create a script to delete the old cluster's data files\n"
222  "because user-defined tablespaces or the new cluster's data directory\n"
223  "exist in the old cluster directory. The old cluster's contents must\n"
224  "be deleted manually.\n");
225 }
uint32 major_version
Definition: pg_upgrade.h:272
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:29
ClusterInfo old_cluster
Definition: pg_upgrade.c:56
void pg_log(eLogType type, const char *fmt,...)
Definition: logging.c:69
void report_clusters_compatible ( void  )

Definition at line 160 of file check.c.

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

Referenced by main().

161 {
162  if (user_opts.check)
163  {
164  pg_log(PG_REPORT, "\n*Clusters are compatible*\n");
165  /* stops new cluster */
166  stop_postmaster(false);
167  exit(0);
168  }
169 
170  pg_log(PG_REPORT, "\n"
171  "If pg_upgrade fails after this point, you must re-initdb the\n"
172  "new cluster before continuing.\n");
173 }
void stop_postmaster(bool fast)
Definition: server.c:308
void pg_log(eLogType type, const char *fmt,...)
Definition: logging.c:69
UserOpts user_opts
Definition: option.c:29
bool check
Definition: pg_upgrade.h:295