mirror of
https://github.com/postgres/postgres.git
synced 2025-06-17 17:02:08 +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:
@ -285,6 +285,59 @@ PostgreSQL documentation
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>--set-char-signedness=</option><replaceable>option</replaceable></term>
|
||||
<listitem>
|
||||
<para>
|
||||
Manually set the default char signedness of new clusters. Possible values
|
||||
are <literal>signed</literal> and <literal>unsigned</literal>.
|
||||
</para>
|
||||
<para>
|
||||
In the C language, the default signedness of the <type>char</type> type
|
||||
(when not explicitly specified) varies across platforms. For example,
|
||||
<type>char</type> defaults to <type>signed char</type> on x86 CPUs but
|
||||
to <type>unsigned char</type> on ARM CPUs.
|
||||
</para>
|
||||
<para>
|
||||
Starting from <productname>PostgreSQL</productname> 18, database clusters
|
||||
maintain their own default char signedness setting, which can be used to
|
||||
ensure consistent behavior across platforms with different default char
|
||||
signedness. By default, <application>pg_upgrade</application> preserves
|
||||
the char signedness setting when upgrading from an existing cluster.
|
||||
However, when upgrading from <productname>PostgreSQL</productname> 17 or
|
||||
earlier, <application>pg_upgrade</application> adopts the char signedness
|
||||
of the platform on which it was built.
|
||||
</para>
|
||||
<para>
|
||||
This option allows you to explicitly set the default char signedness for
|
||||
the new cluster, overriding any inherited values. There are two specific
|
||||
scenarios where this option is relevant:
|
||||
<itemizedlist>
|
||||
<listitem>
|
||||
<para>
|
||||
If you are planning to migrate to a different platform after the upgrade,
|
||||
you should not use this option. The default behavior is right in this case.
|
||||
Instead, perform the upgrade on the original platform without this flag,
|
||||
and then migrate the cluster afterward. This is the recommended and safest
|
||||
approach.
|
||||
</para>
|
||||
</listitem>
|
||||
<listitem>
|
||||
<para>
|
||||
If you have already migrated the cluster to a platform with different
|
||||
char signedness (for example, from an x86-based system to an ARM-based
|
||||
system), you should use this option to specify the signedness matching
|
||||
the original platform's default char signedness. Additionally, it's
|
||||
essential not to modify any data files between migrating data files and
|
||||
running <command>pg_upgrade</command>. <command>pg_upgrade</command>
|
||||
should be the first operation that starts the cluster on the new platform.
|
||||
</para>
|
||||
</listitem>
|
||||
</itemizedlist>
|
||||
</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><option>-?</option></term>
|
||||
<term><option>--help</option></term>
|
||||
|
@ -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();
|
||||
}
|
||||
|
||||
|
@ -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"
|
||||
|
@ -399,7 +399,13 @@ set_new_cluster_char_signedness(void)
|
||||
{
|
||||
bool new_char_signedness;
|
||||
|
||||
/* Inherit the source database's 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 */
|
||||
|
@ -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
|
||||
|
@ -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(
|
||||
[
|
||||
|
Reference in New Issue
Block a user