47#include "catalog/pg_class_d.h"
59#define RESTORE_TRANSACTION_SIZE 1000
92 char *deletion_script_file_name = NULL;
93 bool migrate_logical_slots;
117 pg_fatal(
"could not read permissions of directory \"%s\": %m",
150 "Performing Upgrade\n"
151 "------------------");
199 "\"%s/pg_resetwal\" -o %u \"%s\"",
231 if (migrate_logical_slots)
244 "\"%s/initdb\" --sync-only %s \"%s\" --sync-method %s",
247 "--no-sync-data-files" :
"",
264 pg_free(deletion_script_file_name);
281 time_t run_time = time(NULL);
291 pg_fatal(
"directory path for new cluster is too long");
295 tt = (time_t) time.tv_sec;
296 strftime(timebuf,
sizeof(timebuf),
"%Y%m%dT%H%M%S", localtime(&tt));
298 snprintf(timebuf + strlen(timebuf),
sizeof(timebuf) - strlen(timebuf),
299 ".%03d", (
int) (time.tv_usec / 1000));
304 pg_fatal(
"directory path for new cluster is too long");
311 pg_fatal(
"directory path for new cluster is too long");
318 pg_fatal(
"directory path for new cluster is too long");
333 len =
snprintf(filename_path,
sizeof(filename_path),
"%s/%s",
335 if (
len >=
sizeof(filename_path))
336 pg_fatal(
"directory path for new cluster is too long");
339 pg_fatal(
"could not open log file \"%s\": %m", filename_path);
344 len =
snprintf(filename_path,
sizeof(filename_path),
"%s/%s",
346 if (
len >=
sizeof(filename_path))
347 pg_fatal(
"directory path for new cluster is too long");
348 if ((fp =
fopen_priv(filename_path,
"a")) == NULL)
349 pg_fatal(
"could not write to log file \"%s\": %m", filename_path);
352 "-----------------------------------------------------------------\n"
353 " pg_upgrade run on %s"
354 "-----------------------------------------------------------------\n\n",
380 pg_fatal(
"%s: could not find own program executable",
argv0);
406 pg_fatal(
"There seems to be a postmaster servicing the old cluster.\n"
407 "Please shutdown that postmaster and try again.");
419 pg_fatal(
"There seems to be a postmaster servicing the new cluster.\n"
420 "Please shutdown that postmaster and try again.");
431 bool new_char_signedness;
445 prep_status(
"Setting the default char signedness for new cluster");
448 "\"%s/pg_resetwal\" --char-signedness %s \"%s\"",
450 new_char_signedness ?
"signed" :
"unsigned",
467 PGconn *conn_new_template1;
468 char *datcollate_literal;
469 char *datctype_literal;
470 char *datlocale_literal = NULL;
473 prep_status(
"Setting locale and encoding for new cluster");
480 strlen(
locale->db_collate));
483 strlen(
locale->db_ctype));
488 strlen(
locale->db_locale));
490 datlocale_literal =
"NULL";
495 "UPDATE pg_catalog.pg_database "
496 " SET encoding = %d, "
497 " datlocprovider = '%c', "
501 " WHERE datname = 'template0' ",
509 "UPDATE pg_catalog.pg_database "
510 " SET encoding = %d, "
511 " datlocprovider = '%c', "
514 " daticulocale = %s "
515 " WHERE datname = 'template0' ",
523 "UPDATE pg_catalog.pg_database "
524 " SET encoding = %d, "
527 " WHERE datname = 'template0' ",
551 prep_status(
"Analyzing all rows in the new cluster");
553 "\"%s/vacuumdb\" %s --all --analyze %s",
564 prep_status(
"Freezing all rows in the new cluster");
566 "\"%s/vacuumdb\" %s --all --freeze %s",
584 prep_status(
"Restoring global objects in the new cluster");
599 PGconn *conn_new_template1;
624 const char *create_opts;
627 if (strcmp(old_db->
db_name,
"template1") != 0)
639 create_opts =
"--clean --create";
645 "\"%s/pg_restore\" %s %s --exit-on-error --verbose "
646 "--transaction-size=%d "
647 "--dbname postgres \"%s/%s\"",
663 const char *create_opts;
667 if (strcmp(old_db->
db_name,
"template1") == 0)
679 if (strcmp(old_db->
db_name,
"postgres") == 0)
680 create_opts =
"--clean --create";
682 create_opts =
"--create";
694 txn_size =
Max(txn_size, 10);
699 "\"%s/pg_restore\" %s %s --exit-on-error --verbose "
700 "--transaction-size=%d "
701 "--dbname template1 \"%s/%s\"",
739 if (!
rmtree(new_path, rmtopdir))
740 pg_fatal(
"could not delete directory \"%s\"", new_path);
759 prep_status(
"Copying old %s to new server", old_subdir);
763 "cp -Rf \"%s\" \"%s\"",
766 "xcopy /e /y /q /r \"%s\" \"%s\\\"",
781 "pg_clog" :
"pg_xact",
783 "pg_clog" :
"pg_xact");
787 "\"%s/pg_resetwal\" -f -u %u \"%s\"",
793 prep_status(
"Setting next transaction ID and epoch for new cluster");
795 "\"%s/pg_resetwal\" -f -x %u \"%s\"",
799 "\"%s/pg_resetwal\" -f -e %u \"%s\"",
804 "\"%s/pg_resetwal\" -f -c %u,%u \"%s\"",
823 prep_status(
"Setting next multixact ID and offset for new cluster");
830 "\"%s/pg_resetwal\" -O %" PRIu64
" -m %u,%u \"%s\"",
864 oldstMulti = nxtmulti;
886 prep_status(
"Setting next multixact ID and offset for new cluster");
888 "\"%s/pg_resetwal\" -O %" PRIu64
" -m %u,%u \"%s\"",
890 nxtmxoff, nxtmulti, oldstMulti,
939 prep_status(
"Setting frozenxid and minmxid counters in new cluster");
941 prep_status(
"Setting minmxid counter in new cluster");
948 "UPDATE pg_catalog.pg_database "
949 "SET datfrozenxid = '%u'",
954 "UPDATE pg_catalog.pg_database "
955 "SET datminmxid = '%u'",
960 "SELECT datname, datallowconn "
961 "FROM pg_catalog.pg_database");
964 i_datallowconn =
PQfnumber(dbres,
"datallowconn");
967 for (dbnum = 0; dbnum < ntups; dbnum++)
981 "ALTER DATABASE %s ALLOW_CONNECTIONS = true",
989 "UPDATE pg_catalog.pg_class "
990 "SET relfrozenxid = '%u' "
1000 "UPDATE pg_catalog.pg_class "
1001 "SET relminmxid = '%u' "
1003 "WHERE relkind IN ("
1013 "ALTER DATABASE %s ALLOW_CONNECTIONS = false",
1042 if (slot_arr->
nslots == 0)
1050 for (
int slotnum = 0; slotnum < slot_arr->
nslots; slotnum++)
1057 "pg_catalog.pg_create_logical_replication_slot(");
1063 slot_info->
two_phase ?
"true" :
"false",
1064 slot_info->
failover ?
"true" :
"false");
1092 PGconn *conn_new_template1;
1094 prep_status(
"Creating the replication conflict detection slot");
1097 PQclear(
executeQueryOrDie(conn_new_template1,
"SELECT pg_catalog.binary_upgrade_create_conflict_detection_slot()"));
bool exec_prog(const char *log_filename, const char *opt_log_file, bool report_error, bool exit_on_error, const char *fmt,...)
bool pid_lock_file_exists(const char *datadir)
void verify_directories(void)
bool reap_child(bool wait_for_child)
void parallel_exec_prog(const char *log_file, const char *opt_log_file, const char *fmt,...)
#define PG_TEXTDOMAIN(domain)
TransactionId MultiXactId
void check_cluster_versions(void)
void issue_warnings_and_set_wal_level(void)
void check_cluster_compatibility(void)
void check_new_cluster(void)
void report_clusters_compatible(void)
void create_script_for_old_cluster_deletion(char **deletion_script_file_name)
void check_and_dump_old_cluster(void)
void output_completion_banner(char *deletion_script_file_name)
void output_check_banner(void)
int find_my_exec(const char *argv0, char *retpath)
void set_pglocale_pgservice(const char *argv0, const char *app)
void disable_old_cluster(transferMode transfer_mode)
#define fprintf(file, fmt, msg)
void PQfinish(PGconn *conn)
void PQfreemem(void *ptr)
int PQfnumber(const PGresult *res, const char *field_name)
char * PQescapeLiteral(PGconn *conn, const char *str, size_t len)
char * pg_strdup(const char *in)
void * pg_malloc0(size_t size)
bool GetDataDirectoryCreatePerm(const char *dataDir)
#define PG_MODE_MASK_OWNER
Assert(PointerIsAligned(start, uint64))
int count_old_cluster_logical_slots(void)
void get_db_rel_and_slot_infos(ClusterInfo *cluster)
static void check_ok(void)
void pg_logging_init(const char *argv0)
MultiXactOffset rewrite_multixacts(MultiXactId from_multi, MultiXactId to_multi)
static void adjust_data_dir(void)
static pid_t start_postmaster(void)
static void create_logical_replication_slots(void)
static void set_frozenxids(bool minmxid_only)
static void make_outputdirs(char *pgdata)
static void prepare_new_cluster(void)
static void create_conflict_detection_slot(void)
int main(int argc, char **argv)
static void copy_subdir_files(const char *old_subdir, const char *new_subdir)
static void set_new_cluster_char_signedness(void)
static void create_new_objects(void)
static void remove_new_subdir(const char *subdir, bool rmtopdir)
static void copy_xact_xlog_xid(void)
static void set_locale_and_encoding(void)
static void setup(char *argv0)
#define RESTORE_TRANSACTION_SIZE
static void prepare_new_globals(void)
void transfer_all_new_tablespaces(DbInfoArr *old_db_arr, DbInfoArr *new_db_arr, char *old_pgdata, char *new_pgdata)
#define SERVER_START_LOG_FILE
void check_pghost_envvar(void)
#define MULTIXACT_FORMATCHANGE_CAT_VER
PGresult char * cluster_conn_opts(ClusterInfo *cluster)
PGconn * connectToServer(ClusterInfo *cluster, const char *db_name)
#define MULTIXACTOFFSET_FORMATCHANGE_CAT_VER
#define GLOBALS_DUMP_FILE
#define DB_DUMP_LOG_FILE_MASK
void cleanup_output_dirs(void)
void void pg_log(eLogType type, const char *fmt,...) pg_attribute_printf(2
PGresult * executeQueryOrDie(PGconn *conn, const char *fmt,...) pg_attribute_printf(2
void void prep_status_progress(const char *fmt,...) pg_attribute_printf(1
void void pg_noreturn void void end_progress_output(void)
#define fopen_priv(path, mode)
#define GET_MAJOR_VERSION(v)
void stop_postmaster(bool in_atexit)
void prep_status(const char *fmt,...) pg_attribute_printf(1
#define INTERNAL_LOG_FILE
#define DB_DUMP_FILE_MASK
char * last_dir_separator(const char *filename)
void canonicalize_path(char *path)
PQExpBuffer createPQExpBuffer(void)
void resetPQExpBuffer(PQExpBuffer str)
void appendPQExpBuffer(PQExpBuffer str, const char *fmt,...)
void destroyPQExpBuffer(PQExpBuffer str)
void appendPQExpBufferStr(PQExpBuffer str, const char *data)
void get_restricted_token(void)
bool rmtree(const char *path, bool rmtopdir)
const char * quote_identifier(const char *ident)
void parseCommandLine(int argc, char *argv[])
void get_sock_dir(ClusterInfo *cluster)
void appendStringLiteralConn(PQExpBuffer buf, const char *str, PGconn *conn)
bool sub_retain_dead_tuples
bool default_char_signedness
LogicalSlotInfoArr slot_arr
transferMode transfer_mode
int gettimeofday(struct timeval *tp, void *tzp)