Skip to content

Commit 71e74a2

Browse files
committed
Re-enable pg_resetxlog to accept -l values in hexadecimal (it used to
be able to do that, but the ability seems to have got lost in the shuffle). Add a -o nextOID switch for completeness. Improve the documentation to explain how and why to use these switches.
1 parent 388ad64 commit 71e74a2

File tree

2 files changed

+94
-28
lines changed

2 files changed

+94
-28
lines changed

doc/src/sgml/ref/pg_resetxlog.sgml

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<!--
2-
$Header: /cvsroot/pgsql/doc/src/sgml/ref/pg_resetxlog.sgml,v 1.5 2002/08/29 22:19:03 petere Exp $
2+
$Header: /cvsroot/pgsql/doc/src/sgml/ref/pg_resetxlog.sgml,v 1.6 2002/10/02 21:30:13 tgl Exp $
33
PostgreSQL documentation
44
-->
55

@@ -12,14 +12,15 @@ PostgreSQL documentation
1212

1313
<refnamediv>
1414
<refname>pg_resetxlog</refname>
15-
<refpurpose>reset write-ahead log file and optionally the pg_control file</refpurpose>
15+
<refpurpose>reset write-ahead log and pg_control contents</refpurpose>
1616
</refnamediv>
1717

1818
<refsynopsisdiv>
1919
<cmdsynopsis>
2020
<command>pg_resetxlog</command>
2121
<arg> -f </arg>
2222
<arg> -n </arg>
23+
<arg> -o <replaceable class="parameter">oid</replaceable> </arg>
2324
<arg> -x <replaceable class="parameter">xid</replaceable> </arg>
2425
<arg> -l <replaceable class="parameter">fileid</replaceable>,<replaceable class="parameter">seg</replaceable> </arg>
2526
<arg choice="plain"><replaceable>datadir</replaceable></arg>
@@ -29,8 +30,9 @@ PostgreSQL documentation
2930
<refsect1 id="R1-APP-PGRESETXLOG-1">
3031
<title>Description</title>
3132
<para>
32-
<command>pg_resetxlog</command> clears the write-ahead log file and
33-
optionally the <filename>pg_control</> file. This function is sometimes
33+
<command>pg_resetxlog</command> clears the write-ahead log and
34+
optionally resets some fields in the <filename>pg_control</> file. This
35+
function is sometimes
3436
needed if these files have become corrupted.
3537
It should be used only as a last resort,
3638
when the server will not start due to such corruption.
@@ -55,27 +57,52 @@ PostgreSQL documentation
5557
<para>
5658
If <command>pg_resetxlog</command> complains that it cannot determine
5759
valid data for <filename>pg_control</>, you can force it to proceed anyway
58-
by specifying the <literal>-f</> (force) switch. In this case plausible values
59-
will be substituted for the missing data. If <literal>-f</> is used then
60+
by specifying the <literal>-f</> (force) switch. In this case plausible
61+
values will be substituted for the missing data. Most of the fields can be
62+
expected to match, but manual assistance may be needed for the next OID,
63+
next transaction ID, WAL starting address, and database locale fields.
64+
The first three of these can be set using the switches discussed below.
65+
<command>pg_resetxlog</command>'s own environment is the source for its
66+
guess at the locale fields; take care that <envar>LANG</> and so forth
67+
match the environment that <application>initdb</> was run in.
68+
If you are not able to determine correct values for all these fields,
69+
<literal>-f</> can still be used, but
6070
the recovered database must be treated with even more suspicion than
6171
usual --- an immediate dump and reload is imperative. <emphasis>Do not</>
6272
execute any data-modifying operations in the database before you dump,
6373
as any such action is likely to make the corruption worse.
6474
</para>
6575

76+
<para>
77+
The <literal>-o</>, <literal>-x</>, and <literal>-l</> switches allow
78+
the next OID, next transaction ID, and WAL starting address values to
79+
be set manually. These are only needed when
80+
<command>pg_resetxlog</command> is unable to determine appropriate values
81+
by reading <filename>pg_control</>. A safe value for the
82+
next transaction ID may be determined by looking for the largest
83+
file name in <envar>$PGDATA</><filename>/pg_clog</>, adding one,
84+
and then multiplying by 1048576. Note that the file names are in
85+
hexadecimal. It is usually easiest to specify the switch value in
86+
hexadecimal too. For example, if <filename>0011</> is the largest entry
87+
in <filename>pg_clog</>, <literal>-x 0x1200000</> will work (five trailing
88+
zeroes provide the proper multiplier).
89+
The WAL starting address should be
90+
larger than any file number currently existing in
91+
<envar>$PGDATA</><filename>/pg_xlog</>. These also are in hex, and
92+
have two parts. For example, if <filename>000000FF0000003A</> is the
93+
largest entry in <filename>pg_xlog</>, <literal>-l 0xFF,0x3B</> will work.
94+
There is no comparably easy way to determine a next OID that's beyond
95+
the largest one in the database, but fortunately it is not critical to
96+
get the next-OID setting right.
97+
</para>
98+
6699
<para>
67100
The <literal>-n</> (no operation) switch instructs
68101
<command>pg_resetxlog</command> to print the values reconstructed from
69102
<filename>pg_control</> and then exit without modifying anything.
70103
This is mainly a debugging tool, but may be useful as a sanity check
71104
before allowing <command>pg_resetxlog</command> to proceed for real.
72105
</para>
73-
74-
<para>
75-
The <literal>-x</> and <literal>-l</> switches are intended for use by
76-
<application>pg_upgrade</>. In most cases they should not be used in
77-
manual recovery operations.
78-
</para>
79106
</refsect1>
80107

81108
<refsect1>

src/bin/pg_resetxlog/pg_resetxlog.c

Lines changed: 55 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
* Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
2424
* Portions Copyright (c) 1994, Regents of the University of California
2525
*
26-
* $Header: /cvsroot/pgsql/src/bin/pg_resetxlog/pg_resetxlog.c,v 1.6 2002/10/02 19:45:47 tgl Exp $
26+
* $Header: /cvsroot/pgsql/src/bin/pg_resetxlog/pg_resetxlog.c,v 1.7 2002/10/02 21:30:13 tgl Exp $
2727
*
2828
*-------------------------------------------------------------------------
2929
*/
@@ -90,8 +90,11 @@ main(int argc, char *argv[])
9090
bool force = false;
9191
bool noupdate = false;
9292
TransactionId set_xid = 0;
93+
Oid set_oid = 0;
9394
uint32 minXlogId = 0,
9495
minXlogSeg = 0;
96+
char *endptr;
97+
char *endptr2;
9598
char *DataDir;
9699
int fd;
97100
char path[MAXPGPATH];
@@ -122,7 +125,7 @@ main(int argc, char *argv[])
122125
}
123126

124127

125-
while ((c = getopt(argc, argv, "fl:nx:")) != -1)
128+
while ((c = getopt(argc, argv, "fl:no:x:")) != -1)
126129
{
127130
switch (c)
128131
{
@@ -135,16 +138,45 @@ main(int argc, char *argv[])
135138
break;
136139

137140
case 'x':
138-
set_xid = strtoul(optarg, NULL, 0);
141+
set_xid = strtoul(optarg, &endptr, 0);
142+
if (endptr == optarg || *endptr != '\0')
143+
{
144+
fprintf(stderr, _("%s: invalid argument for -x option\n"), progname);
145+
fprintf(stderr, _("Try '%s --help' for more information.\n"), progname);
146+
exit(1);
147+
}
139148
if (set_xid == 0)
140149
{
141150
fprintf(stderr, _("%s: transaction ID (-x) must not be 0\n"), progname);
142151
exit(1);
143152
}
144153
break;
145154

155+
case 'o':
156+
set_oid = strtoul(optarg, &endptr, 0);
157+
if (endptr == optarg || *endptr != '\0')
158+
{
159+
fprintf(stderr, _("%s: invalid argument for -o option\n"), progname);
160+
fprintf(stderr, _("Try '%s --help' for more information.\n"), progname);
161+
exit(1);
162+
}
163+
if (set_oid == 0)
164+
{
165+
fprintf(stderr, _("%s: OID (-o) must not be 0\n"), progname);
166+
exit(1);
167+
}
168+
break;
169+
146170
case 'l':
147-
if (sscanf(optarg, "%u,%u", &minXlogId, &minXlogSeg) != 2)
171+
minXlogId = strtoul(optarg, &endptr, 0);
172+
if (endptr == optarg || *endptr != ',')
173+
{
174+
fprintf(stderr, _("%s: invalid argument for -l option\n"), progname);
175+
fprintf(stderr, _("Try '%s --help' for more information.\n"), progname);
176+
exit(1);
177+
}
178+
minXlogSeg = strtoul(endptr+1, &endptr2, 0);
179+
if (endptr2 == endptr+1 || *endptr2 != '\0')
148180
{
149181
fprintf(stderr, _("%s: invalid argument for -l option\n"), progname);
150182
fprintf(stderr, _("Try '%s --help' for more information.\n"), progname);
@@ -198,6 +230,24 @@ main(int argc, char *argv[])
198230
if (!ReadControlFile())
199231
GuessControlValues();
200232

233+
/*
234+
* Adjust fields if required by switches. (Do this now so that
235+
* printout, if any, includes these values.)
236+
*/
237+
if (set_xid != 0)
238+
ControlFile.checkPointCopy.nextXid = set_xid;
239+
240+
if (set_oid != 0)
241+
ControlFile.checkPointCopy.nextOid = set_oid;
242+
243+
if (minXlogId > ControlFile.logId ||
244+
(minXlogId == ControlFile.logId &&
245+
minXlogSeg > ControlFile.logSeg))
246+
{
247+
ControlFile.logId = minXlogId;
248+
ControlFile.logSeg = minXlogSeg;
249+
}
250+
201251
/*
202252
* If we had to guess anything, and -f was not given, just print the
203253
* guessed values and exit. Also print if -n is given.
@@ -227,19 +277,7 @@ main(int argc, char *argv[])
227277

228278
/*
229279
* Else, do the dirty deed.
230-
*
231-
* First adjust fields if required by switches.
232280
*/
233-
if (set_xid != 0)
234-
ControlFile.checkPointCopy.nextXid = set_xid;
235-
236-
if (minXlogId > ControlFile.logId ||
237-
(minXlogId == ControlFile.logId && minXlogSeg > ControlFile.logSeg))
238-
{
239-
ControlFile.logId = minXlogId;
240-
ControlFile.logSeg = minXlogSeg;
241-
}
242-
243281
RewriteControlFile();
244282
KillExistingXLOG();
245283
WriteEmptyXLOG();
@@ -659,6 +697,7 @@ usage(void)
659697
printf(_(" -f force update to be done\n"));
660698
printf(_(" -l FILEID,SEG force minimum WAL starting location for new transaction log\n"));
661699
printf(_(" -n no update, just show extracted control values (for testing)\n"));
700+
printf(_(" -o OID set next OID\n"));
662701
printf(_(" -x XID set next transaction ID\n"));
663702
printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));
664703
}

0 commit comments

Comments
 (0)