PostgreSQL Source Code  git master
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 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"
 
#define fopen_priv(path, mode)   fopen(path, mode)
 

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_and_set_wal_level (void)
 
void output_completion_banner (char *analyze_script_file_name, char *deletion_script_file_name)
 
void check_cluster_versions (void)
 
void check_cluster_compatibility (bool live_check)
 
void create_script_for_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 report_error, bool exit_on_error, const char *fmt,...) pg_attribute_printf(5
 
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)
 
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 report_and_exit_on_error)
 
void stop_postmaster (bool in_atexit)
 
uint32 get_major_server_version (ClusterInfo *cluster)
 
void check_pghost_envvar (void)
 
char * quote_identifier (const char *s)
 
int get_user_info (char **user_name_p)
 
void check_ok (void)
 
void report_status (eLogType type, const char *fmt,...) pg_attribute_printf(2
 
void void pg_log (eLogType type, const char *fmt,...) pg_attribute_printf(2
 
void void void pg_fatal (const char *fmt,...) pg_attribute_printf(1
 
void void void pg_attribute_noreturn ()
 
void end_progress_output (void)
 
void prep_status (const char *fmt,...) pg_attribute_printf(1
 
unsigned int str2uint (const char *str)
 
void pg_putenv (const char *var, const char *val)
 
void new_9_0_populate_pg_largeobject_metadata (ClusterInfo *cluster, bool check_mode)
 
void old_9_3_check_for_line_data_type_usage (ClusterInfo *cluster)
 
void old_9_6_check_for_unknown_data_type_usage (ClusterInfo *cluster)
 
void old_9_6_invalidate_hash_indexes (ClusterInfo *cluster, bool check_mode)
 
void parallel_exec_prog (const char *log_file, const char *opt_log_file, const char *fmt,...) pg_attribute_printf(3
 
void void parallel_transfer_all_new_dbs (DbInfoArr *old_db_arr, DbInfoArr *new_db_arr, char *old_pgdata, char *new_pgdata, char *old_tablespace)
 
bool reap_child (bool wait_for_child)
 

Variables

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

Macro Definition Documentation

◆ BINARY_UPGRADE_SERVER_FLAG_CAT_VER

#define BINARY_UPGRADE_SERVER_FLAG_CAT_VER   201104251

Definition at line 102 of file pg_upgrade.h.

Referenced by start_postmaster().

◆ DB_DUMP_FILE_MASK

#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().

◆ DB_DUMP_LOG_FILE_MASK

#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().

◆ DEF_PGUPORT

#define DEF_PGUPORT   50432

Definition at line 16 of file pg_upgrade.h.

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

◆ ECHO_BLANK

#define ECHO_BLANK   ""

Definition at line 82 of file pg_upgrade.h.

Referenced by create_script_for_cluster_analyze().

◆ ECHO_QUOTE

#define ECHO_QUOTE   "'"

Definition at line 81 of file pg_upgrade.h.

Referenced by create_script_for_cluster_analyze().

◆ EXEC_PSQL_ARGS

#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_globals().

◆ fopen_priv

◆ GET_MAJOR_VERSION

◆ GLOBALS_DUMP_FILE

#define GLOBALS_DUMP_FILE   "pg_upgrade_dump_globals.sql"

Definition at line 32 of file pg_upgrade.h.

Referenced by cleanup(), generate_old_dump(), prepare_new_globals(), and verify_directories().

◆ INTERNAL_LOG_FILE

#define INTERNAL_LOG_FILE   "pg_upgrade_internal.log"

Definition at line 38 of file pg_upgrade.h.

Referenced by parseCommandLine().

◆ JSONB_FORMAT_CHANGE_CAT_VER

#define JSONB_FORMAT_CHANGE_CAT_VER   201409291

Definition at line 132 of file pg_upgrade.h.

Referenced by check_and_dump_old_cluster().

◆ LARGE_OBJECT_SIZE_PG_CONTROL_VER

#define LARGE_OBJECT_SIZE_PG_CONTROL_VER   942

Definition at line 127 of file pg_upgrade.h.

Referenced by get_control_data().

◆ LINE_ALLOC

#define LINE_ALLOC   4096

Definition at line 22 of file pg_upgrade.h.

◆ MAX_STRING

#define MAX_STRING   1024

◆ MESSAGE_WIDTH

#define MESSAGE_WIDTH   60

Definition at line 27 of file pg_upgrade.h.

◆ MIGRATOR_API_VERSION

#define MIGRATOR_API_VERSION   1

Definition at line 25 of file pg_upgrade.h.

◆ MULTIXACT_FORMATCHANGE_CAT_VER

#define MULTIXACT_FORMATCHANGE_CAT_VER   201301231

Definition at line 121 of file pg_upgrade.h.

Referenced by copy_xact_xlog_xid(), and get_control_data().

◆ PATH_QUOTE

#define PATH_QUOTE   '\''

Definition at line 76 of file pg_upgrade.h.

Referenced by create_script_for_old_cluster_deletion().

◆ PATH_SEPARATOR

#define PATH_SEPARATOR   '/'

Definition at line 75 of file pg_upgrade.h.

Referenced by create_script_for_old_cluster_deletion().

◆ pg_link_file

#define pg_link_file   link

Definition at line 74 of file pg_upgrade.h.

Referenced by check_hard_link(), and linkFile().

◆ pg_mv_file

#define pg_mv_file   rename

Definition at line 73 of file pg_upgrade.h.

Referenced by disable_old_cluster().

◆ QUERY_ALLOC

#define QUERY_ALLOC   8192

Definition at line 23 of file pg_upgrade.h.

◆ RM_CMD

#define RM_CMD   "rm -f"

Definition at line 77 of file pg_upgrade.h.

Referenced by create_script_for_old_cluster_deletion().

◆ RMDIR_CMD

#define RMDIR_CMD   "rm -rf"

Definition at line 78 of file pg_upgrade.h.

Referenced by create_script_for_old_cluster_deletion().

◆ SCRIPT_EXT

#define SCRIPT_EXT   "sh"

◆ SCRIPT_PREFIX

#define SCRIPT_PREFIX   "./"

◆ SERVER_LOG_FILE

#define SERVER_LOG_FILE   "pg_upgrade_server.log"

Definition at line 36 of file pg_upgrade.h.

Referenced by start_postmaster().

◆ SERVER_START_LOG_FILE

#define SERVER_START_LOG_FILE   SERVER_LOG_FILE

Definition at line 59 of file pg_upgrade.h.

Referenced by start_postmaster().

◆ SERVER_STOP_LOG_FILE

#define SERVER_STOP_LOG_FILE   SERVER_LOG_FILE

Definition at line 60 of file pg_upgrade.h.

Referenced by stop_postmaster().

◆ USER_NAME_SIZE

#define USER_NAME_SIZE   128

Definition at line 19 of file pg_upgrade.h.

◆ UTILITY_LOG_FILE

#define UTILITY_LOG_FILE   "pg_upgrade_utility.log"

◆ VISIBILITY_MAP_CRASHSAFE_CAT_VER

#define VISIBILITY_MAP_CRASHSAFE_CAT_VER   201107031

Definition at line 108 of file pg_upgrade.h.

Referenced by transfer_single_new_db().

◆ VISIBILITY_MAP_FROZEN_BIT_CAT_VER

#define VISIBILITY_MAP_FROZEN_BIT_CAT_VER   201603011

Definition at line 113 of file pg_upgrade.h.

Referenced by transfer_single_new_db().

Typedef Documentation

◆ pgpid_t

Definition at line 254 of file pg_upgrade.h.

Enumeration Type Documentation

◆ eLogType

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

◆ transferMode

Enumerator
TRANSFER_MODE_COPY 
TRANSFER_MODE_LINK 

Definition at line 235 of file pg_upgrade.h.

Function Documentation

◆ adjust_data_dir()

void adjust_data_dir ( ClusterInfo cluster)

Definition at line 384 of file option.c.

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

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

◆ check_and_dump_old_cluster()

void check_and_dump_old_cluster ( bool  live_check)

Definition at line 79 of file check.c.

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

Referenced by main().

80 {
81  /* -- OLD -- */
82 
83  if (!live_check)
85 
86  /* Extract a list of databases and tables from the old cluster */
88 
90 
92 
93 
94  /*
95  * Check for various failure cases
96  */
102 
103  /*
104  * Pre-PG 10 allowed tables with 'unknown' type columns and non WAL logged
105  * hash indexes
106  */
108  {
110  if (user_opts.check)
112  }
113 
114  /* 9.5 and below should not have roles starting with pg_ */
117 
121 
122  /* Pre-PG 9.4 had a different 'line' data type internal format */
125 
126  /* Pre-PG 9.0 had no large object permissions */
129 
130  /*
131  * While not a check option, we do this now because this is the only time
132  * the old server is running.
133  */
134  if (!user_opts.check)
136 
137  if (!live_check)
138  stop_postmaster(false);
139 }
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 old_9_6_invalidate_hash_indexes(ClusterInfo *cluster, bool check_mode)
Definition: version.c:297
static void check_for_reg_data_type_usage(ClusterInfo *cluster)
Definition: check.c:886
static void check_for_prepared_transactions(ClusterInfo *cluster)
Definition: check.c:757
static void check_proper_datallowconn(ClusterInfo *cluster)
Definition: check.c:696
static void check_for_pg_role_prefix(ClusterInfo *cluster)
Definition: check.c:1072
void new_9_0_populate_pg_largeobject_metadata(ClusterInfo *cluster, bool check_mode)
Definition: version.c:25
ClusterInfo old_cluster
Definition: pg_upgrade.c:57
void generate_old_dump(void)
Definition: dump.c:18
static void check_is_install_user(ClusterInfo *cluster)
Definition: check.c:645
static void check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster)
Definition: check.c:792
UserOpts user_opts
Definition: option.c:29
uint32 cat_ver
Definition: pg_upgrade.h:210
void stop_postmaster(bool in_atexit)
Definition: server.c:328
void get_loadable_libraries(void)
Definition: function.c:49
void get_db_and_rel_infos(ClusterInfo *cluster)
Definition: info.c:311
#define JSONB_FORMAT_CHANGE_CAT_VER
Definition: pg_upgrade.h:132
bool check
Definition: pg_upgrade.h:297
static pgpid_t start_postmaster(void)
Definition: pg_ctl.c:444
static void check_for_jsonb_9_4_usage(ClusterInfo *cluster)
Definition: check.c:983
void init_tablespaces(void)
Definition: tablespace.c:19
void old_9_3_check_for_line_data_type_usage(ClusterInfo *cluster)
Definition: version.c:111
void old_9_6_check_for_unknown_data_type_usage(ClusterInfo *cluster)
Definition: version.c:208

◆ check_cluster_compatibility()

void check_cluster_compatibility ( bool  live_check)

Definition at line 275 of file check.c.

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

Referenced by main().

276 {
277  /* get/check pg_control data of servers */
278  get_control_data(&old_cluster, live_check);
279  get_control_data(&new_cluster, false);
281 
282  /* We read the real port number for PG >= 9.1 */
283  if (live_check && GET_MAJOR_VERSION(old_cluster.major_version) < 901 &&
285  pg_fatal("When checking a pre-PG 9.1 live old server, "
286  "you must specify the old server's port number.\n");
287 
288  if (live_check && old_cluster.port == new_cluster.port)
289  pg_fatal("When checking a live server, "
290  "the old and new port numbers must be different.\n");
291 }
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
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:552
ClusterInfo new_cluster
Definition: pg_upgrade.c:57
ClusterInfo old_cluster
Definition: pg_upgrade.c:57
#define DEF_PGUPORT
Definition: pg_upgrade.h:16
void get_control_data(ClusterInfo *cluster, bool live_check)
Definition: controldata.c:34

◆ check_cluster_versions()

void check_cluster_versions ( void  )

Definition at line 233 of file check.c.

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

Referenced by main().

234 {
235  prep_status("Checking cluster versions");
236 
237  /* cluster versions should already have been obtained */
240 
241  /*
242  * We allow upgrades from/to the same major version for alpha/beta
243  * upgrades
244  */
245 
247  pg_fatal("This utility can only upgrade from PostgreSQL version 8.4 and later.\n");
248 
249  /* Only current PG version is supported as a target */
251  pg_fatal("This utility can only upgrade to PostgreSQL version %s.\n",
252  PG_MAJORVERSION);
253 
254  /*
255  * We can't allow downgrading because we use the target pg_dump, and
256  * pg_dump cannot operate on newer database versions, only current and
257  * older versions.
258  */
260  pg_fatal("This utility cannot be used to downgrade to older major PostgreSQL versions.\n");
261 
262  /* Ensure binaries match the designated data directories */
265  pg_fatal("Old cluster data and binary directories are from different major versions.\n");
268  pg_fatal("New cluster data and binary directories are from different major versions.\n");
269 
270  check_ok();
271 }
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:57
void prep_status(const char *fmt,...) pg_attribute_printf(1
ClusterInfo old_cluster
Definition: pg_upgrade.c:57
static void check_ok(void)
Definition: initdb.c:2119
uint32 bin_version
Definition: pg_upgrade.h:276
#define Assert(condition)
Definition: c.h:699

◆ check_control_data()

void check_control_data ( ControlData oldctrl,
ControlData newctrl 
)

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

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

◆ check_hard_link()

void check_hard_link ( void  )

Definition at line 283 of file file.c.

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

Referenced by check_new_cluster().

284 {
285  char existing_file[MAXPGPATH];
286  char new_link_file[MAXPGPATH];
287 
288  snprintf(existing_file, sizeof(existing_file), "%s/PG_VERSION", old_cluster.pgdata);
289  snprintf(new_link_file, sizeof(new_link_file), "%s/PG_VERSION.linktest", new_cluster.pgdata);
290  unlink(new_link_file); /* might fail */
291 
292  if (pg_link_file(existing_file, new_link_file) < 0)
293  pg_fatal("could not create hard link between old and new data directories: %s\n"
294  "In link mode the old and new data directories must be on the same file system.\n",
295  strerror(errno));
296 
297  unlink(new_link_file);
298 }
#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:57
#define MAXPGPATH
ClusterInfo old_cluster
Definition: pg_upgrade.c:57
char * pgdata
Definition: pg_upgrade.h:266
const char * strerror(int errnum)
Definition: strerror.c:19

◆ check_loadable_libraries()

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, 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\": %s"),
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:6116
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:3638
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2647
ClusterInfo new_cluster
Definition: pg_upgrade.c:57
PGconn * conn
Definition: streamutil.c:55
#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:57
size_t PQescapeStringConn(PGconn *conn, char *to, const char *from, size_t length, int *error)
Definition: fe-exec.c:3365
void pg_log(eLogType type, const char *fmt,...)
Definition: logging.c:69
static void check_ok(void)
Definition: initdb.c:2119
PGconn * connectToServer(ClusterInfo *cluster, const char *db_name)
Definition: server.c:28
void PQclear(PGresult *res)
Definition: fe-exec.c:671
#define fopen_priv(path, mode)
Definition: pg_upgrade.h:379
const char * strerror(int errnum)
Definition: strerror.c:19
OSInfo os_info
Definition: pg_upgrade.c:59
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1897
#define _(x)
Definition: elog.c:84

◆ check_new_cluster()

void check_new_cluster ( void  )

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

144 {
146 
149 
151 
153  check_hard_link();
154 
156 
158 }
void check_hard_link(void)
Definition: file.c:283
static void check_databases_are_compatible(void)
Definition: check.c:396
void check_loadable_libraries(void)
Definition: function.c:203
static void check_for_prepared_transactions(ClusterInfo *cluster)
Definition: check.c:757
ClusterInfo new_cluster
Definition: pg_upgrade.c:57
static void check_is_install_user(ClusterInfo *cluster)
Definition: check.c:645
transferMode transfer_mode
Definition: pg_upgrade.h:299
UserOpts user_opts
Definition: option.c:29
static void check_new_cluster_is_empty(void)
Definition: check.c:371
void get_db_and_rel_infos(ClusterInfo *cluster)
Definition: info.c:311

◆ check_ok()

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

◆ check_pghost_envvar()

void check_pghost_envvar ( void  )

Definition at line 355 of file server.c.

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

Referenced by setup().

356 {
358  PQconninfoOption *start;
359 
360  /* Get valid libpq env vars from the PQconndefaults function */
361 
362  start = PQconndefaults();
363 
364  if (!start)
365  pg_fatal("out of memory\n");
366 
367  for (option = start; option->keyword != NULL; option++)
368  {
369  if (option->envvar && (strcmp(option->envvar, "PGHOST") == 0 ||
370  strcmp(option->envvar, "PGHOSTADDR") == 0))
371  {
372  const char *value = getenv(option->envvar);
373 
374  if (value && strlen(value) > 0 &&
375  /* check for 'local' host values */
376  (strcmp(value, "localhost") != 0 && strcmp(value, "127.0.0.1") != 0 &&
377  strcmp(value, "::1") != 0 && value[0] != '/'))
378  pg_fatal("libpq environment variable %s has a non-local server value: %s\n",
379  option->envvar, value);
380  }
381  }
382 
383  /* Free the memory that libpq allocated on our behalf */
384  PQconninfoFree(start);
385 }
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
void PQconninfoFree(PQconninfoOption *connOptions)
Definition: fe-connect.c:5965
static struct @131 value
PQconninfoOption * PQconndefaults(void)
Definition: fe-connect.c:1230

◆ cluster_conn_opts()

PGresult char* cluster_conn_opts ( ClusterInfo cluster)

Definition at line 91 of file server.c.

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

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

92 {
93  static PQExpBuffer buf;
94 
95  if (buf == NULL)
96  buf = createPQExpBuffer();
97  else
98  resetPQExpBuffer(buf);
99 
100  if (cluster->sockdir)
101  {
102  appendPQExpBufferStr(buf, "--host ");
103  appendShellString(buf, cluster->sockdir);
104  appendPQExpBufferChar(buf, ' ');
105  }
106  appendPQExpBuffer(buf, "--port %d --username ", cluster->port);
108 
109  return buf->data;
110 }
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:67
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:71
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:396
void appendShellString(PQExpBuffer buf, const char *str)
Definition: string_utils.c:434
char * sockdir
Definition: pg_upgrade.h:272
OSInfo os_info
Definition: pg_upgrade.c:59
void resetPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:145
char * user
Definition: pg_upgrade.h:311

◆ connectToServer()

PGconn* connectToServer ( ClusterInfo cluster,
const char *  db_name 
)

Definition at line 28 of file server.c.

References _, ALWAYS_SECURE_SEARCH_PATH_SQL, conn, CONNECTION_OK, executeQueryOrDie(), get_db_conn(), pg_log(), PG_REPORT, PQclear(), PQerrorMessage(), PQfinish(), and PQstatus().

Referenced by check_for_isn_and_int8_passing_mismatch(), check_for_jsonb_9_4_usage(), check_for_pg_role_prefix(), check_for_prepared_transactions(), check_for_reg_data_type_usage(), check_is_install_user(), check_loadable_libraries(), check_proper_datallowconn(), get_db_infos(), get_loadable_libraries(), get_rel_infos(), get_tablespace_paths(), new_9_0_populate_pg_largeobject_metadata(), old_9_3_check_for_line_data_type_usage(), old_9_6_check_for_unknown_data_type_usage(), old_9_6_invalidate_hash_indexes(), and set_frozenxids().

29 {
30  PGconn *conn = get_db_conn(cluster, db_name);
31 
32  if (conn == NULL || PQstatus(conn) != CONNECTION_OK)
33  {
34  pg_log(PG_REPORT, "connection to database failed: %s",
35  PQerrorMessage(conn));
36 
37  if (conn)
38  PQfinish(conn);
39 
40  printf(_("Failure, exiting\n"));
41  exit(1);
42  }
43 
45 
46  return conn;
47 }
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6116
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3638
PGconn * conn
Definition: streamutil.c:55
void pg_log(eLogType type, const char *fmt,...)
Definition: logging.c:69
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...)
Definition: server.c:121
void PQclear(PGresult *res)
Definition: fe-exec.c:671
#define ALWAYS_SECURE_SEARCH_PATH_SQL
Definition: connect.h:25
ConnStatusType PQstatus(const PGconn *conn)
Definition: fe-connect.c:6063
static PGconn * get_db_conn(ClusterInfo *cluster, const char *db_name)
Definition: server.c:56
#define _(x)
Definition: elog.c:84

◆ copyFile()

void copyFile ( const char *  src,
const char *  dst,
const char *  schemaName,
const char *  relName 
)

Definition at line 35 of file file.c.

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

Referenced by transfer_relfile().

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

◆ create_script_for_cluster_analyze()

void create_script_for_cluster_analyze ( char **  analyze_script_file_name)

Definition at line 427 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, old_cluster, os_info, pg_fatal(), prep_status(), psprintf(), S_IRWXU, SCRIPT_EXT, SCRIPT_PREFIX, strerror(), termPQExpBuffer(), OSInfo::user, and OSInfo::user_specified.

Referenced by main().

428 {
429  FILE *script = NULL;
430  PQExpBufferData user_specification;
431 
432  prep_status("Creating script to analyze new cluster");
433 
434  initPQExpBuffer(&user_specification);
436  {
437  appendPQExpBufferStr(&user_specification, "-U ");
438  appendShellString(&user_specification, os_info.user);
439  appendPQExpBufferChar(&user_specification, ' ');
440  }
441 
442  *analyze_script_file_name = psprintf("%sanalyze_new_cluster.%s",
444 
445  if ((script = fopen_priv(*analyze_script_file_name, "w")) == NULL)
446  pg_fatal("could not open file \"%s\": %s\n",
447  *analyze_script_file_name, strerror(errno));
448 
449 #ifndef WIN32
450  /* add shebang header */
451  fprintf(script, "#!/bin/sh\n\n");
452 #else
453  /* suppress command echoing */
454  fprintf(script, "@echo off\n");
455 #endif
456 
457  fprintf(script, "echo %sThis script will generate minimal optimizer statistics rapidly%s\n",
459  fprintf(script, "echo %sso your system is usable, and then gather statistics twice more%s\n",
461  fprintf(script, "echo %swith increasing accuracy. When it is done, your system will%s\n",
463  fprintf(script, "echo %shave the default level of optimizer statistics.%s\n",
465  fprintf(script, "echo%s\n\n", ECHO_BLANK);
466 
467  fprintf(script, "echo %sIf you have used ALTER TABLE to modify the statistics target for%s\n",
469  fprintf(script, "echo %sany tables, you might want to remove them and restore them after%s\n",
471  fprintf(script, "echo %srunning this script because they will delay fast statistics generation.%s\n",
473  fprintf(script, "echo%s\n\n", ECHO_BLANK);
474 
475  fprintf(script, "echo %sIf you would like default statistics as quickly as possible, cancel%s\n",
477  fprintf(script, "echo %sthis script and run:%s\n",
479  fprintf(script, "echo %s \"%s/vacuumdb\" %s--all %s%s\n", ECHO_QUOTE,
480  new_cluster.bindir, user_specification.data,
481  /* Did we copy the free space files? */
483  "--analyze-only" : "--analyze", ECHO_QUOTE);
484  fprintf(script, "echo%s\n\n", ECHO_BLANK);
485 
486  fprintf(script, "\"%s/vacuumdb\" %s--all --analyze-in-stages\n",
487  new_cluster.bindir, user_specification.data);
488  /* Did we copy the free space files? */
490  fprintf(script, "\"%s/vacuumdb\" %s--all\n", new_cluster.bindir,
491  user_specification.data);
492 
493  fprintf(script, "echo%s\n\n", ECHO_BLANK);
494  fprintf(script, "echo %sDone%s\n",
496 
497  fclose(script);
498 
499 #ifndef WIN32
500  if (chmod(*analyze_script_file_name, S_IRWXU) != 0)
501  pg_fatal("could not add execute permission to file \"%s\": %s\n",
502  *analyze_script_file_name, strerror(errno));
503 #endif
504 
505  termPQExpBuffer(&user_specification);
506 
507  check_ok();
508 }
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
bool user_specified
Definition: pg_upgrade.h:312
ClusterInfo new_cluster
Definition: pg_upgrade.c:57
void prep_status(const char *fmt,...) pg_attribute_printf(1
ClusterInfo old_cluster
Definition: pg_upgrade.c:57
static void check_ok(void)
Definition: initdb.c:2119
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:434
#define ECHO_BLANK
Definition: pg_upgrade.h:82
#define SCRIPT_PREFIX
Definition: pg_upgrade.h:79
#define fopen_priv(path, mode)
Definition: pg_upgrade.h:379
#define S_IRWXU
Definition: win32_port.h:280
const char * strerror(int errnum)
Definition: strerror.c:19
OSInfo os_info
Definition: pg_upgrade.c:59
#define ECHO_QUOTE
Definition: pg_upgrade.h:81
char * user
Definition: pg_upgrade.h:311
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:89

◆ create_script_for_old_cluster_deletion()

void create_script_for_old_cluster_deletion ( char **  deletion_script_file_name)

Definition at line 517 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, 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, S_IRWXU, SCRIPT_EXT, SCRIPT_PREFIX, strerror(), strlcpy(), and ClusterInfo::tablespace_suffix.

Referenced by main().

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

◆ disable_old_cluster()

void disable_old_cluster ( void  )

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

610 {
611  char old_path[MAXPGPATH],
612  new_path[MAXPGPATH];
613 
614  /* rename pg_control so old server cannot be accidentally started */
615  prep_status("Adding \".old\" suffix to old global/pg_control");
616 
617  snprintf(old_path, sizeof(old_path), "%s/global/pg_control", old_cluster.pgdata);
618  snprintf(new_path, sizeof(new_path), "%s/global/pg_control.old", old_cluster.pgdata);
619  if (pg_mv_file(old_path, new_path) != 0)
620  pg_fatal("Unable to rename %s to %s.\n", old_path, new_path);
621  check_ok();
622 
623  pg_log(PG_REPORT, "\n"
624  "If you want to start the old cluster, you will need to remove\n"
625  "the \".old\" suffix from %s/global/pg_control.old.\n"
626  "Because \"link\" mode was used, the old cluster cannot be safely\n"
627  "started once the new cluster has been started.\n\n", old_cluster.pgdata);
628 }
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:57
void pg_log(eLogType type, const char *fmt,...)
Definition: logging.c:69
static void check_ok(void)
Definition: initdb.c:2119
char * pgdata
Definition: pg_upgrade.h:266
#define pg_mv_file
Definition: pg_upgrade.h:73

◆ end_progress_output()

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

◆ exec_prog()

bool exec_prog ( const char *  log_file,
const char *  opt_log_file,
bool  report_error,
bool  exit_on_error,
const char *  fmt,
  ... 
)

◆ executeQueryOrDie()

◆ gen_db_file_maps()

FileNameMap* gen_db_file_maps ( DbInfo old_db,
DbInfo new_db,
int *  nmaps,
const char *  old_pgdata,
const char *  new_pgdata 
)

Definition at line 41 of file info.c.

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

Referenced by transfer_all_new_dbs().

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

◆ generate_old_dump()

void generate_old_dump ( void  )

Definition at line 18 of file dump.c.

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

Referenced by check_and_dump_old_cluster().

19 {
20  int dbnum;
21 
22  prep_status("Creating dump of global objects");
23 
24  /* run new pg_dumpall binary for globals */
25  exec_prog(UTILITY_LOG_FILE, NULL, true, true,
26  "\"%s/pg_dumpall\" %s --globals-only --quote-all-identifiers "
27  "--binary-upgrade %s -f %s",
29  log_opts.verbose ? "--verbose" : "",
31  check_ok();
32 
33  prep_status("Creating dump of database schemas\n");
34 
35  /* create per-db dump files */
36  for (dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
37  {
38  char sql_file_name[MAXPGPATH],
39  log_file_name[MAXPGPATH];
40  DbInfo *old_db = &old_cluster.dbarr.dbs[dbnum];
42  escaped_connstr;
43 
44  initPQExpBuffer(&connstr);
45  appendPQExpBuffer(&connstr, "dbname=");
46  appendConnStrVal(&connstr, old_db->db_name);
47  initPQExpBuffer(&escaped_connstr);
48  appendShellString(&escaped_connstr, connstr.data);
49  termPQExpBuffer(&connstr);
50 
51  pg_log(PG_STATUS, "%s", old_db->db_name);
52  snprintf(sql_file_name, sizeof(sql_file_name), DB_DUMP_FILE_MASK, old_db->db_oid);
53  snprintf(log_file_name, sizeof(log_file_name), DB_DUMP_LOG_FILE_MASK, old_db->db_oid);
54 
55  parallel_exec_prog(log_file_name, NULL,
56  "\"%s/pg_dump\" %s --schema-only --quote-all-identifiers "
57  "--binary-upgrade --format=custom %s --file=\"%s\" %s",
59  log_opts.verbose ? "--verbose" : "",
60  sql_file_name, escaped_connstr.data);
61 
62  termPQExpBuffer(&escaped_connstr);
63  }
64 
65  /* reap all children */
66  while (reap_child(true) == true)
67  ;
68 
70  check_ok();
71 }
void parallel_exec_prog(const char *log_file, const char *opt_log_file, const char *fmt,...)
Definition: parallel.c:63
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:128
void end_progress_output(void)
Definition: util.c:44
void appendConnStrVal(PQExpBuffer buf, const char *str)
Definition: string_utils.c:551
int snprintf(char *str, size_t count, const char *fmt,...) pg_attribute_printf(3
PGresult char * cluster_conn_opts(ClusterInfo *cluster)
Definition: server.c:91
LogOpts log_opts
Definition: util.c:18
Oid db_oid
Definition: pg_upgrade.h:186
ClusterInfo new_cluster
Definition: pg_upgrade.c:57
#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:57
void pg_log(eLogType type, const char *fmt,...)
Definition: logging.c:69
static void check_ok(void)
Definition: initdb.c:2119
#define DB_DUMP_FILE_MASK
Definition: pg_upgrade.h:33
bool verbose
Definition: pg_upgrade.h:287
char * bindir
Definition: pg_upgrade.h:269
void appendShellString(PQExpBuffer buf, const char *str)
Definition: string_utils.c:434
DbInfoArr dbarr
Definition: pg_upgrade.h:265
#define DB_DUMP_LOG_FILE_MASK
Definition: pg_upgrade.h:35
bool reap_child(bool wait_for_child)
Definition: parallel.c:289
#define UTILITY_LOG_FILE
Definition: pg_upgrade.h:37
char * db_name
Definition: pg_upgrade.h:187
bool exec_prog(const char *log_file, const char *opt_log_file, bool report_error, bool exit_on_error, const char *fmt,...)
Definition: exec.c:80
#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:59

◆ get_control_data()

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, 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, old_cluster, 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  {
477  if (cluster == &old_cluster)
479  "The source cluster lacks some required control information:\n");
480  else
482  "The target cluster lacks some required control information:\n");
483 
484  if (!got_xid)
485  pg_log(PG_REPORT, " checkpoint next XID\n");
486 
487  if (!got_oid)
488  pg_log(PG_REPORT, " latest checkpoint next OID\n");
489 
490  if (!got_multi)
491  pg_log(PG_REPORT, " latest checkpoint next MultiXactId\n");
492 
493  if (!got_oldestmulti &&
495  pg_log(PG_REPORT, " latest checkpoint oldest MultiXactId\n");
496 
497  if (!got_mxoff)
498  pg_log(PG_REPORT, " latest checkpoint next MultiXactOffset\n");
499 
500  if (!live_check && !got_nextxlogfile)
501  pg_log(PG_REPORT, " first WAL segment after reset\n");
502 
503  if (!got_float8_pass_by_value)
504  pg_log(PG_REPORT, " float8 argument passing method\n");
505 
506  if (!got_align)
507  pg_log(PG_REPORT, " maximum alignment\n");
508 
509  if (!got_blocksz)
510  pg_log(PG_REPORT, " block size\n");
511 
512  if (!got_largesz)
513  pg_log(PG_REPORT, " large relation segment size\n");
514 
515  if (!got_walsz)
516  pg_log(PG_REPORT, " WAL block size\n");
517 
518  if (!got_walseg)
519  pg_log(PG_REPORT, " WAL segment size\n");
520 
521  if (!got_ident)
522  pg_log(PG_REPORT, " maximum identifier length\n");
523 
524  if (!got_index)
525  pg_log(PG_REPORT, " maximum number of indexed columns\n");
526 
527  if (!got_toast)
528  pg_log(PG_REPORT, " maximum TOAST chunk size\n");
529 
530  if (!got_large_object &&
532  pg_log(PG_REPORT, " large-object chunk size\n");
533 
534  if (!got_date_is_int)
535  pg_log(PG_REPORT, " dates/times are integers?\n");
536 
537  /* value added in Postgres 9.3 */
538  if (!got_data_checksum_version)
539  pg_log(PG_REPORT, " data checksum version\n");
540 
541  pg_fatal("Cannot continue without required control information, terminating\n");
542  }
543 }
bool date_is_int
Definition: pg_upgrade.h:227
static char * lc_monetary
Definition: initdb.c:127
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:125
ControlData controldata
Definition: pg_upgrade.h:264
static void output(uint64 loop_count)
#define LARGE_OBJECT_SIZE_PG_CONTROL_VER
Definition: pg_upgrade.h:127
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:129
uint32 blocksz
Definition: pg_upgrade.h:219
uint32 chkpnt_nxtxid
Definition: pg_upgrade.h:212
static char * lc_messages
Definition: initdb.c:130
uint32 chkpnt_nxtepoch
Definition: pg_upgrade.h:213
#define MAXPGPATH
static char * lc_ctype
Definition: initdb.c:126
static char * lc_numeric
Definition: initdb.c:128
bool data_checksum_version
Definition: pg_upgrade.h:229
uint32 ident
Definition: pg_upgrade.h:223
ClusterInfo old_cluster
Definition: pg_upgrade.c:57
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
unsigned int uint32
Definition: c.h:325
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
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:121
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

◆ get_db_and_rel_infos()

void get_db_and_rel_infos ( ClusterInfo cluster)

Definition at line 311 of file info.c.

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

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

312 {
313  int dbnum;
314 
315  if (cluster->dbarr.dbs != NULL)
316  free_db_and_rel_infos(&cluster->dbarr);
317 
318  get_db_infos(cluster);
319 
320  for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
321  get_rel_infos(cluster, &cluster->dbarr.dbs[dbnum]);
322 
323  if (cluster == &old_cluster)
324  pg_log(PG_VERBOSE, "\nsource databases:\n");
325  else
326  pg_log(PG_VERBOSE, "\ntarget databases:\n");
327 
328  if (log_opts.verbose)
329  print_db_infos(&cluster->dbarr);
330 }
static void get_db_infos(ClusterInfo *cluster)
Definition: info.c:340
LogOpts log_opts
Definition: util.c:18
static void get_rel_infos(ClusterInfo *cluster, DbInfo *dbinfo)
Definition: info.c:409
ClusterInfo old_cluster
Definition: pg_upgrade.c:57
void pg_log(eLogType type, const char *fmt,...)
Definition: logging.c:69
static void print_db_infos(DbInfoArr *dbinfo)
Definition: info.c:630
bool verbose
Definition: pg_upgrade.h:287
DbInfoArr dbarr
Definition: pg_upgrade.h:265
static void free_db_and_rel_infos(DbInfoArr *db_arr)
Definition: info.c:596
DbInfo * dbs
Definition: pg_upgrade.h:198

◆ get_loadable_libraries()

void get_loadable_libraries ( void  )

Definition at line 49 of file function.c.

References 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;",
74  ClanguageId,
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:3118
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
void PQfinish(PGconn *conn)
Definition: fe-connect.c:3638
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2724
#define FirstNormalObjectId
Definition: transam.h:94
PGconn * conn
Definition: streamutil.c:55
char ** libraries
Definition: pg_upgrade.h:315
ClusterInfo old_cluster
Definition: pg_upgrade.c:57
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:28
void PQclear(PGresult *res)
Definition: fe-exec.c:671
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:59
char * db_name
Definition: pg_upgrade.h:187
#define qsort(a, b, c, d)
Definition: port.h:421
DbInfo * dbs
Definition: pg_upgrade.h:198

◆ get_major_server_version()

uint32 get_major_server_version ( ClusterInfo cluster)

Definition at line 158 of file server.c.

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

Referenced by check_data_dir().

159 {
160  FILE *version_fd;
161  char ver_filename[MAXPGPATH];
162  int v1 = 0,
163  v2 = 0;
164 
165  snprintf(ver_filename, sizeof(ver_filename), "%s/PG_VERSION",
166  cluster->pgdata);
167  if ((version_fd = fopen(ver_filename, "r")) == NULL)
168  pg_fatal("could not open version file: %s\n", ver_filename);
169 
170  if (fscanf(version_fd, "%63s", cluster->major_version_str) == 0 ||
171  sscanf(cluster->major_version_str, "%d.%d", &v1, &v2) < 1)
172  pg_fatal("could not parse PG_VERSION file from %s\n", cluster->pgdata);
173 
174  fclose(version_fd);
175 
176  if (v1 < 10)
177  {
178  /* old style, e.g. 9.6.1 */
179  return v1 * 10000 + v2 * 100;
180  }
181  else
182  {
183  /* new style, e.g. 10.1 */
184  return v1 * 10000;
185  }
186 }
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
char * pgdata
Definition: pg_upgrade.h:266

◆ get_sock_dir()

void get_sock_dir ( ClusterInfo cluster,
bool  live_check 
)

Definition at line 447 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, old_cluster, pg_fatal(), pg_log(), pg_malloc(), pg_strdup(), PG_WARNING, ClusterInfo::pgdata, ClusterInfo::port, snprintf(), ClusterInfo::sockdir, and strerror().

Referenced by main().

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

◆ get_user_info()

int get_user_info ( char **  user_name_p)

Definition at line 212 of file util.c.

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

Referenced by parseCommandLine().

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

◆ init_tablespaces()

void init_tablespaces ( void  )

Definition at line 19 of file tablespace.c.

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

Referenced by check_and_dump_old_cluster().

20 {
22 
25 
26  if (os_info.num_old_tablespaces > 0 &&
28  pg_fatal("Cannot upgrade to/from the same system catalog version when\n"
29  "using tablespaces.\n");
30 }
static void set_tablespace_directory_suffix(ClusterInfo *cluster)
Definition: tablespace.c:109
static void get_tablespace_paths(void)
Definition: tablespace.c:40
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
ClusterInfo new_cluster
Definition: pg_upgrade.c:57
ClusterInfo old_cluster
Definition: pg_upgrade.c:57
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:59

◆ issue_warnings_and_set_wal_level()

void issue_warnings_and_set_wal_level ( void  )

Definition at line 179 of file check.c.

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

Referenced by main().

180 {
181  /*
182  * We unconditionally start/stop the new server because pg_resetwal -o set
183  * wal_level to 'minimum'. If the user is upgrading standby servers using
184  * the rsync instructions, they will need pg_upgrade to write its final
185  * WAL record showing wal_level as 'replica'.
186  */
188 
189  /* Create dummy large object permissions for old < PG 9.0? */
192 
193  /* Reindex hash indexes for old < 10.0 */
196 
197  stop_postmaster(false);
198 }
uint32 major_version
Definition: pg_upgrade.h:274
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:29
void old_9_6_invalidate_hash_indexes(ClusterInfo *cluster, bool check_mode)
Definition: version.c:297
ClusterInfo new_cluster
Definition: pg_upgrade.c:57
void new_9_0_populate_pg_largeobject_metadata(ClusterInfo *cluster, bool check_mode)
Definition: version.c:25
ClusterInfo old_cluster
Definition: pg_upgrade.c:57
void stop_postmaster(bool in_atexit)
Definition: server.c:328
static pgpid_t start_postmaster(void)
Definition: pg_ctl.c:444

◆ linkFile()

void linkFile ( const char *  src,
const char *  dst,
const char *  schemaName,
const char *  relName 
)

Definition at line 104 of file file.c.

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

Referenced by transfer_relfile().

106 {
107  if (pg_link_file(src, dst) < 0)
108  pg_fatal("error while creating link for relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n",
109  schemaName, relName, src, dst, strerror(errno));
110 }
#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

◆ new_9_0_populate_pg_largeobject_metadata()

void new_9_0_populate_pg_largeobject_metadata ( ClusterInfo cluster,
bool  check_mode 
)

Definition at line 25 of file version.c.

References appendPsqlMetaConnect(), check_ok(), conn, connectToServer(), PQExpBufferData::data, DbInfo::db_name, ClusterInfo::dbarr, DbInfoArr::dbs, executeQueryOrDie(), fopen_priv, initPQExpBuffer(), MAXPGPATH, DbInfoArr::ndbs, 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_and_set_wal_level().

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

◆ old_9_3_check_for_line_data_type_usage()

void old_9_3_check_for_line_data_type_usage ( ClusterInfo cluster)

Definition at line 111 of file version.c.

References check_ok(), conn, connectToServer(), DbInfo::db_name, ClusterInfo::dbarr, DbInfoArr::dbs, executeQueryOrDie(), fopen_priv, MAXPGPATH, DbInfoArr::ndbs, pg_fatal(), pg_log(), PG_REPORT, PQclear(), PQfinish(), PQfnumber(), PQgetvalue(), PQntuples(), prep_status(), snprintf(), and strerror().

Referenced by check_and_dump_old_cluster().

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

◆ old_9_6_check_for_unknown_data_type_usage()

void old_9_6_check_for_unknown_data_type_usage ( ClusterInfo cluster)

Definition at line 208 of file version.c.

References check_ok(), conn, connectToServer(), CppAsString2, DbInfo::db_name, ClusterInfo::dbarr, DbInfoArr::dbs, executeQueryOrDie(), fopen_priv, MAXPGPATH, DbInfoArr::ndbs, pg_fatal(), pg_log(), PG_REPORT, PQclear(), PQfinish(), PQfnumber(), PQgetvalue(), PQntuples(), prep_status(), snprintf(), and strerror().

Referenced by check_and_dump_old_cluster().

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

◆ old_9_6_invalidate_hash_indexes()

void old_9_6_invalidate_hash_indexes ( ClusterInfo cluster,
bool  check_mode 
)

Definition at line 297 of file version.c.

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

Referenced by check_and_dump_old_cluster(), and issue_warnings_and_set_wal_level().

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

◆ output_check_banner()

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  {
66  "Performing Consistency Checks on Old Live Server\n"
67  "------------------------------------------------\n");
68  }
69  else
70  {
72  "Performing Consistency Checks\n"
73  "-----------------------------\n");
74  }
75 }
void pg_log(eLogType type, const char *fmt,...)
Definition: logging.c:69
UserOpts user_opts
Definition: option.c:29
bool check
Definition: pg_upgrade.h:297

◆ output_completion_banner()

void output_completion_banner ( char *  analyze_script_file_name,
char *  deletion_script_file_name 
)

Definition at line 202 of file check.c.

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

Referenced by main().

204 {
205  /* Did we copy the free space files? */
208  "Optimizer statistics are not transferred by pg_upgrade so,\n"
209  "once you start the new server, consider running:\n"
210  " %s\n\n", analyze_script_file_name);
211  else
213  "Optimizer statistics and free space information are not transferred\n"
214  "by pg_upgrade so, once you start the new server, consider running:\n"
215  " %s\n\n", analyze_script_file_name);
216 
217 
218  if (deletion_script_file_name)
220  "Running this script will delete the old cluster's data files:\n"
221  " %s\n",
222  deletion_script_file_name);
223  else
225  "Could not create a script to delete the old cluster's data files\n"
226  "because user-defined tablespaces or the new cluster's data directory\n"
227  "exist in the old cluster directory. The old cluster's contents must\n"
228  "be deleted manually.\n");
229 }
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:57
void pg_log(eLogType type, const char *fmt,...)
Definition: logging.c:69

◆ parallel_exec_prog()

void parallel_exec_prog ( const char *  log_file,
const char *  opt_log_file,
const char *  fmt,
  ... 
)

◆ parallel_transfer_all_new_dbs()

void void parallel_transfer_all_new_dbs ( DbInfoArr old_db_arr,
DbInfoArr new_db_arr,
char *  old_pgdata,
char *  new_pgdata,
char *  old_tablespace 
)

Definition at line 178 of file parallel.c.

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

Referenced by transfer_all_new_tablespaces().

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

◆ parseCommandLine()

void parseCommandLine ( int  argc,
char *  argv[] 
)

Definition at line 38 of file option.c.

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

Referenced by main().

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

◆ pg_attribute_noreturn()

void void void pg_attribute_noreturn ( )

◆ pg_fatal()

void void void pg_fatal ( const char *  fmt,
  ... 
)

◆ pg_log()

void void pg_log ( eLogType  type,
const char *  fmt,
  ... 
)

◆ pg_putenv()

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_port.h:487
long val
Definition: informix.c:689
#define unsetenv(x)
Definition: win32_port.h:488

◆ pid_lock_file_exists()

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:12

◆ prep_status()

◆ print_maps()

void print_maps ( FileNameMap maps,
int  n,
const char *  db_name 
)

Definition at line 285 of file info.c.

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

Referenced by transfer_all_new_dbs().

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

◆ quote_identifier()

char* quote_identifier ( const char *  s)

Definition at line 10488 of file ruleutils.c.

10489 {
10490  /*
10491  * Can avoid quoting if ident starts with a lowercase letter or underscore
10492  * and contains only lowercase letters, digits, and underscores, *and* is
10493  * not any SQL keyword. Otherwise, supply quotes.
10494  */
10495  int nquotes = 0;
10496  bool safe;
10497  const char *ptr;
10498  char *result;
10499  char *optr;
10500 
10501  /*
10502  * would like to use <ctype.h> macros here, but they might yield unwanted
10503  * locale-specific results...
10504  */
10505  safe = ((ident[0] >= 'a' && ident[0] <= 'z') || ident[0] == '_');
10506 
10507  for (ptr = ident; *ptr; ptr++)
10508  {
10509  char ch = *ptr;
10510 
10511  if ((ch >= 'a' && ch <= 'z') ||
10512  (ch >= '0' && ch <= '9') ||
10513  (ch == '_'))
10514  {
10515  /* okay */
10516  }
10517  else
10518  {
10519  safe = false;
10520  if (ch == '"')
10521  nquotes++;
10522  }
10523  }
10524 
10526  safe = false;
10527 
10528  if (safe)
10529  {
10530  /*
10531  * Check for keyword. We quote keywords except for unreserved ones.
10532  * (In some cases we could avoid quoting a col_name or type_func_name
10533  * keyword, but it seems much harder than it's worth to tell that.)
10534  *
10535  * Note: ScanKeywordLookup() does case-insensitive comparison, but
10536  * that's fine, since we already know we have all-lower-case.
10537  */
10538  const ScanKeyword *keyword = ScanKeywordLookup(ident,
10539  ScanKeywords,
10540  NumScanKeywords);
10541 
10542  if (keyword != NULL && keyword->category != UNRESERVED_KEYWORD)
10543  safe = false;
10544  }
10545 
10546  if (safe)
10547  return ident; /* no change needed */
10548 
10549  result = (char *) palloc(strlen(ident) + nquotes + 2 + 1);
10550 
10551  optr = result;
10552  *optr++ = '"';
10553  for (ptr = ident; *ptr; ptr++)
10554  {
10555  char ch = *ptr;
10556 
10557  if (ch == '"')
10558  *optr++ = '"';
10559  *optr++ = ch;
10560  }
10561  *optr++ = '"';
10562  *optr = '\0';
10563 
10564  return result;
10565 }
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:301
int16 category
Definition: keywords.h:28
void * palloc(Size size)
Definition: mcxt.c:924

◆ reap_child()

bool reap_child ( bool  wait_for_child)

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

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

◆ report_clusters_compatible()

void report_clusters_compatible ( void  )

Definition at line 162 of file check.c.

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

Referenced by main().

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

◆ report_status()

◆ rewriteVisibilityMap()

void rewriteVisibilityMap ( const char *  fromfile,
const char *  tofile,
const char *  schemaName,
const char *  relName 
)

Definition at line 130 of file file.c.

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

Referenced by transfer_relfile().

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

◆ start_postmaster()

bool start_postmaster ( ClusterInfo cluster,
bool  report_and_exit_on_error 
)

Definition at line 197 of file server.c.

References BINARY_UPGRADE_SERVER_FLAG_CAT_VER, ClusterInfo::bindir, ControlData::cat_ver, cluster(), conn, CONNECTION_OK, ClusterInfo::controldata, exec_prog(), get_db_conn(), GET_MAJOR_VERSION, ClusterInfo::major_version, MAXPGPATH, new_cluster, old_cluster, 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().

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

◆ stop_postmaster()

void stop_postmaster ( bool  in_atexit)

Definition at line 328 of file server.c.

References ClusterInfo::bindir, cluster(), exec_prog(), new_cluster, 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_and_set_wal_level(), main(), report_clusters_compatible(), setup(), and stop_postmaster_atexit().

329 {
331 
333  cluster = &old_cluster;
334  else if (os_info.running_cluster == &new_cluster)
335  cluster = &new_cluster;
336  else
337  return; /* no cluster running */
338 
339  exec_prog(SERVER_STOP_LOG_FILE, NULL, !in_atexit, !in_atexit,
340  "\"%s/pg_ctl\" -w -D \"%s\" -o \"%s\" %s stop",
341  cluster->bindir, cluster->pgconfig,
342  cluster->pgopts ? cluster->pgopts : "",
343  in_atexit ? "-m fast" : "-m smart");
344 
345  os_info.running_cluster = NULL;
346 }
#define SERVER_STOP_LOG_FILE
Definition: pg_upgrade.h:60
char * pgopts
Definition: pg_upgrade.h:270
ClusterInfo new_cluster
Definition: pg_upgrade.c:57
char * pgconfig
Definition: pg_upgrade.h:267
ClusterInfo old_cluster
Definition: pg_upgrade.c:57
void cluster(ClusterStmt *stmt, bool isTopLevel)
Definition: cluster.c:106
char * bindir
Definition: pg_upgrade.h:269
ClusterInfo * running_cluster
Definition: pg_upgrade.h:317
OSInfo os_info
Definition: pg_upgrade.c:59
bool exec_prog(const char *log_file, const char *opt_log_file, bool report_error, bool exit_on_error, const char *fmt,...)
Definition: exec.c:80

◆ str2uint()

unsigned int str2uint ( const char *  str)

Definition at line 241 of file util.c.

Referenced by get_control_data().

242 {
243  return strtoul(str, NULL, 10);
244 }

◆ transfer_all_new_dbs()

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, pg_fatal(), pg_free(), print_maps(), and transfer_single_new_db().

Referenced by parallel_transfer_all_new_dbs().

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

◆ transfer_all_new_tablespaces()

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, 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:178
void pg_log(eLogType type, const char *fmt,...)
Definition: logging.c:69
static void check_ok(void)
Definition: initdb.c:2119
transferMode transfer_mode
Definition: pg_upgrade.h:299
UserOpts user_opts
Definition: option.c:29
char ** old_tablespaces
Definition: pg_upgrade.h:313
bool reap_child(bool wait_for_child)
Definition: parallel.c:289
int num_old_tablespaces
Definition: pg_upgrade.h:314
OSInfo os_info
Definition: pg_upgrade.c:59

◆ verify_directories()

bool void verify_directories ( void  )

Definition at line 248 of file exec.c.

References check_bin_dir(), check_data_dir(), close, fd(), GLOBALS_DUMP_FILE, new_cluster, old_cluster, pg_fatal(), S_IRUSR, and S_IWUSR.

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:364
void pg_fatal(const char *fmt,...)
Definition: logging.c:83
ClusterInfo new_cluster
Definition: pg_upgrade.c:57
ClusterInfo old_cluster
Definition: pg_upgrade.c:57
static void check_data_dir(ClusterInfo *cluster)
Definition: exec.c:326

Variable Documentation

◆ log_opts

◆ new_cluster

◆ old_cluster

◆ os_info

◆ output_files

char* output_files[]

Definition at line 61 of file pg_upgrade.c.

Referenced by cleanup(), and parseCommandLine().

◆ user_opts