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 atooid(x)   ((Oid) strtoul((x), NULL, 10))
 
#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 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 atooid (   x)    ((Oid) strtoul((x), NULL, 10))

Definition at line 100 of file pg_upgrade.h.

#define BINARY_UPGRADE_SERVER_FLAG_CAT_VER   201104251

Definition at line 105 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:55
ClusterInfo new_cluster
Definition: pg_upgrade.c:55
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 360 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 133 of file pg_upgrade.h.

Referenced by check_and_dump_old_cluster().

#define LARGE_OBJECT_SIZE_PG_CONTROL_VER   942

Definition at line 128 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 122 of file pg_upgrade.h.

Referenced by copy_clog_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 103 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 110 of file pg_upgrade.h.

Referenced by transfer_single_new_db().

#define VISIBILITY_MAP_FROZEN_BIT_CAT_VER   201603011

Definition at line 115 of file pg_upgrade.h.

Referenced by transfer_single_new_db().

Typedef Documentation

Definition at line 254 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 244 of file pg_upgrade.h.

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

Definition at line 235 of file pg_upgrade.h.

Function Documentation

void adjust_data_dir ( ClusterInfo cluster)

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

386 {
387  char filename[MAXPGPATH];
388  char cmd[MAXPGPATH],
389  cmd_output[MAX_STRING];
390  FILE *fp,
391  *output;
392 
393  /* If there is no postgresql.conf, it can't be a config-only dir */
394  snprintf(filename, sizeof(filename), "%s/postgresql.conf", cluster->pgconfig);
395  if ((fp = fopen(filename, "r")) == NULL)
396  return;
397  fclose(fp);
398 
399  /* If PG_VERSION exists, it can't be a config-only dir */
400  snprintf(filename, sizeof(filename), "%s/PG_VERSION", cluster->pgconfig);
401  if ((fp = fopen(filename, "r")) != NULL)
402  {
403  fclose(fp);
404  return;
405  }
406 
407  /* Must be a configuration directory, so find the real data directory. */
408 
409  prep_status("Finding the real data directory for the %s cluster",
410  CLUSTER_NAME(cluster));
411 
412  /*
413  * We don't have a data directory yet, so we can't check the PG version,
414  * so this might fail --- only works for PG 9.2+. If this fails,
415  * pg_upgrade will fail anyway because the data files will not be found.
416  */
417  snprintf(cmd, sizeof(cmd), "\"%s/postgres\" -D \"%s\" -C data_directory",
418  cluster->bindir, cluster->pgconfig);
419 
420  if ((output = popen(cmd, "r")) == NULL ||
421  fgets(cmd_output, sizeof(cmd_output), output) == NULL)
422  pg_fatal("could not get data directory using %s: %s\n",
423  cmd, strerror(errno));
424 
425  pclose(output);
426 
427  /* Remove trailing newline */
428  if (strchr(cmd_output, '\n') != NULL)
429  *strchr(cmd_output, '\n') = '\0';
430 
431  cluster->pgdata = pg_strdup(cmd_output);
432 
433  check_ok();
434 }
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:267
#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:1988
char * bindir
Definition: pg_upgrade.h:269
#define MAX_STRING
Definition: pg_upgrade.h:21
#define NULL
Definition: c.h:226
static char * filename
Definition: pg_dumpall.c:84
char * pgdata
Definition: pg_upgrade.h:266
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_cluster, start_postmaster(), stop_postmaster(), and user_opts.

Referenced by main().

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

Definition at line 256 of file check.c.

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

Referenced by main().

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

Definition at line 214 of file check.c.

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

Referenced by main().

215 {
216  prep_status("Checking cluster versions");
217 
218  /* get old and new cluster versions */
221 
222  /*
223  * We allow upgrades from/to the same major version for alpha/beta
224  * upgrades
225  */
226 
228  pg_fatal("This utility can only upgrade from PostgreSQL version 8.4 and later.\n");
229 
230  /* Only current PG version is supported as a target */
232  pg_fatal("This utility can only upgrade to PostgreSQL version %s.\n",
233  PG_MAJORVERSION);
234 
235  /*
236  * We can't allow downgrading because we use the target pg_dump, and
237  * pg_dump cannot operate on newer database versions, only current and
238  * older versions.
239  */
241  pg_fatal("This utility cannot be used to downgrade to older major PostgreSQL versions.\n");
242 
243  /* Ensure binaries match the designated data directories */
246  pg_fatal("Old cluster data and binary directories are from different major versions.\n");
249  pg_fatal("New cluster data and binary directories are from different major versions.\n");
250 
251  check_ok();
252 }
uint32 get_major_server_version(ClusterInfo *cluster)
Definition: server.c:155
uint32 major_version
Definition: pg_upgrade.h:274
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:29
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
ClusterInfo new_cluster
Definition: pg_upgrade.c:55
void prep_status(const char *fmt,...) pg_attribute_printf(1
ClusterInfo old_cluster
Definition: pg_upgrade.c:55
static void check_ok(void)
Definition: initdb.c:1988
uint32 bin_version
Definition: pg_upgrade.h:276
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:227
uint32 walsz
Definition: pg_upgrade.h:221
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
uint32 index
Definition: pg_upgrade.h:224
uint32 blocksz
Definition: pg_upgrade.h:219
bool data_checksum_version
Definition: pg_upgrade.h:229
uint32 ident
Definition: pg_upgrade.h:223
uint32 align
Definition: pg_upgrade.h:218
uint32 walseg
Definition: pg_upgrade.h:222
uint32 largesz
Definition: pg_upgrade.h:220
uint32 toast
Definition: pg_upgrade.h:225
uint32 large_object
Definition: pg_upgrade.h:226
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:55
#define MAXPGPATH
ClusterInfo old_cluster
Definition: pg_upgrade.c:55
int unlink(const char *filename)
char * pgdata
Definition: pg_upgrade.h:266
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:5960
uint32 major_version
Definition: pg_upgrade.h:274
int num_libraries
Definition: pg_upgrade.h:316
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:29
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3517
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
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:55
PGconn * conn
Definition: streamutil.c:45
#define MAXPGPATH
char ** libraries
Definition: pg_upgrade.h:315
void prep_status(const char *fmt,...) pg_attribute_printf(1
ClusterInfo old_cluster
Definition: pg_upgrade.c:55
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:1988
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:226
const char * strerror(int errnum)
Definition: strerror.c:19
OSInfo os_info
Definition: pg_upgrade.c:57
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 134 of file check.c.

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

Referenced by main().

135 {
137 
140 
142 
144  check_hard_link();
145 
147 
149 }
void check_hard_link(void)
Definition: file.c:282
static void check_databases_are_compatible(void)
Definition: check.c:383
void check_loadable_libraries(void)
Definition: function.c:203
static void check_for_prepared_transactions(ClusterInfo *cluster)
Definition: check.c:744
ClusterInfo new_cluster
Definition: pg_upgrade.c:55
static void check_is_install_user(ClusterInfo *cluster)
Definition: check.c:632
transferMode transfer_mode
Definition: pg_upgrade.h:299
UserOpts user_opts
Definition: option.c:30
static void check_new_cluster_is_empty(void)
Definition: check.c:358
void get_db_and_rel_infos(ClusterInfo *cluster)
Definition: info.c:310
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 }
static struct @76 value
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
void PQconninfoFree(PQconninfoOption *connOptions)
Definition: fe-connect.c:5810
#define NULL
Definition: c.h:226
PQconninfoOption * PQconndefaults(void)
Definition: fe-connect.c:1108
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:273
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:262
static char * buf
Definition: pg_test_fsync.c:65
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:430
#define NULL
Definition: c.h:226
char * sockdir
Definition: pg_upgrade.h:272
OSInfo os_info
Definition: pg_upgrade.c:57
void resetPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:145
char * user
Definition: pg_upgrade.h:311
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(), 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:5960
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3517
PGconn * conn
Definition: streamutil.c:45
void pg_log(eLogType type, const char *fmt,...)
Definition: logging.c:69
#define NULL
Definition: c.h:226
ConnStatusType PQstatus(const PGconn *conn)
Definition: fe-connect.c:5907
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(), 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:19
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
#define PG_BINARY
Definition: c.h:1037
#define COPY_BUF_SIZE
void _dosmaperr(unsigned long)
Definition: win32error.c:171
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:17
#define read(a, b, c)
Definition: win32.h:18
void create_script_for_cluster_analyze ( char **  analyze_script_file_name)

Definition at line 414 of file check.c.

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

Referenced by main().

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

Definition at line 504 of file check.c.

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

Referenced by main().

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

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

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

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

20 {
21  int dbnum;
22  mode_t old_umask;
23 
24  prep_status("Creating dump of global objects");
25 
26  /* run new pg_dumpall binary for globals */
28  "\"%s/pg_dumpall\" %s --globals-only --quote-all-identifiers "
29  "--binary-upgrade %s -f %s",
31  log_opts.verbose ? "--verbose" : "",
33  check_ok();
34 
35  prep_status("Creating dump of database schemas\n");
36 
37  /*
38  * Set umask for this function, all functions it calls, and all
39  * subprocesses/threads it creates. We can't use fopen_priv() as Windows
40  * uses threads and umask is process-global.
41  */
42  old_umask = umask(S_IRWXG | S_IRWXO);
43 
44  /* create per-db dump files */
45  for (dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
46  {
47  char sql_file_name[MAXPGPATH],
48  log_file_name[MAXPGPATH];
49  DbInfo *old_db = &old_cluster.dbarr.dbs[dbnum];
51  escaped_connstr;
52 
53  initPQExpBuffer(&connstr);
54  appendPQExpBuffer(&connstr, "dbname=");
55  appendConnStrVal(&connstr, old_db->db_name);
56  initPQExpBuffer(&escaped_connstr);
57  appendShellString(&escaped_connstr, connstr.data);
58  termPQExpBuffer(&connstr);
59 
60  pg_log(PG_STATUS, "%s", old_db->db_name);
61  snprintf(sql_file_name, sizeof(sql_file_name), DB_DUMP_FILE_MASK, old_db->db_oid);
62  snprintf(log_file_name, sizeof(log_file_name), DB_DUMP_LOG_FILE_MASK, old_db->db_oid);
63 
64  parallel_exec_prog(log_file_name, NULL,
65  "\"%s/pg_dump\" %s --schema-only --quote-all-identifiers "
66  "--binary-upgrade --format=custom %s --file=\"%s\" %s",
68  log_opts.verbose ? "--verbose" : "",
69  sql_file_name, escaped_connstr.data);
70 
71  termPQExpBuffer(&escaped_connstr);
72  }
73 
74  /* reap all children */
75  while (reap_child(true) == true)
76  ;
77 
78  umask(old_umask);
79 
81  check_ok();
82 }
void parallel_exec_prog(const char *log_file, const char *opt_log_file, const char *fmt,...)
Definition: parallel.c:66
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:536
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:186
ClusterInfo new_cluster
Definition: pg_upgrade.c:55
#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:55
void pg_log(eLogType type, const char *fmt,...)
Definition: logging.c:69
static void check_ok(void)
Definition: initdb.c:1988
#define DB_DUMP_FILE_MASK
Definition: pg_upgrade.h:33
bool verbose
Definition: pg_upgrade.h:287
char * bindir
Definition: pg_upgrade.h:269
#define S_IRWXO
Definition: win32.h:484
void appendShellString(PQExpBuffer buf, const char *str)
Definition: string_utils.c:430
DbInfoArr dbarr
Definition: pg_upgrade.h:265
#define NULL
Definition: c.h:226
#define DB_DUMP_LOG_FILE_MASK
Definition: pg_upgrade.h:35
bool reap_child(bool wait_for_child)
Definition: parallel.c:293
#define S_IRWXG
Definition: win32.h:480
#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:78
char * db_name
Definition: pg_upgrade.h:187
#define GLOBALS_DUMP_FILE
Definition: pg_upgrade.h:32
DbInfo * dbs
Definition: pg_upgrade.h:198
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89
static char * connstr
Definition: pg_dumpall.c:67
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:227
static char * lc_monetary
Definition: initdb.c:125
uint32 major_version
Definition: pg_upgrade.h:274
unsigned int str2uint(const char *str)
Definition: util.c:241
static char * lc_collate
Definition: initdb.c:123
ControlData controldata
Definition: pg_upgrade.h:264
static void output(uint64 loop_count)
#define LARGE_OBJECT_SIZE_PG_CONTROL_VER
Definition: pg_upgrade.h:128
uint32 chkpnt_nxtoid
Definition: pg_upgrade.h:214
uint32 walsz
Definition: pg_upgrade.h:221
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:29
char nextxlogfile[25]
Definition: pg_upgrade.h:211
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:224
uint32 chkpnt_nxtmxoff
Definition: pg_upgrade.h:216
static char * lc_time
Definition: initdb.c:127
uint32 blocksz
Definition: pg_upgrade.h:219
uint32 chkpnt_nxtxid
Definition: pg_upgrade.h:212
static char * lc_messages
Definition: initdb.c:128
uint32 chkpnt_nxtepoch
Definition: pg_upgrade.h:213
#define MAXPGPATH
static char * lc_ctype
Definition: initdb.c:124
static char * lc_numeric
Definition: initdb.c:126
#define CLUSTER_NAME(cluster)
Definition: pg_upgrade.h:97
bool data_checksum_version
Definition: pg_upgrade.h:229
uint32 ident
Definition: pg_upgrade.h:223
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
unsigned int uint32
Definition: c.h:265
void pg_log(eLogType type, const char *fmt,...)
Definition: logging.c:69
uint32 align
Definition: pg_upgrade.h:218
uint32 chkpnt_oldstMulti
Definition: pg_upgrade.h:217
uint32 walseg
Definition: pg_upgrade.h:222
char * bindir
Definition: pg_upgrade.h:269
#define MAX_STRING
Definition: pg_upgrade.h:21
uint32 cat_ver
Definition: pg_upgrade.h:210
uint32 chkpnt_nxtmulti
Definition: pg_upgrade.h:215
uint32 largesz
Definition: pg_upgrade.h:220
uint32 bin_version
Definition: pg_upgrade.h:276
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
#define NULL
Definition: c.h:226
uint32 toast
Definition: pg_upgrade.h:225
uint32 large_object
Definition: pg_upgrade.h:226
void pg_free(void *ptr)
Definition: fe_memutils.c:105
#define MULTIXACT_FORMATCHANGE_CAT_VER
Definition: pg_upgrade.h:122
uint32 ctrl_ver
Definition: pg_upgrade.h:209
char * pgdata
Definition: pg_upgrade.h:266
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:228
void get_db_and_rel_infos ( ClusterInfo cluster)

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

311 {
312  int dbnum;
313 
314  if (cluster->dbarr.dbs != NULL)
315  free_db_and_rel_infos(&cluster->dbarr);
316 
317  get_db_infos(cluster);
318 
319  for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
320  get_rel_infos(cluster, &cluster->dbarr.dbs[dbnum]);
321 
322  pg_log(PG_VERBOSE, "\n%s databases:\n", CLUSTER_NAME(cluster));
323  if (log_opts.verbose)
324  print_db_infos(&cluster->dbarr);
325 }
static void get_db_infos(ClusterInfo *cluster)
Definition: info.c:335
LogOpts log_opts
Definition: util.c:18
static void get_rel_infos(ClusterInfo *cluster, DbInfo *dbinfo)
Definition: info.c:404
#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:624
bool verbose
Definition: pg_upgrade.h:287
DbInfoArr dbarr
Definition: pg_upgrade.h:265
#define NULL
Definition: c.h:226
static void free_db_and_rel_infos(DbInfoArr *db_arr)
Definition: info.c:590
DbInfo * dbs
Definition: pg_upgrade.h:198
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:274
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:316
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:3517
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:45
char ** libraries
Definition: pg_upgrade.h:315
ClusterInfo old_cluster
Definition: pg_upgrade.c:55
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:265
void pg_free(void *ptr)
Definition: fe_memutils.c:105
int i
OSInfo os_info
Definition: pg_upgrade.c:57
char * db_name
Definition: pg_upgrade.h:187
#define qsort(a, b, c, d)
Definition: port.h:440
DbInfo * dbs
Definition: pg_upgrade.h:198
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:275
#define MAXPGPATH
#define NULL
Definition: c.h:226
char * pgdata
Definition: pg_upgrade.h:266
void get_sock_dir ( ClusterInfo cluster,
bool  live_check 
)

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

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

22 {
24 
27 
28  if (os_info.num_old_tablespaces > 0 &&
30  pg_fatal("Cannot upgrade to/from the same system catalog version when\n"
31  "using tablespaces.\n");
32 }
static void set_tablespace_directory_suffix(ClusterInfo *cluster)
Definition: tablespace.c:111
static void get_tablespace_paths(void)
Definition: tablespace.c:42
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
ClusterInfo new_cluster
Definition: pg_upgrade.c:55
ClusterInfo old_cluster
Definition: pg_upgrade.c:55
const char * tablespace_suffix
Definition: pg_upgrade.h:277
int num_old_tablespaces
Definition: pg_upgrade.h:314
OSInfo os_info
Definition: pg_upgrade.c:57
void issue_warnings ( void  )

Definition at line 170 of file check.c.

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

Referenced by main().

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

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

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

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

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

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

Definition at line 61 of file check.c.

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

Referenced by main().

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

Definition at line 183 of file check.c.

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

Referenced by main().

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

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

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

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

Definition at line 217 of file exec.c.

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

Referenced by setup().

218 {
219  char path[MAXPGPATH];
220  int fd;
221 
222  snprintf(path, sizeof(path), "%s/postmaster.pid", datadir);
223 
224  if ((fd = open(path, O_RDONLY, 0)) < 0)
225  {
226  /* ENOTDIR means we will throw a more useful error later */
227  if (errno != ENOENT && errno != ENOTDIR)
228  pg_fatal("could not open file \"%s\" for reading: %s\n",
229  path, strerror(errno));
230 
231  return false;
232  }
233 
234  close(fd);
235  return true;
236 }
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:17
void print_maps ( FileNameMap maps,
int  n,
const char *  db_name 
)

Definition at line 284 of file info.c.

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

Referenced by transfer_all_new_dbs().

285 {
286  if (log_opts.verbose)
287  {
288  int mapnum;
289 
290  pg_log(PG_VERBOSE, "mappings for database \"%s\":\n", db_name);
291 
292  for (mapnum = 0; mapnum < n_maps; mapnum++)
293  pg_log(PG_VERBOSE, "%s.%s: %u to %u\n",
294  maps[mapnum].nspname, maps[mapnum].relname,
295  maps[mapnum].old_relfilenode,
296  maps[mapnum].new_relfilenode);
297 
298  pg_log(PG_VERBOSE, "\n\n");
299  }
300 }
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:287
char* quote_identifier ( const char *  s)

Definition at line 9975 of file ruleutils.c.

9976 {
9977  /*
9978  * Can avoid quoting if ident starts with a lowercase letter or underscore
9979  * and contains only lowercase letters, digits, and underscores, *and* is
9980  * not any SQL keyword. Otherwise, supply quotes.
9981  */
9982  int nquotes = 0;
9983  bool safe;
9984  const char *ptr;
9985  char *result;
9986  char *optr;
9987 
9988  /*
9989  * would like to use <ctype.h> macros here, but they might yield unwanted
9990  * locale-specific results...
9991  */
9992  safe = ((ident[0] >= 'a' && ident[0] <= 'z') || ident[0] == '_');
9993 
9994  for (ptr = ident; *ptr; ptr++)
9995  {
9996  char ch = *ptr;
9997 
9998  if ((ch >= 'a' && ch <= 'z') ||
9999  (ch >= '0' && ch <= '9') ||
10000  (ch == '_'))
10001  {
10002  /* okay */
10003  }
10004  else
10005  {
10006  safe = false;
10007  if (ch == '"')
10008  nquotes++;
10009  }
10010  }
10011 
10013  safe = false;
10014 
10015  if (safe)
10016  {
10017  /*
10018  * Check for keyword. We quote keywords except for unreserved ones.
10019  * (In some cases we could avoid quoting a col_name or type_func_name
10020  * keyword, but it seems much harder than it's worth to tell that.)
10021  *
10022  * Note: ScanKeywordLookup() does case-insensitive comparison, but
10023  * that's fine, since we already know we have all-lower-case.
10024  */
10025  const ScanKeyword *keyword = ScanKeywordLookup(ident,
10026  ScanKeywords,
10027  NumScanKeywords);
10028 
10029  if (keyword != NULL && keyword->category != UNRESERVED_KEYWORD)
10030  safe = false;
10031  }
10032 
10033  if (safe)
10034  return ident; /* no change needed */
10035 
10036  result = (char *) palloc(strlen(ident) + nquotes + 2 + 1);
10037 
10038  optr = result;
10039  *optr++ = '"';
10040  for (ptr = ident; *ptr; ptr++)
10041  {
10042  char ch = *ptr;
10043 
10044  if (ch == '"')
10045  *optr++ = '"';
10046  *optr++ = ch;
10047  }
10048  *optr++ = '"';
10049  *optr = '\0';
10050 
10051  return result;
10052 }
const ScanKeyword * ScanKeywordLookup(const char *text, const ScanKeyword *keywords, int num_keywords)
Definition: keywords.c:64
const int NumScanKeywords
Definition: keywords.c:45
#define UNRESERVED_KEYWORD
Definition: keywords.h:18
const ScanKeyword ScanKeywords[]
Definition: keywords.c:41
bool quote_all_identifiers
Definition: ruleutils.c:296
#define NULL
Definition: c.h:226
int16 category
Definition: keywords.h:28
void * palloc(Size size)
Definition: mcxt.c:891
bool reap_child ( bool  wait_for_child)

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

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

Definition at line 153 of file check.c.

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

Referenced by main().

154 {
155  if (user_opts.check)
156  {
157  pg_log(PG_REPORT, "\n*Clusters are compatible*\n");
158  /* stops new cluster */
159  stop_postmaster(false);
160  exit(0);
161  }
162 
163  pg_log(PG_REPORT, "\n"
164  "If pg_upgrade fails after this point, you must re-initdb the\n"
165  "new cluster before continuing.\n");
166 }
void stop_postmaster(bool fast)
Definition: server.c:308
void pg_log(eLogType type, const char *fmt,...)
Definition: logging.c:69
UserOpts user_opts
Definition: option.c:30
bool check
Definition: pg_upgrade.h:297
void report_status ( eLogType  type,
const char *  fmt,
  ... 
)
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, 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:264
#define BITS_PER_BYTE
#define write(a, b, c)
Definition: win32.h:19
unsigned char uint8
Definition: c.h:263
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:1037
ClusterInfo new_cluster
Definition: pg_upgrade.c:55
unsigned short uint16
Definition: c.h:264
bool data_checksum_version
Definition: pg_upgrade.h:229
#define BITS_PER_HEAPBLOCK
Definition: visibilitymap.h:23
#define byte(x, n)
Definition: rijndael.c:68
PageHeaderData * PageHeader
Definition: bufpage.h:162
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:17
uint16 pg_checksum_page(char *page, BlockNumber blkno)
#define read(a, b, c)
Definition: win32.h:18
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:5960
uint32 major_version
Definition: pg_upgrade.h:274
ControlData controldata
Definition: pg_upgrade.h:264
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:29
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3517
unsigned short port
Definition: pg_upgrade.h:273
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:270
ClusterInfo new_cluster
Definition: pg_upgrade.c:55
char * pgconfig
Definition: pg_upgrade.h:267
PGconn * conn
Definition: streamutil.c:45
#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:269
uint32 cat_ver
Definition: pg_upgrade.h:210
static void stop_postmaster_atexit(void)
Definition: server.c:179
#define SERVER_LOG_FILE
Definition: pg_upgrade.h:36
#define NULL
Definition: c.h:226
ClusterInfo * running_cluster
Definition: pg_upgrade.h:317
#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:78
char * sockdir
Definition: pg_upgrade.h:272
OSInfo os_info
Definition: pg_upgrade.c:57
#define BINARY_UPGRADE_SERVER_FLAG_CAT_VER
Definition: pg_upgrade.h:105
ConnStatusType PQstatus(const PGconn *conn)
Definition: fe-connect.c:5907
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:270
ClusterInfo new_cluster
Definition: pg_upgrade.c:55
char * pgconfig
Definition: pg_upgrade.h:267
ClusterInfo old_cluster
Definition: pg_upgrade.c:55
void cluster(ClusterStmt *stmt, bool isTopLevel)
Definition: cluster.c:106
char * bindir
Definition: pg_upgrade.h:269
#define NULL
Definition: c.h:226
ClusterInfo * running_cluster
Definition: pg_upgrade.h:317
bool exec_prog(const char *log_file, const char *opt_log_file, bool throw_error, const char *fmt,...)
Definition: exec.c:78
OSInfo os_info
Definition: pg_upgrade.c:57
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:226
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:40
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:284
#define NULL
Definition: c.h:226
void pg_free(void *ptr)
Definition: fe_memutils.c:105
char * db_name
Definition: pg_upgrade.h:187
DbInfo * dbs
Definition: pg_upgrade.h:198
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:300
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:181
void pg_log(eLogType type, const char *fmt,...)
Definition: logging.c:69
static void check_ok(void)
Definition: initdb.c:1988
transferMode transfer_mode
Definition: pg_upgrade.h:299
UserOpts user_opts
Definition: option.c:30
char ** old_tablespaces
Definition: pg_upgrade.h:313
#define NULL
Definition: c.h:226
bool reap_child(bool wait_for_child)
Definition: parallel.c:293
int num_old_tablespaces
Definition: pg_upgrade.h:314
OSInfo os_info
Definition: pg_upgrade.c:57
bool void verify_directories ( void  )

Definition at line 248 of file exec.c.

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

Referenced by setup().

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

Variable Documentation

char* output_files[]

Definition at line 59 of file pg_upgrade.c.

Referenced by cleanup(), and parseCommandLine().