DWORD win32_transfer_all_new_dbs(transfer_thread_arg *args) { transfer_all_new_dbs(args->old_db_arr, args->new_db_arr, args->old_pgdata, args->new_pgdata, args->old_tablespace); /* terminates thread */ return 0; }
int main(int argc, char **argv) { char *sequence_script_file_name = NULL; char *deletion_script_file_name = NULL; bool live_check = false; parseCommandLine(argc, argv); output_check_banner(&live_check); setup(argv[0], live_check); check_cluster_versions(); check_cluster_compatibility(live_check); check_old_cluster(live_check, &sequence_script_file_name); /* -- NEW -- */ start_postmaster(&new_cluster); check_new_cluster(); report_clusters_compatible(); pg_log(PG_REPORT, "\nPerforming Upgrade\n"); pg_log(PG_REPORT, "------------------\n"); disable_old_cluster(); prepare_new_cluster(); stop_postmaster(false); /* * Destructive Changes to New Cluster */ copy_clog_xlog_xid(); /* New now using xids of the old system */ /* -- NEW -- */ start_postmaster(&new_cluster); prepare_new_databases(); create_new_objects(); stop_postmaster(false); transfer_all_new_dbs(&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(true, SYSTEMQUOTE "\"%s/pg_resetxlog\" -o %u \"%s\" > " DEVNULL SYSTEMQUOTE, new_cluster.bindir, old_cluster.controldata.chkpnt_nxtoid, new_cluster.pgdata); check_ok(); create_script_for_old_cluster_deletion(&deletion_script_file_name); issue_warnings(sequence_script_file_name); pg_log(PG_REPORT, "\nUpgrade complete\n"); pg_log(PG_REPORT, "----------------\n"); output_completion_banner(deletion_script_file_name); pg_free(deletion_script_file_name); pg_free(sequence_script_file_name); cleanup(); return 0; }
int main(int argc, char **argv) { char *sequence_script_file_name = NULL; char *analyze_script_file_name = NULL; char *deletion_script_file_name = NULL; bool live_check = false; parseCommandLine(argc, argv); adjust_data_dir(&old_cluster); adjust_data_dir(&new_cluster); output_check_banner(&live_check); setup(argv[0], live_check); check_cluster_versions(); get_sock_dir(&old_cluster, live_check); get_sock_dir(&new_cluster, false); check_cluster_compatibility(live_check); check_and_dump_old_cluster(live_check, &sequence_script_file_name); /* -- NEW -- */ start_postmaster(&new_cluster); check_new_cluster(); report_clusters_compatible(); pg_log(PG_REPORT, "\nPerforming Upgrade\n"); pg_log(PG_REPORT, "------------------\n"); prepare_new_cluster(); stop_postmaster(false); /* * Destructive Changes to New Cluster */ copy_clog_xlog_xid(); /* New now using xids of the old system */ /* -- NEW -- */ start_postmaster(&new_cluster); prepare_new_databases(); 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 linking, which * will link the old and new cluster data files, preventing the old * cluster from being safely started once the new cluster is started. */ if (user_opts.transfer_mode == TRANSFER_MODE_LINK) disable_old_cluster(); transfer_all_new_dbs(&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, "\"%s/pg_resetxlog\" -o %u \"%s\"", new_cluster.bindir, old_cluster.controldata.chkpnt_nxtoid, new_cluster.pgdata); check_ok(); prep_status("Sync data directory to disk"); exec_prog(UTILITY_LOG_FILE, NULL, true, "\"%s/initdb\" --sync-only \"%s\"", new_cluster.bindir, new_cluster.pgdata); check_ok(); create_script_for_cluster_analyze(&analyze_script_file_name); create_script_for_old_cluster_deletion(&deletion_script_file_name); issue_warnings(sequence_script_file_name); pg_log(PG_REPORT, "\nUpgrade Complete\n"); pg_log(PG_REPORT, "----------------\n"); output_completion_banner(analyze_script_file_name, deletion_script_file_name); pg_free(analyze_script_file_name); pg_free(deletion_script_file_name); pg_free(sequence_script_file_name); cleanup(); return 0; }
/* * parallel_transfer_all_new_dbs * * This has the same API as transfer_all_new_dbs, except it does parallel execution * by transferring multiple tablespaces in parallel */ void parallel_transfer_all_new_dbs(DbInfoArr *old_db_arr, DbInfoArr *new_db_arr, char *old_pgdata, char *new_pgdata, char *old_tablespace) { #ifndef WIN32 pid_t child; #else HANDLE child; transfer_thread_arg *new_arg; #endif if (user_opts.jobs <= 1) /* throw_error must be true to allow jobs */ transfer_all_new_dbs(old_db_arr, new_db_arr, old_pgdata, new_pgdata, NULL); else { /* parallel */ #ifdef WIN32 if (thread_handles == NULL) thread_handles = pg_malloc(user_opts.jobs * sizeof(HANDLE)); if (transfer_thread_args == NULL) { int i; transfer_thread_args = pg_malloc(user_opts.jobs * sizeof(transfer_thread_arg *)); /* * For safety and performance, we keep the args allocated during * the entire life of the process, and we don't free the args in a * thread different from the one that allocated it. */ for (i = 0; i < user_opts.jobs; i++) transfer_thread_args[i] = pg_malloc0(sizeof(transfer_thread_arg)); } cur_thread_args = (void **) transfer_thread_args; #endif /* harvest any dead children */ while (reap_child(false) == true) ; /* must we wait for a dead child? */ if (parallel_jobs >= user_opts.jobs) reap_child(true); /* set this before we start the job */ parallel_jobs++; /* Ensure stdio state is quiesced before forking */ fflush(NULL); #ifndef WIN32 child = fork(); if (child == 0) { transfer_all_new_dbs(old_db_arr, new_db_arr, old_pgdata, new_pgdata, old_tablespace); /* if we take another exit path, it will be non-zero */ /* use _exit to skip atexit() functions */ _exit(0); } else if (child < 0) /* fork failed */ pg_fatal("could not create worker process: %s\n", strerror(errno)); #else /* empty array element are always at the end */ new_arg = transfer_thread_args[parallel_jobs - 1]; /* Can only pass one pointer into the function, so use a struct */ new_arg->old_db_arr = old_db_arr; new_arg->new_db_arr = new_db_arr; if (new_arg->old_pgdata) pg_free(new_arg->old_pgdata); new_arg->old_pgdata = pg_strdup(old_pgdata); if (new_arg->new_pgdata) pg_free(new_arg->new_pgdata); new_arg->new_pgdata = pg_strdup(new_pgdata); if (new_arg->old_tablespace) pg_free(new_arg->old_tablespace); new_arg->old_tablespace = old_tablespace ? pg_strdup(old_tablespace) : NULL; child = (HANDLE) _beginthreadex(NULL, 0, (void *) win32_transfer_all_new_dbs, new_arg, 0, NULL); if (child == 0) pg_fatal("could not create worker thread: %s\n", strerror(errno)); thread_handles[parallel_jobs - 1] = child; #endif } return; }