PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
check.c File Reference
#include "postgres_fe.h"
#include "catalog/pg_authid.h"
#include "fe_utils/string_utils.h"
#include "mb/pg_wchar.h"
#include "pg_upgrade.h"
Include dependency graph for check.c:

Go to the source code of this file.

Functions

static void check_new_cluster_is_empty (void)
 
static void check_databases_are_compatible (void)
 
static void check_locale_and_encoding (DbInfo *olddb, DbInfo *newdb)
 
static bool equivalent_locale (int category, const char *loca, const char *locb)
 
static void check_is_install_user (ClusterInfo *cluster)
 
static void check_proper_datallowconn (ClusterInfo *cluster)
 
static void check_for_prepared_transactions (ClusterInfo *cluster)
 
static void check_for_isn_and_int8_passing_mismatch (ClusterInfo *cluster)
 
static void check_for_reg_data_type_usage (ClusterInfo *cluster)
 
static void check_for_jsonb_9_4_usage (ClusterInfo *cluster)
 
static void check_for_pg_role_prefix (ClusterInfo *cluster)
 
static char * get_canonical_locale_name (int category, const char *locale)
 
static char * fix_path_separator (char *path)
 
void output_check_banner (bool live_check)
 
void check_and_dump_old_cluster (bool live_check)
 
void check_new_cluster (void)
 
void report_clusters_compatible (void)
 
void issue_warnings (void)
 
void output_completion_banner (char *analyze_script_file_name, char *deletion_script_file_name)
 
void check_cluster_versions (void)
 
void check_cluster_compatibility (bool live_check)
 
void create_script_for_cluster_analyze (char **analyze_script_file_name)
 
void create_script_for_old_cluster_deletion (char **deletion_script_file_name)
 

Function Documentation

void check_and_dump_old_cluster ( bool  live_check)

Definition at line 77 of file check.c.

References ControlData::cat_ver, UserOpts::check, check_for_isn_and_int8_passing_mismatch(), check_for_jsonb_9_4_usage(), check_for_pg_role_prefix(), check_for_prepared_transactions(), check_for_reg_data_type_usage(), check_is_install_user(), check_proper_datallowconn(), ClusterInfo::controldata, generate_old_dump(), get_db_and_rel_infos(), get_loadable_libraries(), GET_MAJOR_VERSION, init_tablespaces(), JSONB_FORMAT_CHANGE_CAT_VER, ClusterInfo::major_version, new_9_0_populate_pg_largeobject_metadata(), old_9_3_check_for_line_data_type_usage(), old_9_6_check_for_unknown_data_type_usage(), old_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  /* Pre-PG 10 allowed tables with 'unknown' type columns */
104 
105  /* 9.5 and below should not have roles starting with pg_ */
108 
112 
113  /* Pre-PG 9.4 had a different 'line' data type internal format */
116 
117  /* Pre-PG 9.0 had no large object permissions */
120 
121  /*
122  * While not a check option, we do this now because this is the only time
123  * the old server is running.
124  */
125  if (!user_opts.check)
127 
128  if (!live_check)
129  stop_postmaster(false);
130 }
uint32 major_version
Definition: pg_upgrade.h:274
ControlData controldata
Definition: pg_upgrade.h:264
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:29
static void check_for_reg_data_type_usage(ClusterInfo *cluster)
Definition: check.c:869
static void check_for_prepared_transactions(ClusterInfo *cluster)
Definition: check.c:744
void stop_postmaster(bool fast)
Definition: server.c:308
static void check_proper_datallowconn(ClusterInfo *cluster)
Definition: check.c:683
static void check_for_pg_role_prefix(ClusterInfo *cluster)
Definition: check.c:1055
void new_9_0_populate_pg_largeobject_metadata(ClusterInfo *cluster, bool check_mode)
Definition: version.c:23
ClusterInfo old_cluster
Definition: pg_upgrade.c:55
void generate_old_dump(void)
Definition: dump.c:19
static void check_is_install_user(ClusterInfo *cluster)
Definition: check.c:632
static void check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster)
Definition: check.c:775
UserOpts user_opts
Definition: option.c:30
uint32 cat_ver
Definition: pg_upgrade.h:210
void get_loadable_libraries(void)
Definition: function.c:49
void get_db_and_rel_infos(ClusterInfo *cluster)
Definition: info.c:310
#define JSONB_FORMAT_CHANGE_CAT_VER
Definition: pg_upgrade.h:133
bool check
Definition: pg_upgrade.h:297
static pgpid_t start_postmaster(void)
Definition: pg_ctl.c:431
static void check_for_jsonb_9_4_usage(ClusterInfo *cluster)
Definition: check.c:966
void init_tablespaces(void)
Definition: tablespace.c:21
void old_9_3_check_for_line_data_type_usage(ClusterInfo *cluster)
Definition: version.c:109
void old_9_6_check_for_unknown_data_type_usage(ClusterInfo *cluster)
Definition: version.c:206
void check_cluster_compatibility ( bool  live_check)

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

257 {
258  /* get/check pg_control data of servers */
259  get_control_data(&old_cluster, live_check);
260  get_control_data(&new_cluster, false);
262 
263  /* Is it 9.0 but without tablespace directories? */
266  pg_fatal("This utility can only upgrade to PostgreSQL version 9.0 after 2010-01-11\n"
267  "because of backend API changes made during development.\n");
268 
269  /* We read the real port number for PG >= 9.1 */
270  if (live_check && GET_MAJOR_VERSION(old_cluster.major_version) < 901 &&
272  pg_fatal("When checking a pre-PG 9.1 live old server, "
273  "you must specify the old server's port number.\n");
274 
275  if (live_check && old_cluster.port == new_cluster.port)
276  pg_fatal("When checking a live server, "
277  "the old and new port numbers must be different.\n");
278 }
uint32 major_version
Definition: pg_upgrade.h:274
ControlData controldata
Definition: pg_upgrade.h:264
#define TABLE_SPACE_SUBDIRS_CAT_VER
Definition: pg_upgrade.h:103
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:29
unsigned short port
Definition: pg_upgrade.h:273
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:55
ClusterInfo old_cluster
Definition: pg_upgrade.c:55
uint32 cat_ver
Definition: pg_upgrade.h:210
#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 214 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().

215 {
216  prep_status("Checking cluster versions");
217 
218  /* get old and new cluster versions */
221 
222  /*
223  * We allow upgrades from/to the same major version for alpha/beta
224  * upgrades
225  */
226 
228  pg_fatal("This utility can only upgrade from PostgreSQL version 8.4 and later.\n");
229 
230  /* Only current PG version is supported as a target */
232  pg_fatal("This utility can only upgrade to PostgreSQL version %s.\n",
233  PG_MAJORVERSION);
234 
235  /*
236  * We can't allow downgrading because we use the target pg_dump, and
237  * pg_dump cannot operate on newer database versions, only current and
238  * older versions.
239  */
241  pg_fatal("This utility cannot be used to downgrade to older major PostgreSQL versions.\n");
242 
243  /* Ensure binaries match the designated data directories */
246  pg_fatal("Old cluster data and binary directories are from different major versions.\n");
249  pg_fatal("New cluster data and binary directories are from different major versions.\n");
250 
251  check_ok();
252 }
uint32 get_major_server_version(ClusterInfo *cluster)
Definition: server.c:155
uint32 major_version
Definition: pg_upgrade.h:274
#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:55
void prep_status(const char *fmt,...) pg_attribute_printf(1
ClusterInfo old_cluster
Definition: pg_upgrade.c:55
static void check_ok(void)
Definition: initdb.c:1988
uint32 bin_version
Definition: pg_upgrade.h:276
static void check_databases_are_compatible ( void  )
static

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

384 {
385  int newdbnum;
386  int olddbnum;
387  DbInfo *newdbinfo;
388  DbInfo *olddbinfo;
389 
390  for (newdbnum = 0; newdbnum < new_cluster.dbarr.ndbs; newdbnum++)
391  {
392  newdbinfo = &new_cluster.dbarr.dbs[newdbnum];
393 
394  /* Find the corresponding database in the old cluster */
395  for (olddbnum = 0; olddbnum < old_cluster.dbarr.ndbs; olddbnum++)
396  {
397  olddbinfo = &old_cluster.dbarr.dbs[olddbnum];
398  if (strcmp(newdbinfo->db_name, olddbinfo->db_name) == 0)
399  {
400  check_locale_and_encoding(olddbinfo, newdbinfo);
401  break;
402  }
403  }
404  }
405 }
ClusterInfo new_cluster
Definition: pg_upgrade.c:55
ClusterInfo old_cluster
Definition: pg_upgrade.c:55
DbInfoArr dbarr
Definition: pg_upgrade.h:265
char * db_name
Definition: pg_upgrade.h:187
DbInfo * dbs
Definition: pg_upgrade.h:198
static void check_locale_and_encoding(DbInfo *olddb, DbInfo *newdb)
Definition: check.c:288
static void check_for_isn_and_int8_passing_mismatch ( ClusterInfo cluster)
static

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

776 {
777  int dbnum;
778  FILE *script = NULL;
779  bool found = false;
780  char output_path[MAXPGPATH];
781 
782  prep_status("Checking for contrib/isn with bigint-passing mismatch");
783 
786  {
787  /* no mismatch */
788  check_ok();
789  return;
790  }
791 
792  snprintf(output_path, sizeof(output_path),
793  "contrib_isn_and_int8_pass_by_value.txt");
794 
795  for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
796  {
797  PGresult *res;
798  bool db_used = false;
799  int ntups;
800  int rowno;
801  int i_nspname,
802  i_proname;
803  DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
804  PGconn *conn = connectToServer(cluster, active_db->db_name);
805 
806  /* Find any functions coming from contrib/isn */
807  res = executeQueryOrDie(conn,
808  "SELECT n.nspname, p.proname "
809  "FROM pg_catalog.pg_proc p, "
810  " pg_catalog.pg_namespace n "
811  "WHERE p.pronamespace = n.oid AND "
812  " p.probin = '$libdir/isn'");
813 
814  ntups = PQntuples(res);
815  i_nspname = PQfnumber(res, "nspname");
816  i_proname = PQfnumber(res, "proname");
817  for (rowno = 0; rowno < ntups; rowno++)
818  {
819  found = true;
820  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
821  pg_fatal("could not open file \"%s\": %s\n",
822  output_path, strerror(errno));
823  if (!db_used)
824  {
825  fprintf(script, "Database: %s\n", active_db->db_name);
826  db_used = true;
827  }
828  fprintf(script, " %s.%s\n",
829  PQgetvalue(res, rowno, i_nspname),
830  PQgetvalue(res, rowno, i_proname));
831  }
832 
833  PQclear(res);
834 
835  PQfinish(conn);
836  }
837 
838  if (script)
839  fclose(script);
840 
841  if (found)
842  {
843  pg_log(PG_REPORT, "fatal\n");
844  pg_fatal("Your installation contains \"contrib/isn\" functions which rely on the\n"
845  "bigint data type. Your old and new clusters pass bigint values\n"
846  "differently so this cluster cannot currently be upgraded. You can\n"
847  "manually upgrade databases that use \"contrib/isn\" facilities and remove\n"
848  "\"contrib/isn\" from the old cluster and restart the upgrade. A list of\n"
849  "the problem functions is in the file:\n"
850  " %s\n\n", output_path);
851  }
852  else
853  check_ok();
854 }
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3067
ControlData controldata
Definition: pg_upgrade.h:264
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3517
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:55
PGconn * conn
Definition: streamutil.c:45
#define MAXPGPATH
void prep_status(const char *fmt,...) pg_attribute_printf(1
ClusterInfo old_cluster
Definition: pg_upgrade.c:55
void pg_log(eLogType type, const char *fmt,...)
Definition: logging.c:69
static void check_ok(void)
Definition: initdb.c:1988
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:265
#define NULL
Definition: c.h:226
const char * strerror(int errnum)
Definition: strerror.c:19
char * db_name
Definition: pg_upgrade.h:187
DbInfo * dbs
Definition: pg_upgrade.h:198
bool float8_pass_by_value
Definition: pg_upgrade.h:228
static void check_for_jsonb_9_4_usage ( ClusterInfo cluster)
static

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

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

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

1056 {
1057  PGresult *res;
1058  PGconn *conn = connectToServer(cluster, "template1");
1059 
1060  prep_status("Checking for roles starting with 'pg_'");
1061 
1062  res = executeQueryOrDie(conn,
1063  "SELECT * "
1064  "FROM pg_catalog.pg_roles "
1065  "WHERE rolname ~ '^pg_'");
1066 
1067  if (PQntuples(res) != 0)
1068  pg_fatal("The %s cluster contains roles starting with 'pg_'\n",
1069  CLUSTER_NAME(cluster));
1070 
1071  PQclear(res);
1072 
1073  PQfinish(conn);
1074 
1075  check_ok();
1076 }
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3517
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:45
#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:1988
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 744 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().

745 {
746  PGresult *res;
747  PGconn *conn = connectToServer(cluster, "template1");
748 
749  prep_status("Checking for prepared transactions");
750 
751  res = executeQueryOrDie(conn,
752  "SELECT * "
753  "FROM pg_catalog.pg_prepared_xacts");
754 
755  if (PQntuples(res) != 0)
756  pg_fatal("The %s cluster contains prepared transactions\n",
757  CLUSTER_NAME(cluster));
758 
759  PQclear(res);
760 
761  PQfinish(conn);
762 
763  check_ok();
764 }
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3517
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:45
#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:1988
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 869 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().

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

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

633 {
634  PGresult *res;
635  PGconn *conn = connectToServer(cluster, "template1");
636 
637  prep_status("Checking database user is the install user");
638 
639  /* Can't use pg_authid because only superusers can view it. */
640  res = executeQueryOrDie(conn,
641  "SELECT rolsuper, oid "
642  "FROM pg_catalog.pg_roles "
643  "WHERE rolname = current_user "
644  "AND rolname !~ '^pg_'");
645 
646  /*
647  * We only allow the install user in the new cluster (see comment below)
648  * and we preserve pg_authid.oid, so this must be the install user in the
649  * old cluster too.
650  */
651  if (PQntuples(res) != 1 ||
652  atooid(PQgetvalue(res, 0, 1)) != BOOTSTRAP_SUPERUSERID)
653  pg_fatal("database user \"%s\" is not the install user\n",
654  os_info.user);
655 
656  PQclear(res);
657 
658  res = executeQueryOrDie(conn,
659  "SELECT COUNT(*) "
660  "FROM pg_catalog.pg_roles "
661  "WHERE rolname !~ '^pg_'");
662 
663  if (PQntuples(res) != 1)
664  pg_fatal("could not determine the number of users\n");
665 
666  /*
667  * We only allow the install user in the new cluster because other defined
668  * users might match users defined in the old cluster and generate an
669  * error during pg_dump restore.
670  */
671  if (cluster == &new_cluster && atooid(PQgetvalue(res, 0, 0)) != 1)
672  pg_fatal("Only the install user can be defined in the new cluster.\n");
673 
674  PQclear(res);
675 
676  PQfinish(conn);
677 
678  check_ok();
679 }
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:3517
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:55
PGconn * conn
Definition: streamutil.c:45
void prep_status(const char *fmt,...) pg_attribute_printf(1
static void check_ok(void)
Definition: initdb.c:1988
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:104
#define atooid(x)
Definition: lo.c:17
OSInfo os_info
Definition: pg_upgrade.c:57
char * user
Definition: pg_upgrade.h:311
static void check_locale_and_encoding ( DbInfo olddb,
DbInfo newdb 
)
static

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

289 {
290  if (olddb->db_encoding != newdb->db_encoding)
291  pg_fatal("encodings for database \"%s\" do not match: old \"%s\", new \"%s\"\n",
292  olddb->db_name,
295  if (!equivalent_locale(LC_COLLATE, olddb->db_collate, newdb->db_collate))
296  pg_fatal("lc_collate values for database \"%s\" do not match: old \"%s\", new \"%s\"\n",
297  olddb->db_name, olddb->db_collate, newdb->db_collate);
298  if (!equivalent_locale(LC_CTYPE, olddb->db_ctype, newdb->db_ctype))
299  pg_fatal("lc_ctype values for database \"%s\" do not match: old \"%s\", new \"%s\"\n",
300  olddb->db_name, olddb->db_ctype, newdb->db_ctype);
301 }
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:315
char * db_ctype
Definition: pg_upgrade.h:191
const char * pg_encoding_to_char(int encoding)
Definition: encnames.c:531
int db_encoding
Definition: pg_upgrade.h:192
char * db_name
Definition: pg_upgrade.h:187
char * db_collate
Definition: pg_upgrade.h:190
void check_new_cluster ( void  )

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

135 {
137 
140 
142 
144  check_hard_link();
145 
147 
149 }
void check_hard_link(void)
Definition: file.c:282
static void check_databases_are_compatible(void)
Definition: check.c:383
void check_loadable_libraries(void)
Definition: function.c:203
static void check_for_prepared_transactions(ClusterInfo *cluster)
Definition: check.c:744
ClusterInfo new_cluster
Definition: pg_upgrade.c:55
static void check_is_install_user(ClusterInfo *cluster)
Definition: check.c:632
transferMode transfer_mode
Definition: pg_upgrade.h:299
UserOpts user_opts
Definition: option.c:30
static void check_new_cluster_is_empty(void)
Definition: check.c:358
void get_db_and_rel_infos(ClusterInfo *cluster)
Definition: info.c:310
static void check_new_cluster_is_empty ( void  )
static

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

359 {
360  int dbnum;
361 
362  for (dbnum = 0; dbnum < new_cluster.dbarr.ndbs; dbnum++)
363  {
364  int relnum;
365  RelInfoArr *rel_arr = &new_cluster.dbarr.dbs[dbnum].rel_arr;
366 
367  for (relnum = 0; relnum < rel_arr->nrels;
368  relnum++)
369  {
370  /* pg_largeobject and its index should be skipped */
371  if (strcmp(rel_arr->rels[relnum].nspname, "pg_catalog") != 0)
372  pg_fatal("New cluster database \"%s\" is not empty\n",
373  new_cluster.dbarr.dbs[dbnum].db_name);
374  }
375  }
376 }
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
char * nspname
Definition: pg_upgrade.h:141
ClusterInfo new_cluster
Definition: pg_upgrade.c:55
RelInfo * rels
Definition: pg_upgrade.h:154
DbInfoArr dbarr
Definition: pg_upgrade.h:265
RelInfoArr rel_arr
Definition: pg_upgrade.h:193
char * db_name
Definition: pg_upgrade.h:187
DbInfo * dbs
Definition: pg_upgrade.h:198
static void check_proper_datallowconn ( ClusterInfo cluster)
static

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

684 {
685  int dbnum;
686  PGconn *conn_template1;
687  PGresult *dbres;
688  int ntups;
689  int i_datname;
690  int i_datallowconn;
691 
692  prep_status("Checking database connection settings");
693 
694  conn_template1 = connectToServer(cluster, "template1");
695 
696  /* get database names */
697  dbres = executeQueryOrDie(conn_template1,
698  "SELECT datname, datallowconn "
699  "FROM pg_catalog.pg_database");
700 
701  i_datname = PQfnumber(dbres, "datname");
702  i_datallowconn = PQfnumber(dbres, "datallowconn");
703 
704  ntups = PQntuples(dbres);
705  for (dbnum = 0; dbnum < ntups; dbnum++)
706  {
707  char *datname = PQgetvalue(dbres, dbnum, i_datname);
708  char *datallowconn = PQgetvalue(dbres, dbnum, i_datallowconn);
709 
710  if (strcmp(datname, "template0") == 0)
711  {
712  /* avoid restore failure when pg_dumpall tries to create template0 */
713  if (strcmp(datallowconn, "t") == 0)
714  pg_fatal("template0 must not allow connections, "
715  "i.e. its pg_database.datallowconn must be false\n");
716  }
717  else
718  {
719  /*
720  * avoid datallowconn == false databases from being skipped on
721  * restore
722  */
723  if (strcmp(datallowconn, "f") == 0)
724  pg_fatal("All non-template0 databases must allow connections, "
725  "i.e. their pg_database.datallowconn must be true\n");
726  }
727  }
728 
729  PQclear(dbres);
730 
731  PQfinish(conn_template1);
732 
733  check_ok();
734 }
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:3517
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:1988
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 414 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().

415 {
416  FILE *script = NULL;
417  PQExpBufferData user_specification;
418 
419  prep_status("Creating script to analyze new cluster");
420 
421  initPQExpBuffer(&user_specification);
423  {
424  appendPQExpBufferStr(&user_specification, "-U ");
425  appendShellString(&user_specification, os_info.user);
426  appendPQExpBufferChar(&user_specification, ' ');
427  }
428 
429  *analyze_script_file_name = psprintf("%sanalyze_new_cluster.%s",
431 
432  if ((script = fopen_priv(*analyze_script_file_name, "w")) == NULL)
433  pg_fatal("could not open file \"%s\": %s\n",
434  *analyze_script_file_name, strerror(errno));
435 
436 #ifndef WIN32
437  /* add shebang header */
438  fprintf(script, "#!/bin/sh\n\n");
439 #else
440  /* suppress command echoing */
441  fprintf(script, "@echo off\n");
442 #endif
443 
444  fprintf(script, "echo %sThis script will generate minimal optimizer statistics rapidly%s\n",
446  fprintf(script, "echo %sso your system is usable, and then gather statistics twice more%s\n",
448  fprintf(script, "echo %swith increasing accuracy. When it is done, your system will%s\n",
450  fprintf(script, "echo %shave the default level of optimizer statistics.%s\n",
452  fprintf(script, "echo%s\n\n", ECHO_BLANK);
453 
454  fprintf(script, "echo %sIf you have used ALTER TABLE to modify the statistics target for%s\n",
456  fprintf(script, "echo %sany tables, you might want to remove them and restore them after%s\n",
458  fprintf(script, "echo %srunning this script because they will delay fast statistics generation.%s\n",
460  fprintf(script, "echo%s\n\n", ECHO_BLANK);
461 
462  fprintf(script, "echo %sIf you would like default statistics as quickly as possible, cancel%s\n",
464  fprintf(script, "echo %sthis script and run:%s\n",
466  fprintf(script, "echo %s \"%s/vacuumdb\" %s--all %s%s\n", ECHO_QUOTE,
467  new_cluster.bindir, user_specification.data,
468  /* Did we copy the free space files? */
470  "--analyze-only" : "--analyze", ECHO_QUOTE);
471  fprintf(script, "echo%s\n\n", ECHO_BLANK);
472 
473  fprintf(script, "\"%s/vacuumdb\" %s--all --analyze-in-stages\n",
474  new_cluster.bindir, user_specification.data);
475  /* Did we copy the free space files? */
477  fprintf(script, "\"%s/vacuumdb\" %s--all\n", new_cluster.bindir,
478  user_specification.data);
479 
480  fprintf(script, "echo%s\n\n", ECHO_BLANK);
481  fprintf(script, "echo %sDone%s\n",
483 
484  fclose(script);
485 
486 #ifndef WIN32
487  if (chmod(*analyze_script_file_name, S_IRWXU) != 0)
488  pg_fatal("could not add execute permission to file \"%s\": %s\n",
489  *analyze_script_file_name, strerror(errno));
490 #endif
491 
492  termPQExpBuffer(&user_specification);
493 
494  check_ok();
495 }
uint32 major_version
Definition: pg_upgrade.h:274
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:312
ClusterInfo new_cluster
Definition: pg_upgrade.c:55
void prep_status(const char *fmt,...) pg_attribute_printf(1
ClusterInfo old_cluster
Definition: pg_upgrade.c:55
static void check_ok(void)
Definition: initdb.c:1988
char * bindir
Definition: pg_upgrade.h:269
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:396
void appendShellString(PQExpBuffer buf, const char *str)
Definition: string_utils.c:430
#define NULL
Definition: c.h:226
#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:57
#define ECHO_QUOTE
Definition: pg_upgrade.h:81
char * user
Definition: pg_upgrade.h:311
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
void create_script_for_old_cluster_deletion ( char **  deletion_script_file_name)

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

505 {
506  FILE *script = NULL;
507  int tblnum;
508  char old_cluster_pgdata[MAXPGPATH],
509  new_cluster_pgdata[MAXPGPATH];
510 
511  *deletion_script_file_name = psprintf("%sdelete_old_cluster.%s",
513 
514  strlcpy(old_cluster_pgdata, old_cluster.pgdata, MAXPGPATH);
515  canonicalize_path(old_cluster_pgdata);
516 
517  strlcpy(new_cluster_pgdata, new_cluster.pgdata, MAXPGPATH);
518  canonicalize_path(new_cluster_pgdata);
519 
520  /* Some people put the new data directory inside the old one. */
521  if (path_is_prefix_of_path(old_cluster_pgdata, new_cluster_pgdata))
522  {
524  "\nWARNING: new data directory should not be inside the old data directory, e.g. %s\n", old_cluster_pgdata);
525 
526  /* Unlink file in case it is left over from a previous run. */
527  unlink(*deletion_script_file_name);
528  pg_free(*deletion_script_file_name);
529  *deletion_script_file_name = NULL;
530  return;
531  }
532 
533  /*
534  * Some users (oddly) create tablespaces inside the cluster data
535  * directory. We can't create a proper old cluster delete script in that
536  * case.
537  */
538  for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
539  {
540  char old_tablespace_dir[MAXPGPATH];
541 
542  strlcpy(old_tablespace_dir, os_info.old_tablespaces[tblnum], MAXPGPATH);
543  canonicalize_path(old_tablespace_dir);
544  if (path_is_prefix_of_path(old_cluster_pgdata, old_tablespace_dir))
545  {
546  /* reproduce warning from CREATE TABLESPACE that is in the log */
548  "\nWARNING: user-defined tablespace locations should not be inside the data directory, e.g. %s\n", old_tablespace_dir);
549 
550  /* Unlink file in case it is left over from a previous run. */
551  unlink(*deletion_script_file_name);
552  pg_free(*deletion_script_file_name);
553  *deletion_script_file_name = NULL;
554  return;
555  }
556  }
557 
558  prep_status("Creating script to delete old cluster");
559 
560  if ((script = fopen_priv(*deletion_script_file_name, "w")) == NULL)
561  pg_fatal("could not open file \"%s\": %s\n",
562  *deletion_script_file_name, strerror(errno));
563 
564 #ifndef WIN32
565  /* add shebang header */
566  fprintf(script, "#!/bin/sh\n\n");
567 #endif
568 
569  /* delete old cluster's default tablespace */
570  fprintf(script, RMDIR_CMD " %c%s%c\n", PATH_QUOTE,
572 
573  /* delete old cluster's alternate tablespaces */
574  for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
575  {
576  /*
577  * Do the old cluster's per-database directories share a directory
578  * with a new version-specific tablespace?
579  */
580  if (strlen(old_cluster.tablespace_suffix) == 0)
581  {
582  /* delete per-database directories */
583  int dbnum;
584 
585  fprintf(script, "\n");
586  /* remove PG_VERSION? */
588  fprintf(script, RM_CMD " %s%cPG_VERSION\n",
591 
592  for (dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
593  fprintf(script, RMDIR_CMD " %c%s%c%d%c\n", PATH_QUOTE,
596  PATH_QUOTE);
597  }
598  else
599  {
600  char *suffix_path = pg_strdup(old_cluster.tablespace_suffix);
601 
602  /*
603  * Simply delete the tablespace directory, which might be ".old"
604  * or a version-specific subdirectory.
605  */
606  fprintf(script, RMDIR_CMD " %c%s%s%c\n", PATH_QUOTE,
608  fix_path_separator(suffix_path), PATH_QUOTE);
609  pfree(suffix_path);
610  }
611  }
612 
613  fclose(script);
614 
615 #ifndef WIN32
616  if (chmod(*deletion_script_file_name, S_IRWXU) != 0)
617  pg_fatal("could not add execute permission to file \"%s\": %s\n",
618  *deletion_script_file_name, strerror(errno));
619 #endif
620 
621  check_ok();
622 }
uint32 major_version
Definition: pg_upgrade.h:274
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:186
ClusterInfo new_cluster
Definition: pg_upgrade.c:55
void pfree(void *pointer)
Definition: mcxt.c:992
#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:55
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:1988
int unlink(const char *filename)
char ** old_tablespaces
Definition: pg_upgrade.h:313
const char * tablespace_suffix
Definition: pg_upgrade.h:277
DbInfoArr dbarr
Definition: pg_upgrade.h:265
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
#define NULL
Definition: c.h:226
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:266
int num_old_tablespaces
Definition: pg_upgrade.h:314
const char * strerror(int errnum)
Definition: strerror.c:19
OSInfo os_info
Definition: pg_upgrade.c:57
DbInfo * dbs
Definition: pg_upgrade.h:198
#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 315 of file check.c.

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

Referenced by check_locale_and_encoding().

316 {
317  const char *chara;
318  const char *charb;
319  char *canona;
320  char *canonb;
321  int lena;
322  int lenb;
323 
324  /*
325  * If the names are equal, the locales are equivalent. Checking this first
326  * avoids calling setlocale() in the common case that the names are equal.
327  * That's a good thing, if setlocale() is buggy, for example.
328  */
329  if (pg_strcasecmp(loca, locb) == 0)
330  return true;
331 
332  /*
333  * Not identical. Canonicalize both names, remove the encoding parts, and
334  * try again.
335  */
336  canona = get_canonical_locale_name(category, loca);
337  chara = strrchr(canona, '.');
338  lena = chara ? (chara - canona) : strlen(canona);
339 
340  canonb = get_canonical_locale_name(category, locb);
341  charb = strrchr(canonb, '.');
342  lenb = charb ? (charb - canonb) : strlen(canonb);
343 
344  if (lena == lenb && pg_strncasecmp(canona, canonb, lena) == 0)
345  {
346  pg_free(canona);
347  pg_free(canonb);
348  return true;
349  }
350 
351  pg_free(canona);
352  pg_free(canonb);
353  return false;
354 }
static char * get_canonical_locale_name(int category, const char *locale)
Definition: check.c:1086
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().

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

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

Referenced by equivalent_locale().

1087 {
1088  char *save;
1089  char *res;
1090 
1091  /* get the current setting, so we can restore it. */
1092  save = setlocale(category, NULL);
1093  if (!save)
1094  pg_fatal("failed to get the current locale\n");
1095 
1096  /* 'save' may be pointing at a modifiable scratch variable, so copy it. */
1097  save = pg_strdup(save);
1098 
1099  /* set the locale with setlocale, to see if it accepts it. */
1100  res = setlocale(category, locale);
1101 
1102  if (!res)
1103  pg_fatal("failed to get system locale name for \"%s\"\n", locale);
1104 
1105  res = pg_strdup(res);
1106 
1107  /* restore old value. */
1108  if (!setlocale(category, save))
1109  pg_fatal("failed to restore old locale \"%s\"\n", save);
1110 
1111  pg_free(save);
1112 
1113  return res;
1114 }
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:226
void pg_free(void *ptr)
Definition: fe_memutils.c:105
static char * locale
Definition: initdb.c:122
void issue_warnings ( void  )

Definition at line 170 of file check.c.

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

Referenced by main().

171 {
172  /* Create dummy large object permissions for old < PG 9.0? */
174  {
177  stop_postmaster(false);
178  }
179 }
uint32 major_version
Definition: pg_upgrade.h:274
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:29
void stop_postmaster(bool fast)
Definition: server.c:308
ClusterInfo new_cluster
Definition: pg_upgrade.c:55
void new_9_0_populate_pg_largeobject_metadata(ClusterInfo *cluster, bool check_mode)
Definition: version.c:23
ClusterInfo old_cluster
Definition: pg_upgrade.c:55
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:30
bool check
Definition: pg_upgrade.h:297
void output_completion_banner ( char *  analyze_script_file_name,
char *  deletion_script_file_name 
)

Definition at line 183 of file check.c.

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

Referenced by main().

185 {
186  /* Did we copy the free space files? */
189  "Optimizer statistics are not transferred by pg_upgrade so,\n"
190  "once you start the new server, consider running:\n"
191  " %s\n\n", analyze_script_file_name);
192  else
194  "Optimizer statistics and free space information are not transferred\n"
195  "by pg_upgrade so, once you start the new server, consider running:\n"
196  " %s\n\n", analyze_script_file_name);
197 
198 
199  if (deletion_script_file_name)
201  "Running this script will delete the old cluster's data files:\n"
202  " %s\n",
203  deletion_script_file_name);
204  else
206  "Could not create a script to delete the old cluster's data files\n"
207  "because user-defined tablespaces or the new cluster's data directory\n"
208  "exist in the old cluster directory. The old cluster's contents must\n"
209  "be deleted manually.\n");
210 }
uint32 major_version
Definition: pg_upgrade.h:274
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:29
ClusterInfo old_cluster
Definition: pg_upgrade.c:55
void pg_log(eLogType type, const char *fmt,...)
Definition: logging.c:69
void report_clusters_compatible ( void  )

Definition at line 153 of file check.c.

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

Referenced by main().

154 {
155  if (user_opts.check)
156  {
157  pg_log(PG_REPORT, "\n*Clusters are compatible*\n");
158  /* stops new cluster */
159  stop_postmaster(false);
160  exit(0);
161  }
162 
163  pg_log(PG_REPORT, "\n"
164  "If pg_upgrade fails after this point, you must re-initdb the\n"
165  "new cluster before continuing.\n");
166 }
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:30
bool check
Definition: pg_upgrade.h:297