PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
pg_upgrade.h File Reference
#include <unistd.h>
#include <assert.h>
#include <sys/stat.h>
#include <sys/time.h>
#include "libpq-fe.h"
Include dependency graph for pg_upgrade.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  RelInfo
 
struct  RelInfoArr
 
struct  FileNameMap
 
struct  DbInfo
 
struct  DbInfoArr
 
struct  ControlData
 
struct  ClusterInfo
 
struct  LogOpts
 
struct  UserOpts
 
struct  OSInfo
 

Macros

#define DEF_PGUPORT   50432
 
#define USER_NAME_SIZE   128
 
#define MAX_STRING   1024
 
#define LINE_ALLOC   4096
 
#define QUERY_ALLOC   8192
 
#define MIGRATOR_API_VERSION   1
 
#define MESSAGE_WIDTH   60
 
#define GET_MAJOR_VERSION(v)   ((v) / 100)
 
#define GLOBALS_DUMP_FILE   "pg_upgrade_dump_globals.sql"
 
#define DB_DUMP_FILE_MASK   "pg_upgrade_dump_%u.custom"
 
#define DB_DUMP_LOG_FILE_MASK   "pg_upgrade_dump_%u.log"
 
#define SERVER_LOG_FILE   "pg_upgrade_server.log"
 
#define UTILITY_LOG_FILE   "pg_upgrade_utility.log"
 
#define INTERNAL_LOG_FILE   "pg_upgrade_internal.log"
 
#define SERVER_START_LOG_FILE   SERVER_LOG_FILE
 
#define SERVER_STOP_LOG_FILE   SERVER_LOG_FILE
 
#define pg_mv_file   rename
 
#define pg_link_file   link
 
#define PATH_SEPARATOR   '/'
 
#define PATH_QUOTE   '\''
 
#define RM_CMD   "rm -f"
 
#define RMDIR_CMD   "rm -rf"
 
#define SCRIPT_PREFIX   "./"
 
#define SCRIPT_EXT   "sh"
 
#define ECHO_QUOTE   "'"
 
#define ECHO_BLANK   ""
 
#define CLUSTER_NAME(cluster)
 
#define TABLE_SPACE_SUBDIRS_CAT_VER   201001111
 
#define BINARY_UPGRADE_SERVER_FLAG_CAT_VER   201104251
 
#define VISIBILITY_MAP_CRASHSAFE_CAT_VER   201107031
 
#define VISIBILITY_MAP_FROZEN_BIT_CAT_VER   201603011
 
#define MULTIXACT_FORMATCHANGE_CAT_VER   201301231
 
#define LARGE_OBJECT_SIZE_PG_CONTROL_VER   942
 
#define JSONB_FORMAT_CHANGE_CAT_VER   201409291
 
#define EXEC_PSQL_ARGS   "--echo-queries --set ON_ERROR_STOP=on --no-psqlrc --dbname=template1"
 

Typedefs

typedef long pgpid_t
 

Enumerations

enum  transferMode { TRANSFER_MODE_COPY, TRANSFER_MODE_LINK }
 
enum  eLogType {
  PG_DEBUG, PG_PROGRESS, PG_WARNING, PG_FATAL,
  PG_VERBOSE, PG_STATUS, PG_REPORT, PG_WARNING,
  PG_FATAL
}
 

Functions

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_old_cluster_deletion (char **deletion_script_file_name)
 
void create_script_for_cluster_analyze (char **analyze_script_file_name)
 
void get_control_data (ClusterInfo *cluster, bool live_check)
 
void check_control_data (ControlData *oldctrl, ControlData *newctrl)
 
void disable_old_cluster (void)
 
void generate_old_dump (void)
 
bool exec_prog (const char *log_file, const char *opt_log_file, bool throw_error, const char *fmt,...) pg_attribute_printf(4
 
bool void verify_directories (void)
 
bool pid_lock_file_exists (const char *datadir)
 
void copyFile (const char *src, const char *dst, const char *schemaName, const char *relName)
 
void linkFile (const char *src, const char *dst, const char *schemaName, const char *relName)
 
void rewriteVisibilityMap (const char *fromfile, const char *tofile, const char *schemaName, const char *relName)
 
void check_hard_link (void)
 
FILE * fopen_priv (const char *path, const char *mode)
 
void get_loadable_libraries (void)
 
void check_loadable_libraries (void)
 
FileNameMapgen_db_file_maps (DbInfo *old_db, DbInfo *new_db, int *nmaps, const char *old_pgdata, const char *new_pgdata)
 
void get_db_and_rel_infos (ClusterInfo *cluster)
 
void print_maps (FileNameMap *maps, int n, const char *db_name)
 
void parseCommandLine (int argc, char *argv[])
 
void adjust_data_dir (ClusterInfo *cluster)
 
void get_sock_dir (ClusterInfo *cluster, bool live_check)
 
void transfer_all_new_tablespaces (DbInfoArr *old_db_arr, DbInfoArr *new_db_arr, char *old_pgdata, char *new_pgdata)
 
void transfer_all_new_dbs (DbInfoArr *old_db_arr, DbInfoArr *new_db_arr, char *old_pgdata, char *new_pgdata, char *old_tablespace)
 
void init_tablespaces (void)
 
PGconnconnectToServer (ClusterInfo *cluster, const char *db_name)
 
PGresultexecuteQueryOrDie (PGconn *conn, const char *fmt,...) pg_attribute_printf(2
 
PGresult char * cluster_conn_opts (ClusterInfo *cluster)
 
bool start_postmaster (ClusterInfo *cluster, bool throw_error)
 
void stop_postmaster (bool fast)
 
uint32 get_major_server_version (ClusterInfo *cluster)
 
void check_pghost_envvar (void)
 
char * quote_identifier (const char *s)
 
int get_user_info (char **user_name_p)
 
void check_ok (void)
 
void report_status (eLogType type, const char *fmt,...) pg_attribute_printf(2
 
void void pg_log (eLogType type, const char *fmt,...) pg_attribute_printf(2
 
void void void pg_fatal (const char *fmt,...) pg_attribute_printf(1
 
void void void pg_attribute_noreturn ()
 
void end_progress_output (void)
 
void prep_status (const char *fmt,...) pg_attribute_printf(1
 
unsigned int str2uint (const char *str)
 
void pg_putenv (const char *var, const char *val)
 
void new_9_0_populate_pg_largeobject_metadata (ClusterInfo *cluster, bool check_mode)
 
void old_9_3_check_for_line_data_type_usage (ClusterInfo *cluster)
 
void old_9_6_check_for_unknown_data_type_usage (ClusterInfo *cluster)
 
void old_9_6_invalidate_hash_indexes (ClusterInfo *cluster, bool check_mode)
 
void parallel_exec_prog (const char *log_file, const char *opt_log_file, const char *fmt,...) pg_attribute_printf(3
 
void void parallel_transfer_all_new_dbs (DbInfoArr *old_db_arr, DbInfoArr *new_db_arr, char *old_pgdata, char *new_pgdata, char *old_tablespace)
 
bool reap_child (bool wait_for_child)
 

Variables

char * output_files []
 
LogOpts log_opts
 
UserOpts user_opts
 
ClusterInfo old_cluster
 
ClusterInfo new_cluster
 
OSInfo os_info
 

Macro Definition Documentation

#define BINARY_UPGRADE_SERVER_FLAG_CAT_VER   201104251

Definition at line 103 of file pg_upgrade.h.

Referenced by start_postmaster().

#define CLUSTER_NAME (   cluster)
Value:
((cluster) == &old_cluster ? "old" : \
(cluster) == &new_cluster ? "new" : "none")
ClusterInfo old_cluster
Definition: pg_upgrade.c:56
ClusterInfo new_cluster
Definition: pg_upgrade.c:56
void cluster(ClusterStmt *stmt, bool isTopLevel)
Definition: cluster.c:106

Definition at line 97 of file pg_upgrade.h.

Referenced by adjust_data_dir(), check_for_pg_role_prefix(), check_for_prepared_transactions(), get_control_data(), get_db_and_rel_infos(), and start_postmaster().

#define DB_DUMP_FILE_MASK   "pg_upgrade_dump_%u.custom"

Definition at line 33 of file pg_upgrade.h.

Referenced by cleanup(), create_new_objects(), and generate_old_dump().

#define DB_DUMP_LOG_FILE_MASK   "pg_upgrade_dump_%u.log"

Definition at line 35 of file pg_upgrade.h.

Referenced by cleanup(), create_new_objects(), and generate_old_dump().

#define DEF_PGUPORT   50432

Definition at line 16 of file pg_upgrade.h.

Referenced by check_cluster_compatibility(), get_sock_dir(), and parseCommandLine().

#define ECHO_BLANK   ""

Definition at line 82 of file pg_upgrade.h.

Referenced by create_script_for_cluster_analyze().

#define ECHO_QUOTE   "'"

Definition at line 81 of file pg_upgrade.h.

Referenced by create_script_for_cluster_analyze().

#define EXEC_PSQL_ARGS   "--echo-queries --set ON_ERROR_STOP=on --no-psqlrc --dbname=template1"

Definition at line 358 of file pg_upgrade.h.

Referenced by prepare_new_databases().

#define GLOBALS_DUMP_FILE   "pg_upgrade_dump_globals.sql"

Definition at line 32 of file pg_upgrade.h.

Referenced by cleanup(), generate_old_dump(), and prepare_new_databases().

#define INTERNAL_LOG_FILE   "pg_upgrade_internal.log"

Definition at line 38 of file pg_upgrade.h.

Referenced by parseCommandLine().

#define JSONB_FORMAT_CHANGE_CAT_VER   201409291

Definition at line 131 of file pg_upgrade.h.

Referenced by check_and_dump_old_cluster().

#define LARGE_OBJECT_SIZE_PG_CONTROL_VER   942

Definition at line 126 of file pg_upgrade.h.

Referenced by get_control_data().

#define LINE_ALLOC   4096

Definition at line 22 of file pg_upgrade.h.

#define MAX_STRING   1024
#define MESSAGE_WIDTH   60

Definition at line 27 of file pg_upgrade.h.

#define MIGRATOR_API_VERSION   1

Definition at line 25 of file pg_upgrade.h.

#define MULTIXACT_FORMATCHANGE_CAT_VER   201301231

Definition at line 120 of file pg_upgrade.h.

Referenced by copy_xact_xlog_xid(), and get_control_data().

#define PATH_QUOTE   '\''

Definition at line 76 of file pg_upgrade.h.

Referenced by create_script_for_old_cluster_deletion().

#define PATH_SEPARATOR   '/'

Definition at line 75 of file pg_upgrade.h.

Referenced by create_script_for_old_cluster_deletion().

#define pg_link_file   link

Definition at line 74 of file pg_upgrade.h.

Referenced by check_hard_link(), and linkFile().

#define pg_mv_file   rename

Definition at line 73 of file pg_upgrade.h.

Referenced by disable_old_cluster().

#define QUERY_ALLOC   8192

Definition at line 23 of file pg_upgrade.h.

#define RM_CMD   "rm -f"

Definition at line 77 of file pg_upgrade.h.

Referenced by create_script_for_old_cluster_deletion().

#define RMDIR_CMD   "rm -rf"

Definition at line 78 of file pg_upgrade.h.

Referenced by create_script_for_old_cluster_deletion().

#define SCRIPT_EXT   "sh"
#define SCRIPT_PREFIX   "./"
#define SERVER_LOG_FILE   "pg_upgrade_server.log"

Definition at line 36 of file pg_upgrade.h.

Referenced by start_postmaster().

#define SERVER_START_LOG_FILE   SERVER_LOG_FILE

Definition at line 59 of file pg_upgrade.h.

Referenced by start_postmaster().

#define SERVER_STOP_LOG_FILE   SERVER_LOG_FILE

Definition at line 60 of file pg_upgrade.h.

Referenced by stop_postmaster().

#define TABLE_SPACE_SUBDIRS_CAT_VER   201001111

Definition at line 101 of file pg_upgrade.h.

Referenced by check_cluster_compatibility().

#define USER_NAME_SIZE   128

Definition at line 19 of file pg_upgrade.h.

#define UTILITY_LOG_FILE   "pg_upgrade_utility.log"
#define VISIBILITY_MAP_CRASHSAFE_CAT_VER   201107031

Definition at line 108 of file pg_upgrade.h.

Referenced by transfer_single_new_db().

#define VISIBILITY_MAP_FROZEN_BIT_CAT_VER   201603011

Definition at line 113 of file pg_upgrade.h.

Referenced by transfer_single_new_db().

Typedef Documentation

Definition at line 252 of file pg_upgrade.h.

Enumeration Type Documentation

enum eLogType
Enumerator
PG_DEBUG 
PG_PROGRESS 
PG_WARNING 
PG_FATAL 
PG_VERBOSE 
PG_STATUS 
PG_REPORT 
PG_WARNING 
PG_FATAL 

Definition at line 242 of file pg_upgrade.h.

243 {
244  PG_VERBOSE,
245  PG_STATUS,
246  PG_REPORT,
247  PG_WARNING,
248  PG_FATAL
249 } eLogType;
eLogType
Definition: pg_upgrade.h:242
Enumerator
TRANSFER_MODE_COPY 
TRANSFER_MODE_LINK 

Definition at line 233 of file pg_upgrade.h.

Function Documentation

void adjust_data_dir ( ClusterInfo cluster)

Definition at line 384 of file option.c.

References ClusterInfo::bindir, check_ok(), CLUSTER_NAME, filename, MAX_STRING, MAXPGPATH, NULL, output(), pg_fatal(), pg_strdup(), ClusterInfo::pgconfig, ClusterInfo::pgdata, prep_status(), snprintf(), and strerror().

385 {
386  char filename[MAXPGPATH];
387  char cmd[MAXPGPATH],
388  cmd_output[MAX_STRING];
389  FILE *fp,
390  *output;
391 
392  /* If there is no postgresql.conf, it can't be a config-only dir */
393  snprintf(filename, sizeof(filename), "%s/postgresql.conf", cluster->pgconfig);
394  if ((fp = fopen(filename, "r")) == NULL)
395  return;
396  fclose(fp);
397 
398  /* If PG_VERSION exists, it can't be a config-only dir */
399  snprintf(filename, sizeof(filename), "%s/PG_VERSION", cluster->pgconfig);
400  if ((fp = fopen(filename, "r")) != NULL)
401  {
402  fclose(fp);
403  return;
404  }
405 
406  /* Must be a configuration directory, so find the real data directory. */
407 
408  prep_status("Finding the real data directory for the %s cluster",
409  CLUSTER_NAME(cluster));
410 
411  /*
412  * We don't have a data directory yet, so we can't check the PG version,
413  * so this might fail --- only works for PG 9.2+. If this fails,
414  * pg_upgrade will fail anyway because the data files will not be found.
415  */
416  snprintf(cmd, sizeof(cmd), "\"%s/postgres\" -D \"%s\" -C data_directory",
417  cluster->bindir, cluster->pgconfig);
418 
419  if ((output = popen(cmd, "r")) == NULL ||
420  fgets(cmd_output, sizeof(cmd_output), output) == NULL)
421  pg_fatal("could not get data directory using %s: %s\n",
422  cmd, strerror(errno));
423 
424  pclose(output);
425 
426  /* Remove trailing newline */
427  if (strchr(cmd_output, '\n') != NULL)
428  *strchr(cmd_output, '\n') = '\0';
429 
430  cluster->pgdata = pg_strdup(cmd_output);
431 
432  check_ok();
433 }
static void output(uint64 loop_count)
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
char * pgconfig
Definition: pg_upgrade.h:265
#define MAXPGPATH
#define CLUSTER_NAME(cluster)
Definition: pg_upgrade.h:97
void prep_status(const char *fmt,...) pg_attribute_printf(1
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
static void check_ok(void)
Definition: initdb.c:2008
char * bindir
Definition: pg_upgrade.h:267
#define MAX_STRING
Definition: pg_upgrade.h:21
#define NULL
Definition: c.h:229
static char * filename
Definition: pg_dumpall.c:89
char * pgdata
Definition: pg_upgrade.h:264
const char * strerror(int errnum)
Definition: strerror.c:19
void check_and_dump_old_cluster ( bool  live_check)

Definition at line 77 of file check.c.

References ControlData::cat_ver, UserOpts::check, check_for_isn_and_int8_passing_mismatch(), check_for_jsonb_9_4_usage(), check_for_pg_role_prefix(), check_for_prepared_transactions(), check_for_reg_data_type_usage(), check_is_install_user(), check_proper_datallowconn(), ClusterInfo::controldata, generate_old_dump(), get_db_and_rel_infos(), get_loadable_libraries(), GET_MAJOR_VERSION, init_tablespaces(), JSONB_FORMAT_CHANGE_CAT_VER, ClusterInfo::major_version, new_9_0_populate_pg_largeobject_metadata(), old_9_3_check_for_line_data_type_usage(), old_9_6_check_for_unknown_data_type_usage(), old_9_6_invalidate_hash_indexes(), old_cluster, start_postmaster(), stop_postmaster(), and user_opts.

Referenced by main().

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

Definition at line 271 of file check.c.

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

Referenced by main().

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

Definition at line 229 of file check.c.

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

Referenced by main().

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

Definition at line 549 of file controldata.c.

References ControlData::align, ControlData::blocksz, ControlData::data_checksum_version, ControlData::date_is_int, ControlData::ident, ControlData::index, ControlData::large_object, ControlData::largesz, pg_fatal(), ControlData::toast, ControlData::walseg, and ControlData::walsz.

Referenced by check_cluster_compatibility().

551 {
552  if (oldctrl->align == 0 || oldctrl->align != newctrl->align)
553  pg_fatal("old and new pg_controldata alignments are invalid or do not match\n"
554  "Likely one cluster is a 32-bit install, the other 64-bit\n");
555 
556  if (oldctrl->blocksz == 0 || oldctrl->blocksz != newctrl->blocksz)
557  pg_fatal("old and new pg_controldata block sizes are invalid or do not match\n");
558 
559  if (oldctrl->largesz == 0 || oldctrl->largesz != newctrl->largesz)
560  pg_fatal("old and new pg_controldata maximum relation segment sizes are invalid or do not match\n");
561 
562  if (oldctrl->walsz == 0 || oldctrl->walsz != newctrl->walsz)
563  pg_fatal("old and new pg_controldata WAL block sizes are invalid or do not match\n");
564 
565  if (oldctrl->walseg == 0 || oldctrl->walseg != newctrl->walseg)
566  pg_fatal("old and new pg_controldata WAL segment sizes are invalid or do not match\n");
567 
568  if (oldctrl->ident == 0 || oldctrl->ident != newctrl->ident)
569  pg_fatal("old and new pg_controldata maximum identifier lengths are invalid or do not match\n");
570 
571  if (oldctrl->index == 0 || oldctrl->index != newctrl->index)
572  pg_fatal("old and new pg_controldata maximum indexed columns are invalid or do not match\n");
573 
574  if (oldctrl->toast == 0 || oldctrl->toast != newctrl->toast)
575  pg_fatal("old and new pg_controldata maximum TOAST chunk sizes are invalid or do not match\n");
576 
577  /* large_object added in 9.5, so it might not exist in the old cluster */
578  if (oldctrl->large_object != 0 &&
579  oldctrl->large_object != newctrl->large_object)
580  pg_fatal("old and new pg_controldata large-object chunk sizes are invalid or do not match\n");
581 
582  if (oldctrl->date_is_int != newctrl->date_is_int)
583  pg_fatal("old and new pg_controldata date/time storage types do not match\n");
584 
585  /*
586  * float8_pass_by_value does not need to match, but is used in
587  * check_for_isn_and_int8_passing_mismatch().
588  */
589 
590  /*
591  * We might eventually allow upgrades from checksum to no-checksum
592  * clusters.
593  */
594  if (oldctrl->data_checksum_version == 0 &&
595  newctrl->data_checksum_version != 0)
596  pg_fatal("old cluster does not use data checksums but the new one does\n");
597  else if (oldctrl->data_checksum_version != 0 &&
598  newctrl->data_checksum_version == 0)
599  pg_fatal("old cluster uses data checksums but the new one does not\n");
600  else if (oldctrl->data_checksum_version != newctrl->data_checksum_version)
601  pg_fatal("old and new cluster pg_controldata checksum versions do not match\n");
602 }
bool date_is_int
Definition: pg_upgrade.h:225
uint32 walsz
Definition: pg_upgrade.h:219
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
uint32 index
Definition: pg_upgrade.h:222
uint32 blocksz
Definition: pg_upgrade.h:217
bool data_checksum_version
Definition: pg_upgrade.h:227
uint32 ident
Definition: pg_upgrade.h:221
uint32 align
Definition: pg_upgrade.h:216
uint32 walseg
Definition: pg_upgrade.h:220
uint32 largesz
Definition: pg_upgrade.h:218
uint32 toast
Definition: pg_upgrade.h:223
uint32 large_object
Definition: pg_upgrade.h:224
void check_hard_link ( void  )

Definition at line 282 of file file.c.

References MAXPGPATH, new_cluster, old_cluster, pg_fatal(), pg_link_file, ClusterInfo::pgdata, snprintf(), strerror(), and unlink().

Referenced by check_new_cluster().

283 {
284  char existing_file[MAXPGPATH];
285  char new_link_file[MAXPGPATH];
286 
287  snprintf(existing_file, sizeof(existing_file), "%s/PG_VERSION", old_cluster.pgdata);
288  snprintf(new_link_file, sizeof(new_link_file), "%s/PG_VERSION.linktest", new_cluster.pgdata);
289  unlink(new_link_file); /* might fail */
290 
291  if (pg_link_file(existing_file, new_link_file) < 0)
292  pg_fatal("could not create hard link between old and new data directories: %s\n"
293  "In link mode the old and new data directories must be on the same file system volume.\n",
294  strerror(errno));
295 
296  unlink(new_link_file);
297 }
#define pg_link_file
Definition: pg_upgrade.h:74
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
ClusterInfo new_cluster
Definition: pg_upgrade.c:56
#define MAXPGPATH
ClusterInfo old_cluster
Definition: pg_upgrade.c:56
int unlink(const char *filename)
char * pgdata
Definition: pg_upgrade.h:264
const char * strerror(int errnum)
Definition: strerror.c:19
void check_loadable_libraries ( void  )

Definition at line 203 of file function.c.

References _, check_ok(), conn, connectToServer(), fopen_priv(), GET_MAJOR_VERSION, OSInfo::libraries, ClusterInfo::major_version, MAXPGPATH, new_cluster, NULL, OSInfo::num_libraries, old_cluster, os_info, pg_fatal(), pg_log(), PG_REPORT, PGRES_COMMAND_OK, PQclear(), PQerrorMessage(), PQescapeStringConn(), PQexec(), PQfinish(), PQresultStatus(), prep_status(), snprintf(), and strerror().

Referenced by check_new_cluster().

204 {
205  PGconn *conn = connectToServer(&new_cluster, "template1");
206  int libnum;
207  FILE *script = NULL;
208  bool found = false;
209  char output_path[MAXPGPATH];
210 
211  prep_status("Checking for presence of required libraries");
212 
213  snprintf(output_path, sizeof(output_path), "loadable_libraries.txt");
214 
215  for (libnum = 0; libnum < os_info.num_libraries; libnum++)
216  {
217  char *lib = os_info.libraries[libnum];
218  int llen = strlen(lib);
219  char cmd[7 + 2 * MAXPGPATH + 1];
220  PGresult *res;
221 
222  /*
223  * In Postgres 9.0, Python 3 support was added, and to do that, a
224  * plpython2u language was created with library name plpython2.so as a
225  * symbolic link to plpython.so. In Postgres 9.1, only the
226  * plpython2.so library was created, and both plpythonu and plpython2u
227  * pointing to it. For this reason, any reference to library name
228  * "plpython" in an old PG <= 9.1 cluster must look for "plpython2" in
229  * the new cluster.
230  *
231  * For this case, we could check pg_pltemplate, but that only works
232  * for languages, and does not help with function shared objects, so
233  * we just do a general fix.
234  */
236  strcmp(lib, "$libdir/plpython") == 0)
237  {
238  lib = "$libdir/plpython2";
239  llen = strlen(lib);
240  }
241 
242  strcpy(cmd, "LOAD '");
243  PQescapeStringConn(conn, cmd + strlen(cmd), lib, llen, NULL);
244  strcat(cmd, "'");
245 
246  res = PQexec(conn, cmd);
247 
248  if (PQresultStatus(res) != PGRES_COMMAND_OK)
249  {
250  found = true;
251 
252  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
253  pg_fatal("could not open file \"%s\": %s\n",
254  output_path, strerror(errno));
255  fprintf(script, _("could not load library \"%s\":\n%s\n"),
256  lib,
257  PQerrorMessage(conn));
258  }
259 
260  PQclear(res);
261  }
262 
263  PQfinish(conn);
264 
265  if (found)
266  {
267  fclose(script);
268  pg_log(PG_REPORT, "fatal\n");
269  pg_fatal("Your installation references loadable libraries that are missing from the\n"
270  "new installation. You can add these libraries to the new installation,\n"
271  "or remove the functions using them from the old installation. A list of\n"
272  "problem libraries is in the file:\n"
273  " %s\n\n", output_path);
274  }
275  else
276  check_ok();
277 }
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:5988
uint32 major_version
Definition: pg_upgrade.h:272
int num_libraries
Definition: pg_upgrade.h:314
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:29
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3521
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
FILE * fopen_priv(const char *path, const char *mode)
Definition: file.c:321
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2596
ClusterInfo new_cluster
Definition: pg_upgrade.c:56
PGconn * conn
Definition: streamutil.c:42
#define MAXPGPATH
char ** libraries
Definition: pg_upgrade.h:313
void prep_status(const char *fmt,...) pg_attribute_printf(1
ClusterInfo old_cluster
Definition: pg_upgrade.c:56
size_t PQescapeStringConn(PGconn *conn, char *to, const char *from, size_t length, int *error)
Definition: fe-exec.c:3314
void pg_log(eLogType type, const char *fmt,...)
Definition: logging.c:69
static void check_ok(void)
Definition: initdb.c:2008
PGconn * connectToServer(ClusterInfo *cluster, const char *db_name)
Definition: server.c:27
void PQclear(PGresult *res)
Definition: fe-exec.c:650
#define NULL
Definition: c.h:229
const char * strerror(int errnum)
Definition: strerror.c:19
OSInfo os_info
Definition: pg_upgrade.c:58
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1846
#define _(x)
Definition: elog.c:84
void check_new_cluster ( void  )

Definition at line 141 of file check.c.

References check_databases_are_compatible(), check_for_prepared_transactions(), check_hard_link(), check_is_install_user(), check_loadable_libraries(), check_new_cluster_is_empty(), get_db_and_rel_infos(), new_cluster, UserOpts::transfer_mode, TRANSFER_MODE_LINK, and user_opts.

Referenced by main().

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

Definition at line 172 of file util.c.

References PG_REPORT, and report_status().

173 {
174  /* all seems well */
175  report_status(PG_REPORT, "ok");
176  fflush(stdout);
177 }
static void void report_status(eLogType type, const char *fmt,...)
Definition: util.c:29
void check_pghost_envvar ( void  )

Definition at line 335 of file server.c.

References _PQconninfoOption::envvar, _PQconninfoOption::keyword, NULL, pg_fatal(), PQconndefaults(), PQconninfoFree(), and value.

Referenced by setup().

336 {
338  PQconninfoOption *start;
339 
340  /* Get valid libpq env vars from the PQconndefaults function */
341 
342  start = PQconndefaults();
343 
344  if (!start)
345  pg_fatal("out of memory\n");
346 
347  for (option = start; option->keyword != NULL; option++)
348  {
349  if (option->envvar && (strcmp(option->envvar, "PGHOST") == 0 ||
350  strcmp(option->envvar, "PGHOSTADDR") == 0))
351  {
352  const char *value = getenv(option->envvar);
353 
354  if (value && strlen(value) > 0 &&
355  /* check for 'local' host values */
356  (strcmp(value, "localhost") != 0 && strcmp(value, "127.0.0.1") != 0 &&
357  strcmp(value, "::1") != 0 && value[0] != '/'))
358  pg_fatal("libpq environment variable %s has a non-local server value: %s\n",
359  option->envvar, value);
360  }
361  }
362 
363  /* Free the memory that libpq allocated on our behalf */
364  PQconninfoFree(start);
365 }
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
void PQconninfoFree(PQconninfoOption *connOptions)
Definition: fe-connect.c:5838
#define NULL
Definition: c.h:229
PQconninfoOption * PQconndefaults(void)
Definition: fe-connect.c:1112
static struct @121 value
PGresult char* cluster_conn_opts ( ClusterInfo cluster)

Definition at line 88 of file server.c.

References appendPQExpBuffer(), appendPQExpBufferChar(), appendPQExpBufferStr(), appendShellString(), buf, createPQExpBuffer(), PQExpBufferData::data, NULL, os_info, ClusterInfo::port, resetPQExpBuffer(), ClusterInfo::sockdir, and OSInfo::user.

Referenced by create_new_objects(), generate_old_dump(), prepare_new_cluster(), and prepare_new_databases().

89 {
90  static PQExpBuffer buf;
91 
92  if (buf == NULL)
93  buf = createPQExpBuffer();
94  else
95  resetPQExpBuffer(buf);
96 
97  if (cluster->sockdir)
98  {
99  appendPQExpBufferStr(buf, "--host ");
100  appendShellString(buf, cluster->sockdir);
101  appendPQExpBufferChar(buf, ' ');
102  }
103  appendPQExpBuffer(buf, "--port %d --username ", cluster->port);
105 
106  return buf->data;
107 }
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:385
unsigned short port
Definition: pg_upgrade.h:271
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
static char * buf
Definition: pg_test_fsync.c:66
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:71
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
char * sockdir
Definition: pg_upgrade.h:270
OSInfo os_info
Definition: pg_upgrade.c:58
void resetPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:145
char * user
Definition: pg_upgrade.h:309
PGconn* connectToServer ( ClusterInfo cluster,
const char *  db_name 
)

Definition at line 27 of file server.c.

References _, conn, CONNECTION_OK, get_db_conn(), NULL, pg_log(), PG_REPORT, PQerrorMessage(), PQfinish(), and PQstatus().

Referenced by 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_loadable_libraries(), check_proper_datallowconn(), get_db_infos(), get_loadable_libraries(), get_rel_infos(), get_tablespace_paths(), 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(), and set_frozenxids().

28 {
29  PGconn *conn = get_db_conn(cluster, db_name);
30 
31  if (conn == NULL || PQstatus(conn) != CONNECTION_OK)
32  {
33  pg_log(PG_REPORT, "connection to database failed: %s\n",
34  PQerrorMessage(conn));
35 
36  if (conn)
37  PQfinish(conn);
38 
39  printf(_("Failure, exiting\n"));
40  exit(1);
41  }
42 
43  return conn;
44 }
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:5988
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3521
PGconn * conn
Definition: streamutil.c:42
void pg_log(eLogType type, const char *fmt,...)
Definition: logging.c:69
#define NULL
Definition: c.h:229
ConnStatusType PQstatus(const PGconn *conn)
Definition: fe-connect.c:5935
static PGconn * get_db_conn(ClusterInfo *cluster, const char *db_name)
Definition: server.c:53
#define _(x)
Definition: elog.c:84
void copyFile ( const char *  src,
const char *  dst,
const char *  schemaName,
const char *  relName 
)

Definition at line 34 of file file.c.

References _dosmaperr(), buffer, close, COPY_BUF_SIZE, PG_BINARY, pg_fatal(), pg_free(), pg_malloc(), read, strerror(), and write.

Referenced by transfer_relfile().

36 {
37 #ifndef WIN32
38  int src_fd;
39  int dest_fd;
40  char *buffer;
41 
42  if ((src_fd = open(src, O_RDONLY | PG_BINARY, 0)) < 0)
43  pg_fatal("error while copying relation \"%s.%s\": could not open file \"%s\": %s\n",
44  schemaName, relName, src, strerror(errno));
45 
46  if ((dest_fd = open(dst, O_RDWR | O_CREAT | O_EXCL | PG_BINARY,
47  S_IRUSR | S_IWUSR)) < 0)
48  pg_fatal("error while copying relation \"%s.%s\": could not create file \"%s\": %s\n",
49  schemaName, relName, dst, strerror(errno));
50 
51  /* copy in fairly large chunks for best efficiency */
52 #define COPY_BUF_SIZE (50 * BLCKSZ)
53 
54  buffer = (char *) pg_malloc(COPY_BUF_SIZE);
55 
56  /* perform data copying i.e read src source, write to destination */
57  while (true)
58  {
59  ssize_t nbytes = read(src_fd, buffer, COPY_BUF_SIZE);
60 
61  if (nbytes < 0)
62  pg_fatal("error while copying relation \"%s.%s\": could not read file \"%s\": %s\n",
63  schemaName, relName, src, strerror(errno));
64 
65  if (nbytes == 0)
66  break;
67 
68  errno = 0;
69  if (write(dest_fd, buffer, nbytes) != nbytes)
70  {
71  /* if write didn't set errno, assume problem is no disk space */
72  if (errno == 0)
73  errno = ENOSPC;
74  pg_fatal("error while copying relation \"%s.%s\": could not write file \"%s\": %s\n",
75  schemaName, relName, dst, strerror(errno));
76  }
77  }
78 
79  pg_free(buffer);
80  close(src_fd);
81  close(dest_fd);
82 
83 #else /* WIN32 */
84 
85  if (CopyFile(src, dst, true) == 0)
86  {
87  _dosmaperr(GetLastError());
88  pg_fatal("error while copying relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n",
89  schemaName, relName, src, dst, strerror(errno));
90  }
91 
92 #endif /* WIN32 */
93 }
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
#define write(a, b, c)
Definition: win32.h:14
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
#define PG_BINARY
Definition: c.h:1038
#define COPY_BUF_SIZE
void _dosmaperr(unsigned long)
Definition: win32error.c:171
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:211
void pg_free(void *ptr)
Definition: fe_memutils.c:105
const char * strerror(int errnum)
Definition: strerror.c:19
#define close(a)
Definition: win32.h:12
#define read(a, b, c)
Definition: win32.h:13
void create_script_for_cluster_analyze ( char **  analyze_script_file_name)

Definition at line 429 of file check.c.

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

Referenced by main().

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

Definition at line 519 of file check.c.

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

Referenced by main().

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

Definition at line 606 of file controldata.c.

References check_ok(), MAXPGPATH, old_cluster, pg_fatal(), pg_log(), pg_mv_file, PG_REPORT, ClusterInfo::pgdata, prep_status(), and snprintf().

Referenced by main().

607 {
608  char old_path[MAXPGPATH],
609  new_path[MAXPGPATH];
610 
611  /* rename pg_control so old server cannot be accidentally started */
612  prep_status("Adding \".old\" suffix to old global/pg_control");
613 
614  snprintf(old_path, sizeof(old_path), "%s/global/pg_control", old_cluster.pgdata);
615  snprintf(new_path, sizeof(new_path), "%s/global/pg_control.old", old_cluster.pgdata);
616  if (pg_mv_file(old_path, new_path) != 0)
617  pg_fatal("Unable to rename %s to %s.\n", old_path, new_path);
618  check_ok();
619 
620  pg_log(PG_REPORT, "\n"
621  "If you want to start the old cluster, you will need to remove\n"
622  "the \".old\" suffix from %s/global/pg_control.old.\n"
623  "Because \"link\" mode was used, the old cluster cannot be safely\n"
624  "started once the new cluster has been started.\n\n", old_cluster.pgdata);
625 }
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
#define MAXPGPATH
void prep_status(const char *fmt,...) pg_attribute_printf(1
ClusterInfo old_cluster
Definition: pg_upgrade.c:56
void pg_log(eLogType type, const char *fmt,...)
Definition: logging.c:69
static void check_ok(void)
Definition: initdb.c:2008
char * pgdata
Definition: pg_upgrade.h:264
#define pg_mv_file
Definition: pg_upgrade.h:73
void end_progress_output ( void  )

Definition at line 44 of file util.c.

References prep_status().

Referenced by create_new_objects(), generate_old_dump(), and transfer_all_new_tablespaces().

45 {
46  /*
47  * In case nothing printed; pass a space so gcc doesn't complain about
48  * empty format string.
49  */
50  prep_status(" ");
51 }
void prep_status(const char *fmt,...)
Definition: util.c:70
bool exec_prog ( const char *  log_file,
const char *  opt_log_file,
bool  throw_error,
const char *  fmt,
  ... 
)
FILE* fopen_priv ( const char *  path,
const char *  mode 
)

Definition at line 321 of file file.c.

References S_IRWXG, and S_IRWXO.

Referenced by check_for_isn_and_int8_passing_mismatch(), check_for_jsonb_9_4_usage(), check_for_reg_data_type_usage(), check_loadable_libraries(), create_script_for_cluster_analyze(), create_script_for_old_cluster_deletion(), 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(), and parseCommandLine().

322 {
323  mode_t old_umask = umask(S_IRWXG | S_IRWXO);
324  FILE *fp;
325 
326  fp = fopen(path, mode);
327 
328  umask(old_umask); /* we assume this can't change errno */
329 
330  return fp;
331 }
#define S_IRWXO
Definition: win32.h:455
#define S_IRWXG
Definition: win32.h:451
FileNameMap* gen_db_file_maps ( DbInfo old_db,
DbInfo new_db,
int *  nmaps,
const char *  old_pgdata,
const char *  new_pgdata 
)

Definition at line 41 of file info.c.

References create_rel_filename_map(), DbInfo::db_name, GET_MAJOR_VERSION, ClusterInfo::major_version, maps, RelInfoArr::nrels, RelInfo::nspname, NULL, old_cluster, pg_fatal(), pg_log(), pg_malloc(), PG_WARNING, DbInfo::rel_arr, RelInfo::relname, RelInfo::reloid, RelInfoArr::rels, and report_unmatched_relation().

Referenced by transfer_all_new_dbs().

44 {
46  int old_relnum,
47  new_relnum;
48  int num_maps = 0;
49  bool all_matched = true;
50 
51  /* There will certainly not be more mappings than there are old rels */
52  maps = (FileNameMap *) pg_malloc(sizeof(FileNameMap) *
53  old_db->rel_arr.nrels);
54 
55  /*
56  * Each of the RelInfo arrays should be sorted by OID. Scan through them
57  * and match them up. If we fail to match everything, we'll abort, but
58  * first print as much info as we can about mismatches.
59  */
60  old_relnum = new_relnum = 0;
61  while (old_relnum < old_db->rel_arr.nrels ||
62  new_relnum < new_db->rel_arr.nrels)
63  {
64  RelInfo *old_rel = (old_relnum < old_db->rel_arr.nrels) ?
65  &old_db->rel_arr.rels[old_relnum] : NULL;
66  RelInfo *new_rel = (new_relnum < new_db->rel_arr.nrels) ?
67  &new_db->rel_arr.rels[new_relnum] : NULL;
68 
69  /* handle running off one array before the other */
70  if (!new_rel)
71  {
72  /*
73  * old_rel is unmatched. This should never happen, because we
74  * force new rels to have TOAST tables if the old one did.
75  */
76  report_unmatched_relation(old_rel, old_db, false);
77  all_matched = false;
78  old_relnum++;
79  continue;
80  }
81  if (!old_rel)
82  {
83  /*
84  * new_rel is unmatched. This shouldn't really happen either, but
85  * if it's a TOAST table, we can ignore it and continue
86  * processing, assuming that the new server made a TOAST table
87  * that wasn't needed.
88  */
89  if (strcmp(new_rel->nspname, "pg_toast") != 0)
90  {
91  report_unmatched_relation(new_rel, new_db, true);
92  all_matched = false;
93  }
94  new_relnum++;
95  continue;
96  }
97 
98  /* check for mismatched OID */
99  if (old_rel->reloid < new_rel->reloid)
100  {
101  /* old_rel is unmatched, see comment above */
102  report_unmatched_relation(old_rel, old_db, false);
103  all_matched = false;
104  old_relnum++;
105  continue;
106  }
107  else if (old_rel->reloid > new_rel->reloid)
108  {
109  /* new_rel is unmatched, see comment above */
110  if (strcmp(new_rel->nspname, "pg_toast") != 0)
111  {
112  report_unmatched_relation(new_rel, new_db, true);
113  all_matched = false;
114  }
115  new_relnum++;
116  continue;
117  }
118 
119  /*
120  * Verify that rels of same OID have same name. The namespace name
121  * should always match, but the relname might not match for TOAST
122  * tables (and, therefore, their indexes).
123  *
124  * TOAST table names initially match the heap pg_class oid, but
125  * pre-9.0 they can change during certain commands such as CLUSTER, so
126  * don't insist on a match if old cluster is < 9.0.
127  */
128  if (strcmp(old_rel->nspname, new_rel->nspname) != 0 ||
129  (strcmp(old_rel->relname, new_rel->relname) != 0 &&
131  strcmp(old_rel->nspname, "pg_toast") != 0)))
132  {
133  pg_log(PG_WARNING, "Relation names for OID %u in database \"%s\" do not match: "
134  "old name \"%s.%s\", new name \"%s.%s\"\n",
135  old_rel->reloid, old_db->db_name,
136  old_rel->nspname, old_rel->relname,
137  new_rel->nspname, new_rel->relname);
138  all_matched = false;
139  old_relnum++;
140  new_relnum++;
141  continue;
142  }
143 
144  /* OK, create a mapping entry */
145  create_rel_filename_map(old_pgdata, new_pgdata, old_db, new_db,
146  old_rel, new_rel, maps + num_maps);
147  num_maps++;
148  old_relnum++;
149  new_relnum++;
150  }
151 
152  if (!all_matched)
153  pg_fatal("Failed to match up old and new tables in database \"%s\"\n",
154  old_db->db_name);
155 
156  *nmaps = num_maps;
157  return maps;
158 }
uint32 major_version
Definition: pg_upgrade.h:272
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:29
char * relname
Definition: pg_upgrade.h:140
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
Oid reloid
Definition: pg_upgrade.h:141
char * nspname
Definition: pg_upgrade.h:139
RelInfo * rels
Definition: pg_upgrade.h:152
ClusterInfo old_cluster
Definition: pg_upgrade.c:56
void pg_log(eLogType type, const char *fmt,...)
Definition: logging.c:69
static void report_unmatched_relation(const RelInfo *rel, const DbInfo *db, bool is_new_db)
Definition: info.c:224
#define NULL
Definition: c.h:229
RelInfoArr rel_arr
Definition: pg_upgrade.h:191
static const pg_conv_map maps[]
static void create_rel_filename_map(const char *old_data, const char *new_data, const DbInfo *old_db, const DbInfo *new_db, const RelInfo *old_rel, const RelInfo *new_rel, FileNameMap *map)
Definition: info.c:167
char * db_name
Definition: pg_upgrade.h:185
void generate_old_dump ( void  )

Definition at line 18 of file dump.c.

References appendConnStrVal(), appendPQExpBuffer(), appendShellString(), ClusterInfo::bindir, check_ok(), cluster_conn_opts(), connstr, PQExpBufferData::data, DB_DUMP_FILE_MASK, DB_DUMP_LOG_FILE_MASK, DbInfo::db_name, DbInfo::db_oid, ClusterInfo::dbarr, DbInfoArr::dbs, end_progress_output(), exec_prog(), GLOBALS_DUMP_FILE, initPQExpBuffer(), log_opts, MAXPGPATH, DbInfoArr::ndbs, new_cluster, NULL, old_cluster, parallel_exec_prog(), pg_log(), PG_STATUS, prep_status(), reap_child(), S_IRWXG, S_IRWXO, snprintf(), termPQExpBuffer(), UTILITY_LOG_FILE, and LogOpts::verbose.

Referenced by check_and_dump_old_cluster().

19 {
20  int dbnum;
21  mode_t old_umask;
22 
23  prep_status("Creating dump of global objects");
24 
25  /* run new pg_dumpall binary for globals */
27  "\"%s/pg_dumpall\" %s --globals-only --quote-all-identifiers "
28  "--binary-upgrade %s -f %s",
30  log_opts.verbose ? "--verbose" : "",
32  check_ok();
33 
34  prep_status("Creating dump of database schemas\n");
35 
36  /*
37  * Set umask for this function, all functions it calls, and all
38  * subprocesses/threads it creates. We can't use fopen_priv() as Windows
39  * uses threads and umask is process-global.
40  */
41  old_umask = umask(S_IRWXG | S_IRWXO);
42 
43  /* create per-db dump files */
44  for (dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
45  {
46  char sql_file_name[MAXPGPATH],
47  log_file_name[MAXPGPATH];
48  DbInfo *old_db = &old_cluster.dbarr.dbs[dbnum];
50  escaped_connstr;
51 
52  initPQExpBuffer(&connstr);
53  appendPQExpBuffer(&connstr, "dbname=");
54  appendConnStrVal(&connstr, old_db->db_name);
55  initPQExpBuffer(&escaped_connstr);
56  appendShellString(&escaped_connstr, connstr.data);
57  termPQExpBuffer(&connstr);
58 
59  pg_log(PG_STATUS, "%s", old_db->db_name);
60  snprintf(sql_file_name, sizeof(sql_file_name), DB_DUMP_FILE_MASK, old_db->db_oid);
61  snprintf(log_file_name, sizeof(log_file_name), DB_DUMP_LOG_FILE_MASK, old_db->db_oid);
62 
63  parallel_exec_prog(log_file_name, NULL,
64  "\"%s/pg_dump\" %s --schema-only --quote-all-identifiers "
65  "--binary-upgrade --format=custom %s --file=\"%s\" %s",
67  log_opts.verbose ? "--verbose" : "",
68  sql_file_name, escaped_connstr.data);
69 
70  termPQExpBuffer(&escaped_connstr);
71  }
72 
73  /* reap all children */
74  while (reap_child(true) == true)
75  ;
76 
77  umask(old_umask);
78 
80  check_ok();
81 }
void parallel_exec_prog(const char *log_file, const char *opt_log_file, const char *fmt,...)
Definition: parallel.c:63
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
void end_progress_output(void)
Definition: util.c:44
void appendConnStrVal(PQExpBuffer buf, const char *str)
Definition: string_utils.c:551
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
PGresult char * cluster_conn_opts(ClusterInfo *cluster)
Definition: server.c:88
LogOpts log_opts
Definition: util.c:18
Oid db_oid
Definition: pg_upgrade.h:184
ClusterInfo new_cluster
Definition: pg_upgrade.c:56
#define MAXPGPATH
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
void prep_status(const char *fmt,...) pg_attribute_printf(1
ClusterInfo old_cluster
Definition: pg_upgrade.c:56
void pg_log(eLogType type, const char *fmt,...)
Definition: logging.c:69
static void check_ok(void)
Definition: initdb.c:2008
#define DB_DUMP_FILE_MASK
Definition: pg_upgrade.h:33
bool verbose
Definition: pg_upgrade.h:285
char * bindir
Definition: pg_upgrade.h:267
#define S_IRWXO
Definition: win32.h:455
void appendShellString(PQExpBuffer buf, const char *str)
Definition: string_utils.c:434
DbInfoArr dbarr
Definition: pg_upgrade.h:263
#define NULL
Definition: c.h:229
#define DB_DUMP_LOG_FILE_MASK
Definition: pg_upgrade.h:35
bool reap_child(bool wait_for_child)
Definition: parallel.c:290
#define S_IRWXG
Definition: win32.h:451
#define UTILITY_LOG_FILE
Definition: pg_upgrade.h:37
bool exec_prog(const char *log_file, const char *opt_log_file, bool throw_error, const char *fmt,...)
Definition: exec.c:77
char * db_name
Definition: pg_upgrade.h:185
#define GLOBALS_DUMP_FILE
Definition: pg_upgrade.h:32
DbInfo * dbs
Definition: pg_upgrade.h:196
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
static char * connstr
Definition: pg_dumpall.c:64
void get_control_data ( ClusterInfo cluster,
bool  live_check 
)

Definition at line 34 of file controldata.c.

References ControlData::align, ClusterInfo::bin_version, ClusterInfo::bindir, ControlData::blocksz, ControlData::cat_ver, ControlData::chkpnt_nxtepoch, ControlData::chkpnt_nxtmulti, ControlData::chkpnt_nxtmxoff, ControlData::chkpnt_nxtoid, ControlData::chkpnt_nxtxid, ControlData::chkpnt_oldstMulti, CLUSTER_NAME, ClusterInfo::controldata, ControlData::ctrl_ver, ControlData::data_checksum_version, ControlData::date_is_int, ControlData::float8_pass_by_value, GET_MAJOR_VERSION, ControlData::ident, ControlData::index, ControlData::large_object, LARGE_OBJECT_SIZE_PG_CONTROL_VER, ControlData::largesz, lc_collate, lc_ctype, lc_messages, lc_monetary, lc_numeric, lc_time, ClusterInfo::major_version, MAX_STRING, MAXPGPATH, MULTIXACT_FORMATCHANGE_CAT_VER, ControlData::nextxlogfile, NULL, output(), pg_fatal(), pg_free(), pg_log(), pg_putenv(), PG_REPORT, pg_strdup(), PG_VERBOSE, ClusterInfo::pgdata, snprintf(), str2uint(), strerror(), strlcpy(), ControlData::toast, ControlData::walseg, and ControlData::walsz.

Referenced by check_cluster_compatibility().

35 {
36  char cmd[MAXPGPATH];
37  char bufin[MAX_STRING];
38  FILE *output;
39  char *p;
40  bool got_tli = false;
41  bool got_log_id = false;
42  bool got_log_seg = false;
43  bool got_xid = false;
44  bool got_oid = false;
45  bool got_multi = false;
46  bool got_oldestmulti = false;
47  bool got_mxoff = false;
48  bool got_nextxlogfile = false;
49  bool got_float8_pass_by_value = false;
50  bool got_align = false;
51  bool got_blocksz = false;
52  bool got_largesz = false;
53  bool got_walsz = false;
54  bool got_walseg = false;
55  bool got_ident = false;
56  bool got_index = false;
57  bool got_toast = false;
58  bool got_large_object = false;
59  bool got_date_is_int = false;
60  bool got_data_checksum_version = false;
61  char *lc_collate = NULL;
62  char *lc_ctype = NULL;
63  char *lc_monetary = NULL;
64  char *lc_numeric = NULL;
65  char *lc_time = NULL;
66  char *lang = NULL;
67  char *language = NULL;
68  char *lc_all = NULL;
69  char *lc_messages = NULL;
70  uint32 tli = 0;
71  uint32 logid = 0;
72  uint32 segno = 0;
73  char *resetwal_bin;
74 
75 
76  /*
77  * Because we test the pg_resetwal output as strings, it has to be in
78  * English. Copied from pg_regress.c.
79  */
80  if (getenv("LC_COLLATE"))
81  lc_collate = pg_strdup(getenv("LC_COLLATE"));
82  if (getenv("LC_CTYPE"))
83  lc_ctype = pg_strdup(getenv("LC_CTYPE"));
84  if (getenv("LC_MONETARY"))
85  lc_monetary = pg_strdup(getenv("LC_MONETARY"));
86  if (getenv("LC_NUMERIC"))
87  lc_numeric = pg_strdup(getenv("LC_NUMERIC"));
88  if (getenv("LC_TIME"))
89  lc_time = pg_strdup(getenv("LC_TIME"));
90  if (getenv("LANG"))
91  lang = pg_strdup(getenv("LANG"));
92  if (getenv("LANGUAGE"))
93  language = pg_strdup(getenv("LANGUAGE"));
94  if (getenv("LC_ALL"))
95  lc_all = pg_strdup(getenv("LC_ALL"));
96  if (getenv("LC_MESSAGES"))
97  lc_messages = pg_strdup(getenv("LC_MESSAGES"));
98 
99  pg_putenv("LC_COLLATE", NULL);
100  pg_putenv("LC_CTYPE", NULL);
101  pg_putenv("LC_MONETARY", NULL);
102  pg_putenv("LC_NUMERIC", NULL);
103  pg_putenv("LC_TIME", NULL);
104  pg_putenv("LANG",
105 #ifndef WIN32
106  NULL);
107 #else
108  /* On Windows the default locale cannot be English, so force it */
109  "en");
110 #endif
111  pg_putenv("LANGUAGE", NULL);
112  pg_putenv("LC_ALL", NULL);
113  pg_putenv("LC_MESSAGES", "C");
114 
115  /* pg_resetxlog has been renamed to pg_resetwal in version 10 */
116  if (GET_MAJOR_VERSION(cluster->bin_version) < 1000)
117  resetwal_bin = "pg_resetxlog\" -n";
118  else
119  resetwal_bin = "pg_resetwal\" -n";
120  snprintf(cmd, sizeof(cmd), "\"%s/%s \"%s\"",
121  cluster->bindir,
122  live_check ? "pg_controldata\"" : resetwal_bin,
123  cluster->pgdata);
124  fflush(stdout);
125  fflush(stderr);
126 
127  if ((output = popen(cmd, "r")) == NULL)
128  pg_fatal("could not get control data using %s: %s\n",
129  cmd, strerror(errno));
130 
131  /* Only in <= 9.2 */
132  if (GET_MAJOR_VERSION(cluster->major_version) <= 902)
133  {
134  cluster->controldata.data_checksum_version = 0;
135  got_data_checksum_version = true;
136  }
137 
138  /* we have the result of cmd in "output". so parse it line by line now */
139  while (fgets(bufin, sizeof(bufin), output))
140  {
141  pg_log(PG_VERBOSE, "%s", bufin);
142 
143  if ((p = strstr(bufin, "pg_control version number:")) != NULL)
144  {
145  p = strchr(p, ':');
146 
147  if (p == NULL || strlen(p) <= 1)
148  pg_fatal("%d: pg_resetwal problem\n", __LINE__);
149 
150  p++; /* remove ':' char */
151  cluster->controldata.ctrl_ver = str2uint(p);
152  }
153  else if ((p = strstr(bufin, "Catalog version number:")) != NULL)
154  {
155  p = strchr(p, ':');
156 
157  if (p == NULL || strlen(p) <= 1)
158  pg_fatal("%d: controldata retrieval problem\n", __LINE__);
159 
160  p++; /* remove ':' char */
161  cluster->controldata.cat_ver = str2uint(p);
162  }
163  else if ((p = strstr(bufin, "Latest checkpoint's TimeLineID:")) != NULL)
164  {
165  p = strchr(p, ':');
166 
167  if (p == NULL || strlen(p) <= 1)
168  pg_fatal("%d: controldata retrieval problem\n", __LINE__);
169 
170  p++; /* remove ':' char */
171  tli = str2uint(p);
172  got_tli = true;
173  }
174  else if ((p = strstr(bufin, "First log file ID after reset:")) != NULL)
175  {
176  p = strchr(p, ':');
177 
178  if (p == NULL || strlen(p) <= 1)
179  pg_fatal("%d: controldata retrieval problem\n", __LINE__);
180 
181  p++; /* remove ':' char */
182  logid = str2uint(p);
183  got_log_id = true;
184  }
185  else if ((p = strstr(bufin, "First log file segment after reset:")) != NULL)
186  {
187  p = strchr(p, ':');
188 
189  if (p == NULL || strlen(p) <= 1)
190  pg_fatal("%d: controldata retrieval problem\n", __LINE__);
191 
192  p++; /* remove ':' char */
193  segno = str2uint(p);
194  got_log_seg = true;
195  }
196  else if ((p = strstr(bufin, "Latest checkpoint's NextXID:")) != NULL)
197  {
198  p = strchr(p, ':');
199 
200  if (p == NULL || strlen(p) <= 1)
201  pg_fatal("%d: controldata retrieval problem\n", __LINE__);
202 
203  p++; /* remove ':' char */
204  cluster->controldata.chkpnt_nxtepoch = str2uint(p);
205 
206  /*
207  * Delimiter changed from '/' to ':' in 9.6. We don't test for
208  * the catalog version of the change because the catalog version
209  * is pulled from pg_controldata too, and it isn't worth adding an
210  * order dependency for this --- we just check the string.
211  */
212  if (strchr(p, '/') != NULL)
213  p = strchr(p, '/');
214  else if (GET_MAJOR_VERSION(cluster->major_version) >= 906)
215  p = strchr(p, ':');
216  else
217  p = NULL;
218 
219  if (p == NULL || strlen(p) <= 1)
220  pg_fatal("%d: controldata retrieval problem\n", __LINE__);
221 
222  p++; /* remove '/' or ':' char */
223  cluster->controldata.chkpnt_nxtxid = str2uint(p);
224  got_xid = true;
225  }
226  else if ((p = strstr(bufin, "Latest checkpoint's NextOID:")) != NULL)
227  {
228  p = strchr(p, ':');
229 
230  if (p == NULL || strlen(p) <= 1)
231  pg_fatal("%d: controldata retrieval problem\n", __LINE__);
232 
233  p++; /* remove ':' char */
234  cluster->controldata.chkpnt_nxtoid = str2uint(p);
235  got_oid = true;
236  }
237  else if ((p = strstr(bufin, "Latest checkpoint's NextMultiXactId:")) != NULL)
238  {
239  p = strchr(p, ':');
240 
241  if (p == NULL || strlen(p) <= 1)
242  pg_fatal("%d: controldata retrieval problem\n", __LINE__);
243 
244  p++; /* remove ':' char */
245  cluster->controldata.chkpnt_nxtmulti = str2uint(p);
246  got_multi = true;
247  }
248  else if ((p = strstr(bufin, "Latest checkpoint's oldestMultiXid:")) != NULL)
249  {
250  p = strchr(p, ':');
251 
252  if (p == NULL || strlen(p) <= 1)
253  pg_fatal("%d: controldata retrieval problem\n", __LINE__);
254 
255  p++; /* remove ':' char */
256  cluster->controldata.chkpnt_oldstMulti = str2uint(p);
257  got_oldestmulti = true;
258  }
259  else if ((p = strstr(bufin, "Latest checkpoint's NextMultiOffset:")) != NULL)
260  {
261  p = strchr(p, ':');
262 
263  if (p == NULL || strlen(p) <= 1)
264  pg_fatal("%d: controldata retrieval problem\n", __LINE__);
265 
266  p++; /* remove ':' char */
267  cluster->controldata.chkpnt_nxtmxoff = str2uint(p);
268  got_mxoff = true;
269  }
270  else if ((p = strstr(bufin, "First log segment after reset:")) != NULL)
271  {
272  /* Skip the colon and any whitespace after it */
273  p = strchr(p, ':');
274  if (p == NULL || strlen(p) <= 1)
275  pg_fatal("%d: controldata retrieval problem\n", __LINE__);
276  p = strpbrk(p, "01234567890ABCDEF");
277  if (p == NULL || strlen(p) <= 1)
278  pg_fatal("%d: controldata retrieval problem\n", __LINE__);
279 
280  /* Make sure it looks like a valid WAL file name */
281  if (strspn(p, "0123456789ABCDEF") != 24)
282  pg_fatal("%d: controldata retrieval problem\n", __LINE__);
283 
284  strlcpy(cluster->controldata.nextxlogfile, p, 25);
285  got_nextxlogfile = true;
286  }
287  else if ((p = strstr(bufin, "Float8 argument passing:")) != NULL)
288  {
289  p = strchr(p, ':');
290 
291  if (p == NULL || strlen(p) <= 1)
292  pg_fatal("%d: controldata retrieval problem\n", __LINE__);
293 
294  p++; /* remove ':' char */
295  /* used later for contrib check */
296  cluster->controldata.float8_pass_by_value = strstr(p, "by value") != NULL;
297  got_float8_pass_by_value = true;
298  }
299  else if ((p = strstr(bufin, "Maximum data alignment:")) != NULL)
300  {
301  p = strchr(p, ':');
302 
303  if (p == NULL || strlen(p) <= 1)
304  pg_fatal("%d: controldata retrieval problem\n", __LINE__);
305 
306  p++; /* remove ':' char */
307  cluster->controldata.align = str2uint(p);
308  got_align = true;
309  }
310  else if ((p = strstr(bufin, "Database block size:")) != NULL)
311  {
312  p = strchr(p, ':');
313 
314  if (p == NULL || strlen(p) <= 1)
315  pg_fatal("%d: controldata retrieval problem\n", __LINE__);
316 
317  p++; /* remove ':' char */
318  cluster->controldata.blocksz = str2uint(p);
319  got_blocksz = true;
320  }
321  else if ((p = strstr(bufin, "Blocks per segment of large relation:")) != NULL)
322  {
323  p = strchr(p, ':');
324 
325  if (p == NULL || strlen(p) <= 1)
326  pg_fatal("%d: controldata retrieval problem\n", __LINE__);
327 
328  p++; /* remove ':' char */
329  cluster->controldata.largesz = str2uint(p);
330  got_largesz = true;
331  }
332  else if ((p = strstr(bufin, "WAL block size:")) != NULL)
333  {
334  p = strchr(p, ':');
335 
336  if (p == NULL || strlen(p) <= 1)
337  pg_fatal("%d: controldata retrieval problem\n", __LINE__);
338 
339  p++; /* remove ':' char */
340  cluster->controldata.walsz = str2uint(p);
341  got_walsz = true;
342  }
343  else if ((p = strstr(bufin, "Bytes per WAL segment:")) != NULL)
344  {
345  p = strchr(p, ':');
346 
347  if (p == NULL || strlen(p) <= 1)
348  pg_fatal("%d: controldata retrieval problem\n", __LINE__);
349 
350  p++; /* remove ':' char */
351  cluster->controldata.walseg = str2uint(p);
352  got_walseg = true;
353  }
354  else if ((p = strstr(bufin, "Maximum length of identifiers:")) != NULL)
355  {
356  p = strchr(p, ':');
357 
358  if (p == NULL || strlen(p) <= 1)
359  pg_fatal("%d: controldata retrieval problem\n", __LINE__);
360 
361  p++; /* remove ':' char */
362  cluster->controldata.ident = str2uint(p);
363  got_ident = true;
364  }
365  else if ((p = strstr(bufin, "Maximum columns in an index:")) != NULL)
366  {
367  p = strchr(p, ':');
368 
369  if (p == NULL || strlen(p) <= 1)
370  pg_fatal("%d: controldata retrieval problem\n", __LINE__);
371 
372  p++; /* remove ':' char */
373  cluster->controldata.index = str2uint(p);
374  got_index = true;
375  }
376  else if ((p = strstr(bufin, "Maximum size of a TOAST chunk:")) != NULL)
377  {
378  p = strchr(p, ':');
379 
380  if (p == NULL || strlen(p) <= 1)
381  pg_fatal("%d: controldata retrieval problem\n", __LINE__);
382 
383  p++; /* remove ':' char */
384  cluster->controldata.toast = str2uint(p);
385  got_toast = true;
386  }
387  else if ((p = strstr(bufin, "Size of a large-object chunk:")) != NULL)
388  {
389  p = strchr(p, ':');
390 
391  if (p == NULL || strlen(p) <= 1)
392  pg_fatal("%d: controldata retrieval problem\n", __LINE__);
393 
394  p++; /* remove ':' char */
395  cluster->controldata.large_object = str2uint(p);
396  got_large_object = true;
397  }
398  else if ((p = strstr(bufin, "Date/time type storage:")) != NULL)
399  {
400  p = strchr(p, ':');
401 
402  if (p == NULL || strlen(p) <= 1)
403  pg_fatal("%d: controldata retrieval problem\n", __LINE__);
404 
405  p++; /* remove ':' char */
406  cluster->controldata.date_is_int = strstr(p, "64-bit integers") != NULL;
407  got_date_is_int = true;
408  }
409  else if ((p = strstr(bufin, "checksum")) != NULL)
410  {
411  p = strchr(p, ':');
412 
413  if (p == NULL || strlen(p) <= 1)
414  pg_fatal("%d: controldata retrieval problem\n", __LINE__);
415 
416  p++; /* remove ':' char */
417  /* used later for contrib check */
419  got_data_checksum_version = true;
420  }
421  }
422 
423  pclose(output);
424 
425  /*
426  * Restore environment variables
427  */
428  pg_putenv("LC_COLLATE", lc_collate);
429  pg_putenv("LC_CTYPE", lc_ctype);
430  pg_putenv("LC_MONETARY", lc_monetary);
431  pg_putenv("LC_NUMERIC", lc_numeric);
432  pg_putenv("LC_TIME", lc_time);
433  pg_putenv("LANG", lang);
434  pg_putenv("LANGUAGE", language);
435  pg_putenv("LC_ALL", lc_all);
436  pg_putenv("LC_MESSAGES", lc_messages);
437 
438  pg_free(lc_collate);
439  pg_free(lc_ctype);
440  pg_free(lc_monetary);
441  pg_free(lc_numeric);
442  pg_free(lc_time);
443  pg_free(lang);
444  pg_free(language);
445  pg_free(lc_all);
446  pg_free(lc_messages);
447 
448  /*
449  * Before 9.3, pg_resetwal reported the xlogid and segno of the first log
450  * file after reset as separate lines. Starting with 9.3, it reports the
451  * WAL file name. If the old cluster is older than 9.3, we construct the
452  * WAL file name from the xlogid and segno.
453  */
454  if (GET_MAJOR_VERSION(cluster->major_version) <= 902)
455  {
456  if (got_tli && got_log_id && got_log_seg)
457  {
458  snprintf(cluster->controldata.nextxlogfile, 25, "%08X%08X%08X",
459  tli, logid, segno);
460  got_nextxlogfile = true;
461  }
462  }
463 
464  /* verify that we got all the mandatory pg_control data */
465  if (!got_xid || !got_oid ||
466  !got_multi ||
467  (!got_oldestmulti &&
469  !got_mxoff || (!live_check && !got_nextxlogfile) ||
470  !got_float8_pass_by_value || !got_align || !got_blocksz ||
471  !got_largesz || !got_walsz || !got_walseg || !got_ident ||
472  !got_index || !got_toast ||
473  (!got_large_object &&
475  !got_date_is_int || !got_data_checksum_version)
476  {
478  "The %s cluster lacks some required control information:\n",
479  CLUSTER_NAME(cluster));
480 
481  if (!got_xid)
482  pg_log(PG_REPORT, " checkpoint next XID\n");
483 
484  if (!got_oid)
485  pg_log(PG_REPORT, " latest checkpoint next OID\n");
486 
487  if (!got_multi)
488  pg_log(PG_REPORT, " latest checkpoint next MultiXactId\n");
489 
490  if (!got_oldestmulti &&
492  pg_log(PG_REPORT, " latest checkpoint oldest MultiXactId\n");
493 
494  if (!got_mxoff)
495  pg_log(PG_REPORT, " latest checkpoint next MultiXactOffset\n");
496 
497  if (!live_check && !got_nextxlogfile)
498  pg_log(PG_REPORT, " first WAL segment after reset\n");
499 
500  if (!got_float8_pass_by_value)
501  pg_log(PG_REPORT, " float8 argument passing method\n");
502 
503  if (!got_align)
504  pg_log(PG_REPORT, " maximum alignment\n");
505 
506  if (!got_blocksz)
507  pg_log(PG_REPORT, " block size\n");
508 
509  if (!got_largesz)
510  pg_log(PG_REPORT, " large relation segment size\n");
511 
512  if (!got_walsz)
513  pg_log(PG_REPORT, " WAL block size\n");
514 
515  if (!got_walseg)
516  pg_log(PG_REPORT, " WAL segment size\n");
517 
518  if (!got_ident)
519  pg_log(PG_REPORT, " maximum identifier length\n");
520 
521  if (!got_index)
522  pg_log(PG_REPORT, " maximum number of indexed columns\n");
523 
524  if (!got_toast)
525  pg_log(PG_REPORT, " maximum TOAST chunk size\n");
526 
527  if (!got_large_object &&
529  pg_log(PG_REPORT, " large-object chunk size\n");
530 
531  if (!got_date_is_int)
532  pg_log(PG_REPORT, " dates/times are integers?\n");
533 
534  /* value added in Postgres 9.3 */
535  if (!got_data_checksum_version)
536  pg_log(PG_REPORT, " data checksum version\n");
537 
538  pg_fatal("Cannot continue without required control information, terminating\n");
539  }
540 }
bool date_is_int
Definition: pg_upgrade.h:225
static char * lc_monetary
Definition: initdb.c:126
uint32 major_version
Definition: pg_upgrade.h:272
unsigned int str2uint(const char *str)
Definition: util.c:241
static char * lc_collate
Definition: initdb.c:124
ControlData controldata
Definition: pg_upgrade.h:262
static void output(uint64 loop_count)
#define LARGE_OBJECT_SIZE_PG_CONTROL_VER
Definition: pg_upgrade.h:126
uint32 chkpnt_nxtoid
Definition: pg_upgrade.h:212
uint32 walsz
Definition: pg_upgrade.h:219
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:29
char nextxlogfile[25]
Definition: pg_upgrade.h:209
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
uint32 index
Definition: pg_upgrade.h:222
uint32 chkpnt_nxtmxoff
Definition: pg_upgrade.h:214
static char * lc_time
Definition: initdb.c:128
uint32 blocksz
Definition: pg_upgrade.h:217
uint32 chkpnt_nxtxid
Definition: pg_upgrade.h:210
static char * lc_messages
Definition: initdb.c:129
uint32 chkpnt_nxtepoch
Definition: pg_upgrade.h:211
#define MAXPGPATH
static char * lc_ctype
Definition: initdb.c:125
static char * lc_numeric
Definition: initdb.c:127
#define CLUSTER_NAME(cluster)
Definition: pg_upgrade.h:97
bool data_checksum_version
Definition: pg_upgrade.h:227
uint32 ident
Definition: pg_upgrade.h:221
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
unsigned int uint32
Definition: c.h:268
void pg_log(eLogType type, const char *fmt,...)
Definition: logging.c:69
uint32 align
Definition: pg_upgrade.h:216
uint32 chkpnt_oldstMulti
Definition: pg_upgrade.h:215
uint32 walseg
Definition: pg_upgrade.h:220
char * bindir
Definition: pg_upgrade.h:267
#define MAX_STRING
Definition: pg_upgrade.h:21
uint32 cat_ver
Definition: pg_upgrade.h:208
uint32 chkpnt_nxtmulti
Definition: pg_upgrade.h:213
uint32 largesz
Definition: pg_upgrade.h:218
uint32 bin_version
Definition: pg_upgrade.h:274
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
#define NULL
Definition: c.h:229
uint32 toast
Definition: pg_upgrade.h:223
uint32 large_object
Definition: pg_upgrade.h:224
void pg_free(void *ptr)
Definition: fe_memutils.c:105
#define MULTIXACT_FORMATCHANGE_CAT_VER
Definition: pg_upgrade.h:120
uint32 ctrl_ver
Definition: pg_upgrade.h:207
char * pgdata
Definition: pg_upgrade.h:264
const char * strerror(int errnum)
Definition: strerror.c:19
void pg_putenv(const char *var, const char *val)
Definition: util.c:254
bool float8_pass_by_value
Definition: pg_upgrade.h:226
void get_db_and_rel_infos ( ClusterInfo cluster)

Definition at line 311 of file info.c.

References CLUSTER_NAME, ClusterInfo::dbarr, DbInfoArr::dbs, free_db_and_rel_infos(), get_db_infos(), get_rel_infos(), log_opts, DbInfoArr::ndbs, NULL, pg_log(), PG_VERBOSE, print_db_infos(), and LogOpts::verbose.

Referenced by check_and_dump_old_cluster(), check_new_cluster(), create_new_objects(), and prepare_new_databases().

312 {
313  int dbnum;
314 
315  if (cluster->dbarr.dbs != NULL)
316  free_db_and_rel_infos(&cluster->dbarr);
317 
318  get_db_infos(cluster);
319 
320  for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
321  get_rel_infos(cluster, &cluster->dbarr.dbs[dbnum]);
322 
323  pg_log(PG_VERBOSE, "\n%s databases:\n", CLUSTER_NAME(cluster));
324  if (log_opts.verbose)
325  print_db_infos(&cluster->dbarr);
326 }
static void get_db_infos(ClusterInfo *cluster)
Definition: info.c:336
LogOpts log_opts
Definition: util.c:18
static void get_rel_infos(ClusterInfo *cluster, DbInfo *dbinfo)
Definition: info.c:405
#define CLUSTER_NAME(cluster)
Definition: pg_upgrade.h:97
void pg_log(eLogType type, const char *fmt,...)
Definition: logging.c:69
static void print_db_infos(DbInfoArr *dbinfo)
Definition: info.c:626
bool verbose
Definition: pg_upgrade.h:285
DbInfoArr dbarr
Definition: pg_upgrade.h:263
#define NULL
Definition: c.h:229
static void free_db_and_rel_infos(DbInfoArr *db_arr)
Definition: info.c:592
DbInfo * dbs
Definition: pg_upgrade.h:196
void get_loadable_libraries ( void  )

Definition at line 49 of file function.c.

References ClanguageId, conn, connectToServer(), DbInfo::db_name, ClusterInfo::dbarr, DbInfoArr::dbs, executeQueryOrDie(), FirstNormalObjectId, GET_MAJOR_VERSION, i, OSInfo::libraries, library_name_compare(), ClusterInfo::major_version, DbInfoArr::ndbs, OSInfo::num_libraries, old_cluster, os_info, pg_fatal(), pg_free(), pg_log(), pg_malloc(), pg_strdup(), PG_WARNING, PQclear(), PQfinish(), PQgetvalue(), PQntuples(), and qsort.

Referenced by check_and_dump_old_cluster().

50 {
51  PGresult **ress;
52  int totaltups;
53  int dbnum;
54  bool found_public_plpython_handler = false;
55 
56  ress = (PGresult **) pg_malloc(old_cluster.dbarr.ndbs * sizeof(PGresult *));
57  totaltups = 0;
58 
59  /* Fetch all library names, removing duplicates within each DB */
60  for (dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
61  {
62  DbInfo *active_db = &old_cluster.dbarr.dbs[dbnum];
64 
65  /*
66  * Fetch all libraries containing non-built-in C functions in this DB.
67  */
68  ress[dbnum] = executeQueryOrDie(conn,
69  "SELECT DISTINCT probin "
70  "FROM pg_catalog.pg_proc "
71  "WHERE prolang = %u AND "
72  "probin IS NOT NULL AND "
73  "oid >= %u;",
76  totaltups += PQntuples(ress[dbnum]);
77 
78  /*
79  * Systems that install plpython before 8.1 have
80  * plpython_call_handler() defined in the "public" schema, causing
81  * pg_dump to dump it. However that function still references
82  * "plpython" (no "2"), so it throws an error on restore. This code
83  * checks for the problem function, reports affected databases to the
84  * user and explains how to remove them. 8.1 git commit:
85  * e0dedd0559f005d60c69c9772163e69c204bac69
86  * http://archives.postgresql.org/pgsql-hackers/2012-03/msg01101.php
87  * http://archives.postgresql.org/pgsql-bugs/2012-05/msg00206.php
88  */
90  {
91  PGresult *res;
92 
93  res = executeQueryOrDie(conn,
94  "SELECT 1 "
95  "FROM pg_catalog.pg_proc p "
96  " JOIN pg_catalog.pg_namespace n "
97  " ON pronamespace = n.oid "
98  "WHERE proname = 'plpython_call_handler' AND "
99  "nspname = 'public' AND "
100  "prolang = %u AND "
101  "probin = '$libdir/plpython' AND "
102  "p.oid >= %u;",
103  ClanguageId,
105  if (PQntuples(res) > 0)
106  {
107  if (!found_public_plpython_handler)
108  {
110  "\nThe old cluster has a \"plpython_call_handler\" function defined\n"
111  "in the \"public\" schema which is a duplicate of the one defined\n"
112  "in the \"pg_catalog\" schema. You can confirm this by executing\n"
113  "in psql:\n"
114  "\n"
115  " \\df *.plpython_call_handler\n"
116  "\n"
117  "The \"public\" schema version of this function was created by a\n"
118  "pre-8.1 install of plpython, and must be removed for pg_upgrade\n"
119  "to complete because it references a now-obsolete \"plpython\"\n"
120  "shared object file. You can remove the \"public\" schema version\n"
121  "of this function by running the following command:\n"
122  "\n"
123  " DROP FUNCTION public.plpython_call_handler()\n"
124  "\n"
125  "in each affected database:\n"
126  "\n");
127  }
128  pg_log(PG_WARNING, " %s\n", active_db->db_name);
129  found_public_plpython_handler = true;
130  }
131  PQclear(res);
132  }
133 
134  PQfinish(conn);
135  }
136 
137  if (found_public_plpython_handler)
138  pg_fatal("Remove the problem functions from the old cluster to continue.\n");
139 
140  /*
141  * Now we want to remove duplicates across DBs and sort the library names
142  * into order. This avoids multiple probes of the same library, and
143  * ensures that libraries are probed in a consistent order, which is
144  * important for reproducible behavior if one library depends on another.
145  *
146  * First transfer all the names into one array, then sort, then remove
147  * duplicates. Note: we strdup each name in the first loop so that we can
148  * safely clear the PGresults in the same loop. This is a bit wasteful
149  * but it's unlikely there are enough names to matter.
150  */
151  os_info.libraries = (char **) pg_malloc(totaltups * sizeof(char *));
152  totaltups = 0;
153 
154  for (dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
155  {
156  PGresult *res = ress[dbnum];
157  int ntups;
158  int rowno;
159 
160  ntups = PQntuples(res);
161  for (rowno = 0; rowno < ntups; rowno++)
162  {
163  char *lib = PQgetvalue(res, rowno, 0);
164 
165  os_info.libraries[totaltups++] = pg_strdup(lib);
166  }
167  PQclear(res);
168  }
169 
170  pg_free(ress);
171 
172  if (totaltups > 1)
173  {
174  int i,
175  lastnondup;
176 
177  qsort((void *) os_info.libraries, totaltups, sizeof(char *),
179 
180  for (i = 1, lastnondup = 0; i < totaltups; i++)
181  {
182  if (strcmp(os_info.libraries[i],
183  os_info.libraries[lastnondup]) != 0)
184  os_info.libraries[++lastnondup] = os_info.libraries[i];
185  else
187  }
188  totaltups = lastnondup + 1;
189  }
190 
191  os_info.num_libraries = totaltups;
192 }
uint32 major_version
Definition: pg_upgrade.h:272
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3067
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
int num_libraries
Definition: pg_upgrade.h:314
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:29
#define ClanguageId
Definition: pg_language.h:77
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3521
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2673
#define FirstNormalObjectId
Definition: transam.h:94
PGconn * conn
Definition: streamutil.c:42
char ** libraries
Definition: pg_upgrade.h:313
ClusterInfo old_cluster
Definition: pg_upgrade.c:56
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
static int library_name_compare(const void *p1, const void *p2)
Definition: function.c:29
void pg_log(eLogType type, const char *fmt,...)
Definition: logging.c:69
PGconn * connectToServer(ClusterInfo *cluster, const char *db_name)
Definition: server.c:27
void PQclear(PGresult *res)
Definition: fe-exec.c:650
DbInfoArr dbarr
Definition: pg_upgrade.h:263
void pg_free(void *ptr)
Definition: fe_memutils.c:105
int i
OSInfo os_info
Definition: pg_upgrade.c:58
char * db_name
Definition: pg_upgrade.h:185
#define qsort(a, b, c, d)
Definition: port.h:440
DbInfo * dbs
Definition: pg_upgrade.h:196
uint32 get_major_server_version ( ClusterInfo cluster)

Definition at line 155 of file server.c.

References ClusterInfo::major_version_str, MAXPGPATH, NULL, pg_fatal(), ClusterInfo::pgdata, and snprintf().

Referenced by check_cluster_versions(), and check_data_dir().

156 {
157  FILE *version_fd;
158  char ver_filename[MAXPGPATH];
159  int integer_version = 0;
160  int fractional_version = 0;
161 
162  snprintf(ver_filename, sizeof(ver_filename), "%s/PG_VERSION",
163  cluster->pgdata);
164  if ((version_fd = fopen(ver_filename, "r")) == NULL)
165  pg_fatal("could not open version file: %s\n", ver_filename);
166 
167  if (fscanf(version_fd, "%63s", cluster->major_version_str) == 0 ||
168  sscanf(cluster->major_version_str, "%d.%d", &integer_version,
169  &fractional_version) < 1)
170  pg_fatal("could not get version from %s\n", cluster->pgdata);
171 
172  fclose(version_fd);
173 
174  return (100 * integer_version + fractional_version) * 100;
175 }
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
char major_version_str[64]
Definition: pg_upgrade.h:273
#define MAXPGPATH
#define NULL
Definition: c.h:229
char * pgdata
Definition: pg_upgrade.h:264
void get_sock_dir ( ClusterInfo cluster,
bool  live_check 
)

Definition at line 445 of file option.c.

References DEF_PGUPORT, filename, GET_MAJOR_VERSION, LOCK_FILE_LINE_PORT, LOCK_FILE_LINE_SOCKET_DIR, ClusterInfo::major_version, Max, MAXPGPATH, NULL, old_cluster, pg_fatal(), pg_log(), pg_malloc(), pg_strdup(), PG_WARNING, ClusterInfo::pgdata, ClusterInfo::port, snprintf(), and ClusterInfo::sockdir.

Referenced by main().

446 {
447 #ifdef HAVE_UNIX_SOCKETS
448 
449  /*
450  * sockdir and port were added to postmaster.pid in PG 9.1. Pre-9.1 cannot
451  * process pg_ctl -w for sockets in non-default locations.
452  */
453  if (GET_MAJOR_VERSION(cluster->major_version) >= 901)
454  {
455  if (!live_check)
456  {
457  /* Use the current directory for the socket */
458  cluster->sockdir = pg_malloc(MAXPGPATH);
459  if (!getcwd(cluster->sockdir, MAXPGPATH))
460  pg_fatal("cannot find current directory\n");
461  }
462  else
463  {
464  /*
465  * If we are doing a live check, we will use the old cluster's
466  * Unix domain socket directory so we can connect to the live
467  * server.
468  */
469  unsigned short orig_port = cluster->port;
470  char filename[MAXPGPATH],
471  line[MAXPGPATH];
472  FILE *fp;
473  int lineno;
474 
475  snprintf(filename, sizeof(filename), "%s/postmaster.pid",
476  cluster->pgdata);
477  if ((fp = fopen(filename, "r")) == NULL)
478  pg_fatal("Cannot open file %s: %m\n", filename);
479 
480  for (lineno = 1;
482  lineno++)
483  {
484  if (fgets(line, sizeof(line), fp) == NULL)
485  pg_fatal("Cannot read line %d from %s: %m\n", lineno, filename);
486 
487  /* potentially overwrite user-supplied value */
488  if (lineno == LOCK_FILE_LINE_PORT)
489  sscanf(line, "%hu", &old_cluster.port);
490  if (lineno == LOCK_FILE_LINE_SOCKET_DIR)
491  {
492  cluster->sockdir = pg_strdup(line);
493  /* strip off newline */
494  if (strchr(cluster->sockdir, '\n') != NULL)
495  *strchr(cluster->sockdir, '\n') = '\0';
496  }
497  }
498  fclose(fp);
499 
500  /* warn of port number correction */
501  if (orig_port != DEF_PGUPORT && old_cluster.port != orig_port)
502  pg_log(PG_WARNING, "User-supplied old port number %hu corrected to %hu\n",
503  orig_port, cluster->port);
504  }
505  }
506  else
507 
508  /*
509  * Can't get sockdir and pg_ctl -w can't use a non-default, use
510  * default
511  */
512  cluster->sockdir = NULL;
513 #else /* !HAVE_UNIX_SOCKETS */
514  cluster->sockdir = NULL;
515 #endif
516 }
uint32 major_version
Definition: pg_upgrade.h:272
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:29
unsigned short port
Definition: pg_upgrade.h:271
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
#define MAXPGPATH
#define LOCK_FILE_LINE_SOCKET_DIR
Definition: miscadmin.h:450
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
#define DEF_PGUPORT
Definition: pg_upgrade.h:16
#define Max(x, y)
Definition: c.h:800
#define NULL
Definition: c.h:229
#define LOCK_FILE_LINE_PORT
Definition: miscadmin.h:449
static char * filename
Definition: pg_dumpall.c:89
char * pgdata
Definition: pg_upgrade.h:264
char * sockdir
Definition: pg_upgrade.h:270
int get_user_info ( char **  user_name_p)

Definition at line 212 of file util.c.

References get_user_name(), pg_fatal(), and pg_strdup().

Referenced by parseCommandLine().

213 {
214  int user_id;
215  const char *user_name;
216  char *errstr;
217 
218 #ifndef WIN32
219  user_id = geteuid();
220 #else
221  user_id = 1;
222 #endif
223 
224  user_name = get_user_name(&errstr);
225  if (!user_name)
226  pg_fatal("%s\n", errstr);
227 
228  /* make a copy */
229  *user_name_p = pg_strdup(user_name);
230 
231  return user_id;
232 }
const char * get_user_name(char **errstr)
Definition: username.c:31
void pg_fatal(const char *fmt,...)
Definition: util.c:159
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
void init_tablespaces ( void  )

Definition at line 19 of file tablespace.c.

References get_tablespace_paths(), new_cluster, OSInfo::num_old_tablespaces, old_cluster, os_info, pg_fatal(), set_tablespace_directory_suffix(), and ClusterInfo::tablespace_suffix.

Referenced by check_and_dump_old_cluster().

20 {
22 
25 
26  if (os_info.num_old_tablespaces > 0 &&
28  pg_fatal("Cannot upgrade to/from the same system catalog version when\n"
29  "using tablespaces.\n");
30 }
static void set_tablespace_directory_suffix(ClusterInfo *cluster)
Definition: tablespace.c:109
static void get_tablespace_paths(void)
Definition: tablespace.c:40
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
ClusterInfo new_cluster
Definition: pg_upgrade.c:56
ClusterInfo old_cluster
Definition: pg_upgrade.c:56
const char * tablespace_suffix
Definition: pg_upgrade.h:275
int num_old_tablespaces
Definition: pg_upgrade.h:312
OSInfo os_info
Definition: pg_upgrade.c:58
void issue_warnings ( void  )

Definition at line 177 of file check.c.

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

Referenced by main().

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

Definition at line 103 of file file.c.

References pg_fatal(), pg_link_file, and strerror().

Referenced by transfer_relfile().

105 {
106  if (pg_link_file(src, dst) < 0)
107  pg_fatal("error while creating link for relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n",
108  schemaName, relName, src, dst, strerror(errno));
109 }
#define pg_link_file
Definition: pg_upgrade.h:74
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
const char * strerror(int errnum)
Definition: strerror.c:19
void new_9_0_populate_pg_largeobject_metadata ( ClusterInfo cluster,
bool  check_mode 
)

Definition at line 25 of file version.c.

References appendPsqlMetaConnect(), check_ok(), conn, connectToServer(), PQExpBufferData::data, DbInfo::db_name, ClusterInfo::dbarr, DbInfoArr::dbs, executeQueryOrDie(), fopen_priv(), initPQExpBuffer(), MAXPGPATH, DbInfoArr::ndbs, NULL, pg_fatal(), pg_log(), PG_WARNING, PQclear(), PQfinish(), PQfnumber(), PQgetvalue(), prep_status(), report_status(), snprintf(), strerror(), and termPQExpBuffer().

Referenced by check_and_dump_old_cluster(), and issue_warnings().

26 {
27  int dbnum;
28  FILE *script = NULL;
29  bool found = false;
30  char output_path[MAXPGPATH];
31 
32  prep_status("Checking for large objects");
33 
34  snprintf(output_path, sizeof(output_path), "pg_largeobject.sql");
35 
36  for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
37  {
38  PGresult *res;
39  int i_count;
40  DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
41  PGconn *conn = connectToServer(cluster, active_db->db_name);
42 
43  /* find if there are any large objects */
44  res = executeQueryOrDie(conn,
45  "SELECT count(*) "
46  "FROM pg_catalog.pg_largeobject ");
47 
48  i_count = PQfnumber(res, "count");
49  if (atoi(PQgetvalue(res, 0, i_count)) != 0)
50  {
51  found = true;
52  if (!check_mode)
53  {
54  PQExpBufferData connectbuf;
55 
56  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
57  pg_fatal("could not open file \"%s\": %s\n", output_path,
58  strerror(errno));
59 
60  initPQExpBuffer(&connectbuf);
61  appendPsqlMetaConnect(&connectbuf, active_db->db_name);
62  fputs(connectbuf.data, script);
63  termPQExpBuffer(&connectbuf);
64 
65  fprintf(script,
66  "SELECT pg_catalog.lo_create(t.loid)\n"
67  "FROM (SELECT DISTINCT loid FROM pg_catalog.pg_largeobject) AS t;\n");
68  }
69  }
70 
71  PQclear(res);
72  PQfinish(conn);
73  }
74 
75  if (script)
76  fclose(script);
77 
78  if (found)
79  {
80  report_status(PG_WARNING, "warning");
81  if (check_mode)
82  pg_log(PG_WARNING, "\n"
83  "Your installation contains large objects. The new database has an\n"
84  "additional large object permission table. After upgrading, you will be\n"
85  "given a command to populate the pg_largeobject permission table with\n"
86  "default permissions.\n\n");
87  else
88  pg_log(PG_WARNING, "\n"
89  "Your installation contains large objects. The new database has an\n"
90  "additional large object permission table, so default permissions must be\n"
91  "defined for all large objects. The file\n"
92  " %s\n"
93  "when executed by psql by the database superuser will set the default\n"
94  "permissions.\n\n",
95  output_path);
96  }
97  else
98  check_ok();
99 }
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3067
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3521
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
FILE * fopen_priv(const char *path, const char *mode)
Definition: file.c:321
void appendPsqlMetaConnect(PQExpBuffer buf, const char *dbname)
Definition: string_utils.c:596
PGconn * conn
Definition: streamutil.c:42
#define MAXPGPATH
void prep_status(const char *fmt,...) pg_attribute_printf(1
void pg_log(eLogType type, const char *fmt,...)
Definition: logging.c:69
static void check_ok(void)
Definition: initdb.c:2008
PGconn * connectToServer(ClusterInfo *cluster, const char *db_name)
Definition: server.c:27
int PQfnumber(const PGresult *res, const char *field_name)
Definition: fe-exec.c:2781
void PQclear(PGresult *res)
Definition: fe-exec.c:650
DbInfoArr dbarr
Definition: pg_upgrade.h:263
#define NULL
Definition: c.h:229
const char * strerror(int errnum)
Definition: strerror.c:19
void report_status(eLogType type, const char *fmt,...) pg_attribute_printf(2
char * db_name
Definition: pg_upgrade.h:185
DbInfo * dbs
Definition: pg_upgrade.h:196
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
void old_9_3_check_for_line_data_type_usage ( ClusterInfo cluster)

Definition at line 111 of file version.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().

112 {
113  int dbnum;
114  FILE *script = NULL;
115  bool found = false;
116  char output_path[MAXPGPATH];
117 
118  prep_status("Checking for invalid \"line\" user columns");
119 
120  snprintf(output_path, sizeof(output_path), "tables_using_line.txt");
121 
122  for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
123  {
124  PGresult *res;
125  bool db_used = false;
126  int ntups;
127  int rowno;
128  int i_nspname,
129  i_relname,
130  i_attname;
131  DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
132  PGconn *conn = connectToServer(cluster, active_db->db_name);
133 
134  res = executeQueryOrDie(conn,
135  "SELECT n.nspname, c.relname, a.attname "
136  "FROM pg_catalog.pg_class c, "
137  " pg_catalog.pg_namespace n, "
138  " pg_catalog.pg_attribute a "
139  "WHERE c.oid = a.attrelid AND "
140  " NOT a.attisdropped AND "
141  " a.atttypid = 'pg_catalog.line'::pg_catalog.regtype AND "
142  " c.relnamespace = n.oid AND "
143  /* exclude possible orphaned temp tables */
144  " n.nspname !~ '^pg_temp_' AND "
145  " n.nspname !~ '^pg_toast_temp_' AND "
146  " n.nspname NOT IN ('pg_catalog', 'information_schema')");
147 
148  ntups = PQntuples(res);
149  i_nspname = PQfnumber(res, "nspname");
150  i_relname = PQfnumber(res, "relname");
151  i_attname = PQfnumber(res, "attname");
152  for (rowno = 0; rowno < ntups; rowno++)
153  {
154  found = true;
155  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
156  pg_fatal("could not open file \"%s\": %s\n", output_path,
157  strerror(errno));
158  if (!db_used)
159  {
160  fprintf(script, "Database: %s\n", active_db->db_name);
161  db_used = true;
162  }
163  fprintf(script, " %s.%s.%s\n",
164  PQgetvalue(res, rowno, i_nspname),
165  PQgetvalue(res, rowno, i_relname),
166  PQgetvalue(res, rowno, i_attname));
167  }
168 
169  PQclear(res);
170 
171  PQfinish(conn);
172  }
173 
174  if (script)
175  fclose(script);
176 
177  if (found)
178  {
179  pg_log(PG_REPORT, "fatal\n");
180  pg_fatal("Your installation contains the \"line\" data type in user tables. This\n"
181  "data type changed its internal and input/output format between your old\n"
182  "and new clusters so this cluster cannot currently be upgraded. You can\n"
183  "remove the problem tables and restart the upgrade. A list of the problem\n"
184  "columns is in the file:\n"
185  " %s\n\n", output_path);
186  }
187  else
188  check_ok();
189 }
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3067
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3521
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2673
FILE * fopen_priv(const char *path, const char *mode)
Definition: file.c:321
PGconn * conn
Definition: streamutil.c:42
#define MAXPGPATH
void prep_status(const char *fmt,...) pg_attribute_printf(1
void pg_log(eLogType type, const char *fmt,...)
Definition: logging.c:69
static void check_ok(void)
Definition: initdb.c:2008
PGconn * connectToServer(ClusterInfo *cluster, const char *db_name)
Definition: server.c:27
int PQfnumber(const PGresult *res, const char *field_name)
Definition: fe-exec.c:2781
void PQclear(PGresult *res)
Definition: fe-exec.c:650
DbInfoArr dbarr
Definition: pg_upgrade.h:263
#define NULL
Definition: c.h:229
const char * strerror(int errnum)
Definition: strerror.c:19
char * db_name
Definition: pg_upgrade.h:185
DbInfo * dbs
Definition: pg_upgrade.h:196
void old_9_6_check_for_unknown_data_type_usage ( ClusterInfo cluster)

Definition at line 208 of file version.c.

References check_ok(), conn, connectToServer(), CppAsString2, 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(), RELKIND_COMPOSITE_TYPE, RELKIND_MATVIEW, RELKIND_RELATION, snprintf(), and strerror().

Referenced by check_and_dump_old_cluster().

209 {
210  int dbnum;
211  FILE *script = NULL;
212  bool found = false;
213  char output_path[MAXPGPATH];
214 
215  prep_status("Checking for invalid \"unknown\" user columns");
216 
217  snprintf(output_path, sizeof(output_path), "tables_using_unknown.txt");
218 
219  for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
220  {
221  PGresult *res;
222  bool db_used = false;
223  int ntups;
224  int rowno;
225  int i_nspname,
226  i_relname,
227  i_attname;
228  DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
229  PGconn *conn = connectToServer(cluster, active_db->db_name);
230 
231  res = executeQueryOrDie(conn,
232  "SELECT n.nspname, c.relname, a.attname "
233  "FROM pg_catalog.pg_class c, "
234  " pg_catalog.pg_namespace n, "
235  " pg_catalog.pg_attribute a "
236  "WHERE c.oid = a.attrelid AND "
237  " NOT a.attisdropped AND "
238  " a.atttypid = 'pg_catalog.unknown'::pg_catalog.regtype AND "
239  " c.relkind IN ("
242  CppAsString2(RELKIND_MATVIEW) ") AND "
243  " c.relnamespace = n.oid AND "
244  /* exclude possible orphaned temp tables */
245  " n.nspname !~ '^pg_temp_' AND "
246  " n.nspname !~ '^pg_toast_temp_' AND "
247  " n.nspname NOT IN ('pg_catalog', 'information_schema')");
248 
249  ntups = PQntuples(res);
250  i_nspname = PQfnumber(res, "nspname");
251  i_relname = PQfnumber(res, "relname");
252  i_attname = PQfnumber(res, "attname");
253  for (rowno = 0; rowno < ntups; rowno++)
254  {
255  found = true;
256  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
257  pg_fatal("could not open file \"%s\": %s\n", output_path,
258  strerror(errno));
259  if (!db_used)
260  {
261  fprintf(script, "Database: %s\n", active_db->db_name);
262  db_used = true;
263  }
264  fprintf(script, " %s.%s.%s\n",
265  PQgetvalue(res, rowno, i_nspname),
266  PQgetvalue(res, rowno, i_relname),
267  PQgetvalue(res, rowno, i_attname));
268  }
269 
270  PQclear(res);
271 
272  PQfinish(conn);
273  }
274 
275  if (script)
276  fclose(script);
277 
278  if (found)
279  {
280  pg_log(PG_REPORT, "fatal\n");
281  pg_fatal("Your installation contains the \"unknown\" data type in user tables. This\n"
282  "data type is no longer allowed in tables, so this cluster cannot currently\n"
283  "be upgraded. You can remove the problem tables and restart the upgrade.\n"
284  "A list of the problem columns is in the file:\n"
285  " %s\n\n", output_path);
286  }
287  else
288  check_ok();
289 }
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3067
#define RELKIND_MATVIEW
Definition: pg_class.h:165
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3521
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2673
FILE * fopen_priv(const char *path, const char *mode)
Definition: file.c:321
#define RELKIND_COMPOSITE_TYPE
Definition: pg_class.h:166
PGconn * conn
Definition: streamutil.c:42
#define MAXPGPATH
void prep_status(const char *fmt,...) pg_attribute_printf(1
void pg_log(eLogType type, const char *fmt,...)
Definition: logging.c:69
static void check_ok(void)
Definition: initdb.c:2008
PGconn * connectToServer(ClusterInfo *cluster, const char *db_name)
Definition: server.c:27
#define CppAsString2(x)
Definition: c.h:162
int PQfnumber(const PGresult *res, const char *field_name)
Definition: fe-exec.c:2781
void PQclear(PGresult *res)
Definition: fe-exec.c:650
DbInfoArr dbarr
Definition: pg_upgrade.h:263
#define NULL
Definition: c.h:229
const char * strerror(int errnum)
Definition: strerror.c:19
char * db_name
Definition: pg_upgrade.h:185
DbInfo * dbs
Definition: pg_upgrade.h:196
#define RELKIND_RELATION
Definition: pg_class.h:160
void old_9_6_invalidate_hash_indexes ( ClusterInfo cluster,
bool  check_mode 
)

Definition at line 297 of file version.c.

References appendPsqlMetaConnect(), check_ok(), conn, connectToServer(), PQExpBufferData::data, DbInfo::db_name, ClusterInfo::dbarr, DbInfoArr::dbs, executeQueryOrDie(), fopen_priv(), initPQExpBuffer(), DbInfoArr::ndbs, NULL, pg_fatal(), pg_log(), PG_WARNING, PQclear(), PQfinish(), PQfnumber(), PQgetvalue(), PQntuples(), prep_status(), quote_identifier(), report_status(), strerror(), and termPQExpBuffer().

Referenced by check_and_dump_old_cluster(), and issue_warnings().

298 {
299  int dbnum;
300  FILE *script = NULL;
301  bool found = false;
302  char *output_path = "reindex_hash.sql";
303 
304  prep_status("Checking for hash indexes");
305 
306  for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
307  {
308  PGresult *res;
309  bool db_used = false;
310  int ntups;
311  int rowno;
312  int i_nspname,
313  i_relname;
314  DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
315  PGconn *conn = connectToServer(cluster, active_db->db_name);
316 
317  /* find hash indexes */
318  res = executeQueryOrDie(conn,
319  "SELECT n.nspname, c.relname "
320  "FROM pg_catalog.pg_class c, "
321  " pg_catalog.pg_index i, "
322  " pg_catalog.pg_am a, "
323  " pg_catalog.pg_namespace n "
324  "WHERE i.indexrelid = c.oid AND "
325  " c.relam = a.oid AND "
326  " c.relnamespace = n.oid AND "
327  " a.amname = 'hash'"
328  );
329 
330  ntups = PQntuples(res);
331  i_nspname = PQfnumber(res, "nspname");
332  i_relname = PQfnumber(res, "relname");
333  for (rowno = 0; rowno < ntups; rowno++)
334  {
335  found = true;
336  if (!check_mode)
337  {
338  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
339  pg_fatal("could not open file \"%s\": %s\n", output_path,
340  strerror(errno));
341  if (!db_used)
342  {
343  PQExpBufferData connectbuf;
344 
345  initPQExpBuffer(&connectbuf);
346  appendPsqlMetaConnect(&connectbuf, active_db->db_name);
347  fputs(connectbuf.data, script);
348  termPQExpBuffer(&connectbuf);
349  db_used = true;
350  }
351  fprintf(script, "REINDEX INDEX %s.%s;\n",
352  quote_identifier(PQgetvalue(res, rowno, i_nspname)),
353  quote_identifier(PQgetvalue(res, rowno, i_relname)));
354  }
355  }
356 
357  PQclear(res);
358 
359  if (!check_mode && db_used)
360  {
361  /* mark hash indexes as invalid */
363  "UPDATE pg_catalog.pg_index i "
364  "SET indisvalid = false "
365  "FROM pg_catalog.pg_class c, "
366  " pg_catalog.pg_am a, "
367  " pg_catalog.pg_namespace n "
368  "WHERE i.indexrelid = c.oid AND "
369  " c.relam = a.oid AND "
370  " c.relnamespace = n.oid AND "
371  " a.amname = 'hash'"));
372  }
373 
374  PQfinish(conn);
375  }
376 
377  if (script)
378  fclose(script);
379 
380  if (found)
381  {
382  report_status(PG_WARNING, "warning");
383  if (check_mode)
384  pg_log(PG_WARNING, "\n"
385  "Your installation contains hash indexes. These indexes have different\n"
386  "internal formats between your old and new clusters, so they must be\n"
387  "reindexed with the REINDEX command. After upgrading, you will be given\n"
388  "REINDEX instructions.\n\n");
389  else
390  pg_log(PG_WARNING, "\n"
391  "Your installation contains hash indexes. These indexes have different\n"
392  "internal formats between your old and new clusters, so they must be\n"
393  "reindexed with the REINDEX command. The file:\n"
394  " %s\n"
395  "when executed by psql by the database superuser will recreate all invalid\n"
396  "indexes; until then, none of these indexes will be used.\n\n",
397  output_path);
398  }
399  else
400  check_ok();
401 }
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:10284
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3067
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3521
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2673
FILE * fopen_priv(const char *path, const char *mode)
Definition: file.c:321
void appendPsqlMetaConnect(PQExpBuffer buf, const char *dbname)
Definition: string_utils.c:596
PGconn * conn
Definition: streamutil.c:42
void prep_status(const char *fmt,...) pg_attribute_printf(1
void pg_log(eLogType type, const char *fmt,...)
Definition: logging.c:69
static void check_ok(void)
Definition: initdb.c:2008
PGconn * connectToServer(ClusterInfo *cluster, const char *db_name)
Definition: server.c:27
int PQfnumber(const PGresult *res, const char *field_name)
Definition: fe-exec.c:2781
void PQclear(PGresult *res)
Definition: fe-exec.c:650
DbInfoArr dbarr
Definition: pg_upgrade.h:263
#define NULL
Definition: c.h:229
const char * strerror(int errnum)
Definition: strerror.c:19
void report_status(eLogType type, const char *fmt,...) pg_attribute_printf(2
char * db_name
Definition: pg_upgrade.h:185
DbInfo * dbs
Definition: pg_upgrade.h:196
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
void output_check_banner ( bool  live_check)

Definition at line 61 of file check.c.

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

Referenced by main().

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

Definition at line 198 of file check.c.

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

Referenced by main().

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

Definition at line 178 of file parallel.c.

References i, UserOpts::jobs, NULL, parallel_jobs, pg_fatal(), pg_free(), pg_malloc(), pg_malloc0(), pg_strdup(), reap_child(), strerror(), transfer_all_new_dbs(), and user_opts.

Referenced by transfer_all_new_tablespaces().

181 {
182 #ifndef WIN32
183  pid_t child;
184 #else
185  HANDLE child;
186  transfer_thread_arg *new_arg;
187 #endif
188 
189  if (user_opts.jobs <= 1)
190  /* throw_error must be true to allow jobs */
191  transfer_all_new_dbs(old_db_arr, new_db_arr, old_pgdata, new_pgdata, NULL);
192  else
193  {
194  /* parallel */
195 #ifdef WIN32
196  if (thread_handles == NULL)
197  thread_handles = pg_malloc(user_opts.jobs * sizeof(HANDLE));
198 
199  if (transfer_thread_args == NULL)
200  {
201  int i;
202 
203  transfer_thread_args = pg_malloc(user_opts.jobs * sizeof(transfer_thread_arg *));
204 
205  /*
206  * For safety and performance, we keep the args allocated during
207  * the entire life of the process, and we don't free the args in a
208  * thread different from the one that allocated it.
209  */
210  for (i = 0; i < user_opts.jobs; i++)
211  transfer_thread_args[i] = pg_malloc0(sizeof(transfer_thread_arg));
212  }
213 
214  cur_thread_args = (void **) transfer_thread_args;
215 #endif
216  /* harvest any dead children */
217  while (reap_child(false) == true)
218  ;
219 
220  /* must we wait for a dead child? */
222  reap_child(true);
223 
224  /* set this before we start the job */
225  parallel_jobs++;
226 
227  /* Ensure stdio state is quiesced before forking */
228  fflush(NULL);
229 
230 #ifndef WIN32
231  child = fork();
232  if (child == 0)
233  {
234  transfer_all_new_dbs(old_db_arr, new_db_arr, old_pgdata, new_pgdata,
235  old_tablespace);
236  /* if we take another exit path, it will be non-zero */
237  /* use _exit to skip atexit() functions */
238  _exit(0);
239  }
240  else if (child < 0)
241  /* fork failed */
242  pg_fatal("could not create worker process: %s\n", strerror(errno));
243 #else
244  /* empty array element are always at the end */
245  new_arg = transfer_thread_args[parallel_jobs - 1];
246 
247  /* Can only pass one pointer into the function, so use a struct */
248  new_arg->old_db_arr = old_db_arr;
249  new_arg->new_db_arr = new_db_arr;
250  if (new_arg->old_pgdata)
251  pg_free(new_arg->old_pgdata);
252  new_arg->old_pgdata = pg_strdup(old_pgdata);
253  if (new_arg->new_pgdata)
254  pg_free(new_arg->new_pgdata);
255  new_arg->new_pgdata = pg_strdup(new_pgdata);
256  if (new_arg->old_tablespace)
257  pg_free(new_arg->old_tablespace);
258  new_arg->old_tablespace = old_tablespace ? pg_strdup(old_tablespace) : NULL;
259 
260  child = (HANDLE) _beginthreadex(NULL, 0, (void *) win32_transfer_all_new_dbs,
261  new_arg, 0, NULL);
262  if (child == 0)
263  pg_fatal("could not create worker thread: %s\n", strerror(errno));
264 
265  thread_handles[parallel_jobs - 1] = child;
266 #endif
267  }
268 
269  return;
270 }
void transfer_all_new_dbs(DbInfoArr *old_db_arr, DbInfoArr *new_db_arr, char *old_pgdata, char *new_pgdata, char *old_tablespace)
Definition: relfilenode.c:81
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
int jobs
Definition: pg_upgrade.h:298
void * pg_malloc0(size_t size)
Definition: fe_memutils.c:53
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
UserOpts user_opts
Definition: option.c:29
#define NULL
Definition: c.h:229
void pg_free(void *ptr)
Definition: fe_memutils.c:105
bool reap_child(bool wait_for_child)
Definition: parallel.c:290
int i
const char * strerror(int errnum)
Definition: strerror.c:19
static int parallel_jobs
Definition: parallel.c:20
void parseCommandLine ( int  argc,
char *  argv[] 
)

Definition at line 38 of file option.c.

References _, ClusterInfo::bindir, canonicalize_path(), UserOpts::check, check_required_directory(), DEF_PGUPORT, filename, FIX_DEFAULT_READ_ONLY, fopen_priv(), free, get_progname(), get_user_info(), getopt_long(), LogOpts::internal, INTERNAL_LOG_FILE, UserOpts::jobs, log_opts, MAXPGPATH, new_cluster, no_argument, NULL, old_cluster, optarg, os_info, output_files, path_is_prefix_of_path(), pfree(), pg_fatal(), pg_free(), pg_log(), pg_putenv(), PG_REPORT, pg_strdup(), ClusterInfo::pgconfig, ClusterInfo::pgdata, ClusterInfo::pgopts, ClusterInfo::port, OSInfo::progname, psprintf(), required_argument, LogOpts::retain, strlcpy(), UserOpts::transfer_mode, TRANSFER_MODE_COPY, TRANSFER_MODE_LINK, usage(), OSInfo::user, OSInfo::user_specified, and LogOpts::verbose.

Referenced by main().

39 {
40  static struct option long_options[] = {
41  {"old-datadir", required_argument, NULL, 'd'},
42  {"new-datadir", required_argument, NULL, 'D'},
43  {"old-bindir", required_argument, NULL, 'b'},
44  {"new-bindir", required_argument, NULL, 'B'},
45  {"old-options", required_argument, NULL, 'o'},
46  {"new-options", required_argument, NULL, 'O'},
47  {"old-port", required_argument, NULL, 'p'},
48  {"new-port", required_argument, NULL, 'P'},
49 
50  {"username", required_argument, NULL, 'U'},
51  {"check", no_argument, NULL, 'c'},
52  {"link", no_argument, NULL, 'k'},
53  {"retain", no_argument, NULL, 'r'},
54  {"jobs", required_argument, NULL, 'j'},
55  {"verbose", no_argument, NULL, 'v'},
56  {NULL, 0, NULL, 0}
57  };
58  int option; /* Command line option */
59  int optindex = 0; /* used by getopt_long */
60  int os_user_effective_id;
61  FILE *fp;
62  char **filename;
63  time_t run_time = time(NULL);
64 
66 
67  os_info.progname = get_progname(argv[0]);
68 
69  /* Process libpq env. variables; load values here for usage() output */
70  old_cluster.port = getenv("PGPORTOLD") ? atoi(getenv("PGPORTOLD")) : DEF_PGUPORT;
71  new_cluster.port = getenv("PGPORTNEW") ? atoi(getenv("PGPORTNEW")) : DEF_PGUPORT;
72 
73  os_user_effective_id = get_user_info(&os_info.user);
74  /* we override just the database user name; we got the OS id above */
75  if (getenv("PGUSER"))
76  {
78  /* must save value, getenv()'s pointer is not stable */
79  os_info.user = pg_strdup(getenv("PGUSER"));
80  }
81 
82  if (argc > 1)
83  {
84  if (strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-?") == 0)
85  {
86  usage();
87  exit(0);
88  }
89  if (strcmp(argv[1], "--version") == 0 || strcmp(argv[1], "-V") == 0)
90  {
91  puts("pg_upgrade (PostgreSQL) " PG_VERSION);
92  exit(0);
93  }
94  }
95 
96  /* Allow help and version to be run as root, so do the test here. */
97  if (os_user_effective_id == 0)
98  pg_fatal("%s: cannot be run as root\n", os_info.progname);
99 
101  pg_fatal("cannot write to log file %s\n", INTERNAL_LOG_FILE);
102 
103  while ((option = getopt_long(argc, argv, "d:D:b:B:cj:ko:O:p:P:rU:v",
104  long_options, &optindex)) != -1)
105  {
106  switch (option)
107  {
108  case 'b':
110  break;
111 
112  case 'B':
114  break;
115 
116  case 'c':
117  user_opts.check = true;
118  break;
119 
120  case 'd':
123  break;
124 
125  case 'D':
128  break;
129 
130  case 'j':
131  user_opts.jobs = atoi(optarg);
132  break;
133 
134  case 'k':
136  break;
137 
138  case 'o':
139  /* append option? */
140  if (!old_cluster.pgopts)
142  else
143  {
144  char *old_pgopts = old_cluster.pgopts;
145 
146  old_cluster.pgopts = psprintf("%s %s", old_pgopts, optarg);
147  free(old_pgopts);
148  }
149  break;
150 
151  case 'O':
152  /* append option? */
153  if (!new_cluster.pgopts)
155  else
156  {
157  char *new_pgopts = new_cluster.pgopts;
158 
159  new_cluster.pgopts = psprintf("%s %s", new_pgopts, optarg);
160  free(new_pgopts);
161  }
162  break;
163 
164  /*
165  * Someday, the port number option could be removed and passed
166  * using -o/-O, but that requires postmaster -C to be
167  * supported on all old/new versions (added in PG 9.2).
168  */
169  case 'p':
170  if ((old_cluster.port = atoi(optarg)) <= 0)
171  {
172  pg_fatal("invalid old port number\n");
173  exit(1);
174  }
175  break;
176 
177  case 'P':
178  if ((new_cluster.port = atoi(optarg)) <= 0)
179  {
180  pg_fatal("invalid new port number\n");
181  exit(1);
182  }
183  break;
184 
185  case 'r':
186  log_opts.retain = true;
187  break;
188 
189  case 'U':
192  os_info.user_specified = true;
193 
194  /*
195  * Push the user name into the environment so pre-9.1
196  * pg_ctl/libpq uses it.
197  */
198  pg_putenv("PGUSER", os_info.user);
199  break;
200 
201  case 'v':
202  pg_log(PG_REPORT, "Running in verbose mode\n");
203  log_opts.verbose = true;
204  break;
205 
206  default:
207  pg_fatal("Try \"%s --help\" for more information.\n",
208  os_info.progname);
209  break;
210  }
211  }
212 
213  /* label start of upgrade in logfiles */
214  for (filename = output_files; *filename != NULL; filename++)
215  {
216  if ((fp = fopen_priv(*filename, "a")) == NULL)
217  pg_fatal("cannot write to log file %s\n", *filename);
218 
219  /* Start with newline because we might be appending to a file. */
220  fprintf(fp, "\n"
221  "-----------------------------------------------------------------\n"
222  " pg_upgrade run on %s"
223  "-----------------------------------------------------------------\n\n",
224  ctime(&run_time));
225  fclose(fp);
226  }
227 
228  /* Turn off read-only mode; add prefix to PGOPTIONS? */
229  if (getenv("PGOPTIONS"))
230  {
231  char *pgoptions = psprintf("%s %s", FIX_DEFAULT_READ_ONLY,
232  getenv("PGOPTIONS"));
233 
234  pg_putenv("PGOPTIONS", pgoptions);
235  pfree(pgoptions);
236  }
237  else
238  pg_putenv("PGOPTIONS", FIX_DEFAULT_READ_ONLY);
239 
240  /* Get values from env if not already set */
241  check_required_directory(&old_cluster.bindir, NULL, "PGBINOLD", "-b",
242  _("old cluster binaries reside"));
243  check_required_directory(&new_cluster.bindir, NULL, "PGBINNEW", "-B",
244  _("new cluster binaries reside"));
246  "PGDATAOLD", "-d", _("old cluster data resides"));
248  "PGDATANEW", "-D", _("new cluster data resides"));
249 
250 #ifdef WIN32
251 
252  /*
253  * On Windows, initdb --sync-only will fail with a "Permission denied"
254  * error on file pg_upgrade_utility.log if pg_upgrade is run inside the
255  * new cluster directory, so we do a check here.
256  */
257  {
258  char cwd[MAXPGPATH],
259  new_cluster_pgdata[MAXPGPATH];
260 
261  strlcpy(new_cluster_pgdata, new_cluster.pgdata, MAXPGPATH);
262  canonicalize_path(new_cluster_pgdata);
263 
264  if (!getcwd(cwd, MAXPGPATH))
265  pg_fatal("cannot find current directory\n");
266  canonicalize_path(cwd);
267  if (path_is_prefix_of_path(new_cluster_pgdata, cwd))
268  pg_fatal("cannot run pg_upgrade from inside the new cluster data directory on Windows\n");
269  }
270 #endif
271 }
const char * get_progname(const char *argv0)
Definition: path.c:453
int getopt_long(int argc, char *const argv[], const char *optstring, const struct option *longopts, int *longindex)
Definition: getopt_long.c:57
bool path_is_prefix_of_path(const char *path1, const char *path2)
Definition: path.c:438
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
int get_user_info(char **user_name_p)
Definition: util.c:212
#define FIX_DEFAULT_READ_ONLY
Definition: option.c:26
void canonicalize_path(char *path)
Definition: path.c:254
unsigned short port
Definition: pg_upgrade.h:271
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
LogOpts log_opts
Definition: util.c:18
int jobs
Definition: pg_upgrade.h:298
FILE * fopen_priv(const char *path, const char *mode)
Definition: file.c:321
static void check_required_directory(char **dirpath, char **configpath, char *envVarName, char *cmdLineOption, char *description)
Definition: option.c:343
bool user_specified
Definition: pg_upgrade.h:310
char * pgopts
Definition: pg_upgrade.h:268
ClusterInfo new_cluster
Definition: pg_upgrade.c:56
#define required_argument
Definition: getopt_long.h:25
void pfree(void *pointer)
Definition: mcxt.c:950
char * pgconfig
Definition: pg_upgrade.h:265
#define MAXPGPATH
char * output_files[]
Definition: pg_upgrade.c:60
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
transferMode transfer_mode
Definition: pg_upgrade.h:297
UserOpts user_opts
Definition: option.c:29
bool verbose
Definition: pg_upgrade.h:285
char * bindir
Definition: pg_upgrade.h:267
#define no_argument
Definition: getopt_long.h:24
#define DEF_PGUPORT
Definition: pg_upgrade.h:16
#define INTERNAL_LOG_FILE
Definition: pg_upgrade.h:38
#define free(a)
Definition: header.h:65
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
const char * progname
Definition: pg_upgrade.h:307
#define NULL
Definition: c.h:229
FILE * internal
Definition: pg_upgrade.h:284
bool check
Definition: pg_upgrade.h:295
void pg_free(void *ptr)
Definition: fe_memutils.c:105
static char * filename
Definition: pg_dumpall.c:89
char * pgdata
Definition: pg_upgrade.h:264
char * optarg
Definition: getopt.c:53
OSInfo os_info
Definition: pg_upgrade.c:58
void pg_putenv(const char *var, const char *val)
Definition: util.c:254
bool retain
Definition: pg_upgrade.h:286
char * user
Definition: pg_upgrade.h:309
#define _(x)
Definition: elog.c:84
static void usage(void)
Definition: option.c:275
void void void pg_attribute_noreturn ( )
void void void pg_fatal ( const char *  fmt,
  ... 
)
void void pg_log ( eLogType  type,
const char *  fmt,
  ... 
)
void pg_putenv ( const char *  var,
const char *  val 
)

Definition at line 254 of file util.c.

References psprintf(), putenv, and unsetenv.

Referenced by get_control_data(), and parseCommandLine().

255 {
256  if (val)
257  {
258 #ifndef WIN32
259  char *envstr;
260 
261  envstr = psprintf("%s=%s", var, val);
262  putenv(envstr);
263 
264  /*
265  * Do not free envstr because it becomes part of the environment on
266  * some operating systems. See port/unsetenv.c::unsetenv.
267  */
268 #else
269  SetEnvironmentVariableA(var, val);
270 #endif
271  }
272  else
273  {
274 #ifndef WIN32
275  unsetenv(var);
276 #else
277  SetEnvironmentVariableA(var, "");
278 #endif
279  }
280 }
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
#define putenv(x)
Definition: win32.h:411
#define unsetenv(x)
Definition: win32.h:412
long val
Definition: informix.c:689
bool pid_lock_file_exists ( const char *  datadir)

Definition at line 216 of file exec.c.

References close, fd(), MAXPGPATH, pg_fatal(), snprintf(), and strerror().

Referenced by setup().

217 {
218  char path[MAXPGPATH];
219  int fd;
220 
221  snprintf(path, sizeof(path), "%s/postmaster.pid", datadir);
222 
223  if ((fd = open(path, O_RDONLY, 0)) < 0)
224  {
225  /* ENOTDIR means we will throw a more useful error later */
226  if (errno != ENOENT && errno != ENOTDIR)
227  pg_fatal("could not open file \"%s\" for reading: %s\n",
228  path, strerror(errno));
229 
230  return false;
231  }
232 
233  close(fd);
234  return true;
235 }
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define MAXPGPATH
char * datadir
const char * strerror(int errnum)
Definition: strerror.c:19
#define close(a)
Definition: win32.h:12
void print_maps ( FileNameMap maps,
int  n,
const char *  db_name 
)

Definition at line 285 of file info.c.

References log_opts, pg_log(), PG_VERBOSE, and LogOpts::verbose.

Referenced by transfer_all_new_dbs().

286 {
287  if (log_opts.verbose)
288  {
289  int mapnum;
290 
291  pg_log(PG_VERBOSE, "mappings for database \"%s\":\n", db_name);
292 
293  for (mapnum = 0; mapnum < n_maps; mapnum++)
294  pg_log(PG_VERBOSE, "%s.%s: %u to %u\n",
295  maps[mapnum].nspname, maps[mapnum].relname,
296  maps[mapnum].old_relfilenode,
297  maps[mapnum].new_relfilenode);
298 
299  pg_log(PG_VERBOSE, "\n\n");
300  }
301 }
LogOpts log_opts
Definition: util.c:18
void pg_log(eLogType type, const char *fmt,...)
Definition: logging.c:69
bool verbose
Definition: pg_upgrade.h:285
char* quote_identifier ( const char *  s)

Definition at line 10284 of file ruleutils.c.

10285 {
10286  /*
10287  * Can avoid quoting if ident starts with a lowercase letter or underscore
10288  * and contains only lowercase letters, digits, and underscores, *and* is
10289  * not any SQL keyword. Otherwise, supply quotes.
10290  */
10291  int nquotes = 0;
10292  bool safe;
10293  const char *ptr;
10294  char *result;
10295  char *optr;
10296 
10297  /*
10298  * would like to use <ctype.h> macros here, but they might yield unwanted
10299  * locale-specific results...
10300  */
10301  safe = ((ident[0] >= 'a' && ident[0] <= 'z') || ident[0] == '_');
10302 
10303  for (ptr = ident; *ptr; ptr++)
10304  {
10305  char ch = *ptr;
10306 
10307  if ((ch >= 'a' && ch <= 'z') ||
10308  (ch >= '0' && ch <= '9') ||
10309  (ch == '_'))
10310  {
10311  /* okay */
10312  }
10313  else
10314  {
10315  safe = false;
10316  if (ch == '"')
10317  nquotes++;
10318  }
10319  }
10320 
10322  safe = false;
10323 
10324  if (safe)
10325  {
10326  /*
10327  * Check for keyword. We quote keywords except for unreserved ones.
10328  * (In some cases we could avoid quoting a col_name or type_func_name
10329  * keyword, but it seems much harder than it's worth to tell that.)
10330  *
10331  * Note: ScanKeywordLookup() does case-insensitive comparison, but
10332  * that's fine, since we already know we have all-lower-case.
10333  */
10334  const ScanKeyword *keyword = ScanKeywordLookup(ident,
10335  ScanKeywords,
10336  NumScanKeywords);
10337 
10338  if (keyword != NULL && keyword->category != UNRESERVED_KEYWORD)
10339  safe = false;
10340  }
10341 
10342  if (safe)
10343  return ident; /* no change needed */
10344 
10345  result = (char *) palloc(strlen(ident) + nquotes + 2 + 1);
10346 
10347  optr = result;
10348  *optr++ = '"';
10349  for (ptr = ident; *ptr; ptr++)
10350  {
10351  char ch = *ptr;
10352 
10353  if (ch == '"')
10354  *optr++ = '"';
10355  *optr++ = ch;
10356  }
10357  *optr++ = '"';
10358  *optr = '\0';
10359 
10360  return result;
10361 }
const ScanKeyword * ScanKeywordLookup(const char *text, const ScanKeyword *keywords, int num_keywords)
Definition: keywords.c:64
const int NumScanKeywords
Definition: keywords.c:45
return result
Definition: formatting.c:1632
#define UNRESERVED_KEYWORD
Definition: keywords.h:18
const ScanKeyword ScanKeywords[]
Definition: keywords.c:41
bool quote_all_identifiers
Definition: ruleutils.c:298
#define NULL
Definition: c.h:229
int16 category
Definition: keywords.h:28
void * palloc(Size size)
Definition: mcxt.c:849
bool reap_child ( bool  wait_for_child)

Definition at line 290 of file parallel.c.

References UserOpts::jobs, parallel_jobs, pg_fatal(), strerror(), user_opts, WEXITSTATUS, and WIFEXITED.

Referenced by create_new_objects(), generate_old_dump(), parallel_exec_prog(), parallel_transfer_all_new_dbs(), and transfer_all_new_tablespaces().

291 {
292 #ifndef WIN32
293  int work_status;
294  int ret;
295 #else
296  int thread_num;
297  DWORD res;
298 #endif
299 
300  if (user_opts.jobs <= 1 || parallel_jobs == 0)
301  return false;
302 
303 #ifndef WIN32
304  ret = waitpid(-1, &work_status, wait_for_child ? 0 : WNOHANG);
305 
306  /* no children or, for WNOHANG, no dead children */
307  if (ret <= 0 || !WIFEXITED(work_status))
308  return false;
309 
310  if (WEXITSTATUS(work_status) != 0)
311  pg_fatal("child worker exited abnormally: %s\n", strerror(errno));
312 #else
313  /* wait for one to finish */
314  thread_num = WaitForMultipleObjects(parallel_jobs, thread_handles,
315  false, wait_for_child ? INFINITE : 0);
316 
317  if (thread_num == WAIT_TIMEOUT || thread_num == WAIT_FAILED)
318  return false;
319 
320  /* compute thread index in active_threads */
321  thread_num -= WAIT_OBJECT_0;
322 
323  /* get the result */
324  GetExitCodeThread(thread_handles[thread_num], &res);
325  if (res != 0)
326  pg_fatal("child worker exited abnormally: %s\n", strerror(errno));
327 
328  /* dispose of handle to stop leaks */
329  CloseHandle(thread_handles[thread_num]);
330 
331  /* Move last slot into dead child's position */
332  if (thread_num != parallel_jobs - 1)
333  {
334  void *tmp_args;
335 
336  thread_handles[thread_num] = thread_handles[parallel_jobs - 1];
337 
338  /*
339  * Move last active thead arg struct into the now-dead slot, and the
340  * now-dead slot to the end for reuse by the next thread. Though the
341  * thread struct is in use by another thread, we can safely swap the
342  * struct pointers within the array.
343  */
344  tmp_args = cur_thread_args[thread_num];
345  cur_thread_args[thread_num] = cur_thread_args[parallel_jobs - 1];
346  cur_thread_args[parallel_jobs - 1] = tmp_args;
347  }
348 #endif
349 
350  /* do this after job has been removed */
351  parallel_jobs--;
352 
353  return true;
354 }
#define WIFEXITED(w)
Definition: win32.h:172
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
int jobs
Definition: pg_upgrade.h:298
UserOpts user_opts
Definition: option.c:29
#define WEXITSTATUS(w)
Definition: win32.h:174
const char * strerror(int errnum)
Definition: strerror.c:19
static int parallel_jobs
Definition: parallel.c:20
void report_clusters_compatible ( void  )

Definition at line 160 of file check.c.

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

Referenced by main().

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

Definition at line 129 of file file.c.

References BITS_PER_BYTE, BITS_PER_HEAPBLOCK, buffer, byte, close, ClusterInfo::controldata, ControlData::data_checksum_version, i, new_cluster, PG_BINARY, pg_checksum_page(), pg_fatal(), pg_free(), pg_malloc(), read, SizeOfPageHeaderData, strerror(), VISIBILITYMAP_ALL_VISIBLE, and write.

Referenced by transfer_relfile().

131 {
132  int src_fd;
133  int dst_fd;
134  char *buffer;
135  char *new_vmbuf;
136  ssize_t totalBytesRead = 0;
137  ssize_t src_filesize;
138  int rewriteVmBytesPerPage;
139  BlockNumber new_blkno = 0;
140  struct stat statbuf;
141 
142  /* Compute number of old-format bytes per new page */
143  rewriteVmBytesPerPage = (BLCKSZ - SizeOfPageHeaderData) / 2;
144 
145  if ((src_fd = open(fromfile, O_RDONLY | PG_BINARY, 0)) < 0)
146  pg_fatal("error while copying relation \"%s.%s\": could not open file \"%s\": %s\n",
147  schemaName, relName, fromfile, strerror(errno));
148 
149  if (fstat(src_fd, &statbuf) != 0)
150  pg_fatal("error while copying relation \"%s.%s\": could not stat file \"%s\": %s\n",
151  schemaName, relName, fromfile, strerror(errno));
152 
153  if ((dst_fd = open(tofile, O_RDWR | O_CREAT | O_EXCL | PG_BINARY,
154  S_IRUSR | S_IWUSR)) < 0)
155  pg_fatal("error while copying relation \"%s.%s\": could not create file \"%s\": %s\n",
156  schemaName, relName, tofile, strerror(errno));
157 
158  /* Save old file size */
159  src_filesize = statbuf.st_size;
160 
161  /*
162  * Malloc the work buffers, rather than making them local arrays, to
163  * ensure adequate alignment.
164  */
165  buffer = (char *) pg_malloc(BLCKSZ);
166  new_vmbuf = (char *) pg_malloc(BLCKSZ);
167 
168  /*
169  * Turn each visibility map page into 2 pages one by one. Each new page
170  * has the same page header as the old one. If the last section of the
171  * last page is empty, we skip it, mostly to avoid turning one-page
172  * visibility maps for small relations into two pages needlessly.
173  */
174  while (totalBytesRead < src_filesize)
175  {
176  ssize_t bytesRead;
177  char *old_cur;
178  char *old_break;
179  char *old_blkend;
180  PageHeaderData pageheader;
181  bool old_lastblk;
182 
183  if ((bytesRead = read(src_fd, buffer, BLCKSZ)) != BLCKSZ)
184  {
185  if (bytesRead < 0)
186  pg_fatal("error while copying relation \"%s.%s\": could not read file \"%s\": %s\n",
187  schemaName, relName, fromfile, strerror(errno));
188  else
189  pg_fatal("error while copying relation \"%s.%s\": partial page found in file \"%s\"\n",
190  schemaName, relName, fromfile);
191  }
192 
193  totalBytesRead += BLCKSZ;
194  old_lastblk = (totalBytesRead == src_filesize);
195 
196  /* Save the page header data */
197  memcpy(&pageheader, buffer, SizeOfPageHeaderData);
198 
199  /*
200  * These old_* variables point to old visibility map page. old_cur
201  * points to current position on old page. old_blkend points to end of
202  * old block. old_break is the end+1 position on the old page for the
203  * data that will be transferred to the current new page.
204  */
205  old_cur = buffer + SizeOfPageHeaderData;
206  old_blkend = buffer + bytesRead;
207  old_break = old_cur + rewriteVmBytesPerPage;
208 
209  while (old_break <= old_blkend)
210  {
211  char *new_cur;
212  bool empty = true;
213  bool old_lastpart;
214 
215  /* First, copy old page header to new page */
216  memcpy(new_vmbuf, &pageheader, SizeOfPageHeaderData);
217 
218  /* Rewriting the last part of the last old page? */
219  old_lastpart = old_lastblk && (old_break == old_blkend);
220 
221  new_cur = new_vmbuf + SizeOfPageHeaderData;
222 
223  /* Process old page bytes one by one, and turn it into new page. */
224  while (old_cur < old_break)
225  {
226  uint8 byte = *(uint8 *) old_cur;
227  uint16 new_vmbits = 0;
228  int i;
229 
230  /* Generate new format bits while keeping old information */
231  for (i = 0; i < BITS_PER_BYTE; i++)
232  {
233  if (byte & (1 << i))
234  {
235  empty = false;
236  new_vmbits |=
238  }
239  }
240 
241  /* Copy new visibility map bytes to new-format page */
242  new_cur[0] = (char) (new_vmbits & 0xFF);
243  new_cur[1] = (char) (new_vmbits >> 8);
244 
245  old_cur++;
246  new_cur += BITS_PER_HEAPBLOCK;
247  }
248 
249  /* If the last part of the last page is empty, skip writing it */
250  if (old_lastpart && empty)
251  break;
252 
253  /* Set new checksum for visibility map page, if enabled */
255  ((PageHeader) new_vmbuf)->pd_checksum =
256  pg_checksum_page(new_vmbuf, new_blkno);
257 
258  errno = 0;
259  if (write(dst_fd, new_vmbuf, BLCKSZ) != BLCKSZ)
260  {
261  /* if write didn't set errno, assume problem is no disk space */
262  if (errno == 0)
263  errno = ENOSPC;
264  pg_fatal("error while copying relation \"%s.%s\": could not write file \"%s\": %s\n",
265  schemaName, relName, tofile, strerror(errno));
266  }
267 
268  /* Advance for next new page */
269  old_break += rewriteVmBytesPerPage;
270  new_blkno++;
271  }
272  }
273 
274  /* Clean up */
275  pg_free(buffer);
276  pg_free(new_vmbuf);
277  close(dst_fd);
278  close(src_fd);
279 }
void * pg_malloc(size_t size)
Definition: fe_memutils.c:47
ControlData controldata
Definition: pg_upgrade.h:262
#define BITS_PER_BYTE
#define write(a, b, c)
Definition: win32.h:14
unsigned char uint8
Definition: c.h:266
uint32 BlockNumber
Definition: block.h:31
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
#define SizeOfPageHeaderData
Definition: bufpage.h:213
#define PG_BINARY
Definition: c.h:1038
ClusterInfo new_cluster
Definition: pg_upgrade.c:56
unsigned short uint16
Definition: c.h:267
bool data_checksum_version
Definition: pg_upgrade.h:227
#define BITS_PER_HEAPBLOCK
Definition: visibilitymap.h:23
#define byte(x, n)
Definition: rijndael.c:68
PageHeaderData * PageHeader
Definition: bufpage.h:162
WalTimeSample buffer[LAG_TRACKER_BUFFER_SIZE]
Definition: walsender.c:211
void pg_free(void *ptr)
Definition: fe_memutils.c:105
#define VISIBILITYMAP_ALL_VISIBLE
Definition: visibilitymap.h:26
int i
const char * strerror(int errnum)
Definition: strerror.c:19
#define close(a)
Definition: win32.h:12
uint16 pg_checksum_page(char *page, BlockNumber blkno)
#define read(a, b, c)
Definition: win32.h:13
bool start_postmaster ( ClusterInfo cluster,
bool  throw_error 
)

Definition at line 186 of file server.c.

References BINARY_UPGRADE_SERVER_FLAG_CAT_VER, ClusterInfo::bindir, ControlData::cat_ver, cluster(), CLUSTER_NAME, conn, CONNECTION_OK, ClusterInfo::controldata, exec_prog(), get_db_conn(), GET_MAJOR_VERSION, ClusterInfo::major_version, MAXPGPATH, new_cluster, NULL, os_info, pg_fatal(), pg_log(), PG_REPORT, ClusterInfo::pgconfig, ClusterInfo::pgopts, ClusterInfo::port, PQerrorMessage(), PQfinish(), PQstatus(), OSInfo::running_cluster, SERVER_LOG_FILE, SERVER_START_LOG_FILE, snprintf(), ClusterInfo::sockdir, and stop_postmaster_atexit().

187 {
188  char cmd[MAXPGPATH * 4 + 1000];
189  PGconn *conn;
190  bool pg_ctl_return = false;
191  char socket_string[MAXPGPATH + 200];
192 
193  static bool exit_hook_registered = false;
194 
195  if (!exit_hook_registered)
196  {
197  atexit(stop_postmaster_atexit);
198  exit_hook_registered = true;
199  }
200 
201  socket_string[0] = '\0';
202 
203 #ifdef HAVE_UNIX_SOCKETS
204  /* prevent TCP/IP connections, restrict socket access */
205  strcat(socket_string,
206  " -c listen_addresses='' -c unix_socket_permissions=0700");
207 
208  /* Have a sockdir? Tell the postmaster. */
209  if (cluster->sockdir)
210  snprintf(socket_string + strlen(socket_string),
211  sizeof(socket_string) - strlen(socket_string),
212  " -c %s='%s'",
213  (GET_MAJOR_VERSION(cluster->major_version) < 903) ?
214  "unix_socket_directory" : "unix_socket_directories",
215  cluster->sockdir);
216 #endif
217 
218  /*
219  * Since PG 9.1, we have used -b to disable autovacuum. For earlier
220  * releases, setting autovacuum=off disables cleanup vacuum and analyze,
221  * but freeze vacuums can still happen, so we set
222  * autovacuum_freeze_max_age to its maximum.
223  * (autovacuum_multixact_freeze_max_age was introduced after 9.1, so there
224  * is no need to set that.) We assume all datfrozenxid and relfrozenxid
225  * values are less than a gap of 2000000000 from the current xid counter,
226  * so autovacuum will not touch them.
227  *
228  * Turn off durability requirements to improve object creation speed, and
229  * we only modify the new cluster, so only use it there. If there is a
230  * crash, the new cluster has to be recreated anyway. fsync=off is a big
231  * win on ext4.
232  */
233  snprintf(cmd, sizeof(cmd),
234  "\"%s/pg_ctl\" -w -l \"%s\" -D \"%s\" -o \"-p %d%s%s %s%s\" start",
235  cluster->bindir, SERVER_LOG_FILE, cluster->pgconfig, cluster->port,
236  (cluster->controldata.cat_ver >=
238  " -c autovacuum=off -c autovacuum_freeze_max_age=2000000000",
239  (cluster == &new_cluster) ?
240  " -c synchronous_commit=off -c fsync=off -c full_page_writes=off" : "",
241  cluster->pgopts ? cluster->pgopts : "", socket_string);
242 
243  /*
244  * Don't throw an error right away, let connecting throw the error because
245  * it might supply a reason for the failure.
246  */
247  pg_ctl_return = exec_prog(SERVER_START_LOG_FILE,
248  /* pass both file names if they differ */
249  (strcmp(SERVER_LOG_FILE,
250  SERVER_START_LOG_FILE) != 0) ?
252  false,
253  "%s", cmd);
254 
255  /* Did it fail and we are just testing if the server could be started? */
256  if (!pg_ctl_return && !throw_error)
257  return false;
258 
259  /*
260  * We set this here to make sure atexit() shuts down the server, but only
261  * if we started the server successfully. We do it before checking for
262  * connectivity in case the server started but there is a connectivity
263  * failure. If pg_ctl did not return success, we will exit below.
264  *
265  * Pre-9.1 servers do not have PQping(), so we could be leaving the server
266  * running if authentication was misconfigured, so someday we might went
267  * to be more aggressive about doing server shutdowns even if pg_ctl
268  * fails, but now (2013-08-14) it seems prudent to be cautious. We don't
269  * want to shutdown a server that might have been accidentally started
270  * during the upgrade.
271  */
272  if (pg_ctl_return)
274 
275  /*
276  * pg_ctl -w might have failed because the server couldn't be started, or
277  * there might have been a connection problem in _checking_ if the server
278  * has started. Therefore, even if pg_ctl failed, we continue and test
279  * for connectivity in case we get a connection reason for the failure.
280  */
281  if ((conn = get_db_conn(cluster, "template1")) == NULL ||
282  PQstatus(conn) != CONNECTION_OK)
283  {
284  pg_log(PG_REPORT, "\nconnection to database failed: %s\n",
285  PQerrorMessage(conn));
286  if (conn)
287  PQfinish(conn);
288  pg_fatal("could not connect to %s postmaster started with the command:\n"
289  "%s\n",
290  CLUSTER_NAME(cluster), cmd);
291  }
292  PQfinish(conn);
293 
294  /*
295  * If pg_ctl failed, and the connection didn't fail, and throw_error is
296  * enabled, fail now. This could happen if the server was already
297  * running.
298  */
299  if (!pg_ctl_return)
300  pg_fatal("pg_ctl failed to start the %s server, or connection failed\n",
301  CLUSTER_NAME(cluster));
302 
303  return true;
304 }
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:5988
uint32 major_version
Definition: pg_upgrade.h:272
ControlData controldata
Definition: pg_upgrade.h:262
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:29
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3521
unsigned short port
Definition: pg_upgrade.h:271
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
char * pgopts
Definition: pg_upgrade.h:268
ClusterInfo new_cluster
Definition: pg_upgrade.c:56
char * pgconfig
Definition: pg_upgrade.h:265
PGconn * conn
Definition: streamutil.c:42
#define MAXPGPATH
#define CLUSTER_NAME(cluster)
Definition: pg_upgrade.h:97
void cluster(ClusterStmt *stmt, bool isTopLevel)
Definition: cluster.c:106
void pg_log(eLogType type, const char *fmt,...)
Definition: logging.c:69
char * bindir
Definition: pg_upgrade.h:267
uint32 cat_ver
Definition: pg_upgrade.h:208
static void stop_postmaster_atexit(void)
Definition: server.c:179
#define SERVER_LOG_FILE
Definition: pg_upgrade.h:36
#define NULL
Definition: c.h:229
ClusterInfo * running_cluster
Definition: pg_upgrade.h:315
#define SERVER_START_LOG_FILE
Definition: pg_upgrade.h:59
bool exec_prog(const char *log_file, const char *opt_log_file, bool throw_error, const char *fmt,...)
Definition: exec.c:77
char * sockdir
Definition: pg_upgrade.h:270
OSInfo os_info
Definition: pg_upgrade.c:58
#define BINARY_UPGRADE_SERVER_FLAG_CAT_VER
Definition: pg_upgrade.h:103
ConnStatusType PQstatus(const PGconn *conn)
Definition: fe-connect.c:5935
static PGconn * get_db_conn(ClusterInfo *cluster, const char *db_name)
Definition: server.c:53
void stop_postmaster ( bool  fast)

Definition at line 308 of file server.c.

References ClusterInfo::bindir, cluster(), exec_prog(), new_cluster, NULL, old_cluster, os_info, ClusterInfo::pgconfig, ClusterInfo::pgopts, OSInfo::running_cluster, and SERVER_STOP_LOG_FILE.

Referenced by check_and_dump_old_cluster(), issue_warnings(), main(), report_clusters_compatible(), setup(), and stop_postmaster_atexit().

309 {
311 
313  cluster = &old_cluster;
314  else if (os_info.running_cluster == &new_cluster)
315  cluster = &new_cluster;
316  else
317  return; /* no cluster running */
318 
320  "\"%s/pg_ctl\" -w -D \"%s\" -o \"%s\" %s stop",
321  cluster->bindir, cluster->pgconfig,
322  cluster->pgopts ? cluster->pgopts : "",
323  fast ? "-m fast" : "-m smart");
324 
326 }
#define SERVER_STOP_LOG_FILE
Definition: pg_upgrade.h:60
char * pgopts
Definition: pg_upgrade.h:268
ClusterInfo new_cluster
Definition: pg_upgrade.c:56
char * pgconfig
Definition: pg_upgrade.h:265
ClusterInfo old_cluster
Definition: pg_upgrade.c:56
void cluster(ClusterStmt *stmt, bool isTopLevel)
Definition: cluster.c:106
char * bindir
Definition: pg_upgrade.h:267
#define NULL
Definition: c.h:229
ClusterInfo * running_cluster
Definition: pg_upgrade.h:315
bool exec_prog(const char *log_file, const char *opt_log_file, bool throw_error, const char *fmt,...)
Definition: exec.c:77
OSInfo os_info
Definition: pg_upgrade.c:58
unsigned int str2uint ( const char *  str)

Definition at line 241 of file util.c.

References NULL.

Referenced by get_control_data().

242 {
243  return strtoul(str, NULL, 10);
244 }
#define NULL
Definition: c.h:229
void transfer_all_new_dbs ( DbInfoArr old_db_arr,
DbInfoArr new_db_arr,
char *  old_pgdata,
char *  new_pgdata,
char *  old_tablespace 
)

Definition at line 81 of file relfilenode.c.

References DbInfo::db_name, DbInfoArr::dbs, gen_db_file_maps(), DbInfoArr::ndbs, NULL, pg_fatal(), pg_free(), print_maps(), and transfer_single_new_db().

Referenced by parallel_transfer_all_new_dbs().

83 {
84  int old_dbnum,
85  new_dbnum;
86 
87  /* Scan the old cluster databases and transfer their files */
88  for (old_dbnum = new_dbnum = 0;
89  old_dbnum < old_db_arr->ndbs;
90  old_dbnum++, new_dbnum++)
91  {
92  DbInfo *old_db = &old_db_arr->dbs[old_dbnum],
93  *new_db = NULL;
94  FileNameMap *mappings;
95  int n_maps;
96 
97  /*
98  * Advance past any databases that exist in the new cluster but not in
99  * the old, e.g. "postgres". (The user might have removed the
100  * 'postgres' database from the old cluster.)
101  */
102  for (; new_dbnum < new_db_arr->ndbs; new_dbnum++)
103  {
104  new_db = &new_db_arr->dbs[new_dbnum];
105  if (strcmp(old_db->db_name, new_db->db_name) == 0)
106  break;
107  }
108 
109  if (new_dbnum >= new_db_arr->ndbs)
110  pg_fatal("old database \"%s\" not found in the new cluster\n",
111  old_db->db_name);
112 
113  mappings = gen_db_file_maps(old_db, new_db, &n_maps, old_pgdata,
114  new_pgdata);
115  if (n_maps)
116  {
117  print_maps(mappings, n_maps, new_db->db_name);
118 
119  transfer_single_new_db(mappings, n_maps, old_tablespace);
120  }
121  /* We allocate something even for n_maps == 0 */
122  pg_free(mappings);
123  }
124 
125  return;
126 }
FileNameMap * gen_db_file_maps(DbInfo *old_db, DbInfo *new_db, int *nmaps, const char *old_pgdata, const char *new_pgdata)
Definition: info.c:41
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
void print_maps(FileNameMap *maps, int n_maps, const char *db_name)
Definition: info.c:285
#define NULL
Definition: c.h:229
void pg_free(void *ptr)
Definition: fe_memutils.c:105
char * db_name
Definition: pg_upgrade.h:185
DbInfo * dbs
Definition: pg_upgrade.h:196
static void transfer_single_new_db(FileNameMap *maps, int size, char *old_tablespace)
Definition: relfilenode.c:134
void transfer_all_new_tablespaces ( DbInfoArr old_db_arr,
DbInfoArr new_db_arr,
char *  old_pgdata,
char *  new_pgdata 
)

Definition at line 30 of file relfilenode.c.

References check_ok(), end_progress_output(), UserOpts::jobs, NULL, OSInfo::num_old_tablespaces, OSInfo::old_tablespaces, os_info, parallel_transfer_all_new_dbs(), pg_log(), PG_REPORT, reap_child(), UserOpts::transfer_mode, TRANSFER_MODE_LINK, and user_opts.

Referenced by main().

32 {
34  pg_log(PG_REPORT, "Linking user relation files\n");
35  else
36  pg_log(PG_REPORT, "Copying user relation files\n");
37 
38  /*
39  * Transferring files by tablespace is tricky because a single database
40  * can use multiple tablespaces. For non-parallel mode, we just pass a
41  * NULL tablespace path, which matches all tablespaces. In parallel mode,
42  * we pass the default tablespace and all user-created tablespaces and let
43  * those operations happen in parallel.
44  */
45  if (user_opts.jobs <= 1)
46  parallel_transfer_all_new_dbs(old_db_arr, new_db_arr, old_pgdata,
47  new_pgdata, NULL);
48  else
49  {
50  int tblnum;
51 
52  /* transfer default tablespace */
53  parallel_transfer_all_new_dbs(old_db_arr, new_db_arr, old_pgdata,
54  new_pgdata, old_pgdata);
55 
56  for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
58  new_db_arr,
59  old_pgdata,
60  new_pgdata,
61  os_info.old_tablespaces[tblnum]);
62  /* reap all children */
63  while (reap_child(true) == true)
64  ;
65  }
66 
68  check_ok();
69 
70  return;
71 }
void end_progress_output(void)
Definition: util.c:44
int jobs
Definition: pg_upgrade.h:298
void parallel_transfer_all_new_dbs(DbInfoArr *old_db_arr, DbInfoArr *new_db_arr, char *old_pgdata, char *new_pgdata, char *old_tablespace)
Definition: parallel.c:178
void pg_log(eLogType type, const char *fmt,...)
Definition: logging.c:69
static void check_ok(void)
Definition: initdb.c:2008
transferMode transfer_mode
Definition: pg_upgrade.h:297
UserOpts user_opts
Definition: option.c:29
char ** old_tablespaces
Definition: pg_upgrade.h:311
#define NULL
Definition: c.h:229
bool reap_child(bool wait_for_child)
Definition: parallel.c:290
int num_old_tablespaces
Definition: pg_upgrade.h:312
OSInfo os_info
Definition: pg_upgrade.c:58
bool void verify_directories ( void  )

Definition at line 247 of file exec.c.

References check_bin_dir(), check_data_dir(), new_cluster, old_cluster, and pg_fatal().

Referenced by setup().

248 {
249 #ifndef WIN32
250  if (access(".", R_OK | W_OK | X_OK) != 0)
251 #else
252  if (win32_check_directory_write_permissions() != 0)
253 #endif
254  pg_fatal("You must have read and write access in the current directory.\n");
255 
260 }
static void check_bin_dir(ClusterInfo *cluster)
Definition: exec.c:364
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
ClusterInfo new_cluster
Definition: pg_upgrade.c:56
ClusterInfo old_cluster
Definition: pg_upgrade.c:56
static void check_data_dir(ClusterInfo *cluster)
Definition: exec.c:325

Variable Documentation

char* output_files[]

Definition at line 60 of file pg_upgrade.c.

Referenced by cleanup(), and parseCommandLine().