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_and_set_wal_level (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:886
static void check_for_prepared_transactions(ClusterInfo *cluster)
Definition: check.c:761
void stop_postmaster(bool fast)
Definition: server.c:308
static void check_proper_datallowconn(ClusterInfo *cluster)
Definition: check.c:700
static void check_for_pg_role_prefix(ClusterInfo *cluster)
Definition: check.c:1072
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:649
static void check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster)
Definition: check.c:792
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:431
static void check_for_jsonb_9_4_usage(ClusterInfo *cluster)
Definition: check.c:983
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 273 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().

274 {
275  /* get/check pg_control data of servers */
276  get_control_data(&old_cluster, live_check);
277  get_control_data(&new_cluster, false);
279 
280  /* Is it 9.0 but without tablespace directories? */
283  pg_fatal("This utility can only upgrade to PostgreSQL version 9.0 after 2010-01-11\n"
284  "because of backend API changes made during development.\n");
285 
286  /* We read the real port number for PG >= 9.1 */
287  if (live_check && GET_MAJOR_VERSION(old_cluster.major_version) < 901 &&
289  pg_fatal("When checking a pre-PG 9.1 live old server, "
290  "you must specify the old server's port number.\n");
291 
292  if (live_check && old_cluster.port == new_cluster.port)
293  pg_fatal("When checking a live server, "
294  "the old and new port numbers must be different.\n");
295 }
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 231 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().

232 {
233  prep_status("Checking cluster versions");
234 
235  /* get old and new cluster versions */
238 
239  /*
240  * We allow upgrades from/to the same major version for alpha/beta
241  * upgrades
242  */
243 
245  pg_fatal("This utility can only upgrade from PostgreSQL version 8.4 and later.\n");
246 
247  /* Only current PG version is supported as a target */
249  pg_fatal("This utility can only upgrade to PostgreSQL version %s.\n",
250  PG_MAJORVERSION);
251 
252  /*
253  * We can't allow downgrading because we use the target pg_dump, and
254  * pg_dump cannot operate on newer database versions, only current and
255  * older versions.
256  */
258  pg_fatal("This utility cannot be used to downgrade to older major PostgreSQL versions.\n");
259 
260  /* Ensure binaries match the designated data directories */
263  pg_fatal("Old cluster data and binary directories are from different major versions.\n");
266  pg_fatal("New cluster data and binary directories are from different major versions.\n");
267 
268  check_ok();
269 }
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:2023
uint32 bin_version
Definition: pg_upgrade.h:274
static void check_databases_are_compatible ( void  )
static

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

401 {
402  int newdbnum;
403  int olddbnum;
404  DbInfo *newdbinfo;
405  DbInfo *olddbinfo;
406 
407  for (newdbnum = 0; newdbnum < new_cluster.dbarr.ndbs; newdbnum++)
408  {
409  newdbinfo = &new_cluster.dbarr.dbs[newdbnum];
410 
411  /* Find the corresponding database in the old cluster */
412  for (olddbnum = 0; olddbnum < old_cluster.dbarr.ndbs; olddbnum++)
413  {
414  olddbinfo = &old_cluster.dbarr.dbs[olddbnum];
415  if (strcmp(newdbinfo->db_name, olddbinfo->db_name) == 0)
416  {
417  check_locale_and_encoding(olddbinfo, newdbinfo);
418  break;
419  }
420  }
421  }
422 }
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:305
static void check_for_isn_and_int8_passing_mismatch ( ClusterInfo cluster)
static

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

793 {
794  int dbnum;
795  FILE *script = NULL;
796  bool found = false;
797  char output_path[MAXPGPATH];
798 
799  prep_status("Checking for contrib/isn with bigint-passing mismatch");
800 
803  {
804  /* no mismatch */
805  check_ok();
806  return;
807  }
808 
809  snprintf(output_path, sizeof(output_path),
810  "contrib_isn_and_int8_pass_by_value.txt");
811 
812  for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
813  {
814  PGresult *res;
815  bool db_used = false;
816  int ntups;
817  int rowno;
818  int i_nspname,
819  i_proname;
820  DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
821  PGconn *conn = connectToServer(cluster, active_db->db_name);
822 
823  /* Find any functions coming from contrib/isn */
824  res = executeQueryOrDie(conn,
825  "SELECT n.nspname, p.proname "
826  "FROM pg_catalog.pg_proc p, "
827  " pg_catalog.pg_namespace n "
828  "WHERE p.pronamespace = n.oid AND "
829  " p.probin = '$libdir/isn'");
830 
831  ntups = PQntuples(res);
832  i_nspname = PQfnumber(res, "nspname");
833  i_proname = PQfnumber(res, "proname");
834  for (rowno = 0; rowno < ntups; rowno++)
835  {
836  found = true;
837  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
838  pg_fatal("could not open file \"%s\": %s\n",
839  output_path, strerror(errno));
840  if (!db_used)
841  {
842  fprintf(script, "Database: %s\n", active_db->db_name);
843  db_used = true;
844  }
845  fprintf(script, " %s.%s\n",
846  PQgetvalue(res, rowno, i_nspname),
847  PQgetvalue(res, rowno, i_proname));
848  }
849 
850  PQclear(res);
851 
852  PQfinish(conn);
853  }
854 
855  if (script)
856  fclose(script);
857 
858  if (found)
859  {
860  pg_log(PG_REPORT, "fatal\n");
861  pg_fatal("Your installation contains \"contrib/isn\" functions which rely on the\n"
862  "bigint data type. Your old and new clusters pass bigint values\n"
863  "differently so this cluster cannot currently be upgraded. You can\n"
864  "manually upgrade databases that use \"contrib/isn\" facilities and remove\n"
865  "\"contrib/isn\" from the old cluster and restart the upgrade. A list of\n"
866  "the problem functions is in the file:\n"
867  " %s\n\n", output_path);
868  }
869  else
870  check_ok();
871 }
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:3556
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:2023
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 983 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().

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

1073 {
1074  PGresult *res;
1075  PGconn *conn = connectToServer(cluster, "template1");
1076 
1077  prep_status("Checking for roles starting with 'pg_'");
1078 
1079  res = executeQueryOrDie(conn,
1080  "SELECT * "
1081  "FROM pg_catalog.pg_roles "
1082  "WHERE rolname ~ '^pg_'");
1083 
1084  if (PQntuples(res) != 0)
1085  pg_fatal("The %s cluster contains roles starting with 'pg_'\n",
1086  CLUSTER_NAME(cluster));
1087 
1088  PQclear(res);
1089 
1090  PQfinish(conn);
1091 
1092  check_ok();
1093 }
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3556
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:2023
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 761 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().

762 {
763  PGresult *res;
764  PGconn *conn = connectToServer(cluster, "template1");
765 
766  prep_status("Checking for prepared transactions");
767 
768  res = executeQueryOrDie(conn,
769  "SELECT * "
770  "FROM pg_catalog.pg_prepared_xacts");
771 
772  if (PQntuples(res) != 0)
773  pg_fatal("The %s cluster contains prepared transactions\n",
774  CLUSTER_NAME(cluster));
775 
776  PQclear(res);
777 
778  PQfinish(conn);
779 
780  check_ok();
781 }
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3556
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:2023
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 886 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().

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

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

306 {
307  if (olddb->db_encoding != newdb->db_encoding)
308  pg_fatal("encodings for database \"%s\" do not match: old \"%s\", new \"%s\"\n",
309  olddb->db_name,
312  if (!equivalent_locale(LC_COLLATE, olddb->db_collate, newdb->db_collate))
313  pg_fatal("lc_collate values for database \"%s\" do not match: old \"%s\", new \"%s\"\n",
314  olddb->db_name, olddb->db_collate, newdb->db_collate);
315  if (!equivalent_locale(LC_CTYPE, olddb->db_ctype, newdb->db_ctype))
316  pg_fatal("lc_ctype values for database \"%s\" do not match: old \"%s\", new \"%s\"\n",
317  olddb->db_name, olddb->db_ctype, newdb->db_ctype);
318 }
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:332
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:400
void check_loadable_libraries(void)
Definition: function.c:203
static void check_for_prepared_transactions(ClusterInfo *cluster)
Definition: check.c:761
ClusterInfo new_cluster
Definition: pg_upgrade.c:56
static void check_is_install_user(ClusterInfo *cluster)
Definition: check.c:649
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:375
void get_db_and_rel_infos(ClusterInfo *cluster)
Definition: info.c:311
static void check_new_cluster_is_empty ( void  )
static

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

376 {
377  int dbnum;
378 
379  for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++)
380  {
381  int relnum;
382  RelInfoArr *rel_arr = &new_cluster.dbarr.dbs[dbnum].rel_arr;
383 
384  for (relnum = 0; relnum < rel_arr->nrels;
385  relnum++)
386  {
387  /* pg_largeobject and its index should be skipped */
388  if (strcmp(rel_arr->rels[relnum].nspname, "pg_catalog") != 0)
389  pg_fatal("New cluster database \"%s\" is not empty\n",
390  new_cluster.dbarr.dbs[dbnum].db_name);
391  }
392  }
393 }
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 700 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().

701 {
702  int dbnum;
703  PGconn *conn_template1;
704  PGresult *dbres;
705  int ntups;
706  int i_datname;
707  int i_datallowconn;
708 
709  prep_status("Checking database connection settings");
710 
711  conn_template1 = connectToServer(cluster, "template1");
712 
713  /* get database names */
714  dbres = executeQueryOrDie(conn_template1,
715  "SELECT datname, datallowconn "
716  "FROM pg_catalog.pg_database");
717 
718  i_datname = PQfnumber(dbres, "datname");
719  i_datallowconn = PQfnumber(dbres, "datallowconn");
720 
721  ntups = PQntuples(dbres);
722  for (dbnum = 0; dbnum < ntups; dbnum++)
723  {
724  char *datname = PQgetvalue(dbres, dbnum, i_datname);
725  char *datallowconn = PQgetvalue(dbres, dbnum, i_datallowconn);
726 
727  if (strcmp(datname, "template0") == 0)
728  {
729  /* avoid restore failure when pg_dumpall tries to create template0 */
730  if (strcmp(datallowconn, "t") == 0)
731  pg_fatal("template0 must not allow connections, "
732  "i.e. its pg_database.datallowconn must be false\n");
733  }
734  else
735  {
736  /*
737  * avoid datallowconn == false databases from being skipped on
738  * restore
739  */
740  if (strcmp(datallowconn, "f") == 0)
741  pg_fatal("All non-template0 databases must allow connections, "
742  "i.e. their pg_database.datallowconn must be true\n");
743  }
744  }
745 
746  PQclear(dbres);
747 
748  PQfinish(conn_template1);
749 
750  check_ok();
751 }
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:3556
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:2023
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 431 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().

432 {
433  FILE *script = NULL;
434  PQExpBufferData user_specification;
435 
436  prep_status("Creating script to analyze new cluster");
437 
438  initPQExpBuffer(&user_specification);
440  {
441  appendPQExpBufferStr(&user_specification, "-U ");
442  appendShellString(&user_specification, os_info.user);
443  appendPQExpBufferChar(&user_specification, ' ');
444  }
445 
446  *analyze_script_file_name = psprintf("%sanalyze_new_cluster.%s",
448 
449  if ((script = fopen_priv(*analyze_script_file_name, "w")) == NULL)
450  pg_fatal("could not open file \"%s\": %s\n",
451  *analyze_script_file_name, strerror(errno));
452 
453 #ifndef WIN32
454  /* add shebang header */
455  fprintf(script, "#!/bin/sh\n\n");
456 #else
457  /* suppress command echoing */
458  fprintf(script, "@echo off\n");
459 #endif
460 
461  fprintf(script, "echo %sThis script will generate minimal optimizer statistics rapidly%s\n",
463  fprintf(script, "echo %sso your system is usable, and then gather statistics twice more%s\n",
465  fprintf(script, "echo %swith increasing accuracy. When it is done, your system will%s\n",
467  fprintf(script, "echo %shave the default level of optimizer statistics.%s\n",
469  fprintf(script, "echo%s\n\n", ECHO_BLANK);
470 
471  fprintf(script, "echo %sIf you have used ALTER TABLE to modify the statistics target for%s\n",
473  fprintf(script, "echo %sany tables, you might want to remove them and restore them after%s\n",
475  fprintf(script, "echo %srunning this script because they will delay fast statistics generation.%s\n",
477  fprintf(script, "echo%s\n\n", ECHO_BLANK);
478 
479  fprintf(script, "echo %sIf you would like default statistics as quickly as possible, cancel%s\n",
481  fprintf(script, "echo %sthis script and run:%s\n",
483  fprintf(script, "echo %s \"%s/vacuumdb\" %s--all %s%s\n", ECHO_QUOTE,
484  new_cluster.bindir, user_specification.data,
485  /* Did we copy the free space files? */
487  "--analyze-only" : "--analyze", ECHO_QUOTE);
488  fprintf(script, "echo%s\n\n", ECHO_BLANK);
489 
490  fprintf(script, "\"%s/vacuumdb\" %s--all --analyze-in-stages\n",
491  new_cluster.bindir, user_specification.data);
492  /* Did we copy the free space files? */
494  fprintf(script, "\"%s/vacuumdb\" %s--all\n", new_cluster.bindir,
495  user_specification.data);
496 
497  fprintf(script, "echo%s\n\n", ECHO_BLANK);
498  fprintf(script, "echo %sDone%s\n",
500 
501  fclose(script);
502 
503 #ifndef WIN32
504  if (chmod(*analyze_script_file_name, S_IRWXU) != 0)
505  pg_fatal("could not add execute permission to file \"%s\": %s\n",
506  *analyze_script_file_name, strerror(errno));
507 #endif
508 
509  termPQExpBuffer(&user_specification);
510 
511  check_ok();
512 }
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:2023
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 521 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().

522 {
523  FILE *script = NULL;
524  int tblnum;
525  char old_cluster_pgdata[MAXPGPATH],
526  new_cluster_pgdata[MAXPGPATH];
527 
528  *deletion_script_file_name = psprintf("%sdelete_old_cluster.%s",
530 
531  strlcpy(old_cluster_pgdata, old_cluster.pgdata, MAXPGPATH);
532  canonicalize_path(old_cluster_pgdata);
533 
534  strlcpy(new_cluster_pgdata, new_cluster.pgdata, MAXPGPATH);
535  canonicalize_path(new_cluster_pgdata);
536 
537  /* Some people put the new data directory inside the old one. */
538  if (path_is_prefix_of_path(old_cluster_pgdata, new_cluster_pgdata))
539  {
541  "\nWARNING: new data directory should not be inside the old data directory, e.g. %s\n", old_cluster_pgdata);
542 
543  /* Unlink file in case it is left over from a previous run. */
544  unlink(*deletion_script_file_name);
545  pg_free(*deletion_script_file_name);
546  *deletion_script_file_name = NULL;
547  return;
548  }
549 
550  /*
551  * Some users (oddly) create tablespaces inside the cluster data
552  * directory. We can't create a proper old cluster delete script in that
553  * case.
554  */
555  for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
556  {
557  char old_tablespace_dir[MAXPGPATH];
558 
559  strlcpy(old_tablespace_dir, os_info.old_tablespaces[tblnum], MAXPGPATH);
560  canonicalize_path(old_tablespace_dir);
561  if (path_is_prefix_of_path(old_cluster_pgdata, old_tablespace_dir))
562  {
563  /* reproduce warning from CREATE TABLESPACE that is in the log */
565  "\nWARNING: user-defined tablespace locations should not be inside the data directory, e.g. %s\n", old_tablespace_dir);
566 
567  /* Unlink file in case it is left over from a previous run. */
568  unlink(*deletion_script_file_name);
569  pg_free(*deletion_script_file_name);
570  *deletion_script_file_name = NULL;
571  return;
572  }
573  }
574 
575  prep_status("Creating script to delete old cluster");
576 
577  if ((script = fopen_priv(*deletion_script_file_name, "w")) == NULL)
578  pg_fatal("could not open file \"%s\": %s\n",
579  *deletion_script_file_name, strerror(errno));
580 
581 #ifndef WIN32
582  /* add shebang header */
583  fprintf(script, "#!/bin/sh\n\n");
584 #endif
585 
586  /* delete old cluster's default tablespace */
587  fprintf(script, RMDIR_CMD " %c%s%c\n", PATH_QUOTE,
589 
590  /* delete old cluster's alternate tablespaces */
591  for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
592  {
593  /*
594  * Do the old cluster's per-database directories share a directory
595  * with a new version-specific tablespace?
596  */
597  if (strlen(old_cluster.tablespace_suffix) == 0)
598  {
599  /* delete per-database directories */
600  int dbnum;
601 
602  fprintf(script, "\n");
603  /* remove PG_VERSION? */
605  fprintf(script, RM_CMD " %s%cPG_VERSION\n",
608 
609  for (dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
610  fprintf(script, RMDIR_CMD " %c%s%c%d%c\n", PATH_QUOTE,
613  PATH_QUOTE);
614  }
615  else
616  {
617  char *suffix_path = pg_strdup(old_cluster.tablespace_suffix);
618 
619  /*
620  * Simply delete the tablespace directory, which might be ".old"
621  * or a version-specific subdirectory.
622  */
623  fprintf(script, RMDIR_CMD " %c%s%s%c\n", PATH_QUOTE,
625  fix_path_separator(suffix_path), PATH_QUOTE);
626  pfree(suffix_path);
627  }
628  }
629 
630  fclose(script);
631 
632 #ifndef WIN32
633  if (chmod(*deletion_script_file_name, S_IRWXU) != 0)
634  pg_fatal("could not add execute permission to file \"%s\": %s\n",
635  *deletion_script_file_name, strerror(errno));
636 #endif
637 
638  check_ok();
639 }
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:2023
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 332 of file check.c.

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

Referenced by check_locale_and_encoding().

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

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

Referenced by equivalent_locale().

1104 {
1105  char *save;
1106  char *res;
1107 
1108  /* get the current setting, so we can restore it. */
1109  save = setlocale(category, NULL);
1110  if (!save)
1111  pg_fatal("failed to get the current locale\n");
1112 
1113  /* 'save' may be pointing at a modifiable scratch variable, so copy it. */
1114  save = pg_strdup(save);
1115 
1116  /* set the locale with setlocale, to see if it accepts it. */
1117  res = setlocale(category, locale);
1118 
1119  if (!res)
1120  pg_fatal("failed to get system locale name for \"%s\"\n", locale);
1121 
1122  res = pg_strdup(res);
1123 
1124  /* restore old value. */
1125  if (!setlocale(category, save))
1126  pg_fatal("failed to restore old locale \"%s\"\n", save);
1127 
1128  pg_free(save);
1129 
1130  return res;
1131 }
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_and_set_wal_level ( 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  /*
180  * We unconditionally start/stop the new server because pg_resetwal -o set
181  * wal_level to 'minimum'. If the user is upgrading standby servers using
182  * the rsync instructions, they will need pg_upgrade to write its final
183  * WAL record showing wal_level as 'replica'.
184  */
186 
187  /* Create dummy large object permissions for old < PG 9.0? */
190 
191  /* Reindex hash indexes for old < 10.0 */
194 
195  stop_postmaster(false);
196 }
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:431
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 200 of file check.c.

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

Referenced by main().

202 {
203  /* Did we copy the free space files? */
206  "Optimizer statistics are not transferred by pg_upgrade so,\n"
207  "once you start the new server, consider running:\n"
208  " %s\n\n", analyze_script_file_name);
209  else
211  "Optimizer statistics and free space information are not transferred\n"
212  "by pg_upgrade so, once you start the new server, consider running:\n"
213  " %s\n\n", analyze_script_file_name);
214 
215 
216  if (deletion_script_file_name)
218  "Running this script will delete the old cluster's data files:\n"
219  " %s\n",
220  deletion_script_file_name);
221  else
223  "Could not create a script to delete the old cluster's data files\n"
224  "because user-defined tablespaces or the new cluster's data directory\n"
225  "exist in the old cluster directory. The old cluster's contents must\n"
226  "be deleted manually.\n");
227 }
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