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:270
ControlData controldata
Definition: pg_upgrade.h:260
#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:890
static void check_for_prepared_transactions(ClusterInfo *cluster)
Definition: check.c:761
void stop_postmaster(bool fast)
Definition: server.c:317
static void check_proper_datallowconn(ClusterInfo *cluster)
Definition: check.c:700
static void check_for_pg_role_prefix(ClusterInfo *cluster)
Definition: check.c:1076
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:796
UserOpts user_opts
Definition: option.c:29
uint32 cat_ver
Definition: pg_upgrade.h:206
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:129
bool check
Definition: pg_upgrade.h:293
static pgpid_t start_postmaster(void)
Definition: pg_ctl.c:450
static void check_for_jsonb_9_4_usage(ClusterInfo *cluster)
Definition: check.c:987
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:270
ControlData controldata
Definition: pg_upgrade.h:260
#define TABLE_SPACE_SUBDIRS_CAT_VER
Definition: pg_upgrade.h:99
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:29
unsigned short port
Definition: pg_upgrade.h:269
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
void check_control_data(ControlData *oldctrl, ControlData *newctrl)
Definition: controldata.c:552
ClusterInfo new_cluster
Definition: pg_upgrade.c:56
ClusterInfo old_cluster
Definition: pg_upgrade.c:56
uint32 cat_ver
Definition: pg_upgrade.h:206
#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:270
#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:272
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:261
char * db_name
Definition: pg_upgrade.h:183
DbInfo * dbs
Definition: pg_upgrade.h:194
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 796 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().

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

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

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

Definition at line 1076 of file check.c.

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

Referenced by check_and_dump_old_cluster().

1077 {
1078  PGresult *res;
1079  PGconn *conn = connectToServer(cluster, "template1");
1080 
1081  prep_status("Checking for roles starting with 'pg_'");
1082 
1083  res = executeQueryOrDie(conn,
1084  "SELECT * "
1085  "FROM pg_catalog.pg_roles "
1086  "WHERE rolname ~ '^pg_'");
1087 
1088  if (PQntuples(res) != 0)
1089  {
1090  if (cluster == &old_cluster)
1091  pg_fatal("The source cluster contains roles starting with 'pg_'\n");
1092  else
1093  pg_fatal("The target cluster contains roles starting with 'pg_'\n");
1094  }
1095 
1096  PQclear(res);
1097 
1098  PQfinish(conn);
1099 
1100  check_ok();
1101 }
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3630
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:43
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
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(), conn, connectToServer(), executeQueryOrDie(), old_cluster, 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  {
774  if (cluster == &old_cluster)
775  pg_fatal("The source cluster contains prepared transactions\n");
776  else
777  pg_fatal("The target cluster contains prepared transactions\n");
778  }
779 
780  PQclear(res);
781 
782  PQfinish(conn);
783 
784  check_ok();
785 }
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3630
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:43
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
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 890 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().

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

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

Referenced by equivalent_locale().

1112 {
1113  char *save;
1114  char *res;
1115 
1116  /* get the current setting, so we can restore it. */
1117  save = setlocale(category, NULL);
1118  if (!save)
1119  pg_fatal("failed to get the current locale\n");
1120 
1121  /* 'save' may be pointing at a modifiable scratch variable, so copy it. */
1122  save = pg_strdup(save);
1123 
1124  /* set the locale with setlocale, to see if it accepts it. */
1125  res = setlocale(category, locale);
1126 
1127  if (!res)
1128  pg_fatal("failed to get system locale name for \"%s\"\n", locale);
1129 
1130  res = pg_strdup(res);
1131 
1132  /* restore old value. */
1133  if (!setlocale(category, save))
1134  pg_fatal("failed to restore old locale \"%s\"\n", save);
1135 
1136  pg_free(save);
1137 
1138  return res;
1139 }
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:270
#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:317
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:450
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:293
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:270
#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:317
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:293