Re-enable pg_resetxlog to accept -l values in hexadecimal (it used to
authorTom Lane
Wed, 2 Oct 2002 21:30:13 +0000 (21:30 +0000)
committerTom Lane
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 @@
 
 
@@ -12,7 +12,7 @@ PostgreSQL documentation
 
  
   pg_resetxlog
-  reset write-ahead log file and optionally the pg_control file
+  reset write-ahead log and pg_control contents
  
 
  
@@ -20,6 +20,7 @@ PostgreSQL documentation
    pg_resetxlog
     -f 
     -n 
+    -o oid 
     -x xid 
     -l fileid,seg 
    datadir
@@ -29,8 +30,9 @@ PostgreSQL documentation
  
   Description
   
-   pg_resetxlog clears the write-ahead log file and
-   optionally the pg_control file.  This function is sometimes
+   pg_resetxlog clears the write-ahead log and
+   optionally resets some fields in the 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
   
    If pg_resetxlog complains that it cannot determine
    valid data for pg_control, you can force it to proceed anyway
-   by specifying the -f (force) switch.  In this case plausible values
-   will be substituted for the missing data.  If -f is used then
+   by specifying the -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.
+   pg_resetxlog's own environment is the source for its
+   guess at the locale fields; take care that LANG and so forth
+   match the environment that initdb was run in.
+   If you are not able to determine correct values for all these fields,
+   -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.  Do not
    execute any data-modifying operations in the database before you dump,
    as any such action is likely to make the corruption worse.
   
 
+  
+   The -o, -x, and -l switches allow
+   the next OID, next transaction ID, and WAL starting address values to
+   be set manually.  These are only needed when
+   pg_resetxlog is unable to determine appropriate values
+   by reading pg_control.  A safe value for the
+   next transaction ID may be determined by looking for the largest
+   file name in $PGDATA/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 0011 is the largest entry
+   in pg_clog, -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
+   $PGDATA/pg_xlog.  These also are in hex, and
+   have two parts.   For example, if 000000FF0000003A is the
+   largest entry in pg_xlog, -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.
+  
+
   
    The -n (no operation) switch instructs
    pg_resetxlog 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 pg_resetxlog to proceed for real.
   
-
-  
-   The -x and -l switches are intended for use by
-   pg_upgrade.  In most cases they should not be used in
-   manual recovery operations.
-  
  
 
  
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 .\n"));
 }