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  LibraryInfo
 
struct  OSInfo
 

Macros

#define DEF_PGUPORT   50432
 
#define MAX_STRING   1024
 
#define QUERY_ALLOC   8192
 
#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_CLONE, TRANSFER_MODE_COPY, TRANSFER_MODE_LINK }
 
enum  eLogType {
  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 cloneFile (const char *src, const char *dst, const char *schemaName, const char *relName)
 
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_file_clone (void)
 
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 old_11_check_for_sql_identifier_data_type_usage (ClusterInfo *cluster)
 
void parallel_exec_prog (const char *log_file, const char *opt_log_file, const char *fmt,...) pg_attribute_printf(3
 
void void parallel_transfer_all_new_dbs (DbInfoArr *old_db_arr, DbInfoArr *new_db_arr, char *old_pgdata, char *new_pgdata, char *old_tablespace)
 
bool reap_child (bool wait_for_child)
 

Variables

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

Macro Definition Documentation

◆ BINARY_UPGRADE_SERVER_FLAG_CAT_VER

#define BINARY_UPGRADE_SERVER_FLAG_CAT_VER   201104251

Definition at line 96 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 27 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 29 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 76 of file pg_upgrade.h.

Referenced by create_script_for_cluster_analyze().

◆ ECHO_QUOTE

#define ECHO_QUOTE   "'"

Definition at line 75 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 26 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 32 of file pg_upgrade.h.

Referenced by parseCommandLine().

◆ JSONB_FORMAT_CHANGE_CAT_VER

#define JSONB_FORMAT_CHANGE_CAT_VER   201409291

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

Referenced by get_control_data().

◆ MAX_STRING

#define MAX_STRING   1024

◆ MESSAGE_WIDTH

#define MESSAGE_WIDTH   60

Definition at line 21 of file pg_upgrade.h.

Referenced by pg_log_v(), and prep_status().

◆ MULTIXACT_FORMATCHANGE_CAT_VER

#define MULTIXACT_FORMATCHANGE_CAT_VER   201301231

Definition at line 115 of file pg_upgrade.h.

Referenced by copy_xact_xlog_xid(), and get_control_data().

◆ PATH_QUOTE

#define PATH_QUOTE   '\''

Definition at line 70 of file pg_upgrade.h.

Referenced by create_script_for_old_cluster_deletion().

◆ PATH_SEPARATOR

#define PATH_SEPARATOR   '/'

Definition at line 69 of file pg_upgrade.h.

Referenced by create_script_for_old_cluster_deletion().

◆ pg_link_file

#define pg_link_file   link

Definition at line 68 of file pg_upgrade.h.

Referenced by check_hard_link(), and linkFile().

◆ pg_mv_file

#define pg_mv_file   rename

Definition at line 67 of file pg_upgrade.h.

Referenced by disable_old_cluster().

◆ QUERY_ALLOC

#define QUERY_ALLOC   8192

◆ RM_CMD

#define RM_CMD   "rm -f"

Definition at line 71 of file pg_upgrade.h.

Referenced by create_script_for_old_cluster_deletion().

◆ RMDIR_CMD

#define RMDIR_CMD   "rm -rf"

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

Referenced by start_postmaster().

◆ SERVER_START_LOG_FILE

#define SERVER_START_LOG_FILE   SERVER_LOG_FILE

Definition at line 53 of file pg_upgrade.h.

Referenced by start_postmaster().

◆ SERVER_STOP_LOG_FILE

#define SERVER_STOP_LOG_FILE   SERVER_LOG_FILE

Definition at line 54 of file pg_upgrade.h.

Referenced by stop_postmaster().

◆ 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 102 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 107 of file pg_upgrade.h.

Referenced by transfer_single_new_db().

Typedef Documentation

◆ pgpid_t

typedef long pgpid_t

Definition at line 249 of file pg_upgrade.h.

Enumeration Type Documentation

◆ eLogType

enum eLogType
Enumerator
PG_VERBOSE 
PG_STATUS 
PG_REPORT 
PG_WARNING 
PG_FATAL 

Definition at line 239 of file pg_upgrade.h.

240 {
241  PG_VERBOSE,
242  PG_STATUS,
243  PG_REPORT,
244  PG_WARNING,
245  PG_FATAL
246 } eLogType;
eLogType
Definition: pg_upgrade.h:239

◆ transferMode

Enumerator
TRANSFER_MODE_CLONE 
TRANSFER_MODE_COPY 
TRANSFER_MODE_LINK 

Definition at line 229 of file pg_upgrade.h.

Function Documentation

◆ adjust_data_dir()

void adjust_data_dir ( ClusterInfo cluster)

Definition at line 403 of file option.c.

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

404 {
405  char filename[MAXPGPATH];
406  char cmd[MAXPGPATH],
407  cmd_output[MAX_STRING];
408  FILE *fp,
409  *output;
410 
411  /* Initially assume config dir and data dir are the same */
412  cluster->pgconfig = pg_strdup(cluster->pgdata);
413 
414  /* If there is no postgresql.conf, it can't be a config-only dir */
415  snprintf(filename, sizeof(filename), "%s/postgresql.conf", cluster->pgconfig);
416  if ((fp = fopen(filename, "r")) == NULL)
417  return;
418  fclose(fp);
419 
420  /* If PG_VERSION exists, it can't be a config-only dir */
421  snprintf(filename, sizeof(filename), "%s/PG_VERSION", cluster->pgconfig);
422  if ((fp = fopen(filename, "r")) != NULL)
423  {
424  fclose(fp);
425  return;
426  }
427 
428  /* Must be a configuration directory, so find the real data directory. */
429 
430  if (cluster == &old_cluster)
431  prep_status("Finding the real data directory for the source cluster");
432  else
433  prep_status("Finding the real data directory for the target cluster");
434 
435  /*
436  * We don't have a data directory yet, so we can't check the PG version,
437  * so this might fail --- only works for PG 9.2+. If this fails,
438  * pg_upgrade will fail anyway because the data files will not be found.
439  */
440  snprintf(cmd, sizeof(cmd), "\"%s/postgres\" -D \"%s\" -C data_directory",
441  cluster->bindir, cluster->pgconfig);
442 
443  if ((output = popen(cmd, "r")) == NULL ||
444  fgets(cmd_output, sizeof(cmd_output), output) == NULL)
445  pg_fatal("could not get data directory using %s: %s\n",
446  cmd, strerror(errno));
447 
448  pclose(output);
449 
450  /* strip trailing newline and carriage return */
451  (void) pg_strip_crlf(cmd_output);
452 
453  cluster->pgdata = pg_strdup(cmd_output);
454 
455  check_ok();
456 }
int pg_strip_crlf(char *str)
Definition: string.c:105
static void output(uint64 loop_count)
#define pg_fatal(...)
Definition: pg_rewind.h:43
char * pgconfig
Definition: pg_upgrade.h:262
#define MAXPGPATH
void prep_status(const char *fmt,...) pg_attribute_printf(1
ClusterInfo old_cluster
Definition: pg_upgrade.c:59
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
static void check_ok(void)
Definition: initdb.c:2079
char * bindir
Definition: pg_upgrade.h:264
#define MAX_STRING
Definition: pg_upgrade.h:18
#define strerror
Definition: port.h:205
static char * filename
Definition: pg_dumpall.c:90
char * pgdata
Definition: pg_upgrade.h:261
#define snprintf
Definition: port.h:192

◆ 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_for_tables_with_oids(), 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_11_check_for_sql_identifier_data_type_usage(), 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 12 allowed tables to be declared WITH OIDS, which is not
105  * supported anymore. Verify there are none, iff applicable.
106  */
109 
110  /*
111  * PG 12 changed the 'sql_identifier' type storage to be based on name,
112  * not varchar, which breaks on-disk format for existing data. So we need
113  * to prevent upgrade when used in user objects (tables, indexes, ...).
114  */
117 
118  /*
119  * Pre-PG 10 allowed tables with 'unknown' type columns and non WAL logged
120  * hash indexes
121  */
123  {
125  if (user_opts.check)
127  }
128 
129  /* 9.5 and below should not have roles starting with pg_ */
132 
136 
137  /* Pre-PG 9.4 had a different 'line' data type internal format */
140 
141  /* Pre-PG 9.0 had no large object permissions */
144 
145  /*
146  * While not a check option, we do this now because this is the only time
147  * the old server is running.
148  */
149  if (!user_opts.check)
151 
152  if (!live_check)
153  stop_postmaster(false);
154 }
uint32 major_version
Definition: pg_upgrade.h:269
ControlData controldata
Definition: pg_upgrade.h:259
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:23
void old_9_6_invalidate_hash_indexes(ClusterInfo *cluster, bool check_mode)
Definition: version.c:299
static void check_for_reg_data_type_usage(ClusterInfo *cluster)
Definition: check.c:989
static void check_for_prepared_transactions(ClusterInfo *cluster)
Definition: check.c:783
static void check_proper_datallowconn(ClusterInfo *cluster)
Definition: check.c:722
static void check_for_pg_role_prefix(ClusterInfo *cluster)
Definition: check.c:1183
void new_9_0_populate_pg_largeobject_metadata(ClusterInfo *cluster, bool check_mode)
Definition: version.c:22
ClusterInfo old_cluster
Definition: pg_upgrade.c:59
static void check_for_tables_with_oids(ClusterInfo *cluster)
Definition: check.c:904
void generate_old_dump(void)
Definition: dump.c:16
static void check_is_install_user(ClusterInfo *cluster)
Definition: check.c:671
static void check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster)
Definition: check.c:818
UserOpts user_opts
Definition: option.c:30
uint32 cat_ver
Definition: pg_upgrade.h:204
void stop_postmaster(bool in_atexit)
Definition: server.c:327
void get_loadable_libraries(void)
Definition: function.c:53
void get_db_and_rel_infos(ClusterInfo *cluster)
Definition: info.c:309
#define JSONB_FORMAT_CHANGE_CAT_VER
Definition: pg_upgrade.h:126
bool check
Definition: pg_upgrade.h:292
static pgpid_t start_postmaster(void)
Definition: pg_ctl.c:445
static void check_for_jsonb_9_4_usage(ClusterInfo *cluster)
Definition: check.c:1094
void init_tablespaces(void)
Definition: tablespace.c:19
void old_9_3_check_for_line_data_type_usage(ClusterInfo *cluster)
Definition: version.c:235
void old_11_check_for_sql_identifier_data_type_usage(ClusterInfo *cluster)
Definition: version.c:414
void old_9_6_check_for_unknown_data_type_usage(ClusterInfo *cluster)
Definition: version.c:272

◆ check_cluster_compatibility()

void check_cluster_compatibility ( bool  live_check)

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

300 {
301  /* get/check pg_control data of servers */
302  get_control_data(&old_cluster, live_check);
303  get_control_data(&new_cluster, false);
305 
306  /* We read the real port number for PG >= 9.1 */
307  if (live_check && GET_MAJOR_VERSION(old_cluster.major_version) < 901 &&
309  pg_fatal("When checking a pre-PG 9.1 live old server, "
310  "you must specify the old server's port number.\n");
311 
312  if (live_check && old_cluster.port == new_cluster.port)
313  pg_fatal("When checking a live server, "
314  "the old and new port numbers must be different.\n");
315 }
uint32 major_version
Definition: pg_upgrade.h:269
ControlData controldata
Definition: pg_upgrade.h:259
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:23
#define pg_fatal(...)
Definition: pg_rewind.h:43
unsigned short port
Definition: pg_upgrade.h:268
void check_control_data(ControlData *oldctrl, ControlData *newctrl)
Definition: controldata.c:619
ClusterInfo new_cluster
Definition: pg_upgrade.c:59
ClusterInfo old_cluster
Definition: pg_upgrade.c:59
#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 257 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().

258 {
259  prep_status("Checking cluster versions");
260 
261  /* cluster versions should already have been obtained */
264 
265  /*
266  * We allow upgrades from/to the same major version for alpha/beta
267  * upgrades
268  */
269 
271  pg_fatal("This utility can only upgrade from PostgreSQL version 8.4 and later.\n");
272 
273  /* Only current PG version is supported as a target */
275  pg_fatal("This utility can only upgrade to PostgreSQL version %s.\n",
276  PG_MAJORVERSION);
277 
278  /*
279  * We can't allow downgrading because we use the target pg_dump, and
280  * pg_dump cannot operate on newer database versions, only current and
281  * older versions.
282  */
284  pg_fatal("This utility cannot be used to downgrade to older major PostgreSQL versions.\n");
285 
286  /* Ensure binaries match the designated data directories */
289  pg_fatal("Old cluster data and binary directories are from different major versions.\n");
292  pg_fatal("New cluster data and binary directories are from different major versions.\n");
293 
294  check_ok();
295 }
uint32 major_version
Definition: pg_upgrade.h:269
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:23
#define pg_fatal(...)
Definition: pg_rewind.h:43
ClusterInfo new_cluster
Definition: pg_upgrade.c:59
void prep_status(const char *fmt,...) pg_attribute_printf(1
ClusterInfo old_cluster
Definition: pg_upgrade.c:59
static void check_ok(void)
Definition: initdb.c:2079
uint32 bin_version
Definition: pg_upgrade.h:271
#define Assert(condition)
Definition: c.h:733

◆ check_control_data()

void check_control_data ( ControlData oldctrl,
ControlData newctrl 
)

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

621 {
622  if (oldctrl->align == 0 || oldctrl->align != newctrl->align)
623  pg_fatal("old and new pg_controldata alignments are invalid or do not match\n"
624  "Likely one cluster is a 32-bit install, the other 64-bit\n");
625 
626  if (oldctrl->blocksz == 0 || oldctrl->blocksz != newctrl->blocksz)
627  pg_fatal("old and new pg_controldata block sizes are invalid or do not match\n");
628 
629  if (oldctrl->largesz == 0 || oldctrl->largesz != newctrl->largesz)
630  pg_fatal("old and new pg_controldata maximum relation segment sizes are invalid or do not match\n");
631 
632  if (oldctrl->walsz == 0 || oldctrl->walsz != newctrl->walsz)
633  pg_fatal("old and new pg_controldata WAL block sizes are invalid or do not match\n");
634 
635  if (oldctrl->walseg == 0 || oldctrl->walseg != newctrl->walseg)
636  pg_fatal("old and new pg_controldata WAL segment sizes are invalid or do not match\n");
637 
638  if (oldctrl->ident == 0 || oldctrl->ident != newctrl->ident)
639  pg_fatal("old and new pg_controldata maximum identifier lengths are invalid or do not match\n");
640 
641  if (oldctrl->index == 0 || oldctrl->index != newctrl->index)
642  pg_fatal("old and new pg_controldata maximum indexed columns are invalid or do not match\n");
643 
644  if (oldctrl->toast == 0 || oldctrl->toast != newctrl->toast)
645  pg_fatal("old and new pg_controldata maximum TOAST chunk sizes are invalid or do not match\n");
646 
647  /* large_object added in 9.5, so it might not exist in the old cluster */
648  if (oldctrl->large_object != 0 &&
649  oldctrl->large_object != newctrl->large_object)
650  pg_fatal("old and new pg_controldata large-object chunk sizes are invalid or do not match\n");
651 
652  if (oldctrl->date_is_int != newctrl->date_is_int)
653  pg_fatal("old and new pg_controldata date/time storage types do not match\n");
654 
655  /*
656  * float8_pass_by_value does not need to match, but is used in
657  * check_for_isn_and_int8_passing_mismatch().
658  */
659 
660  /*
661  * We might eventually allow upgrades from checksum to no-checksum
662  * clusters.
663  */
664  if (oldctrl->data_checksum_version == 0 &&
665  newctrl->data_checksum_version != 0)
666  pg_fatal("old cluster does not use data checksums but the new one does\n");
667  else if (oldctrl->data_checksum_version != 0 &&
668  newctrl->data_checksum_version == 0)
669  pg_fatal("old cluster uses data checksums but the new one does not\n");
670  else if (oldctrl->data_checksum_version != newctrl->data_checksum_version)
671  pg_fatal("old and new cluster pg_controldata checksum versions do not match\n");
672 }
bool date_is_int
Definition: pg_upgrade.h:221
uint32 walsz
Definition: pg_upgrade.h:215
#define pg_fatal(...)
Definition: pg_rewind.h:43
uint32 index
Definition: pg_upgrade.h:218
uint32 blocksz
Definition: pg_upgrade.h:213
bool data_checksum_version
Definition: pg_upgrade.h:223
uint32 ident
Definition: pg_upgrade.h:217
uint32 align
Definition: pg_upgrade.h:212
uint32 walseg
Definition: pg_upgrade.h:216
uint32 largesz
Definition: pg_upgrade.h:214
uint32 toast
Definition: pg_upgrade.h:219
uint32 large_object
Definition: pg_upgrade.h:220

◆ check_file_clone()

void check_file_clone ( void  )

Definition at line 321 of file file.c.

References close, MAXPGPATH, new_cluster, old_cluster, PG_BINARY, pg_fatal, pg_file_create_mode, ClusterInfo::pgdata, snprintf, and strerror.

Referenced by check_new_cluster().

322 {
323  char existing_file[MAXPGPATH];
324  char new_link_file[MAXPGPATH];
325 
326  snprintf(existing_file, sizeof(existing_file), "%s/PG_VERSION", old_cluster.pgdata);
327  snprintf(new_link_file, sizeof(new_link_file), "%s/PG_VERSION.clonetest", new_cluster.pgdata);
328  unlink(new_link_file); /* might fail */
329 
330 #if defined(HAVE_COPYFILE) && defined(COPYFILE_CLONE_FORCE)
331  if (copyfile(existing_file, new_link_file, NULL, COPYFILE_CLONE_FORCE) < 0)
332  pg_fatal("could not clone file between old and new data directories: %s\n",
333  strerror(errno));
334 #elif defined(__linux__) && defined(FICLONE)
335  {
336  int src_fd;
337  int dest_fd;
338 
339  if ((src_fd = open(existing_file, O_RDONLY | PG_BINARY, 0)) < 0)
340  pg_fatal("could not open file \"%s\": %s\n",
341  existing_file, strerror(errno));
342 
343  if ((dest_fd = open(new_link_file, O_RDWR | O_CREAT | O_EXCL | PG_BINARY,
344  pg_file_create_mode)) < 0)
345  pg_fatal("could not create file \"%s\": %s\n",
346  new_link_file, strerror(errno));
347 
348  if (ioctl(dest_fd, FICLONE, src_fd) < 0)
349  pg_fatal("could not clone file between old and new data directories: %s\n",
350  strerror(errno));
351 
352  close(src_fd);
353  close(dest_fd);
354  }
355 #else
356  pg_fatal("file cloning not supported on this platform\n");
357 #endif
358 
359  unlink(new_link_file);
360 }
int pg_file_create_mode
Definition: file_perm.c:19
#define pg_fatal(...)
Definition: pg_rewind.h:43
#define PG_BINARY
Definition: c.h:1216
ClusterInfo new_cluster
Definition: pg_upgrade.c:59
#define MAXPGPATH
ClusterInfo old_cluster
Definition: pg_upgrade.c:59
#define strerror
Definition: port.h:205
char * pgdata
Definition: pg_upgrade.h:261
#define close(a)
Definition: win32.h:12
#define snprintf
Definition: port.h:192

◆ check_hard_link()

void check_hard_link ( void  )

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

364 {
365  char existing_file[MAXPGPATH];
366  char new_link_file[MAXPGPATH];
367 
368  snprintf(existing_file, sizeof(existing_file), "%s/PG_VERSION", old_cluster.pgdata);
369  snprintf(new_link_file, sizeof(new_link_file), "%s/PG_VERSION.linktest", new_cluster.pgdata);
370  unlink(new_link_file); /* might fail */
371 
372  if (pg_link_file(existing_file, new_link_file) < 0)
373  pg_fatal("could not create hard link between old and new data directories: %s\n"
374  "In link mode the old and new data directories must be on the same file system.\n",
375  strerror(errno));
376 
377  unlink(new_link_file);
378 }
#define pg_link_file
Definition: pg_upgrade.h:68
#define pg_fatal(...)
Definition: pg_rewind.h:43
ClusterInfo new_cluster
Definition: pg_upgrade.c:59
#define MAXPGPATH
ClusterInfo old_cluster
Definition: pg_upgrade.c:59
#define strerror
Definition: port.h:205
char * pgdata
Definition: pg_upgrade.h:261
#define snprintf
Definition: port.h:192

◆ check_loadable_libraries()

void check_loadable_libraries ( void  )

Definition at line 180 of file function.c.

References _, check_ok(), conn, connectToServer(), DbInfo::db_name, ClusterInfo::dbarr, LibraryInfo::dbnum, DbInfoArr::dbs, fopen_priv, fprintf, GET_MAJOR_VERSION, OSInfo::libraries, library_name_compare(), ClusterInfo::major_version, MAXPGPATH, LibraryInfo::name, 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(), qsort, snprintf, and strerror.

Referenced by check_new_cluster().

181 {
182  PGconn *conn = connectToServer(&new_cluster, "template1");
183  int libnum;
184  int was_load_failure = false;
185  FILE *script = NULL;
186  bool found = false;
187  char output_path[MAXPGPATH];
188 
189  prep_status("Checking for presence of required libraries");
190 
191  snprintf(output_path, sizeof(output_path), "loadable_libraries.txt");
192 
193  /*
194  * Now we want to sort the library names into order. This avoids multiple
195  * probes of the same library, and ensures that libraries are probed in a
196  * consistent order, which is important for reproducible behavior if one
197  * library depends on another.
198  */
201 
202  for (libnum = 0; libnum < os_info.num_libraries; libnum++)
203  {
204  char *lib = os_info.libraries[libnum].name;
205  int llen = strlen(lib);
206  char cmd[7 + 2 * MAXPGPATH + 1];
207  PGresult *res;
208 
209  /* Did the library name change? Probe it. */
210  if (libnum == 0 || strcmp(lib, os_info.libraries[libnum - 1].name) != 0)
211  {
212  /*
213  * In Postgres 9.0, Python 3 support was added, and to do that, a
214  * plpython2u language was created with library name plpython2.so
215  * as a symbolic link to plpython.so. In Postgres 9.1, only the
216  * plpython2.so library was created, and both plpythonu and
217  * plpython2u pointing to it. For this reason, any reference to
218  * library name "plpython" in an old PG <= 9.1 cluster must look
219  * for "plpython2" in the new cluster.
220  *
221  * For this case, we could check pg_pltemplate, but that only
222  * works for languages, and does not help with function shared
223  * objects, so we just do a general fix.
224  */
226  strcmp(lib, "$libdir/plpython") == 0)
227  {
228  lib = "$libdir/plpython2";
229  llen = strlen(lib);
230  }
231 
232  strcpy(cmd, "LOAD '");
233  PQescapeStringConn(conn, cmd + strlen(cmd), lib, llen, NULL);
234  strcat(cmd, "'");
235 
236  res = PQexec(conn, cmd);
237 
238  if (PQresultStatus(res) != PGRES_COMMAND_OK)
239  {
240  found = true;
241  was_load_failure = true;
242 
243  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
244  pg_fatal("could not open file \"%s\": %s\n",
245  output_path, strerror(errno));
246  fprintf(script, _("could not load library \"%s\": %s"),
247  lib,
248  PQerrorMessage(conn));
249  }
250  else
251  was_load_failure = false;
252 
253  PQclear(res);
254  }
255 
256  if (was_load_failure)
257  fprintf(script, _("In database: %s\n"),
259  }
260 
261  PQfinish(conn);
262 
263  if (found)
264  {
265  fclose(script);
266  pg_log(PG_REPORT, "fatal\n");
267  pg_fatal("Your installation references loadable libraries that are missing from the\n"
268  "new installation. You can add these libraries to the new installation,\n"
269  "or remove the functions using them from the old installation. A list of\n"
270  "problem libraries is in the file:\n"
271  " %s\n\n", output_path);
272  }
273  else
274  check_ok();
275 }
char * name
Definition: pg_upgrade.h:301
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6617
uint32 major_version
Definition: pg_upgrade.h:269
int num_libraries
Definition: pg_upgrade.h:316
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:23
#define pg_fatal(...)
Definition: pg_rewind.h:43
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4119
#define fprintf
Definition: port.h:196
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:2692
ClusterInfo new_cluster
Definition: pg_upgrade.c:59
PGconn * conn
Definition: streamutil.c:54
#define MAXPGPATH
void prep_status(const char *fmt,...) pg_attribute_printf(1
ClusterInfo old_cluster
Definition: pg_upgrade.c:59
size_t PQescapeStringConn(PGconn *conn, char *to, const char *from, size_t length, int *error)
Definition: fe-exec.c:3410
static int library_name_compare(const void *p1, const void *p2)
Definition: function.c:28
LibraryInfo * libraries
Definition: pg_upgrade.h:315
static void check_ok(void)
Definition: initdb.c:2079
PGconn * connectToServer(ClusterInfo *cluster, const char *db_name)
Definition: server.c:27
void PQclear(PGresult *res)
Definition: fe-exec.c:694
DbInfoArr dbarr
Definition: pg_upgrade.h:260
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
#define strerror
Definition: port.h:205
#define fopen_priv(path, mode)
Definition: pg_upgrade.h:382
OSInfo os_info
Definition: pg_upgrade.c:61
char * db_name
Definition: pg_upgrade.h:181
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:1939
#define qsort(a, b, c, d)
Definition: port.h:492
DbInfo * dbs
Definition: pg_upgrade.h:192
#define snprintf
Definition: port.h:192
#define _(x)
Definition: elog.c:87

◆ check_new_cluster()

void check_new_cluster ( void  )

Definition at line 158 of file check.c.

References check_databases_are_compatible(), check_file_clone(), 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_CLONE, TRANSFER_MODE_COPY, TRANSFER_MODE_LINK, and user_opts.

Referenced by main().

159 {
161 
164 
166 
167  switch (user_opts.transfer_mode)
168  {
169  case TRANSFER_MODE_CLONE:
171  break;
172  case TRANSFER_MODE_COPY:
173  break;
174  case TRANSFER_MODE_LINK:
175  check_hard_link();
176  break;
177  }
178 
180 
182 }
void check_file_clone(void)
Definition: file.c:321
void check_hard_link(void)
Definition: file.c:363
static void check_databases_are_compatible(void)
Definition: check.c:422
void check_loadable_libraries(void)
Definition: function.c:180
static void check_for_prepared_transactions(ClusterInfo *cluster)
Definition: check.c:783
ClusterInfo new_cluster
Definition: pg_upgrade.c:59
static void check_is_install_user(ClusterInfo *cluster)
Definition: check.c:671
transferMode transfer_mode
Definition: pg_upgrade.h:294
UserOpts user_opts
Definition: option.c:30
static void check_new_cluster_is_empty(void)
Definition: check.c:395
void get_db_and_rel_infos(ClusterInfo *cluster)
Definition: info.c:309

◆ check_ok()

void void check_ok ( void  )

Definition at line 171 of file util.c.

References PG_REPORT, report_status(), and generate_unaccent_rules::stdout.

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

◆ check_pghost_envvar()

void check_pghost_envvar ( void  )

Definition at line 354 of file server.c.

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

Referenced by setup().

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

◆ cloneFile()

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

Definition at line 42 of file file.c.

References close, PG_BINARY, pg_fatal, pg_file_create_mode, and strerror.

Referenced by transfer_relfile().

44 {
45 #if defined(HAVE_COPYFILE) && defined(COPYFILE_CLONE_FORCE)
46  if (copyfile(src, dst, NULL, COPYFILE_CLONE_FORCE) < 0)
47  pg_fatal("error while cloning relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n",
48  schemaName, relName, src, dst, strerror(errno));
49 #elif defined(__linux__) && defined(FICLONE)
50  int src_fd;
51  int dest_fd;
52 
53  if ((src_fd = open(src, O_RDONLY | PG_BINARY, 0)) < 0)
54  pg_fatal("error while cloning relation \"%s.%s\": could not open file \"%s\": %s\n",
55  schemaName, relName, src, strerror(errno));
56 
57  if ((dest_fd = open(dst, O_RDWR | O_CREAT | O_EXCL | PG_BINARY,
58  pg_file_create_mode)) < 0)
59  pg_fatal("error while cloning relation \"%s.%s\": could not create file \"%s\": %s\n",
60  schemaName, relName, dst, strerror(errno));
61 
62  if (ioctl(dest_fd, FICLONE, src_fd) < 0)
63  {
64  unlink(dst);
65  pg_fatal("error while cloning relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n",
66  schemaName, relName, src, dst, strerror(errno));
67  }
68 
69  close(src_fd);
70  close(dest_fd);
71 #endif
72 }
int pg_file_create_mode
Definition: file_perm.c:19
#define pg_fatal(...)
Definition: pg_rewind.h:43
#define PG_BINARY
Definition: c.h:1216
#define strerror
Definition: port.h:205
#define close(a)
Definition: win32.h:12

◆ cluster_conn_opts()

PGresult char* cluster_conn_opts ( ClusterInfo cluster)

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

91 {
92  static PQExpBuffer buf;
93 
94  if (buf == NULL)
95  buf = createPQExpBuffer();
96  else
97  resetPQExpBuffer(buf);
98 
99  if (cluster->sockdir)
100  {
101  appendPQExpBufferStr(buf, "--host ");
102  appendShellString(buf, cluster->sockdir);
103  appendPQExpBufferChar(buf, ' ');
104  }
105  appendPQExpBuffer(buf, "--port %d --username ", cluster->port);
107 
108  return buf->data;
109 }
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
unsigned short port
Definition: pg_upgrade.h:268
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:267
static char * buf
Definition: pg_test_fsync.c:67
PQExpBuffer createPQExpBuffer(void)
Definition: pqexpbuffer.c:74
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:380
void appendShellString(PQExpBuffer buf, const char *str)
Definition: string_utils.c:429
char * sockdir
Definition: pg_upgrade.h:267
OSInfo os_info
Definition: pg_upgrade.c:61
void resetPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:148
char * user
Definition: pg_upgrade.h:311

◆ connectToServer()

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

Definition at line 27 of file server.c.

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

Referenced by check_for_data_type_usage(), 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_for_tables_with_oids(), 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_6_invalidate_hash_indexes(), and set_frozenxids().

28 {
29  PGconn *conn = get_db_conn(cluster, db_name);
30 
31  if (conn == NULL || PQstatus(conn) != CONNECTION_OK)
32  {
33  pg_log(PG_REPORT, "connection to database failed: %s",
34  PQerrorMessage(conn));
35 
36  if (conn)
37  PQfinish(conn);
38 
39  printf(_("Failure, exiting\n"));
40  exit(1);
41  }
42 
44 
45  return conn;
46 }
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6617
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4119
#define printf(...)
Definition: port.h:198
PGconn * conn
Definition: streamutil.c:54
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...)
Definition: server.c:120
void PQclear(PGresult *res)
Definition: fe-exec.c:694
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
#define ALWAYS_SECURE_SEARCH_PATH_SQL
Definition: connect.h:25
ConnStatusType PQstatus(const PGconn *conn)
Definition: fe-connect.c:6564
static PGconn * get_db_conn(ClusterInfo *cluster, const char *db_name)
Definition: server.c:55
#define _(x)
Definition: elog.c:87

◆ copyFile()

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

Definition at line 82 of file file.c.

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

Referenced by transfer_relfile().

84 {
85 #ifndef WIN32
86  int src_fd;
87  int dest_fd;
88  char *buffer;
89 
90  if ((src_fd = open(src, O_RDONLY | PG_BINARY, 0)) < 0)
91  pg_fatal("error while copying relation \"%s.%s\": could not open file \"%s\": %s\n",
92  schemaName, relName, src, strerror(errno));
93 
94  if ((dest_fd = open(dst, O_RDWR | O_CREAT | O_EXCL | PG_BINARY,
95  pg_file_create_mode)) < 0)
96  pg_fatal("error while copying relation \"%s.%s\": could not create file \"%s\": %s\n",
97  schemaName, relName, dst, strerror(errno));
98 
99  /* copy in fairly large chunks for best efficiency */
100 #define COPY_BUF_SIZE (50 * BLCKSZ)
101 
102  buffer = (char *) pg_malloc(COPY_BUF_SIZE);
103 
104  /* perform data copying i.e read src source, write to destination */
105  while (true)
106  {
107  ssize_t nbytes = read(src_fd, buffer, COPY_BUF_SIZE);
108 
109  if (nbytes < 0)
110  pg_fatal("error while copying relation \"%s.%s\": could not read file \"%s\": %s\n",
111  schemaName, relName, src, strerror(errno));
112 
113  if (nbytes == 0)
114  break;
115 
116  errno = 0;
117  if (write(dest_fd, buffer, nbytes) != nbytes)
118  {
119  /* if write didn't set errno, assume problem is no disk space */
120  if (errno == 0)
121  errno = ENOSPC;
122  pg_fatal("error while copying relation \"%s.%s\": could not write file \"%s\": %s\n",
123  schemaName, relName, dst, strerror(errno));
124  }
125  }
126 
127  pg_free(buffer);
128  close(src_fd);
129  close(dest_fd);
130 
131 #else /* WIN32 */
132 
133  if (CopyFile(src, dst, true) == 0)
134  {
135  _dosmaperr(GetLastError());
136  pg_fatal("error while copying relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n",
137  schemaName, relName, src, dst, strerror(errno));
138  }
139 
140 #endif /* WIN32 */
141 }
int pg_file_create_mode
Definition: file_perm.c:19
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
#define pg_fatal(...)
Definition: pg_rewind.h:43
#define PG_BINARY
Definition: c.h:1216
#define COPY_BUF_SIZE
#define strerror
Definition: port.h:205
void pg_free(void *ptr)
Definition: fe_memutils.c:105
#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 453 of file check.c.

References appendPQExpBufferChar(), appendPQExpBufferStr(), appendShellString(), ClusterInfo::bindir, check_ok(), PQExpBufferData::data, ECHO_BLANK, ECHO_QUOTE, fopen_priv, fprintf, 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().

454 {
455  FILE *script = NULL;
456  PQExpBufferData user_specification;
457 
458  prep_status("Creating script to analyze new cluster");
459 
460  initPQExpBuffer(&user_specification);
462  {
463  appendPQExpBufferStr(&user_specification, "-U ");
464  appendShellString(&user_specification, os_info.user);
465  appendPQExpBufferChar(&user_specification, ' ');
466  }
467 
468  *analyze_script_file_name = psprintf("%sanalyze_new_cluster.%s",
470 
471  if ((script = fopen_priv(*analyze_script_file_name, "w")) == NULL)
472  pg_fatal("could not open file \"%s\": %s\n",
473  *analyze_script_file_name, strerror(errno));
474 
475 #ifndef WIN32
476  /* add shebang header */
477  fprintf(script, "#!/bin/sh\n\n");
478 #else
479  /* suppress command echoing */
480  fprintf(script, "@echo off\n");
481 #endif
482 
483  fprintf(script, "echo %sThis script will generate minimal optimizer statistics rapidly%s\n",
485  fprintf(script, "echo %sso your system is usable, and then gather statistics twice more%s\n",
487  fprintf(script, "echo %swith increasing accuracy. When it is done, your system will%s\n",
489  fprintf(script, "echo %shave the default level of optimizer statistics.%s\n",
491  fprintf(script, "echo%s\n\n", ECHO_BLANK);
492 
493  fprintf(script, "echo %sIf you have used ALTER TABLE to modify the statistics target for%s\n",
495  fprintf(script, "echo %sany tables, you might want to remove them and restore them after%s\n",
497  fprintf(script, "echo %srunning this script because they will delay fast statistics generation.%s\n",
499  fprintf(script, "echo%s\n\n", ECHO_BLANK);
500 
501  fprintf(script, "echo %sIf you would like default statistics as quickly as possible, cancel%s\n",
503  fprintf(script, "echo %sthis script and run:%s\n",
505  fprintf(script, "echo %s \"%s/vacuumdb\" %s--all %s%s\n", ECHO_QUOTE,
506  new_cluster.bindir, user_specification.data,
507  /* Did we copy the free space files? */
509  "--analyze-only" : "--analyze", ECHO_QUOTE);
510  fprintf(script, "echo%s\n\n", ECHO_BLANK);
511 
512  fprintf(script, "\"%s/vacuumdb\" %s--all --analyze-in-stages\n",
513  new_cluster.bindir, user_specification.data);
514  /* Did we copy the free space files? */
516  fprintf(script, "\"%s/vacuumdb\" %s--all\n", new_cluster.bindir,
517  user_specification.data);
518 
519  fprintf(script, "echo%s\n\n", ECHO_BLANK);
520  fprintf(script, "echo %sDone%s\n",
522 
523  fclose(script);
524 
525 #ifndef WIN32
526  if (chmod(*analyze_script_file_name, S_IRWXU) != 0)
527  pg_fatal("could not add execute permission to file \"%s\": %s\n",
528  *analyze_script_file_name, strerror(errno));
529 #endif
530 
531  termPQExpBuffer(&user_specification);
532 
533  check_ok();
534 }
uint32 major_version
Definition: pg_upgrade.h:269
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:131
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
#define SCRIPT_EXT
Definition: pg_upgrade.h:74
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:23
#define pg_fatal(...)
Definition: pg_rewind.h:43
#define fprintf
Definition: port.h:196
bool user_specified
Definition: pg_upgrade.h:312
ClusterInfo new_cluster
Definition: pg_upgrade.c:59
void prep_status(const char *fmt,...) pg_attribute_printf(1
ClusterInfo old_cluster
Definition: pg_upgrade.c:59
static void check_ok(void)
Definition: initdb.c:2079
char * bindir
Definition: pg_upgrade.h:264
void appendPQExpBufferChar(PQExpBuffer str, char ch)
Definition: pqexpbuffer.c:380
void appendShellString(PQExpBuffer buf, const char *str)
Definition: string_utils.c:429
#define strerror
Definition: port.h:205
#define ECHO_BLANK
Definition: pg_upgrade.h:76
#define SCRIPT_PREFIX
Definition: pg_upgrade.h:73
#define fopen_priv(path, mode)
Definition: pg_upgrade.h:382
#define S_IRWXU
Definition: win32_port.h:269
OSInfo os_info
Definition: pg_upgrade.c:61
#define ECHO_QUOTE
Definition: pg_upgrade.h:75
char * user
Definition: pg_upgrade.h:311
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:92

◆ create_script_for_old_cluster_deletion()

void create_script_for_old_cluster_deletion ( char **  deletion_script_file_name)

Definition at line 543 of file check.c.

References canonicalize_path(), check_ok(), DbInfo::db_oid, ClusterInfo::dbarr, DbInfoArr::dbs, fix_path_separator(), fopen_priv, fprintf, 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().

544 {
545  FILE *script = NULL;
546  int tblnum;
547  char old_cluster_pgdata[MAXPGPATH],
548  new_cluster_pgdata[MAXPGPATH];
549 
550  *deletion_script_file_name = psprintf("%sdelete_old_cluster.%s",
552 
553  strlcpy(old_cluster_pgdata, old_cluster.pgdata, MAXPGPATH);
554  canonicalize_path(old_cluster_pgdata);
555 
556  strlcpy(new_cluster_pgdata, new_cluster.pgdata, MAXPGPATH);
557  canonicalize_path(new_cluster_pgdata);
558 
559  /* Some people put the new data directory inside the old one. */
560  if (path_is_prefix_of_path(old_cluster_pgdata, new_cluster_pgdata))
561  {
563  "\nWARNING: new data directory should not be inside the old data directory, e.g. %s\n", old_cluster_pgdata);
564 
565  /* Unlink file in case it is left over from a previous run. */
566  unlink(*deletion_script_file_name);
567  pg_free(*deletion_script_file_name);
568  *deletion_script_file_name = NULL;
569  return;
570  }
571 
572  /*
573  * Some users (oddly) create tablespaces inside the cluster data
574  * directory. We can't create a proper old cluster delete script in that
575  * case.
576  */
577  for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
578  {
579  char old_tablespace_dir[MAXPGPATH];
580 
581  strlcpy(old_tablespace_dir, os_info.old_tablespaces[tblnum], MAXPGPATH);
582  canonicalize_path(old_tablespace_dir);
583  if (path_is_prefix_of_path(old_cluster_pgdata, old_tablespace_dir))
584  {
585  /* reproduce warning from CREATE TABLESPACE that is in the log */
587  "\nWARNING: user-defined tablespace locations should not be inside the data directory, e.g. %s\n", old_tablespace_dir);
588 
589  /* Unlink file in case it is left over from a previous run. */
590  unlink(*deletion_script_file_name);
591  pg_free(*deletion_script_file_name);
592  *deletion_script_file_name = NULL;
593  return;
594  }
595  }
596 
597  prep_status("Creating script to delete old cluster");
598 
599  if ((script = fopen_priv(*deletion_script_file_name, "w")) == NULL)
600  pg_fatal("could not open file \"%s\": %s\n",
601  *deletion_script_file_name, strerror(errno));
602 
603 #ifndef WIN32
604  /* add shebang header */
605  fprintf(script, "#!/bin/sh\n\n");
606 #endif
607 
608  /* delete old cluster's default tablespace */
609  fprintf(script, RMDIR_CMD " %c%s%c\n", PATH_QUOTE,
611 
612  /* delete old cluster's alternate tablespaces */
613  for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
614  {
615  /*
616  * Do the old cluster's per-database directories share a directory
617  * with a new version-specific tablespace?
618  */
619  if (strlen(old_cluster.tablespace_suffix) == 0)
620  {
621  /* delete per-database directories */
622  int dbnum;
623 
624  fprintf(script, "\n");
625  /* remove PG_VERSION? */
627  fprintf(script, RM_CMD " %s%cPG_VERSION\n",
630 
631  for (dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
632  fprintf(script, RMDIR_CMD " %c%s%c%d%c\n", PATH_QUOTE,
635  PATH_QUOTE);
636  }
637  else
638  {
639  char *suffix_path = pg_strdup(old_cluster.tablespace_suffix);
640 
641  /*
642  * Simply delete the tablespace directory, which might be ".old"
643  * or a version-specific subdirectory.
644  */
645  fprintf(script, RMDIR_CMD " %c%s%s%c\n", PATH_QUOTE,
647  fix_path_separator(suffix_path), PATH_QUOTE);
648  pfree(suffix_path);
649  }
650  }
651 
652  fclose(script);
653 
654 #ifndef WIN32
655  if (chmod(*deletion_script_file_name, S_IRWXU) != 0)
656  pg_fatal("could not add execute permission to file \"%s\": %s\n",
657  *deletion_script_file_name, strerror(errno));
658 #endif
659 
660  check_ok();
661 }
uint32 major_version
Definition: pg_upgrade.h:269
bool path_is_prefix_of_path(const char *path1, const char *path2)
Definition: path.c:438
#define PATH_SEPARATOR
Definition: pg_upgrade.h:69
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
#define SCRIPT_EXT
Definition: pg_upgrade.h:74
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:23
void canonicalize_path(char *path)
Definition: path.c:254
#define pg_fatal(...)
Definition: pg_rewind.h:43
#define fprintf
Definition: port.h:196
Oid db_oid
Definition: pg_upgrade.h:180
ClusterInfo new_cluster
Definition: pg_upgrade.c:59
void pfree(void *pointer)
Definition: mcxt.c:1056
#define MAXPGPATH
#define RMDIR_CMD
Definition: pg_upgrade.h:72
void prep_status(const char *fmt,...) pg_attribute_printf(1
ClusterInfo old_cluster
Definition: pg_upgrade.c:59
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
static void check_ok(void)
Definition: initdb.c:2079
char ** old_tablespaces
Definition: pg_upgrade.h:313
const char * tablespace_suffix
Definition: pg_upgrade.h:272
DbInfoArr dbarr
Definition: pg_upgrade.h:260
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
size_t strlcpy(char *dst, const char *src, size_t siz)
Definition: strlcpy.c:45
#define strerror
Definition: port.h:205
void pg_free(void *ptr)
Definition: fe_memutils.c:105
#define SCRIPT_PREFIX
Definition: pg_upgrade.h:73
#define PATH_QUOTE
Definition: pg_upgrade.h:70
#define fopen_priv(path, mode)
Definition: pg_upgrade.h:382
char * pgdata
Definition: pg_upgrade.h:261
#define S_IRWXU
Definition: win32_port.h:269
int num_old_tablespaces
Definition: pg_upgrade.h:314
OSInfo os_info
Definition: pg_upgrade.c:61
DbInfo * dbs
Definition: pg_upgrade.h:192
#define RM_CMD
Definition: pg_upgrade.h:71
static char * fix_path_separator(char *path)
Definition: check.c:40

◆ disable_old_cluster()

void disable_old_cluster ( void  )

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

677 {
678  char old_path[MAXPGPATH],
679  new_path[MAXPGPATH];
680 
681  /* rename pg_control so old server cannot be accidentally started */
682  prep_status("Adding \".old\" suffix to old global/pg_control");
683 
684  snprintf(old_path, sizeof(old_path), "%s/global/pg_control", old_cluster.pgdata);
685  snprintf(new_path, sizeof(new_path), "%s/global/pg_control.old", old_cluster.pgdata);
686  if (pg_mv_file(old_path, new_path) != 0)
687  pg_fatal("Unable to rename %s to %s.\n", old_path, new_path);
688  check_ok();
689 
690  pg_log(PG_REPORT, "\n"
691  "If you want to start the old cluster, you will need to remove\n"
692  "the \".old\" suffix from %s/global/pg_control.old.\n"
693  "Because \"link\" mode was used, the old cluster cannot be safely\n"
694  "started once the new cluster has been started.\n\n", old_cluster.pgdata);
695 }
#define pg_fatal(...)
Definition: pg_rewind.h:43
#define MAXPGPATH
void prep_status(const char *fmt,...) pg_attribute_printf(1
ClusterInfo old_cluster
Definition: pg_upgrade.c:59
static void check_ok(void)
Definition: initdb.c:2079
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
char * pgdata
Definition: pg_upgrade.h:261
#define pg_mv_file
Definition: pg_upgrade.h:67
#define snprintf
Definition: port.h:192

◆ end_progress_output()

void end_progress_output ( void  )

Definition at line 43 of file util.c.

References prep_status().

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

44 {
45  /*
46  * In case nothing printed; pass a space so gcc doesn't complain about
47  * empty format string.
48  */
49  prep_status(" ");
50 }
void prep_status(const char *fmt,...)
Definition: util.c:69

◆ 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 39 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().

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

◆ generate_old_dump()

void generate_old_dump ( void  )

Definition at line 16 of file dump.c.

References appendConnStrVal(), appendPQExpBufferStr(), 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().

17 {
18  int dbnum;
19 
20  prep_status("Creating dump of global objects");
21 
22  /* run new pg_dumpall binary for globals */
23  exec_prog(UTILITY_LOG_FILE, NULL, true, true,
24  "\"%s/pg_dumpall\" %s --globals-only --quote-all-identifiers "
25  "--binary-upgrade %s -f %s",
27  log_opts.verbose ? "--verbose" : "",
29  check_ok();
30 
31  prep_status("Creating dump of database schemas\n");
32 
33  /* create per-db dump files */
34  for (dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
35  {
36  char sql_file_name[MAXPGPATH],
37  log_file_name[MAXPGPATH];
38  DbInfo *old_db = &old_cluster.dbarr.dbs[dbnum];
40  escaped_connstr;
41 
42  initPQExpBuffer(&connstr);
43  appendPQExpBufferStr(&connstr, "dbname=");
44  appendConnStrVal(&connstr, old_db->db_name);
45  initPQExpBuffer(&escaped_connstr);
46  appendShellString(&escaped_connstr, connstr.data);
47  termPQExpBuffer(&connstr);
48 
49  pg_log(PG_STATUS, "%s", old_db->db_name);
50  snprintf(sql_file_name, sizeof(sql_file_name), DB_DUMP_FILE_MASK, old_db->db_oid);
51  snprintf(log_file_name, sizeof(log_file_name), DB_DUMP_LOG_FILE_MASK, old_db->db_oid);
52 
53  parallel_exec_prog(log_file_name, NULL,
54  "\"%s/pg_dump\" %s --schema-only --quote-all-identifiers "
55  "--binary-upgrade --format=custom %s --file=\"%s\" %s",
57  log_opts.verbose ? "--verbose" : "",
58  sql_file_name, escaped_connstr.data);
59 
60  termPQExpBuffer(&escaped_connstr);
61  }
62 
63  /* reap all children */
64  while (reap_child(true) == true)
65  ;
66 
68  check_ok();
69 }
void parallel_exec_prog(const char *log_file, const char *opt_log_file, const char *fmt,...)
Definition: parallel.c:62
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:131
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
void end_progress_output(void)
Definition: util.c:43
void appendConnStrVal(PQExpBuffer buf, const char *str)
Definition: string_utils.c:545
PGresult char * cluster_conn_opts(ClusterInfo *cluster)
Definition: server.c:90
LogOpts log_opts
Definition: util.c:17
Oid db_oid
Definition: pg_upgrade.h:180
ClusterInfo new_cluster
Definition: pg_upgrade.c:59
#define MAXPGPATH
void prep_status(const char *fmt,...) pg_attribute_printf(1
ClusterInfo old_cluster
Definition: pg_upgrade.c:59
static void check_ok(void)
Definition: initdb.c:2079
#define DB_DUMP_FILE_MASK
Definition: pg_upgrade.h:27
bool verbose
Definition: pg_upgrade.h:282
char * bindir
Definition: pg_upgrade.h:264
void appendShellString(PQExpBuffer buf, const char *str)
Definition: string_utils.c:429
DbInfoArr dbarr
Definition: pg_upgrade.h:260
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
#define DB_DUMP_LOG_FILE_MASK
Definition: pg_upgrade.h:29
bool reap_child(bool wait_for_child)
Definition: parallel.c:288
#define UTILITY_LOG_FILE
Definition: pg_upgrade.h:31
char * db_name
Definition: pg_upgrade.h:181
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:26
DbInfo * dbs
Definition: pg_upgrade.h:192
#define snprintf
Definition: port.h:192
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:92
static char * connstr
Definition: pg_dumpall.c:61

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

◆ get_db_and_rel_infos()

void get_db_and_rel_infos ( ClusterInfo cluster)

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

310 {
311  int dbnum;
312 
313  if (cluster->dbarr.dbs != NULL)
314  free_db_and_rel_infos(&cluster->dbarr);
315 
316  get_db_infos(cluster);
317 
318  for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
319  get_rel_infos(cluster, &cluster->dbarr.dbs[dbnum]);
320 
321  if (cluster == &old_cluster)
322  pg_log(PG_VERBOSE, "\nsource databases:\n");
323  else
324  pg_log(PG_VERBOSE, "\ntarget databases:\n");
325 
326  if (log_opts.verbose)
327  print_db_infos(&cluster->dbarr);
328 }
static void get_db_infos(ClusterInfo *cluster)
Definition: info.c:338
LogOpts log_opts
Definition: util.c:17
static void get_rel_infos(ClusterInfo *cluster, DbInfo *dbinfo)
Definition: info.c:407
ClusterInfo old_cluster
Definition: pg_upgrade.c:59
static void print_db_infos(DbInfoArr *dbinfo)
Definition: info.c:625
bool verbose
Definition: pg_upgrade.h:282
DbInfoArr dbarr
Definition: pg_upgrade.h:260
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
static void free_db_and_rel_infos(DbInfoArr *db_arr)
Definition: info.c:591
DbInfo * dbs
Definition: pg_upgrade.h:192

◆ get_loadable_libraries()

void get_loadable_libraries ( void  )

Definition at line 53 of file function.c.

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

Referenced by check_and_dump_old_cluster().

54 {
55  PGresult **ress;
56  int totaltups;
57  int dbnum;
58  bool found_public_plpython_handler = false;
59 
60  ress = (PGresult **) pg_malloc(old_cluster.dbarr.ndbs * sizeof(PGresult *));
61  totaltups = 0;
62 
63  /* Fetch all library names, removing duplicates within each DB */
64  for (dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
65  {
66  DbInfo *active_db = &old_cluster.dbarr.dbs[dbnum];
68 
69  /*
70  * Fetch all libraries containing non-built-in C functions in this DB.
71  */
72  ress[dbnum] = executeQueryOrDie(conn,
73  "SELECT DISTINCT probin "
74  "FROM pg_catalog.pg_proc "
75  "WHERE prolang = %u AND "
76  "probin IS NOT NULL AND "
77  "oid >= %u;",
78  ClanguageId,
80  totaltups += PQntuples(ress[dbnum]);
81 
82  /*
83  * Systems that install plpython before 8.1 have
84  * plpython_call_handler() defined in the "public" schema, causing
85  * pg_dump to dump it. However that function still references
86  * "plpython" (no "2"), so it throws an error on restore. This code
87  * checks for the problem function, reports affected databases to the
88  * user and explains how to remove them. 8.1 git commit:
89  * e0dedd0559f005d60c69c9772163e69c204bac69
90  * http://archives.postgresql.org/pgsql-hackers/2012-03/msg01101.php
91  * http://archives.postgresql.org/pgsql-bugs/2012-05/msg00206.php
92  */
94  {
95  PGresult *res;
96 
97  res = executeQueryOrDie(conn,
98  "SELECT 1 "
99  "FROM pg_catalog.pg_proc p "
100  " JOIN pg_catalog.pg_namespace n "
101  " ON pronamespace = n.oid "
102  "WHERE proname = 'plpython_call_handler' AND "
103  "nspname = 'public' AND "
104  "prolang = %u AND "
105  "probin = '$libdir/plpython' AND "
106  "p.oid >= %u;",
107  ClanguageId,
109  if (PQntuples(res) > 0)
110  {
111  if (!found_public_plpython_handler)
112  {
114  "\nThe old cluster has a \"plpython_call_handler\" function defined\n"
115  "in the \"public\" schema which is a duplicate of the one defined\n"
116  "in the \"pg_catalog\" schema. You can confirm this by executing\n"
117  "in psql:\n"
118  "\n"
119  " \\df *.plpython_call_handler\n"
120  "\n"
121  "The \"public\" schema version of this function was created by a\n"
122  "pre-8.1 install of plpython, and must be removed for pg_upgrade\n"
123  "to complete because it references a now-obsolete \"plpython\"\n"
124  "shared object file. You can remove the \"public\" schema version\n"
125  "of this function by running the following command:\n"
126  "\n"
127  " DROP FUNCTION public.plpython_call_handler()\n"
128  "\n"
129  "in each affected database:\n"
130  "\n");
131  }
132  pg_log(PG_WARNING, " %s\n", active_db->db_name);
133  found_public_plpython_handler = true;
134  }
135  PQclear(res);
136  }
137 
138  PQfinish(conn);
139  }
140 
141  if (found_public_plpython_handler)
142  pg_fatal("Remove the problem functions from the old cluster to continue.\n");
143 
144  os_info.libraries = (LibraryInfo *) pg_malloc(totaltups * sizeof(LibraryInfo));
145  totaltups = 0;
146 
147  for (dbnum = 0; dbnum < old_cluster.dbarr.ndbs; dbnum++)
148  {
149  PGresult *res = ress[dbnum];
150  int ntups;
151  int rowno;
152 
153  ntups = PQntuples(res);
154  for (rowno = 0; rowno < ntups; rowno++)
155  {
156  char *lib = PQgetvalue(res, rowno, 0);
157 
158  os_info.libraries[totaltups].name = pg_strdup(lib);
159  os_info.libraries[totaltups].dbnum = dbnum;
160 
161  totaltups++;
162  }
163  PQclear(res);
164  }
165 
166  pg_free(ress);
167 
168  os_info.num_libraries = totaltups;
169 }
char * name
Definition: pg_upgrade.h:301
uint32 major_version
Definition: pg_upgrade.h:269
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3163
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:23
#define pg_fatal(...)
Definition: pg_rewind.h:43
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4119
int PQntuples(const PGresult *res)
Definition: fe-exec.c:2769
#define FirstNormalObjectId
Definition: transam.h:141
PGconn * conn
Definition: streamutil.c:54
ClusterInfo old_cluster
Definition: pg_upgrade.c:59
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
LibraryInfo * libraries
Definition: pg_upgrade.h:315
PGconn * connectToServer(ClusterInfo *cluster, const char *db_name)
Definition: server.c:27
void PQclear(PGresult *res)
Definition: fe-exec.c:694
DbInfoArr dbarr
Definition: pg_upgrade.h:260
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
void pg_free(void *ptr)
Definition: fe_memutils.c:105
OSInfo os_info
Definition: pg_upgrade.c:61
char * db_name
Definition: pg_upgrade.h:181
DbInfo * dbs
Definition: pg_upgrade.h:192

◆ get_major_server_version()

uint32 get_major_server_version ( ClusterInfo cluster)

Definition at line 157 of file server.c.

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

Referenced by check_data_dir().

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

◆ get_sock_dir()

void get_sock_dir ( ClusterInfo cluster,
bool  live_check 
)

Definition at line 468 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_strdup(), pg_strip_crlf(), PG_WARNING, ClusterInfo::pgdata, ClusterInfo::port, snprintf, ClusterInfo::sockdir, UserOpts::socketdir, and strerror.

Referenced by main().

469 {
470 #ifdef HAVE_UNIX_SOCKETS
471 
472  /*
473  * sockdir and port were added to postmaster.pid in PG 9.1. Pre-9.1 cannot
474  * process pg_ctl -w for sockets in non-default locations.
475  */
476  if (GET_MAJOR_VERSION(cluster->major_version) >= 901)
477  {
478  if (!live_check)
479  cluster->sockdir = user_opts.socketdir;
480  else
481  {
482  /*
483  * If we are doing a live check, we will use the old cluster's
484  * Unix domain socket directory so we can connect to the live
485  * server.
486  */
487  unsigned short orig_port = cluster->port;
488  char filename[MAXPGPATH],
489  line[MAXPGPATH];
490  FILE *fp;
491  int lineno;
492 
493  snprintf(filename, sizeof(filename), "%s/postmaster.pid",
494  cluster->pgdata);
495  if ((fp = fopen(filename, "r")) == NULL)
496  pg_fatal("could not open file \"%s\": %s\n",
497  filename, strerror(errno));
498 
499  for (lineno = 1;
501  lineno++)
502  {
503  if (fgets(line, sizeof(line), fp) == NULL)
504  pg_fatal("could not read line %d from file \"%s\": %s\n",
505  lineno, filename, strerror(errno));
506 
507  /* potentially overwrite user-supplied value */
508  if (lineno == LOCK_FILE_LINE_PORT)
509  sscanf(line, "%hu", &old_cluster.port);
510  if (lineno == LOCK_FILE_LINE_SOCKET_DIR)
511  {
512  /* strip trailing newline and carriage return */
513  cluster->sockdir = pg_strdup(line);
514  (void) pg_strip_crlf(cluster->sockdir);
515  }
516  }
517  fclose(fp);
518 
519  /* warn of port number correction */
520  if (orig_port != DEF_PGUPORT && old_cluster.port != orig_port)
521  pg_log(PG_WARNING, "user-supplied old port number %hu corrected to %hu\n",
522  orig_port, cluster->port);
523  }
524  }
525  else
526 
527  /*
528  * Can't get sockdir and pg_ctl -w can't use a non-default, use
529  * default
530  */
531  cluster->sockdir = NULL;
532 #else /* !HAVE_UNIX_SOCKETS */
533  cluster->sockdir = NULL;
534 #endif
535 }
uint32 major_version
Definition: pg_upgrade.h:269
int pg_strip_crlf(char *str)
Definition: string.c:105
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:23
#define pg_fatal(...)
Definition: pg_rewind.h:43
unsigned short port
Definition: pg_upgrade.h:268
#define LOCK_FILE_LINE_SOCKET_DIR
Definition: pidfile.h:41
#define MAXPGPATH
ClusterInfo old_cluster
Definition: pg_upgrade.c:59
char * pg_strdup(const char *in)
Definition: fe_memutils.c:85
UserOpts user_opts
Definition: option.c:30
#define DEF_PGUPORT
Definition: pg_upgrade.h:16
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
#define Max(x, y)
Definition: c.h:899
#define LOCK_FILE_LINE_PORT
Definition: pidfile.h:40
#define strerror
Definition: port.h:205
static char * filename
Definition: pg_dumpall.c:90
char * pgdata
Definition: pg_upgrade.h:261
char * sockdir
Definition: pg_upgrade.h:267
#define snprintf
Definition: port.h:192
char * socketdir
Definition: pg_upgrade.h:296

◆ get_user_info()

int get_user_info ( char **  user_name_p)

Definition at line 211 of file util.c.

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

Referenced by parseCommandLine().

212 {
213  int user_id;
214  const char *user_name;
215  char *errstr;
216 
217 #ifndef WIN32
218  user_id = geteuid();
219 #else
220  user_id = 1;
221 #endif
222 
223  user_name = get_user_name(&errstr);
224  if (!user_name)
225  pg_fatal("%s\n", errstr);
226 
227  /* make a copy */
228  *user_name_p = pg_strdup(user_name);
229 
230  return user_id;
231 }
const char * get_user_name(char **errstr)
Definition: username.c:31
void pg_fatal(const char *fmt,...)
Definition: util.c:158
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
#define pg_fatal(...)
Definition: pg_rewind.h:43
ClusterInfo new_cluster
Definition: pg_upgrade.c:59
ClusterInfo old_cluster
Definition: pg_upgrade.c:59
const char * tablespace_suffix
Definition: pg_upgrade.h:272
int num_old_tablespaces
Definition: pg_upgrade.h:314
OSInfo os_info
Definition: pg_upgrade.c:61

◆ issue_warnings_and_set_wal_level()

void issue_warnings_and_set_wal_level ( void  )

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

204 {
205  /*
206  * We unconditionally start/stop the new server because pg_resetwal -o set
207  * wal_level to 'minimum'. If the user is upgrading standby servers using
208  * the rsync instructions, they will need pg_upgrade to write its final
209  * WAL record showing wal_level as 'replica'.
210  */
212 
213  /* Create dummy large object permissions for old < PG 9.0? */
216 
217  /* Reindex hash indexes for old < 10.0 */
220 
221  stop_postmaster(false);
222 }
uint32 major_version
Definition: pg_upgrade.h:269
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:23
void old_9_6_invalidate_hash_indexes(ClusterInfo *cluster, bool check_mode)
Definition: version.c:299
ClusterInfo new_cluster
Definition: pg_upgrade.c:59
void new_9_0_populate_pg_largeobject_metadata(ClusterInfo *cluster, bool check_mode)
Definition: version.c:22
ClusterInfo old_cluster
Definition: pg_upgrade.c:59
void stop_postmaster(bool in_atexit)
Definition: server.c:327
static pgpid_t start_postmaster(void)
Definition: pg_ctl.c:445

◆ linkFile()

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

Definition at line 151 of file file.c.

References pg_fatal, pg_link_file, and strerror.

Referenced by transfer_relfile().

153 {
154  if (pg_link_file(src, dst) < 0)
155  pg_fatal("error while creating link for relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n",
156  schemaName, relName, src, dst, strerror(errno));
157 }
#define pg_link_file
Definition: pg_upgrade.h:68
#define pg_fatal(...)
Definition: pg_rewind.h:43
#define strerror
Definition: port.h:205

◆ new_9_0_populate_pg_largeobject_metadata()

void new_9_0_populate_pg_largeobject_metadata ( ClusterInfo cluster,
bool  check_mode 
)

Definition at line 22 of file version.c.

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

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

◆ old_11_check_for_sql_identifier_data_type_usage()

void old_11_check_for_sql_identifier_data_type_usage ( ClusterInfo cluster)

Definition at line 414 of file version.c.

References check_for_data_type_usage(), check_ok(), MAXPGPATH, pg_fatal, pg_log(), PG_REPORT, prep_status(), and snprintf.

Referenced by check_and_dump_old_cluster().

415 {
416  char output_path[MAXPGPATH];
417 
418  prep_status("Checking for invalid \"sql_identifier\" user columns");
419 
420  snprintf(output_path, sizeof(output_path), "tables_using_sql_identifier.txt");
421 
422  if (check_for_data_type_usage(cluster, "information_schema.sql_identifier",
423  output_path))
424  {
425  pg_log(PG_REPORT, "fatal\n");
426  pg_fatal("Your installation contains the \"sql_identifier\" data type in user tables\n"
427  "and/or indexes. The on-disk format for this data type has changed, so this\n"
428  "cluster cannot currently be upgraded. You can remove the problem tables or\n"
429  "change the data type to \"name\" and restart the upgrade.\n"
430  "A list of the problem columns is in the file:\n"
431  " %s\n\n", output_path);
432  }
433  else
434  check_ok();
435 }
#define pg_fatal(...)
Definition: pg_rewind.h:43
#define MAXPGPATH
static bool check_for_data_type_usage(ClusterInfo *cluster, const char *typename, char *output_path)
Definition: version.c:109
void prep_status(const char *fmt,...) pg_attribute_printf(1
static void check_ok(void)
Definition: initdb.c:2079
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
#define snprintf
Definition: port.h:192

◆ old_9_3_check_for_line_data_type_usage()

void old_9_3_check_for_line_data_type_usage ( ClusterInfo cluster)

Definition at line 235 of file version.c.

References check_for_data_type_usage(), check_ok(), MAXPGPATH, pg_fatal, pg_log(), PG_REPORT, prep_status(), and snprintf.

Referenced by check_and_dump_old_cluster().

236 {
237  char output_path[MAXPGPATH];
238 
239  prep_status("Checking for incompatible \"line\" data type");
240 
241  snprintf(output_path, sizeof(output_path), "tables_using_line.txt");
242 
243  if (check_for_data_type_usage(cluster, "pg_catalog.line", output_path))
244  {
245  pg_log(PG_REPORT, "fatal\n");
246  pg_fatal("Your installation contains the \"line\" data type in user tables. This\n"
247  "data type changed its internal and input/output format between your old\n"
248  "and new clusters so this cluster cannot currently be upgraded. You can\n"
249  "remove the problem tables and restart the upgrade. A list of the problem\n"
250  "columns is in the file:\n"
251  " %s\n\n", output_path);
252  }
253  else
254  check_ok();
255 }
#define pg_fatal(...)
Definition: pg_rewind.h:43
#define MAXPGPATH
static bool check_for_data_type_usage(ClusterInfo *cluster, const char *typename, char *output_path)
Definition: version.c:109
void prep_status(const char *fmt,...) pg_attribute_printf(1
static void check_ok(void)
Definition: initdb.c:2079
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
#define snprintf
Definition: port.h:192

◆ old_9_6_check_for_unknown_data_type_usage()

void old_9_6_check_for_unknown_data_type_usage ( ClusterInfo cluster)

Definition at line 272 of file version.c.

References check_for_data_type_usage(), check_ok(), MAXPGPATH, pg_fatal, pg_log(), PG_REPORT, prep_status(), and snprintf.

Referenced by check_and_dump_old_cluster().

273 {
274  char output_path[MAXPGPATH];
275 
276  prep_status("Checking for invalid \"unknown\" user columns");
277 
278  snprintf(output_path, sizeof(output_path), "tables_using_unknown.txt");
279 
280  if (check_for_data_type_usage(cluster, "pg_catalog.unknown", output_path))
281  {
282  pg_log(PG_REPORT, "fatal\n");
283  pg_fatal("Your installation contains the \"unknown\" data type in user tables. This\n"
284  "data type is no longer allowed in tables, so this cluster cannot currently\n"
285  "be upgraded. You can remove the problem tables and restart the upgrade.\n"
286  "A list of the problem columns is in the file:\n"
287  " %s\n\n", output_path);
288  }
289  else
290  check_ok();
291 }
#define pg_fatal(...)
Definition: pg_rewind.h:43
#define MAXPGPATH
static bool check_for_data_type_usage(ClusterInfo *cluster, const char *typename, char *output_path)
Definition: version.c:109
void prep_status(const char *fmt,...) pg_attribute_printf(1
static void check_ok(void)
Definition: initdb.c:2079
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
#define snprintf
Definition: port.h:192

◆ old_9_6_invalidate_hash_indexes()

void old_9_6_invalidate_hash_indexes ( ClusterInfo cluster,
bool  check_mode 
)

Definition at line 299 of file version.c.

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

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

◆ 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 }
UserOpts user_opts
Definition: option.c:30
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
bool check
Definition: pg_upgrade.h:292

◆ output_completion_banner()

void output_completion_banner ( char *  analyze_script_file_name,
char *  deletion_script_file_name 
)

Definition at line 226 of file check.c.

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

Referenced by main().

228 {
229  /* Did we copy the free space files? */
232  "Optimizer statistics are not transferred by pg_upgrade so,\n"
233  "once you start the new server, consider running:\n"
234  " %s\n\n", analyze_script_file_name);
235  else
237  "Optimizer statistics and free space information are not transferred\n"
238  "by pg_upgrade so, once you start the new server, consider running:\n"
239  " %s\n\n", analyze_script_file_name);
240 
241 
242  if (deletion_script_file_name)
244  "Running this script will delete the old cluster's data files:\n"
245  " %s\n",
246  deletion_script_file_name);
247  else
249  "Could not create a script to delete the old cluster's data files\n"
250  "because user-defined tablespaces or the new cluster's data directory\n"
251  "exist in the old cluster directory. The old cluster's contents must\n"
252  "be deleted manually.\n");
253 }
uint32 major_version
Definition: pg_upgrade.h:269
#define GET_MAJOR_VERSION(v)
Definition: pg_upgrade.h:23
ClusterInfo old_cluster
Definition: pg_upgrade.c:59
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2

◆ 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 177 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().

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

◆ parseCommandLine()

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

Definition at line 39 of file option.c.

References _, ClusterInfo::bindir, canonicalize_path(), UserOpts::check, check_required_directory(), DEF_PGUPORT, filename, FIX_DEFAULT_READ_ONLY, fopen_priv, fprintf, 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, optind, os_info, output_files, path_is_prefix_of_path(), pfree(), pg_fatal, pg_free(), pg_log(), pg_putenv(), PG_REPORT, pg_strdup(), ClusterInfo::pgdata, ClusterInfo::pgopts, ClusterInfo::port, OSInfo::progname, psprintf(), required_argument, LogOpts::retain, UserOpts::socketdir, strlcpy(), UserOpts::transfer_mode, TRANSFER_MODE_CLONE, TRANSFER_MODE_COPY, TRANSFER_MODE_LINK, usage(), OSInfo::user, OSInfo::user_specified, and LogOpts::verbose.

Referenced by main().

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

◆ pg_attribute_noreturn()

void void void pg_attribute_noreturn ( )

◆ pg_fatal()

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

◆ pg_log()

◆ pg_putenv()

void pg_putenv ( const char *  var,
const char *  val 
)

Definition at line 253 of file util.c.

References psprintf(), putenv, and unsetenv.

Referenced by get_control_data(), and parseCommandLine().

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

◆ pid_lock_file_exists()

bool pid_lock_file_exists ( const char *  datadir)

Definition at line 219 of file exec.c.

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

Referenced by setup().

220 {
221  char path[MAXPGPATH];
222  int fd;
223 
224  snprintf(path, sizeof(path), "%s/postmaster.pid", datadir);
225 
226  if ((fd = open(path, O_RDONLY, 0)) < 0)
227  {
228  /* ENOTDIR means we will throw a more useful error later */
229  if (errno != ENOENT && errno != ENOTDIR)
230  pg_fatal("could not open file \"%s\" for reading: %s\n",
231  path, strerror(errno));
232 
233  return false;
234  }
235 
236  close(fd);
237  return true;
238 }
#define pg_fatal(...)
Definition: pg_rewind.h:43
static int fd(const char *x, int i)
Definition: preproc-init.c:105
#define MAXPGPATH
char * datadir
#define strerror
Definition: port.h:205
#define close(a)
Definition: win32.h:12
#define snprintf
Definition: port.h:192

◆ prep_status()

◆ print_maps()

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

Definition at line 283 of file info.c.

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

Referenced by transfer_all_new_dbs().

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

◆ quote_identifier()

char* quote_identifier ( const char *  s)

Definition at line 10640 of file ruleutils.c.

10641 {
10642  /*
10643  * Can avoid quoting if ident starts with a lowercase letter or underscore
10644  * and contains only lowercase letters, digits, and underscores, *and* is
10645  * not any SQL keyword. Otherwise, supply quotes.
10646  */
10647  int nquotes = 0;
10648  bool safe;
10649  const char *ptr;
10650  char *result;
10651  char *optr;
10652 
10653  /*
10654  * would like to use <ctype.h> macros here, but they might yield unwanted
10655  * locale-specific results...
10656  */
10657  safe = ((ident[0] >= 'a' && ident[0] <= 'z') || ident[0] == '_');
10658 
10659  for (ptr = ident; *ptr; ptr++)
10660  {
10661  char ch = *ptr;
10662 
10663  if ((ch >= 'a' && ch <= 'z') ||
10664  (ch >= '0' && ch <= '9') ||
10665  (ch == '_'))
10666  {
10667  /* okay */
10668  }
10669  else
10670  {
10671  safe = false;
10672  if (ch == '"')
10673  nquotes++;
10674  }
10675  }
10676 
10678  safe = false;
10679 
10680  if (safe)
10681  {
10682  /*
10683  * Check for keyword. We quote keywords except for unreserved ones.
10684  * (In some cases we could avoid quoting a col_name or type_func_name
10685  * keyword, but it seems much harder than it's worth to tell that.)
10686  *
10687  * Note: ScanKeywordLookup() does case-insensitive comparison, but
10688  * that's fine, since we already know we have all-lower-case.
10689  */
10690  int kwnum = ScanKeywordLookup(ident, &ScanKeywords);
10691 
10692  if (kwnum >= 0 && ScanKeywordCategories[kwnum] != UNRESERVED_KEYWORD)
10693  safe = false;
10694  }
10695 
10696  if (safe)
10697  return ident; /* no change needed */
10698 
10699  result = (char *) palloc(strlen(ident) + nquotes + 2 + 1);
10700 
10701  optr = result;
10702  *optr++ = '"';
10703  for (ptr = ident; *ptr; ptr++)
10704  {
10705  char ch = *ptr;
10706 
10707  if (ch == '"')
10708  *optr++ = '"';
10709  *optr++ = ch;
10710  }
10711  *optr++ = '"';
10712  *optr = '\0';
10713 
10714  return result;
10715 }
const uint8 ScanKeywordCategories[SCANKEYWORDS_NUM_KEYWORDS]
Definition: keywords.c:29
#define UNRESERVED_KEYWORD
Definition: keywords.h:20
PGDLLIMPORT const ScanKeywordList ScanKeywords
bool quote_all_identifiers
Definition: ruleutils.c:301
void * palloc(Size size)
Definition: mcxt.c:949
int ScanKeywordLookup(const char *str, const ScanKeywordList *keywords)
Definition: kwlookup.c:38

◆ reap_child()

bool reap_child ( bool  wait_for_child)

Definition at line 288 of file parallel.c.

References UserOpts::jobs, parallel_jobs, pg_fatal, strerror, and user_opts.

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

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

◆ report_clusters_compatible()

void report_clusters_compatible ( void  )

Definition at line 186 of file check.c.

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

Referenced by main().

187 {
188  if (user_opts.check)
189  {
190  pg_log(PG_REPORT, "\n*Clusters are compatible*\n");
191  /* stops new cluster */
192  stop_postmaster(false);
193  exit(0);
194  }
195 
196  pg_log(PG_REPORT, "\n"
197  "If pg_upgrade fails after this point, you must re-initdb the\n"
198  "new cluster before continuing.\n");
199 }
UserOpts user_opts
Definition: option.c:30
void stop_postmaster(bool in_atexit)
Definition: server.c:327
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
bool check
Definition: pg_upgrade.h:292

◆ report_status()

◆ rewriteVisibilityMap()

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

Definition at line 177 of file file.c.

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

Referenced by transfer_relfile().

179 {
180  int src_fd;
181  int dst_fd;
182  PGAlignedBlock buffer;
183  PGAlignedBlock new_vmbuf;
184  ssize_t totalBytesRead = 0;
185  ssize_t src_filesize;
186  int rewriteVmBytesPerPage;
187  BlockNumber new_blkno = 0;
188  struct stat statbuf;
189 
190  /* Compute number of old-format bytes per new page */
191  rewriteVmBytesPerPage = (BLCKSZ - SizeOfPageHeaderData) / 2;
192 
193  if ((src_fd = open(fromfile, O_RDONLY | PG_BINARY, 0)) < 0)
194  pg_fatal("error while copying relation \"%s.%s\": could not open file \"%s\": %s\n",
195  schemaName, relName, fromfile, strerror(errno));
196 
197  if (fstat(src_fd, &statbuf) != 0)
198  pg_fatal("error while copying relation \"%s.%s\": could not stat file \"%s\": %s\n",
199  schemaName, relName, fromfile, strerror(errno));
200 
201  if ((dst_fd = open(tofile, O_RDWR | O_CREAT | O_EXCL | PG_BINARY,
202  pg_file_create_mode)) < 0)
203  pg_fatal("error while copying relation \"%s.%s\": could not create file \"%s\": %s\n",
204  schemaName, relName, tofile, strerror(errno));
205 
206  /* Save old file size */
207  src_filesize = statbuf.st_size;
208 
209  /*
210  * Turn each visibility map page into 2 pages one by one. Each new page
211  * has the same page header as the old one. If the last section of the
212  * last page is empty, we skip it, mostly to avoid turning one-page
213  * visibility maps for small relations into two pages needlessly.
214  */
215  while (totalBytesRead < src_filesize)
216  {
217  ssize_t bytesRead;
218  char *old_cur;
219  char *old_break;
220  char *old_blkend;
221  PageHeaderData pageheader;
222  bool old_lastblk;
223 
224  if ((bytesRead = read(src_fd, buffer.data, BLCKSZ)) != BLCKSZ)
225  {
226  if (bytesRead < 0)
227  pg_fatal("error while copying relation \"%s.%s\": could not read file \"%s\": %s\n",
228  schemaName, relName, fromfile, strerror(errno));
229  else
230  pg_fatal("error while copying relation \"%s.%s\": partial page found in file \"%s\"\n",
231  schemaName, relName, fromfile);
232  }
233 
234  totalBytesRead += BLCKSZ;
235  old_lastblk = (totalBytesRead == src_filesize);
236 
237  /* Save the page header data */
238  memcpy(&pageheader, buffer.data, SizeOfPageHeaderData);
239 
240  /*
241  * These old_* variables point to old visibility map page. old_cur
242  * points to current position on old page. old_blkend points to end of
243  * old block. old_break is the end+1 position on the old page for the
244  * data that will be transferred to the current new page.
245  */
246  old_cur = buffer.data + SizeOfPageHeaderData;
247  old_blkend = buffer.data + bytesRead;
248  old_break = old_cur + rewriteVmBytesPerPage;
249 
250  while (old_break <= old_blkend)
251  {
252  char *new_cur;
253  bool empty = true;
254  bool old_lastpart;
255 
256  /* First, copy old page header to new page */
257  memcpy(new_vmbuf.data, &pageheader, SizeOfPageHeaderData);
258 
259  /* Rewriting the last part of the last old page? */
260  old_lastpart = old_lastblk && (old_break == old_blkend);
261 
262  new_cur = new_vmbuf.data + SizeOfPageHeaderData;
263 
264  /* Process old page bytes one by one, and turn it into new page. */
265  while (old_cur < old_break)
266  {
267  uint8 byte = *(uint8 *) old_cur;
268  uint16 new_vmbits = 0;
269  int i;
270 
271  /* Generate new format bits while keeping old information */
272  for (i = 0; i < BITS_PER_BYTE; i++)
273  {
274  if (byte & (1 << i))
275  {
276  empty = false;
277  new_vmbits |=
279  }
280  }
281 
282  /* Copy new visibility map bytes to new-format page */
283  new_cur[0] = (char) (new_vmbits & 0xFF);
284  new_cur[1] = (char) (new_vmbits >> 8);
285 
286  old_cur++;
287  new_cur += BITS_PER_HEAPBLOCK;
288  }
289 
290  /* If the last part of the last page is empty, skip writing it */
291  if (old_lastpart && empty)
292  break;
293 
294  /* Set new checksum for visibility map page, if enabled */
296  ((PageHeader) new_vmbuf.data)->pd_checksum =
297  pg_checksum_page(new_vmbuf.data, new_blkno);
298 
299  errno = 0;
300  if (write(dst_fd, new_vmbuf.data, BLCKSZ) != BLCKSZ)
301  {
302  /* if write didn't set errno, assume problem is no disk space */
303  if (errno == 0)
304  errno = ENOSPC;
305  pg_fatal("error while copying relation \"%s.%s\": could not write file \"%s\": %s\n",
306  schemaName, relName, tofile, strerror(errno));
307  }
308 
309  /* Advance for next new page */
310  old_break += rewriteVmBytesPerPage;
311  new_blkno++;
312  }
313  }
314 
315  /* Clean up */
316  close(dst_fd);
317  close(src_fd);
318 }
int pg_file_create_mode
Definition: file_perm.c:19
ControlData controldata
Definition: pg_upgrade.h:259
#define BITS_PER_BYTE
#define write(a, b, c)
Definition: win32.h:14
unsigned char uint8
Definition: c.h:357
#define pg_fatal(...)
Definition: pg_rewind.h:43
uint32 BlockNumber
Definition: block.h:31
#define SizeOfPageHeaderData
Definition: bufpage.h:216
#define PG_BINARY
Definition: c.h:1216
ClusterInfo new_cluster
Definition: pg_upgrade.c:59
char data[BLCKSZ]
Definition: c.h:1085
unsigned short uint16
Definition: c.h:358
bool data_checksum_version
Definition: pg_upgrade.h:223
#define BITS_PER_HEAPBLOCK
Definition: visibilitymap.h:23
#define byte(x, n)
Definition: rijndael.c:68
#define stat(a, b)
Definition: win32_port.h:255
PageHeaderData * PageHeader
Definition: bufpage.h:166
#define strerror
Definition: port.h:205
#define VISIBILITYMAP_ALL_VISIBLE
Definition: visibilitymap.h:26
int i
#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 196 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().

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

◆ stop_postmaster()

void stop_postmaster ( bool  in_atexit)

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

328 {
330 
332  cluster = &old_cluster;
333  else if (os_info.running_cluster == &new_cluster)
334  cluster = &new_cluster;
335  else
336  return; /* no cluster running */
337 
338  exec_prog(SERVER_STOP_LOG_FILE, NULL, !in_atexit, !in_atexit,
339  "\"%s/pg_ctl\" -w -D \"%s\" -o \"%s\" %s stop",
340  cluster->bindir, cluster->pgconfig,
341  cluster->pgopts ? cluster->pgopts : "",
342  in_atexit ? "-m fast" : "-m smart");
343 
344  os_info.running_cluster = NULL;
345 }
#define SERVER_STOP_LOG_FILE
Definition: pg_upgrade.h:54
char * pgopts
Definition: pg_upgrade.h:265
ClusterInfo new_cluster
Definition: pg_upgrade.c:59
char * pgconfig
Definition: pg_upgrade.h:262
ClusterInfo old_cluster
Definition: pg_upgrade.c:59
void cluster(ClusterStmt *stmt, bool isTopLevel)
Definition: cluster.c:102
char * bindir
Definition: pg_upgrade.h:264
ClusterInfo * running_cluster
Definition: pg_upgrade.h:317
OSInfo os_info
Definition: pg_upgrade.c:61
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 240 of file util.c.

Referenced by get_control_data().

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

◆ 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 88 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().

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

◆ 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 29 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_CLONE, TRANSFER_MODE_COPY, TRANSFER_MODE_LINK, and user_opts.

Referenced by main().

31 {
32  switch (user_opts.transfer_mode)
33  {
35  pg_log(PG_REPORT, "Cloning user relation files\n");
36  break;
37  case TRANSFER_MODE_COPY:
38  pg_log(PG_REPORT, "Copying user relation files\n");
39  break;
40  case TRANSFER_MODE_LINK:
41  pg_log(PG_REPORT, "Linking user relation files\n");
42  break;
43  }
44 
45  /*
46  * Transferring files by tablespace is tricky because a single database
47  * can use multiple tablespaces. For non-parallel mode, we just pass a
48  * NULL tablespace path, which matches all tablespaces. In parallel mode,
49  * we pass the default tablespace and all user-created tablespaces and let
50  * those operations happen in parallel.
51  */
52  if (user_opts.jobs <= 1)
53  parallel_transfer_all_new_dbs(old_db_arr, new_db_arr, old_pgdata,
54  new_pgdata, NULL);
55  else
56  {
57  int tblnum;
58 
59  /* transfer default tablespace */
60  parallel_transfer_all_new_dbs(old_db_arr, new_db_arr, old_pgdata,
61  new_pgdata, old_pgdata);
62 
63  for (tblnum = 0; tblnum < os_info.num_old_tablespaces; tblnum++)
65  new_db_arr,
66  old_pgdata,
67  new_pgdata,
68  os_info.old_tablespaces[tblnum]);
69  /* reap all children */
70  while (reap_child(true) == true)
71  ;
72  }
73 
75  check_ok();
76 
77  return;
78 }
void end_progress_output(void)
Definition: util.c:43
int jobs
Definition: pg_upgrade.h:295
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:177
static void check_ok(void)
Definition: initdb.c:2079
transferMode transfer_mode
Definition: pg_upgrade.h:294
UserOpts user_opts
Definition: option.c:30
char ** old_tablespaces
Definition: pg_upgrade.h:313
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
bool reap_child(bool wait_for_child)
Definition: parallel.c:288
int num_old_tablespaces
Definition: pg_upgrade.h:314
OSInfo os_info
Definition: pg_upgrade.c:61

◆ verify_directories()

bool void verify_directories ( void  )

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

251 {
252 #ifndef WIN32
253  if (access(".", R_OK | W_OK | X_OK) != 0)
254 #else
255  if (win32_check_directory_write_permissions() != 0)
256 #endif
257  pg_fatal("You must have read and write access in the current directory.\n");
258