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 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 *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 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)
 
bool check_for_data_types_usage (ClusterInfo *cluster, const char *base_query, const char *output_path)
 
bool check_for_data_type_usage (ClusterInfo *cluster, const char *type_name, const char *output_path)
 
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 report_extension_updates (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 95 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 75 of file pg_upgrade.h.

◆ ECHO_QUOTE

#define ECHO_QUOTE   "'"

Definition at line 74 of file pg_upgrade.h.

◆ EXEC_PSQL_ARGS

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

Definition at line 358 of file pg_upgrade.h.

Referenced by prepare_new_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 125 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 120 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 114 of file pg_upgrade.h.

Referenced by copy_xact_xlog_xid(), and get_control_data().

◆ PATH_QUOTE

#define PATH_QUOTE   '\''

Definition at line 69 of file pg_upgrade.h.

Referenced by create_script_for_old_cluster_deletion().

◆ PATH_SEPARATOR

#define PATH_SEPARATOR   '/'

Definition at line 68 of file pg_upgrade.h.

Referenced by create_script_for_old_cluster_deletion().

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

Referenced by create_script_for_old_cluster_deletion().

◆ RMDIR_CMD

#define RMDIR_CMD   "rm -rf"

Definition at line 71 of file pg_upgrade.h.

Referenced by create_script_for_old_cluster_deletion().

◆ SCRIPT_EXT

#define SCRIPT_EXT   "sh"

Definition at line 73 of file pg_upgrade.h.

Referenced by create_script_for_old_cluster_deletion().

◆ SCRIPT_PREFIX

#define SCRIPT_PREFIX   "./"

Definition at line 72 of file pg_upgrade.h.

Referenced by create_script_for_old_cluster_deletion().

◆ 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 101 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 106 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 404 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.

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

◆ check_and_dump_old_cluster()

void check_and_dump_old_cluster ( bool  live_check)

Definition at line 83 of file check.c.

References ControlData::cat_ver, UserOpts::check, check_for_composite_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_for_user_defined_encoding_conversions(), check_for_user_defined_postfix_ops(), 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().

84 {
85  /* -- OLD -- */
86 
87  if (!live_check)
89 
90  /* Extract a list of databases and tables from the old cluster */
92 
94 
96 
97 
98  /*
99  * Check for various failure cases
100  */
107 
108  /*
109  * PG 14 changed the function signature of encoding conversion functions.
110  * Conversions from older versions cannot be upgraded automatically
111  * because the user-defined functions used by the encoding conversions
112  * need to be changed to match the new signature.
113  */
116 
117  /*
118  * Pre-PG 14 allowed user defined postfix operators, which are not
119  * supported anymore. Verify there are none, iff applicable.
120  */
123 
124  /*
125  * Pre-PG 12 allowed tables to be declared WITH OIDS, which is not
126  * supported anymore. Verify there are none, iff applicable.
127  */
130 
131  /*
132  * PG 12 changed the 'sql_identifier' type storage to be based on name,
133  * not varchar, which breaks on-disk format for existing data. So we need
134  * to prevent upgrade when used in user objects (tables, indexes, ...).
135  */
138 
139  /*
140  * Pre-PG 10 allowed tables with 'unknown' type columns and non WAL logged
141  * hash indexes
142  */
144  {
146  if (user_opts.check)
148  }
149 
150  /* 9.5 and below should not have roles starting with pg_ */
153 
157 
158  /* Pre-PG 9.4 had a different 'line' data type internal format */
161 
162  /* Pre-PG 9.0 had no large object permissions */
165 
166  /*
167  * While not a check option, we do this now because this is the only time
168  * the old server is running.
169  */
170  if (!user_opts.check)
172 
173  if (!live_check)
174  stop_postmaster(false);
175 }
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:334
static void check_for_reg_data_type_usage(ClusterInfo *cluster)
Definition: check.c:1119
static void check_for_prepared_transactions(ClusterInfo *cluster)
Definition: check.c:758
static void check_for_user_defined_postfix_ops(ClusterInfo *cluster)
Definition: check.c:878
static void check_proper_datallowconn(ClusterInfo *cluster)
Definition: check.c:697
static void check_for_pg_role_prefix(ClusterInfo *cluster)
Definition: check.c:1201
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:977
void generate_old_dump(void)
Definition: dump.c:16
static void check_is_install_user(ClusterInfo *cluster)
Definition: check.c:646
static void check_for_isn_and_int8_passing_mismatch(ClusterInfo *cluster)
Definition: check.c:793
UserOpts user_opts
Definition: option.c:30
uint32 cat_ver
Definition: pg_upgrade.h:203
void stop_postmaster(bool in_atexit)
Definition: server.c:330
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:125
bool check
Definition: pg_upgrade.h:292
static pgpid_t start_postmaster(void)
Definition: pg_ctl.c:443
static void check_for_jsonb_9_4_usage(ClusterInfo *cluster)
Definition: check.c:1173
void init_tablespaces(void)
Definition: tablespace.c:19
void old_9_3_check_for_line_data_type_usage(ClusterInfo *cluster)
Definition: version.c:268
static void check_for_composite_data_type_usage(ClusterInfo *cluster)
Definition: check.c:1060
static void check_for_user_defined_encoding_conversions(ClusterInfo *cluster)
Definition: check.c:1232
void old_11_check_for_sql_identifier_data_type_usage(ClusterInfo *cluster)
Definition: version.c:449
void old_9_6_check_for_unknown_data_type_usage(ClusterInfo *cluster)
Definition: version.c:306

◆ check_cluster_compatibility()

void check_cluster_compatibility ( bool  live_check)

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

328 {
329  /* get/check pg_control data of servers */
330  get_control_data(&old_cluster, live_check);
331  get_control_data(&new_cluster, false);
333 
334  /* We read the real port number for PG >= 9.1 */
335  if (live_check && GET_MAJOR_VERSION(old_cluster.major_version) <= 900 &&
337  pg_fatal("When checking a pre-PG 9.1 live old server, "
338  "you must specify the old server's port number.\n");
339 
340  if (live_check && old_cluster.port == new_cluster.port)
341  pg_fatal("When checking a live server, "
342  "the old and new port numbers must be different.\n");
343 }
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:37
unsigned short port
Definition: pg_upgrade.h:268
void check_control_data(ControlData *oldctrl, ControlData *newctrl)
Definition: controldata.c:648
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 285 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().

286 {
287  prep_status("Checking cluster versions");
288 
289  /* cluster versions should already have been obtained */
292 
293  /*
294  * We allow upgrades from/to the same major version for alpha/beta
295  * upgrades
296  */
297 
299  pg_fatal("This utility can only upgrade from PostgreSQL version 8.4 and later.\n");
300 
301  /* Only current PG version is supported as a target */
303  pg_fatal("This utility can only upgrade to PostgreSQL version %s.\n",
304  PG_MAJORVERSION);
305 
306  /*
307  * We can't allow downgrading because we use the target pg_dump, and
308  * pg_dump cannot operate on newer database versions, only current and
309  * older versions.
310  */
312  pg_fatal("This utility cannot be used to downgrade to older major PostgreSQL versions.\n");
313 
314  /* Ensure binaries match the designated data directories */
317  pg_fatal("Old cluster data and binary directories are from different major versions.\n");
320  pg_fatal("New cluster data and binary directories are from different major versions.\n");
321 
322  check_ok();
323 }
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:37
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:1920
uint32 bin_version
Definition: pg_upgrade.h:271
#define Assert(condition)
Definition: c.h:804

◆ check_control_data()

void check_control_data ( ControlData oldctrl,
ControlData newctrl 
)

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

650 {
651  if (oldctrl->align == 0 || oldctrl->align != newctrl->align)
652  pg_fatal("old and new pg_controldata alignments are invalid or do not match\n"
653  "Likely one cluster is a 32-bit install, the other 64-bit\n");
654 
655  if (oldctrl->blocksz == 0 || oldctrl->blocksz != newctrl->blocksz)
656  pg_fatal("old and new pg_controldata block sizes are invalid or do not match\n");
657 
658  if (oldctrl->largesz == 0 || oldctrl->largesz != newctrl->largesz)
659  pg_fatal("old and new pg_controldata maximum relation segment sizes are invalid or do not match\n");
660 
661  if (oldctrl->walsz == 0 || oldctrl->walsz != newctrl->walsz)
662  pg_fatal("old and new pg_controldata WAL block sizes are invalid or do not match\n");
663 
664  if (oldctrl->walseg == 0 || oldctrl->walseg != newctrl->walseg)
665  pg_fatal("old and new pg_controldata WAL segment sizes are invalid or do not match\n");
666 
667  if (oldctrl->ident == 0 || oldctrl->ident != newctrl->ident)
668  pg_fatal("old and new pg_controldata maximum identifier lengths are invalid or do not match\n");
669 
670  if (oldctrl->index == 0 || oldctrl->index != newctrl->index)
671  pg_fatal("old and new pg_controldata maximum indexed columns are invalid or do not match\n");
672 
673  if (oldctrl->toast == 0 || oldctrl->toast != newctrl->toast)
674  pg_fatal("old and new pg_controldata maximum TOAST chunk sizes are invalid or do not match\n");
675 
676  /* large_object added in 9.5, so it might not exist in the old cluster */
677  if (oldctrl->large_object != 0 &&
678  oldctrl->large_object != newctrl->large_object)
679  pg_fatal("old and new pg_controldata large-object chunk sizes are invalid or do not match\n");
680 
681  if (oldctrl->date_is_int != newctrl->date_is_int)
682  pg_fatal("old and new pg_controldata date/time storage types do not match\n");
683 
684  /*
685  * float8_pass_by_value does not need to match, but is used in
686  * check_for_isn_and_int8_passing_mismatch().
687  */
688 
689  /*
690  * We might eventually allow upgrades from checksum to no-checksum
691  * clusters.
692  */
693  if (oldctrl->data_checksum_version == 0 &&
694  newctrl->data_checksum_version != 0)
695  pg_fatal("old cluster does not use data checksums but the new one does\n");
696  else if (oldctrl->data_checksum_version != 0 &&
697  newctrl->data_checksum_version == 0)
698  pg_fatal("old cluster uses data checksums but the new one does not\n");
699  else if (oldctrl->data_checksum_version != newctrl->data_checksum_version)
700  pg_fatal("old and new cluster pg_controldata checksum versions do not match\n");
701 }
bool date_is_int
Definition: pg_upgrade.h:221
uint32 walsz
Definition: pg_upgrade.h:215
#define pg_fatal(...)
Definition: pg_rewind.h:37
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 317 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().

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

◆ check_for_data_type_usage()

bool check_for_data_type_usage ( ClusterInfo cluster,
const char *  type_name,
const char *  output_path 
)

Definition at line 241 of file version.c.

References check_for_data_types_usage(), free, and psprintf().

Referenced by check_for_jsonb_9_4_usage(), old_11_check_for_sql_identifier_data_type_usage(), old_9_3_check_for_line_data_type_usage(), and old_9_6_check_for_unknown_data_type_usage().

244 {
245  bool found;
246  char *base_query;
247 
248  base_query = psprintf("SELECT '%s'::pg_catalog.regtype AS oid",
249  type_name);
250 
251  found = check_for_data_types_usage(cluster, base_query, output_path);
252 
253  free(base_query);
254 
255  return found;
256 }
char * psprintf(const char *fmt,...)
Definition: psprintf.c:46
bool check_for_data_types_usage(ClusterInfo *cluster, const char *base_query, const char *output_path)
Definition: version.c:113
#define free(a)
Definition: header.h:65

◆ check_for_data_types_usage()

bool check_for_data_types_usage ( ClusterInfo cluster,
const char *  base_query,
const char *  output_path 
)

Definition at line 113 of file version.c.

References appendPQExpBuffer(), appendPQExpBufferStr(), conn, connectToServer(), CppAsString2, PQExpBufferData::data, DbInfo::db_name, ClusterInfo::dbarr, DbInfoArr::dbs, executeQueryOrDie(), fopen_priv, fprintf, GET_MAJOR_VERSION, initPQExpBuffer(), ClusterInfo::major_version, DbInfoArr::ndbs, pg_fatal, PQclear(), PQfinish(), PQfnumber(), PQgetvalue(), PQntuples(), strerror, and termPQExpBuffer().

Referenced by check_for_composite_data_type_usage(), check_for_data_type_usage(), and check_for_reg_data_type_usage().

116 {
117  bool found = false;
118  FILE *script = NULL;
119  int dbnum;
120 
121  for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
122  {
123  DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
124  PGconn *conn = connectToServer(cluster, active_db->db_name);
125  PQExpBufferData querybuf;
126  PGresult *res;
127  bool db_used = false;
128  int ntups;
129  int rowno;
130  int i_nspname,
131  i_relname,
132  i_attname;
133 
134  /*
135  * The type(s) of interest might be wrapped in a domain, array,
136  * composite, or range, and these container types can be nested (to
137  * varying extents depending on server version, but that's not of
138  * concern here). To handle all these cases we need a recursive CTE.
139  */
140  initPQExpBuffer(&querybuf);
141  appendPQExpBuffer(&querybuf,
142  "WITH RECURSIVE oids AS ( "
143  /* start with the type(s) returned by base_query */
144  " %s "
145  " UNION ALL "
146  " SELECT * FROM ( "
147  /* inner WITH because we can only reference the CTE once */
148  " WITH x AS (SELECT oid FROM oids) "
149  /* domains on any type selected so far */
150  " SELECT t.oid FROM pg_catalog.pg_type t, x WHERE typbasetype = x.oid AND typtype = 'd' "
151  " UNION ALL "
152  /* arrays over any type selected so far */
153  " SELECT t.oid FROM pg_catalog.pg_type t, x WHERE typelem = x.oid AND typtype = 'b' "
154  " UNION ALL "
155  /* composite types containing any type selected so far */
156  " SELECT t.oid FROM pg_catalog.pg_type t, pg_catalog.pg_class c, pg_catalog.pg_attribute a, x "
157  " WHERE t.typtype = 'c' AND "
158  " t.oid = c.reltype AND "
159  " c.oid = a.attrelid AND "
160  " NOT a.attisdropped AND "
161  " a.atttypid = x.oid ",
162  base_query);
163 
164  /* Ranges were introduced in 9.2 */
165  if (GET_MAJOR_VERSION(cluster->major_version) >= 902)
166  appendPQExpBufferStr(&querybuf,
167  " UNION ALL "
168  /* ranges containing any type selected so far */
169  " SELECT t.oid FROM pg_catalog.pg_type t, pg_catalog.pg_range r, x "
170  " WHERE t.typtype = 'r' AND r.rngtypid = t.oid AND r.rngsubtype = x.oid");
171 
172  appendPQExpBufferStr(&querybuf,
173  " ) foo "
174  ") "
175  /* now look for stored columns of any such type */
176  "SELECT n.nspname, c.relname, a.attname "
177  "FROM pg_catalog.pg_class c, "
178  " pg_catalog.pg_namespace n, "
179  " pg_catalog.pg_attribute a "
180  "WHERE c.oid = a.attrelid AND "
181  " NOT a.attisdropped AND "
182  " a.atttypid IN (SELECT oid FROM oids) AND "
183  " c.relkind IN ("
184  CppAsString2(RELKIND_RELATION) ", "
185  CppAsString2(RELKIND_MATVIEW) ", "
186  CppAsString2(RELKIND_INDEX) ") AND "
187  " c.relnamespace = n.oid AND "
188  /* exclude possible orphaned temp tables */
189  " n.nspname !~ '^pg_temp_' AND "
190  " n.nspname !~ '^pg_toast_temp_' AND "
191  /* exclude system catalogs, too */
192  " n.nspname NOT IN ('pg_catalog', 'information_schema')");
193 
194  res = executeQueryOrDie(conn, "%s", querybuf.data);
195 
196  ntups = PQntuples(res);
197  i_nspname = PQfnumber(res, "nspname");
198  i_relname = PQfnumber(res, "relname");
199  i_attname = PQfnumber(res, "attname");
200  for (rowno = 0; rowno < ntups; rowno++)
201  {
202  found = true;
203  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
204  pg_fatal("could not open file \"%s\": %s\n", output_path,
205  strerror(errno));
206  if (!db_used)
207  {
208  fprintf(script, "In database: %s\n", active_db->db_name);
209  db_used = true;
210  }
211  fprintf(script, " %s.%s.%s\n",
212  PQgetvalue(res, rowno, i_nspname),
213  PQgetvalue(res, rowno, i_relname),
214  PQgetvalue(res, rowno, i_attname));
215  }
216 
217  PQclear(res);
218 
219  termPQExpBuffer(&querybuf);
220 
221  PQfinish(conn);
222  }
223 
224  if (script)
225  fclose(script);
226 
227  return found;
228 }
uint32 major_version
Definition: pg_upgrade.h:269
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3642
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:131
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
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:37
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4231
int PQntuples(const PGresult *res)
Definition: fe-exec.c:3248
#define fprintf
Definition: port.h:221
PGconn * conn
Definition: streamutil.c:54
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
Definition: pqexpbuffer.c:267
PGconn * connectToServer(ClusterInfo *cluster, const char *db_name)
Definition: server.c:27
#define CppAsString2(x)
Definition: c.h:289
int PQfnumber(const PGresult *res, const char *field_name)
Definition: fe-exec.c:3356
void PQclear(PGresult *res)
Definition: fe-exec.c:694
DbInfoArr dbarr
Definition: pg_upgrade.h:260
#define strerror
Definition: port.h:230
#define fopen_priv(path, mode)
Definition: pg_upgrade.h:380
char * db_name
Definition: pg_upgrade.h:180
DbInfo * dbs
Definition: pg_upgrade.h:191
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:92

◆ check_hard_link()

void check_hard_link ( void  )

Definition at line 359 of file file.c.

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

Referenced by check_new_cluster().

360 {
361  char existing_file[MAXPGPATH];
362  char new_link_file[MAXPGPATH];
363 
364  snprintf(existing_file, sizeof(existing_file), "%s/PG_VERSION", old_cluster.pgdata);
365  snprintf(new_link_file, sizeof(new_link_file), "%s/PG_VERSION.linktest", new_cluster.pgdata);
366  unlink(new_link_file); /* might fail */
367 
368  if (link(existing_file, new_link_file) < 0)
369  pg_fatal("could not create hard link between old and new data directories: %s\n"
370  "In link mode the old and new data directories must be on the same file system.\n",
371  strerror(errno));
372 
373  unlink(new_link_file);
374 }
#define pg_fatal(...)
Definition: pg_rewind.h:37
ClusterInfo new_cluster
Definition: pg_upgrade.c:59
#define MAXPGPATH
ClusterInfo old_cluster
Definition: pg_upgrade.c:59
#define strerror
Definition: port.h:230
char * pgdata
Definition: pg_upgrade.h:261
int link(const char *src, const char *dst)
#define snprintf
Definition: port.h:217

◆ 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 point 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  */
222  strcmp(lib, "$libdir/plpython") == 0)
223  {
224  lib = "$libdir/plpython2";
225  llen = strlen(lib);
226  }
227 
228  strcpy(cmd, "LOAD '");
229  PQescapeStringConn(conn, cmd + strlen(cmd), lib, llen, NULL);
230  strcat(cmd, "'");
231 
232  res = PQexec(conn, cmd);
233 
234  if (PQresultStatus(res) != PGRES_COMMAND_OK)
235  {
236  found = true;
237  was_load_failure = true;
238 
239  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
240  pg_fatal("could not open file \"%s\": %s\n",
241  output_path, strerror(errno));
242  fprintf(script, _("could not load library \"%s\": %s"),
243  lib,
244  PQerrorMessage(conn));
245  }
246  else
247  was_load_failure = false;
248 
249  PQclear(res);
250  }
251 
252  if (was_load_failure)
253  fprintf(script, _("In database: %s\n"),
255  }
256 
257  PQfinish(conn);
258 
259  if (found)
260  {
261  fclose(script);
262  pg_log(PG_REPORT, "fatal\n");
263  pg_fatal("Your installation references loadable libraries that are missing from the\n"
264  "new installation. You can add these libraries to the new installation,\n"
265  "or remove the functions using them from the old installation. A list of\n"
266  "problem libraries is in the file:\n"
267  " %s\n\n", output_path);
268  }
269  else
270  check_ok();
271 }
char * name
Definition: pg_upgrade.h:301
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6744
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:37
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4231
#define fprintf
Definition: port.h:221
ExecStatusType PQresultStatus(const PGresult *res)
Definition: fe-exec.c:3178
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:3910
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:1920
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:230
#define fopen_priv(path, mode)
Definition: pg_upgrade.h:380
OSInfo os_info
Definition: pg_upgrade.c:61
char * db_name
Definition: pg_upgrade.h:180
PGresult * PQexec(PGconn *conn, const char *query)
Definition: fe-exec.c:2193
#define qsort(a, b, c, d)
Definition: port.h:505
DbInfo * dbs
Definition: pg_upgrade.h:191
#define snprintf
Definition: port.h:217
#define _(x)
Definition: elog.c:89

◆ check_new_cluster()

void check_new_cluster ( void  )

Definition at line 179 of file check.c.

References check_databases_are_compatible(), check_file_clone(), check_for_new_tablespace_dir(), 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().

180 {
182 
185 
187 
188  switch (user_opts.transfer_mode)
189  {
190  case TRANSFER_MODE_CLONE:
192  break;
193  case TRANSFER_MODE_COPY:
194  break;
195  case TRANSFER_MODE_LINK:
196  check_hard_link();
197  break;
198  }
199 
201 
203 
205 }
void check_file_clone(void)
Definition: file.c:317
void check_hard_link(void)
Definition: file.c:359
static void check_databases_are_compatible(void)
Definition: check.c:450
void check_loadable_libraries(void)
Definition: function.c:180
static void check_for_prepared_transactions(ClusterInfo *cluster)
Definition: check.c:758
ClusterInfo new_cluster
Definition: pg_upgrade.c:59
static void check_for_new_tablespace_dir(ClusterInfo *new_cluster)
Definition: check.c:489
static void check_is_install_user(ClusterInfo *cluster)
Definition: check.c:646
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:423
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 357 of file server.c.

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

Referenced by setup().

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

◆ cloneFile()

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

Definition at line 38 of file file.c.

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

Referenced by transfer_relfile().

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

◆ cluster_conn_opts()

PGresult char* cluster_conn_opts ( ClusterInfo cluster)

Definition at line 91 of file server.c.

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

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

92 {
93  static PQExpBuffer buf;
94 
95  if (buf == NULL)
96  buf = createPQExpBuffer();
97  else
98  resetPQExpBuffer(buf);
99 
100  if (cluster->sockdir)
101  {
102  appendPQExpBufferStr(buf, "--host ");
103  appendShellString(buf, cluster->sockdir);
104  appendPQExpBufferChar(buf, ' ');
105  }
106  appendPQExpBuffer(buf, "--port %d --username ", cluster->port);
108 
109  return buf->data;
110 }
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c: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:68
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_types_usage(), check_for_isn_and_int8_passing_mismatch(), check_for_pg_role_prefix(), check_for_prepared_transactions(), check_for_tables_with_oids(), check_for_user_defined_encoding_conversions(), check_for_user_defined_postfix_ops(), 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(), report_extension_updates(), 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, "%s", PQerrorMessage(conn));
34 
35  if (conn)
36  PQfinish(conn);
37 
38  printf(_("Failure, exiting\n"));
39  exit(1);
40  }
41 
43 
44  return conn;
45 }
char * PQerrorMessage(const PGconn *conn)
Definition: fe-connect.c:6744
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4231
#define printf(...)
Definition: port.h:223
PGconn * conn
Definition: streamutil.c:54
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...)
Definition: server.c:121
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:6691
static PGconn * get_db_conn(ClusterInfo *cluster, const char *db_name)
Definition: server.c:56
#define _(x)
Definition: elog.c:89

◆ copyFile()

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

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

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

void create_script_for_old_cluster_deletion ( char **  deletion_script_file_name)

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

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

◆ disable_old_cluster()

void disable_old_cluster ( void  )

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

706 {
707  char old_path[MAXPGPATH],
708  new_path[MAXPGPATH];
709 
710  /* rename pg_control so old server cannot be accidentally started */
711  prep_status("Adding \".old\" suffix to old global/pg_control");
712 
713  snprintf(old_path, sizeof(old_path), "%s/global/pg_control", old_cluster.pgdata);
714  snprintf(new_path, sizeof(new_path), "%s/global/pg_control.old", old_cluster.pgdata);
715  if (pg_mv_file(old_path, new_path) != 0)
716  pg_fatal("Unable to rename %s to %s.\n", old_path, new_path);
717  check_ok();
718 
719  pg_log(PG_REPORT, "\n"
720  "If you want to start the old cluster, you will need to remove\n"
721  "the \".old\" suffix from %s/global/pg_control.old.\n"
722  "Because \"link\" mode was used, the old cluster cannot be safely\n"
723  "started once the new cluster has been started.\n\n", old_cluster.pgdata);
724 }
#define pg_fatal(...)
Definition: pg_rewind.h:37
#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:1920
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:217

◆ 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:135
#define pg_fatal(...)
Definition: pg_rewind.h:37
Oid reloid
Definition: pg_upgrade.h:136
char * nspname
Definition: pg_upgrade.h:134
RelInfo * rels
Definition: pg_upgrade.h:147
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:186
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:180

◆ 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:91
LogOpts log_opts
Definition: util.c:17
Oid db_oid
Definition: pg_upgrade.h:179
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:1920
#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:284
#define UTILITY_LOG_FILE
Definition: pg_upgrade.h:31
char * db_name
Definition: pg_upgrade.h:180
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:81
#define GLOBALS_DUMP_FILE
Definition: pg_upgrade.h:26
DbInfo * dbs
Definition: pg_upgrade.h:191
#define snprintf
Definition: port.h:217
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:92
static char * connstr
Definition: pg_dumpall.c:62

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

◆ 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:191

◆ 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:3642
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:37
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4231
int PQntuples(const PGresult *res)
Definition: fe-exec.c:3248
#define FirstNormalObjectId
Definition: transam.h:197
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:180
DbInfo * dbs
Definition: pg_upgrade.h:191

◆ get_major_server_version()

uint32 get_major_server_version ( ClusterInfo cluster)

Definition at line 158 of file server.c.

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

Referenced by check_data_dir().

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

◆ get_sock_dir()

void get_sock_dir ( ClusterInfo cluster,
bool  live_check 
)

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

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

Referenced by main().

227 {
228  /*
229  * We unconditionally start/stop the new server because pg_resetwal -o set
230  * wal_level to 'minimum'. If the user is upgrading standby servers using
231  * the rsync instructions, they will need pg_upgrade to write its final
232  * WAL record showing wal_level as 'replica'.
233  */
235 
236  /* Create dummy large object permissions for old < PG 9.0? */
239 
240  /* Reindex hash indexes for old < 10.0 */
243 
245 
246  stop_postmaster(false);
247 }
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:334
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 report_extension_updates(ClusterInfo *cluster)
Definition: version.c:478
void stop_postmaster(bool in_atexit)
Definition: server.c:330
static pgpid_t start_postmaster(void)
Definition: pg_ctl.c:443

◆ linkFile()

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

Definition at line 147 of file file.c.

References link(), pg_fatal, and strerror.

Referenced by transfer_relfile().

149 {
150  if (link(src, dst) < 0)
151  pg_fatal("error while creating link for relation \"%s.%s\" (\"%s\" to \"%s\"): %s\n",
152  schemaName, relName, src, dst, strerror(errno));
153 }
#define pg_fatal(...)
Definition: pg_rewind.h:37
#define strerror
Definition: port.h:230
int link(const char *src, const char *dst)

◆ 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:3642
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:37
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4231
#define fprintf
Definition: port.h:221
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:1920
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:3356
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:230
#define fopen_priv(path, mode)
Definition: pg_upgrade.h:380
void report_status(eLogType type, const char *fmt,...) pg_attribute_printf(2
char * db_name
Definition: pg_upgrade.h:180
DbInfo * dbs
Definition: pg_upgrade.h:191
#define snprintf
Definition: port.h:217
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 449 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().

450 {
451  char output_path[MAXPGPATH];
452 
453  prep_status("Checking for invalid \"sql_identifier\" user columns");
454 
455  snprintf(output_path, sizeof(output_path), "tables_using_sql_identifier.txt");
456 
457  if (check_for_data_type_usage(cluster, "information_schema.sql_identifier",
458  output_path))
459  {
460  pg_log(PG_REPORT, "fatal\n");
461  pg_fatal("Your installation contains the \"sql_identifier\" data type in user tables.\n"
462  "The on-disk format for this data type has changed, so this\n"
463  "cluster cannot currently be upgraded. You can\n"
464  "drop the problem columns and restart the upgrade.\n"
465  "A list of the problem columns is in the file:\n"
466  " %s\n\n", output_path);
467  }
468  else
469  check_ok();
470 }
#define pg_fatal(...)
Definition: pg_rewind.h:37
#define MAXPGPATH
void prep_status(const char *fmt,...) pg_attribute_printf(1
static void check_ok(void)
Definition: initdb.c:1920
bool check_for_data_type_usage(ClusterInfo *cluster, const char *type_name, const char *output_path)
Definition: version.c:241
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
#define snprintf
Definition: port.h:217

◆ old_9_3_check_for_line_data_type_usage()

void old_9_3_check_for_line_data_type_usage ( ClusterInfo cluster)

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

269 {
270  char output_path[MAXPGPATH];
271 
272  prep_status("Checking for incompatible \"line\" data type");
273 
274  snprintf(output_path, sizeof(output_path), "tables_using_line.txt");
275 
276  if (check_for_data_type_usage(cluster, "pg_catalog.line", output_path))
277  {
278  pg_log(PG_REPORT, "fatal\n");
279  pg_fatal("Your installation contains the \"line\" data type in user tables.\n"
280  "This data type changed its internal and input/output format\n"
281  "between your old and new versions so this\n"
282  "cluster cannot currently be upgraded. You can\n"
283  "drop the problem columns and restart the upgrade.\n"
284  "A list of the problem columns is in the file:\n"
285  " %s\n\n", output_path);
286  }
287  else
288  check_ok();
289 }
#define pg_fatal(...)
Definition: pg_rewind.h:37
#define MAXPGPATH
void prep_status(const char *fmt,...) pg_attribute_printf(1
static void check_ok(void)
Definition: initdb.c:1920
bool check_for_data_type_usage(ClusterInfo *cluster, const char *type_name, const char *output_path)
Definition: version.c:241
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
#define snprintf
Definition: port.h:217

◆ old_9_6_check_for_unknown_data_type_usage()

void old_9_6_check_for_unknown_data_type_usage ( ClusterInfo cluster)

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

307 {
308  char output_path[MAXPGPATH];
309 
310  prep_status("Checking for invalid \"unknown\" user columns");
311 
312  snprintf(output_path, sizeof(output_path), "tables_using_unknown.txt");
313 
314  if (check_for_data_type_usage(cluster, "pg_catalog.unknown", output_path))
315  {
316  pg_log(PG_REPORT, "fatal\n");
317  pg_fatal("Your installation contains the \"unknown\" data type in user tables.\n"
318  "This data type is no longer allowed in tables, so this\n"
319  "cluster cannot currently be upgraded. You can\n"
320  "drop the problem columns and restart the upgrade.\n"
321  "A list of the problem columns is in the file:\n"
322  " %s\n\n", output_path);
323  }
324  else
325  check_ok();
326 }
#define pg_fatal(...)
Definition: pg_rewind.h:37
#define MAXPGPATH
void prep_status(const char *fmt,...) pg_attribute_printf(1
static void check_ok(void)
Definition: initdb.c:1920
bool check_for_data_type_usage(ClusterInfo *cluster, const char *type_name, const char *output_path)
Definition: version.c:241
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
#define snprintf
Definition: port.h:217

◆ old_9_6_invalidate_hash_indexes()

void old_9_6_invalidate_hash_indexes ( ClusterInfo cluster,
bool  check_mode 
)

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

335 {
336  int dbnum;
337  FILE *script = NULL;
338  bool found = false;
339  char *output_path = "reindex_hash.sql";
340 
341  prep_status("Checking for hash indexes");
342 
343  for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
344  {
345  PGresult *res;
346  bool db_used = false;
347  int ntups;
348  int rowno;
349  int i_nspname,
350  i_relname;
351  DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
352  PGconn *conn = connectToServer(cluster, active_db->db_name);
353 
354  /* find hash indexes */
355  res = executeQueryOrDie(conn,
356  "SELECT n.nspname, c.relname "
357  "FROM pg_catalog.pg_class c, "
358  " pg_catalog.pg_index i, "
359  " pg_catalog.pg_am a, "
360  " pg_catalog.pg_namespace n "
361  "WHERE i.indexrelid = c.oid AND "
362  " c.relam = a.oid AND "
363  " c.relnamespace = n.oid AND "
364  " a.amname = 'hash'"
365  );
366 
367  ntups = PQntuples(res);
368  i_nspname = PQfnumber(res, "nspname");
369  i_relname = PQfnumber(res, "relname");
370  for (rowno = 0; rowno < ntups; rowno++)
371  {
372  found = true;
373  if (!check_mode)
374  {
375  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
376  pg_fatal("could not open file \"%s\": %s\n", output_path,
377  strerror(errno));
378  if (!db_used)
379  {
380  PQExpBufferData connectbuf;
381 
382  initPQExpBuffer(&connectbuf);
383  appendPsqlMetaConnect(&connectbuf, active_db->db_name);
384  fputs(connectbuf.data, script);
385  termPQExpBuffer(&connectbuf);
386  db_used = true;
387  }
388  fprintf(script, "REINDEX INDEX %s.%s;\n",
389  quote_identifier(PQgetvalue(res, rowno, i_nspname)),
390  quote_identifier(PQgetvalue(res, rowno, i_relname)));
391  }
392  }
393 
394  PQclear(res);
395 
396  if (!check_mode && db_used)
397  {
398  /* mark hash indexes as invalid */
400  "UPDATE pg_catalog.pg_index i "
401  "SET indisvalid = false "
402  "FROM pg_catalog.pg_class c, "
403  " pg_catalog.pg_am a, "
404  " pg_catalog.pg_namespace n "
405  "WHERE i.indexrelid = c.oid AND "
406  " c.relam = a.oid AND "
407  " c.relnamespace = n.oid AND "
408  " a.amname = 'hash'"));
409  }
410 
411  PQfinish(conn);
412  }
413 
414  if (script)
415  fclose(script);
416 
417  if (found)
418  {
419  report_status(PG_WARNING, "warning");
420  if (check_mode)
421  pg_log(PG_WARNING, "\n"
422  "Your installation contains hash indexes. These indexes have different\n"
423  "internal formats between your old and new clusters, so they must be\n"
424  "reindexed with the REINDEX command. After upgrading, you will be given\n"
425  "REINDEX instructions.\n\n");
426  else
427  pg_log(PG_WARNING, "\n"
428  "Your installation contains hash indexes. These indexes have different\n"
429  "internal formats between your old and new clusters, so they must be\n"
430  "reindexed with the REINDEX command. The file\n"
431  " %s\n"
432  "when executed by psql by the database superuser will recreate all invalid\n"
433  "indexes; until then, none of these indexes will be used.\n\n",
434  output_path);
435  }
436  else
437  check_ok();
438 }
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:11374
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3642
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:37
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4231
int PQntuples(const PGresult *res)
Definition: fe-exec.c:3248
#define fprintf
Definition: port.h:221
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:1920
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:3356
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:230
#define fopen_priv(path, mode)
Definition: pg_upgrade.h:380
void report_status(eLogType type, const char *fmt,...) pg_attribute_printf(2
char * db_name
Definition: pg_upgrade.h:180
DbInfo * dbs
Definition: pg_upgrade.h:191
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:92

◆ output_check_banner()

void output_check_banner ( bool  live_check)

Definition at line 65 of file check.c.

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

Referenced by main().

66 {
67  if (user_opts.check && live_check)
68  {
70  "Performing Consistency Checks on Old Live Server\n"
71  "------------------------------------------------\n");
72  }
73  else
74  {
76  "Performing Consistency Checks\n"
77  "-----------------------------\n");
78  }
79 }
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 *  deletion_script_file_name)

Definition at line 251 of file check.c.

References appendPQExpBufferChar(), appendPQExpBufferStr(), appendShellString(), ClusterInfo::bindir, PQExpBufferData::data, initPQExpBuffer(), new_cluster, os_info, pg_log(), PG_REPORT, termPQExpBuffer(), OSInfo::user, and OSInfo::user_specified.

Referenced by main().

252 {
253  PQExpBufferData user_specification;
254 
255  initPQExpBuffer(&user_specification);
257  {
258  appendPQExpBufferStr(&user_specification, "-U ");
259  appendShellString(&user_specification, os_info.user);
260  appendPQExpBufferChar(&user_specification, ' ');
261  }
262 
264  "Optimizer statistics are not transferred by pg_upgrade.\n"
265  "Once you start the new server, consider running:\n"
266  " %s/vacuumdb %s--all --analyze-in-stages\n\n", new_cluster.bindir, user_specification.data);
267 
268  if (deletion_script_file_name)
270  "Running this script will delete the old cluster's data files:\n"
271  " %s\n",
272  deletion_script_file_name);
273  else
275  "Could not create a script to delete the old cluster's data files\n"
276  "because user-defined tablespaces or the new cluster's data directory\n"
277  "exist in the old cluster directory. The old cluster's contents must\n"
278  "be deleted manually.\n");
279 
280  termPQExpBuffer(&user_specification);
281 }
void termPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:131
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
Definition: pqexpbuffer.c:369
bool user_specified
Definition: pg_upgrade.h:312
ClusterInfo new_cluster
Definition: pg_upgrade.c:59
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
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
OSInfo os_info
Definition: pg_upgrade.c:61
char * user
Definition: pg_upgrade.h:311
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:92

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

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

◆ pid_lock_file_exists()

bool pid_lock_file_exists ( const char *  datadir)

Definition at line 220 of file exec.c.

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

Referenced by setup().

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

◆ 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:38
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 11374 of file ruleutils.c.

11375 {
11376  /*
11377  * Can avoid quoting if ident starts with a lowercase letter or underscore
11378  * and contains only lowercase letters, digits, and underscores, *and* is
11379  * not any SQL keyword. Otherwise, supply quotes.
11380  */
11381  int nquotes = 0;
11382  bool safe;
11383  const char *ptr;
11384  char *result;
11385  char *optr;
11386 
11387  /*
11388  * would like to use <ctype.h> macros here, but they might yield unwanted
11389  * locale-specific results...
11390  */
11391  safe = ((ident[0] >= 'a' && ident[0] <= 'z') || ident[0] == '_');
11392 
11393  for (ptr = ident; *ptr; ptr++)
11394  {
11395  char ch = *ptr;
11396 
11397  if ((ch >= 'a' && ch <= 'z') ||
11398  (ch >= '0' && ch <= '9') ||
11399  (ch == '_'))
11400  {
11401  /* okay */
11402  }
11403  else
11404  {
11405  safe = false;
11406  if (ch == '"')
11407  nquotes++;
11408  }
11409  }
11410 
11412  safe = false;
11413 
11414  if (safe)
11415  {
11416  /*
11417  * Check for keyword. We quote keywords except for unreserved ones.
11418  * (In some cases we could avoid quoting a col_name or type_func_name
11419  * keyword, but it seems much harder than it's worth to tell that.)
11420  *
11421  * Note: ScanKeywordLookup() does case-insensitive comparison, but
11422  * that's fine, since we already know we have all-lower-case.
11423  */
11424  int kwnum = ScanKeywordLookup(ident, &ScanKeywords);
11425 
11426  if (kwnum >= 0 && ScanKeywordCategories[kwnum] != UNRESERVED_KEYWORD)
11427  safe = false;
11428  }
11429 
11430  if (safe)
11431  return ident; /* no change needed */
11432 
11433  result = (char *) palloc(strlen(ident) + nquotes + 2 + 1);
11434 
11435  optr = result;
11436  *optr++ = '"';
11437  for (ptr = ident; *ptr; ptr++)
11438  {
11439  char ch = *ptr;
11440 
11441  if (ch == '"')
11442  *optr++ = '"';
11443  *optr++ = ch;
11444  }
11445  *optr++ = '"';
11446  *optr = '\0';
11447 
11448  return result;
11449 }
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:318
void * palloc(Size size)
Definition: mcxt.c:1062
int ScanKeywordLookup(const char *str, const ScanKeywordList *keywords)
Definition: kwlookup.c:38

◆ reap_child()

bool reap_child ( bool  wait_for_child)

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

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

◆ report_clusters_compatible()

void report_clusters_compatible ( void  )

Definition at line 209 of file check.c.

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

Referenced by main().

210 {
211  if (user_opts.check)
212  {
213  pg_log(PG_REPORT, "\n*Clusters are compatible*\n");
214  /* stops new cluster */
215  stop_postmaster(false);
216  exit(0);
217  }
218 
219  pg_log(PG_REPORT, "\n"
220  "If pg_upgrade fails after this point, you must re-initdb the\n"
221  "new cluster before continuing.\n");
222 }
UserOpts user_opts
Definition: option.c:30
void stop_postmaster(bool in_atexit)
Definition: server.c:330
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
bool check
Definition: pg_upgrade.h:292

◆ report_extension_updates()

void report_extension_updates ( ClusterInfo cluster)

Definition at line 478 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_REPORT, PQclear(), PQfinish(), PQfnumber(), PQgetvalue(), PQntuples(), prep_status(), quote_identifier(), report_status(), strerror, and termPQExpBuffer().

Referenced by issue_warnings_and_set_wal_level().

479 {
480  int dbnum;
481  FILE *script = NULL;
482  bool found = false;
483  char *output_path = "update_extensions.sql";
484 
485  prep_status("Checking for extension updates");
486 
487  for (dbnum = 0; dbnum < cluster->dbarr.ndbs; dbnum++)
488  {
489  PGresult *res;
490  bool db_used = false;
491  int ntups;
492  int rowno;
493  int i_name;
494  DbInfo *active_db = &cluster->dbarr.dbs[dbnum];
495  PGconn *conn = connectToServer(cluster, active_db->db_name);
496 
497  /* find extensions needing updates */
498  res = executeQueryOrDie(conn,
499  "SELECT name "
500  "FROM pg_available_extensions "
501  "WHERE installed_version != default_version"
502  );
503 
504  ntups = PQntuples(res);
505  i_name = PQfnumber(res, "name");
506  for (rowno = 0; rowno < ntups; rowno++)
507  {
508  found = true;
509 
510  if (script == NULL && (script = fopen_priv(output_path, "w")) == NULL)
511  pg_fatal("could not open file \"%s\": %s\n", output_path,
512  strerror(errno));
513  if (!db_used)
514  {
515  PQExpBufferData connectbuf;
516 
517  initPQExpBuffer(&connectbuf);
518  appendPsqlMetaConnect(&connectbuf, active_db->db_name);
519  fputs(connectbuf.data, script);
520  termPQExpBuffer(&connectbuf);
521  db_used = true;
522  }
523  fprintf(script, "ALTER EXTENSION %s UPDATE;\n",
524  quote_identifier(PQgetvalue(res, rowno, i_name)));
525  }
526 
527  PQclear(res);
528 
529  PQfinish(conn);
530  }
531 
532  if (script)
533  fclose(script);
534 
535  if (found)
536  {
537  report_status(PG_REPORT, "notice");
538  pg_log(PG_REPORT, "\n"
539  "Your installation contains extensions that should be updated\n"
540  "with the ALTER EXTENSION command. The file\n"
541  " %s\n"
542  "when executed by psql by the database superuser will update\n"
543  "these extensions.\n\n",
544  output_path);
545  }
546  else
547  check_ok();
548 }
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:11374
char * PQgetvalue(const PGresult *res, int tup_num, int field_num)
Definition: fe-exec.c:3642
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:37
void PQfinish(PGconn *conn)
Definition: fe-connect.c:4231
int PQntuples(const PGresult *res)
Definition: fe-exec.c:3248
#define fprintf
Definition: port.h:221
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:1920
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:3356
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:230
#define fopen_priv(path, mode)
Definition: pg_upgrade.h:380
void report_status(eLogType type, const char *fmt,...) pg_attribute_printf(2
char * db_name
Definition: pg_upgrade.h:180
DbInfo * dbs
Definition: pg_upgrade.h:191
void initPQExpBuffer(PQExpBuffer str)
Definition: pqexpbuffer.c:92

◆ report_status()

◆ rewriteVisibilityMap()

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

Definition at line 173 of file file.c.

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

Referenced by transfer_relfile().

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

◆ start_postmaster()

bool start_postmaster ( ClusterInfo cluster,
bool  report_and_exit_on_error 
)

Definition at line 197 of file server.c.

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

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

◆ stop_postmaster()