postgresql pg_upgrade源码阅读--doing
pg_upgrade升级时支持如下参数
static struct option long_options[] = {{"old-datadir", required_argument, NULL, 'd'}, //旧版本数据目录{"new-datadir", required_argument, NULL, 'D'}, //新版本数据目录{"old-bindir", required_argument, NULL, 'b'}, //旧版本bin目录{"new-bindir", required_argument, NULL, 'B'}, //新版本bin目录{"no-sync", no_argument, NULL, 'N'}, //不同步{"old-options", required_argument, NULL, 'o'}, //旧版本数据目录{"new-options", required_argument, NULL, 'O'}, //旧版本数据目录{"old-port", required_argument, NULL, 'p'}, //旧版本连接的端口号{"new-port", required_argument, NULL, 'P'}, //新版本连接的端口号{"username", required_argument, NULL, 'U'},{"check", no_argument, NULL, 'c'},{"link", no_argument, NULL, 'k'},{"retain", no_argument, NULL, 'r'},{"jobs", required_argument, NULL, 'j'}, //导入导出时并行的进程数{"socketdir", required_argument, NULL, 's'},{"verbose", no_argument, NULL, 'v'},{"clone", no_argument, NULL, 1},{"copy", no_argument, NULL, 2},{"copy-file-range", no_argument, NULL, 3},{"sync-method", required_argument, NULL, 4},{"no-statistics", no_argument, NULL, 5},{"set-char-signedness", required_argument, NULL, 6},{"swap", no_argument, NULL, 7},{NULL, 0, NULL, 0}};
int
main(int argc, char **argv)
{char *deletion_script_file_name = NULL;//配置日志的颜色输出pg_logging_init(argv[0]);set_pglocale_pgservice(argv[0], PG_TEXTDOMAIN("pg_upgrade"));/* Set default restrictive mask until new cluster permissions are read */umask(PG_MODE_MASK_OWNER);parseCommandLine(argc, argv);get_restricted_token();//获取实际的old_cluster->pgdata new_cluster->pgdata,通过postgres执行data_directory获取adjust_data_dir(&old_cluster);adjust_data_dir(&new_cluster);//设置对data目录的访问权限if (!GetDataDirectoryCreatePerm(new_cluster.pgdata))pg_fatal("could not read permissions of directory \"%s\": %m",new_cluster.pgdata);umask(pg_mode_mask);//创建升级中的数据目录,pg_upgrade_output.d等make_outputdirs(new_cluster.pgdata);// 检查新旧数据库的bin,data,检查是新旧数据库在运行setup(argv[0]);output_check_banner();//检查新旧集群的版本,旧版本<9.2不能升级,新版本的大版本要与pg_upgrade的版本一致,新旧版本的版本号与pg_ctl返回的要一致//旧版本不能大于新版本check_cluster_versions();//获取sock路径get_sock_dir(&old_cluster);get_sock_dir(&new_cluster);//检查pg_control中数据是否兼容check_cluster_compatibility();// 检查新旧库的兼容,pg_dumpall和pg_dump 旧库中的数据check_and_dump_old_cluster();/* -- NEW -- */start_postmaster(&new_cluster, true);check_new_cluster();report_clusters_compatible();pg_log(PG_REPORT,"\n""Performing Upgrade\n""------------------");set_locale_and_encoding();prepare_new_cluster();stop_postmaster(false);/** Destructive Changes to New Cluster*/copy_xact_xlog_xid();set_new_cluster_char_signedness();/* New now using xids of the old system *//* -- NEW -- */start_postmaster(&new_cluster, true);prepare_new_globals();create_new_objects();stop_postmaster(false);/** Most failures happen in create_new_objects(), which has completed at* this point. We do this here because it is just before file transfer,* which for --link will make it unsafe to start the old cluster once the* new cluster is started, and for --swap will make it unsafe to start the* old cluster at all.*/if (user_opts.transfer_mode == TRANSFER_MODE_LINK ||user_opts.transfer_mode == TRANSFER_MODE_SWAP)disable_old_cluster(user_opts.transfer_mode);transfer_all_new_tablespaces(&old_cluster.dbarr, &new_cluster.dbarr,old_cluster.pgdata, new_cluster.pgdata);/** Assuming OIDs are only used in system tables, there is no need to* restore the OID counter because we have not transferred any OIDs from* the old system, but we do it anyway just in case. We do it late here* because there is no need to have the schema load use new oids.*/prep_status("Setting next OID for new cluster");exec_prog(UTILITY_LOG_FILE, NULL, true, true,"\"%s/pg_resetwal\" -o %u \"%s\"",new_cluster.bindir, old_cluster.controldata.chkpnt_nxtoid,new_cluster.pgdata);check_ok();/** Migrate the logical slots to the new cluster. Note that we need to do* this after resetting WAL because otherwise the required WAL would be* removed and slots would become unusable. There is a possibility that* background processes might generate some WAL before we could create the* slots in the new cluster but we can ignore that WAL as that won't be* required downstream.*/if (count_old_cluster_logical_slots()){start_postmaster(&new_cluster, true);create_logical_replication_slots();stop_postmaster(false);}if (user_opts.do_sync){prep_status("Sync data directory to disk");exec_prog(UTILITY_LOG_FILE, NULL, true, true,"\"%s/initdb\" --sync-only %s \"%s\" --sync-method %s",new_cluster.bindir,(user_opts.transfer_mode == TRANSFER_MODE_SWAP) ?"--no-sync-data-files" : "",new_cluster.pgdata,user_opts.sync_method);check_ok();}create_script_for_old_cluster_deletion(&deletion_script_file_name);issue_warnings_and_set_wal_level();pg_log(PG_REPORT,"\n""Upgrade Complete\n""----------------");output_completion_banner(deletion_script_file_name);pg_free(deletion_script_file_name);cleanup_output_dirs();return 0;
}
