1
0
mirror of https://github.com/postgres/postgres.git synced 2025-11-22 12:22:45 +03:00

pg_upgrade: Add --set-char-signedness to set the default char signedness of new cluster.

This change adds a new option --set-char-signedness to pg_upgrade. It
enables user to set arbitrary signedness during pg_upgrade. This helps
cases where user who knew they copied the v17 source cluster from
x86 (signedness=true) to ARM (signedness=false) can pg_upgrade
properly without the prerequisite of acquiring an x86 VM.

Reviewed-by: Noah Misch <noah@leadboat.com>
Discussion: https://postgr.es/m/CB11ADBC-0C3F-4FE0-A678-666EE80CBB07%40amazon.com
This commit is contained in:
Masahiko Sawada
2025-02-21 10:23:39 -08:00
parent a8238f87f9
commit 1aab680591
6 changed files with 105 additions and 2 deletions

View File

@@ -838,6 +838,18 @@ check_cluster_versions(void)
GET_MAJOR_VERSION(new_cluster.bin_version))
pg_fatal("New cluster data and binary directories are from different major versions.");
/*
* Since from version 18, newly created database clusters always have
* 'signed' default char-signedness, it makes less sense to use
* --set-char-signedness option for upgrading from version 18 or later.
* Users who want to change the default char signedness of the new
* cluster, they can use pg_resetwal manually before the upgrade.
*/
if (GET_MAJOR_VERSION(old_cluster.major_version) >= 1800 &&
user_opts.char_signedness != -1)
pg_fatal("%s option cannot be used to upgrade from PostgreSQL %s and later.",
"--set-char-signedness", "18");
check_ok();
}

View File

@@ -61,6 +61,7 @@ parseCommandLine(int argc, char *argv[])
{"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},
{NULL, 0, NULL, 0}
};
@@ -72,6 +73,7 @@ parseCommandLine(int argc, char *argv[])
user_opts.do_sync = true;
user_opts.transfer_mode = TRANSFER_MODE_COPY;
user_opts.do_statistics = true;
user_opts.char_signedness = -1;
os_info.progname = get_progname(argv[0]);
@@ -218,6 +220,14 @@ parseCommandLine(int argc, char *argv[])
user_opts.do_statistics = false;
break;
case 6:
if (pg_strcasecmp(optarg, "signed") == 0)
user_opts.char_signedness = 1;
else if (pg_strcasecmp(optarg, "unsigned") == 0)
user_opts.char_signedness = 0;
else
pg_fatal("invalid argument for option %s", "--set-char-signedness");
break;
default:
fprintf(stderr, _("Try \"%s --help\" for more information.\n"),
os_info.progname);
@@ -313,6 +323,8 @@ usage(void)
printf(_(" --copy copy files to new cluster (default)\n"));
printf(_(" --copy-file-range copy files to new cluster with copy_file_range\n"));
printf(_(" --no-statistics do not import statistics from old cluster\n"));
printf(_(" --set-char-signedness=OPTION set new cluster char signedness to \"signed\" or\n"));
printf(_(" \"unsigned\"\n"));
printf(_(" --sync-method=METHOD set method for syncing files to disk\n"));
printf(_(" -?, --help show this help, then exit\n"));
printf(_("\n"

View File

@@ -399,8 +399,14 @@ set_new_cluster_char_signedness(void)
{
bool new_char_signedness;
/* Inherit the source database's signedness */
new_char_signedness = old_cluster.controldata.default_char_signedness;
/*
* Use the specified char signedness if specified. Otherwise we inherit
* the source database's signedness.
*/
if (user_opts.char_signedness != -1)
new_char_signedness = (user_opts.char_signedness == 1);
else
new_char_signedness = old_cluster.controldata.default_char_signedness;
/* Change the char signedness of the new cluster, if necessary */
if (new_cluster.controldata.default_char_signedness != new_char_signedness)

View File

@@ -334,6 +334,9 @@ typedef struct
char *socketdir; /* directory to use for Unix sockets */
char *sync_method;
bool do_statistics; /* carry over statistics from old cluster */
int char_signedness; /* default char signedness: -1 for initial
* value, 1 for "signed" and 0 for
* "unsigned" */
} UserOpts;
typedef struct

View File

@@ -40,6 +40,23 @@ command_like(
qr/Default char data signedness:\s+unsigned/,
'updated default char signedness is unsigned in control file');
# Cannot use --set-char-signedness option for upgrading from v18+
command_fails(
[
'pg_upgrade', '--no-sync',
'-d', $old->data_dir,
'-D', $new->data_dir,
'-b', $old->config_data('--bindir'),
'-B', $new->config_data('--bindir'),
'-s', $new->host,
'-p', $old->port,
'-P', $new->port,
'-set-char-signedness', 'signed',
$mode
],
'--set-char-signedness option cannot be used for upgrading from v18 or later'
);
# pg_upgrade should be successful.
command_ok(
[