From ae06a73a417505f2c74d9751b09d08597c72d448 Mon Sep 17 00:00:00 2001 From: Shihao Date: Thu, 1 Oct 2026 22:34:04 -0600 Subject: [PATCH v2 3/4] pg_resetwal: Add --cluster-state option pg_resetwal always marks the cluster as shut down. This option stores another state instead. With any other state the next start goes through crash recovery, which for example empties unlogged tables. Discussion: https://postgr.es/m/ar8mhs05SzC4hjmu@paquier.xyz --- doc/src/sgml/ref/pg_resetwal.sgml | 22 +++++++++++++++++ src/bin/pg_resetwal/pg_resetwal.c | 40 ++++++++++++++++++++++++++++++- 2 files changed, 61 insertions(+), 1 deletion(-) diff --git a/doc/src/sgml/ref/pg_resetwal.sgml b/doc/src/sgml/ref/pg_resetwal.sgml index 229cf34f00b..0170a5029bf 100644 --- a/doc/src/sgml/ref/pg_resetwal.sgml +++ b/doc/src/sgml/ref/pg_resetwal.sgml @@ -396,6 +396,28 @@ PostgreSQL documentation + + + + + Manually set the database cluster state stored in + pg_control. Possible values are + shut-down (the default), + shut-down-in-recovery, + shutting-down, + in-crash-recovery, + in-archive-recovery and + in-production. + + + With any state other than shut-down, the server + goes through crash recovery at its next start. There is no WAL to + replay after a reset, but the other steps of crash recovery still + run. For example, unlogged tables are emptied. + + + + diff --git a/src/bin/pg_resetwal/pg_resetwal.c b/src/bin/pg_resetwal/pg_resetwal.c index bc81463c180..6ee74187fdc 100644 --- a/src/bin/pg_resetwal/pg_resetwal.c +++ b/src/bin/pg_resetwal/pg_resetwal.c @@ -97,6 +97,10 @@ static int wal_segsize_val; static bool char_signedness_given = false; static bool char_signedness_val; +static bool cluster_state_given = false; +static DBState cluster_state_val; +static const char *cluster_state_name; + static TimeLineID minXlogTli = 0; static XLogSegNo minXlogSegNo = 0; @@ -135,6 +139,7 @@ main(int argc, char *argv[]) {"next-transaction-id", required_argument, NULL, 'x'}, {"wal-segsize", required_argument, NULL, 1}, {"char-signedness", required_argument, NULL, 2}, + {"cluster-state", required_argument, NULL, 3}, {NULL, 0, NULL, 0} }; @@ -356,6 +361,32 @@ main(int argc, char *argv[]) break; } + case 3: + { + /* DB_STARTUP is left out, the server rejects it */ + if (strcmp(optarg, "shut-down") == 0) + cluster_state_val = DB_SHUTDOWNED; + else if (strcmp(optarg, "shut-down-in-recovery") == 0) + cluster_state_val = DB_SHUTDOWNED_IN_RECOVERY; + else if (strcmp(optarg, "shutting-down") == 0) + cluster_state_val = DB_SHUTDOWNING; + else if (strcmp(optarg, "in-crash-recovery") == 0) + cluster_state_val = DB_IN_CRASH_RECOVERY; + else if (strcmp(optarg, "in-archive-recovery") == 0) + cluster_state_val = DB_IN_ARCHIVE_RECOVERY; + else if (strcmp(optarg, "in-production") == 0) + cluster_state_val = DB_IN_PRODUCTION; + else + { + pg_log_error("invalid argument for option %s", "--cluster-state"); + pg_log_error_hint("Try \"%s --help\" for more information.", progname); + exit(1); + } + cluster_state_name = optarg; + cluster_state_given = true; + break; + } + default: /* getopt_long already emitted a complaint */ pg_log_error_hint("Try \"%s --help\" for more information.", progname); @@ -919,6 +950,12 @@ PrintNewControlValues(void) printf(_("Bytes per WAL segment: %u\n"), ControlFile.xlog_seg_size); } + + if (cluster_state_given) + { + printf(_("Database cluster state: %s\n"), + cluster_state_name); + } } @@ -936,7 +973,7 @@ RewriteControlFile(void) ControlFile.checkPointCopy.redo); ControlFile.checkPointCopy.time = (pg_time_t) time(NULL); - ControlFile.state = DB_SHUTDOWNED; + ControlFile.state = cluster_state_given ? cluster_state_val : DB_SHUTDOWNED; ControlFile.checkPoint = ControlFile.checkPointCopy.redo; ControlFile.minRecoveryPoint = InvalidXLogRecPtr; ControlFile.minRecoveryPointTLI = 0; @@ -1269,6 +1306,7 @@ usage(void) printf(_(" -u, --oldest-transaction-id=XID set oldest transaction ID\n")); printf(_(" -x, --next-transaction-id=XID set next transaction ID\n")); printf(_(" --char-signedness=OPTION set char signedness to \"signed\" or \"unsigned\"\n")); + printf(_(" --cluster-state=STATE set database cluster state\n")); printf(_(" --wal-segsize=SIZE size of WAL segments, in megabytes\n")); printf(_("\nReport bugs to <%s>.\n"), PACKAGE_BUGREPORT); -- 2.37.1 (Apple Git-137.1)