postgresql pg_upgrade源码阅读--doing

pg_upgrade升级时支持如下参数

c 复制代码
	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}
	};
c 复制代码
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;
}

pg_dump在升级中的使用
pg_dump

相关推荐
苦学编程的谢2 小时前
Redis_6_String
数据库·redis·缓存
秋已杰爱2 小时前
技术准备十:etcd
数据库·etcd
研究司马懿2 小时前
【ETCD】ETCD集群部署(TLS)
数据库·chrome·云原生·自动化·运维开发·etcd
行者游学2 小时前
ETCD 备份脚本
数据库·etcd
研究司马懿2 小时前
【ETCD】ETCD单节点二进制部署(TLS)
数据库·chrome·云原生·运维开发·etcd·argocd·gitops
行者游学2 小时前
ETCD 压力测试脚本
数据库·压力测试·etcd
春生野草3 小时前
SpringBoot配置文件
java·数据库·spring boot
奇点 ♡3 小时前
MySQL基础题
数据库·sql·mysql
唐古乌梁海4 小时前
【mysql】MySQL 数据库迁移
数据库·mysql·adb