]> granicus.if.org Git - postgresql/commitdiff
Re-enable pg_resetxlog to accept -l values in hexadecimal (it used to
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 2 Oct 2002 21:30:13 +0000 (21:30 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 2 Oct 2002 21:30:13 +0000 (21:30 +0000)
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.

doc/src/sgml/ref/pg_resetxlog.sgml
src/bin/pg_resetxlog/pg_resetxlog.c

index 00b24fe01687b3c492d8572770c43fdd27b3f95f..61fce46a17d8360fd7c9b78e5df6666e92bafc1e 100644 (file)
@@ -1,5 +1,5 @@
 <!--
-$Header: /cvsroot/pgsql/doc/src/sgml/ref/pg_resetxlog.sgml,v 1.5 2002/08/29 22:19:03 petere Exp $
+$Header: /cvsroot/pgsql/doc/src/sgml/ref/pg_resetxlog.sgml,v 1.6 2002/10/02 21:30:13 tgl Exp $
 PostgreSQL documentation
 -->
 
@@ -12,7 +12,7 @@ PostgreSQL documentation
 
  <refnamediv>
   <refname>pg_resetxlog</refname>
-  <refpurpose>reset write-ahead log file and optionally the pg_control file</refpurpose>
+  <refpurpose>reset write-ahead log and pg_control contents</refpurpose>
  </refnamediv>
 
  <refsynopsisdiv>
@@ -20,6 +20,7 @@ PostgreSQL documentation
    <command>pg_resetxlog</command>
    <arg> -f </arg>
    <arg> -n </arg>
+   <arg> -o <replaceable class="parameter">oid</replaceable> </arg>
    <arg> -x <replaceable class="parameter">xid</replaceable> </arg>
    <arg> -l <replaceable class="parameter">fileid</replaceable>,<replaceable class="parameter">seg</replaceable> </arg>
    <arg choice="plain"><replaceable>datadir</replaceable></arg>
@@ -29,8 +30,9 @@ PostgreSQL documentation
  <refsect1 id="R1-APP-PGRESETXLOG-1">
   <title>Description</title>
   <para>
-   <command>pg_resetxlog</command> clears the write-ahead log file and
-   optionally the <filename>pg_control</> file.  This function is sometimes
+   <command>pg_resetxlog</command> clears the write-ahead log and
+   optionally resets some fields in the <filename>pg_control</> file.  This
+   function is sometimes 
    needed if these files have become corrupted.
    It should be used only as a last resort,
    when the server will not start due to such corruption.
@@ -55,14 +57,45 @@ PostgreSQL documentation
   <para>
    If <command>pg_resetxlog</command> complains that it cannot determine
    valid data for <filename>pg_control</>, you can force it to proceed anyway
-   by specifying the <literal>-f</> (force) switch.  In this case plausible values
-   will be substituted for the missing data.  If <literal>-f</> is used then
+   by specifying the <literal>-f</> (force) switch.  In this case plausible
+   values will be substituted for the missing data.  Most of the fields can be
+   expected to match, but manual assistance may be needed for the next OID,
+   next transaction ID, WAL starting address, and database locale fields.
+   The first three of these can be set using the switches discussed below.
+   <command>pg_resetxlog</command>'s own environment is the source for its
+   guess at the locale fields; take care that <envar>LANG</> and so forth
+   match the environment that <application>initdb</> was run in.
+   If you are not able to determine correct values for all these fields,
+   <literal>-f</> can still be used, but
    the recovered database must be treated with even more suspicion than
    usual --- an immediate dump and reload is imperative.  <emphasis>Do not</>
    execute any data-modifying operations in the database before you dump,
    as any such action is likely to make the corruption worse.
   </para>
 
+  <para>
+   The <literal>-o</>, <literal>-x</>, and <literal>-l</> switches allow
+   the next OID, next transaction ID, and WAL starting address values to
+   be set manually.  These are only needed when
+   <command>pg_resetxlog</command> is unable to determine appropriate values
+   by reading <filename>pg_control</>.  A safe value for the
+   next transaction ID may be determined by looking for the largest
+   file name in <envar>$PGDATA</><filename>/pg_clog</>, adding one,
+   and then multiplying by 1048576.  Note that the file names are in
+   hexadecimal.  It is usually easiest to specify the switch value in
+   hexadecimal too. For example, if <filename>0011</> is the largest entry
+   in <filename>pg_clog</>, <literal>-x 0x1200000</> will work (five trailing
+   zeroes provide the proper multiplier).
+   The WAL starting address should be
+   larger than any file number currently existing in
+   <envar>$PGDATA</><filename>/pg_xlog</>.  These also are in hex, and
+   have two parts.   For example, if <filename>000000FF0000003A</> is the
+   largest entry in <filename>pg_xlog</>, <literal>-l 0xFF,0x3B</> will work.
+   There is no comparably easy way to determine a next OID that's beyond
+   the largest one in the database, but fortunately it is not critical to
+   get the next-OID setting right.
+  </para>
+
   <para>
    The <literal>-n</> (no operation) switch instructs
    <command>pg_resetxlog</command> to print the values reconstructed from
@@ -70,12 +103,6 @@ PostgreSQL documentation
    This is mainly a debugging tool, but may be useful as a sanity check
    before allowing <command>pg_resetxlog</command> to proceed for real.
   </para>
-
-  <para>
-   The <literal>-x</> and <literal>-l</> switches are intended for use by
-   <application>pg_upgrade</>.  In most cases they should not be used in
-   manual recovery operations.
-  </para>
  </refsect1>
 
  <refsect1>
index 56621cd5569942833c9657455006389f358478f0..81fb79b3a3937835b038766581fd7e7be087bcd2 100644 (file)
@@ -23,7 +23,7 @@
  * Portions Copyright (c) 1996-2002, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $Header: /cvsroot/pgsql/src/bin/pg_resetxlog/pg_resetxlog.c,v 1.6 2002/10/02 19:45:47 tgl Exp $
+ * $Header: /cvsroot/pgsql/src/bin/pg_resetxlog/pg_resetxlog.c,v 1.7 2002/10/02 21:30:13 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -90,8 +90,11 @@ main(int argc, char *argv[])
        bool            force = false;
        bool            noupdate = false;
        TransactionId set_xid = 0;
+       Oid                     set_oid = 0;
        uint32          minXlogId = 0,
                                minXlogSeg = 0;
+       char       *endptr;
+       char       *endptr2;
        char       *DataDir;
        int                     fd;
        char            path[MAXPGPATH];
@@ -122,7 +125,7 @@ main(int argc, char *argv[])
        }
 
 
-       while ((c = getopt(argc, argv, "fl:nx:")) != -1)
+       while ((c = getopt(argc, argv, "fl:no:x:")) != -1)
        {
                switch (c)
                {
@@ -135,7 +138,13 @@ main(int argc, char *argv[])
                                break;
 
                        case 'x':
-                               set_xid = strtoul(optarg, NULL, 0);
+                               set_xid = strtoul(optarg, &endptr, 0);
+                               if (endptr == optarg || *endptr != '\0')
+                               {
+                                       fprintf(stderr, _("%s: invalid argument for -x option\n"), progname);
+                                       fprintf(stderr, _("Try '%s --help' for more information.\n"), progname);
+                                       exit(1);
+                               }
                                if (set_xid == 0)
                                {
                                        fprintf(stderr, _("%s: transaction ID (-x) must not be 0\n"), progname);
@@ -143,8 +152,31 @@ main(int argc, char *argv[])
                                }
                                break;
 
+                       case 'o':
+                               set_oid = strtoul(optarg, &endptr, 0);
+                               if (endptr == optarg || *endptr != '\0')
+                               {
+                                       fprintf(stderr, _("%s: invalid argument for -o option\n"), progname);
+                                       fprintf(stderr, _("Try '%s --help' for more information.\n"), progname);
+                                       exit(1);
+                               }
+                               if (set_oid == 0)
+                               {
+                                       fprintf(stderr, _("%s: OID (-o) must not be 0\n"), progname);
+                                       exit(1);
+                               }
+                               break;
+
                        case 'l':
-                               if (sscanf(optarg, "%u,%u", &minXlogId, &minXlogSeg) != 2)
+                               minXlogId = strtoul(optarg, &endptr, 0);
+                               if (endptr == optarg || *endptr != ',')
+                               {
+                                       fprintf(stderr, _("%s: invalid argument for -l option\n"), progname);
+                                       fprintf(stderr, _("Try '%s --help' for more information.\n"), progname);
+                                       exit(1);
+                               }
+                               minXlogSeg = strtoul(endptr+1, &endptr2, 0);
+                               if (endptr2 == endptr+1 || *endptr2 != '\0')
                                {
                                        fprintf(stderr, _("%s: invalid argument for -l option\n"), progname);
                                        fprintf(stderr, _("Try '%s --help' for more information.\n"), progname);
@@ -198,6 +230,24 @@ main(int argc, char *argv[])
        if (!ReadControlFile())
                GuessControlValues();
 
+       /*
+        * Adjust fields if required by switches.  (Do this now so that
+        * printout, if any, includes these values.)
+        */
+       if (set_xid != 0)
+               ControlFile.checkPointCopy.nextXid = set_xid;
+
+       if (set_oid != 0)
+               ControlFile.checkPointCopy.nextOid = set_oid;
+
+       if (minXlogId > ControlFile.logId ||
+               (minXlogId == ControlFile.logId &&
+                minXlogSeg > ControlFile.logSeg))
+       {
+               ControlFile.logId = minXlogId;
+               ControlFile.logSeg = minXlogSeg;
+       }
+
        /*
         * If we had to guess anything, and -f was not given, just print the
         * guessed values and exit.  Also print if -n is given.
@@ -227,19 +277,7 @@ main(int argc, char *argv[])
 
        /*
         * Else, do the dirty deed.
-        *
-        * First adjust fields if required by switches.
         */
-       if (set_xid != 0)
-               ControlFile.checkPointCopy.nextXid = set_xid;
-
-       if (minXlogId > ControlFile.logId ||
-        (minXlogId == ControlFile.logId && minXlogSeg > ControlFile.logSeg))
-       {
-               ControlFile.logId = minXlogId;
-               ControlFile.logSeg = minXlogSeg;
-       }
-
        RewriteControlFile();
        KillExistingXLOG();
        WriteEmptyXLOG();
@@ -659,6 +697,7 @@ usage(void)
        printf(_("  -f                force update to be done\n"));
        printf(_("  -l FILEID,SEG     force minimum WAL starting location for new transaction log\n"));
        printf(_("  -n                no update, just show extracted control values (for testing)\n"));
+       printf(_("  -o OID            set next OID\n"));
        printf(_("  -x XID            set next transaction ID\n"));
        printf(_("\nReport bugs to <pgsql-bugs@postgresql.org>.\n"));
 }