Add check against accidental start of GTM with an XID lower than what it's
authorPavan Deolasee <[email protected]>
Tue, 12 Apr 2016 10:45:49 +0000 (16:15 +0530)
committerPavan Deolasee <[email protected]>
Tue, 12 Apr 2016 10:45:49 +0000 (16:15 +0530)
saved in its control file.

User must now explicitly specify -f option to forcefully start GTM with the
given value. This should protect users from incorrect usage of the -x option
(like we saw in a recent bug report)

src/gtm/main/gtm_standby.c
src/gtm/main/main.c
src/include/gtm/gtm_txn.h

index 141495d7a0bb557a392344d52f227652acd235a0..5c8a6a49795512b73fefafbc9c9e2dfc685f55b4 100644 (file)
@@ -68,7 +68,7 @@ gtm_standby_restore_next_gxid(void)
        GlobalTransactionId next_gxid = InvalidGlobalTransactionId;
 
        next_gxid = get_next_gxid(GTM_ActiveConn);
-       GTM_RestoreTxnInfo(NULL, next_gxid, NULL);
+       GTM_RestoreTxnInfo(NULL, next_gxid, NULL, true);
 
        elog(DEBUG1, "Restoring the next GXID done.");
        return 1;
index 3f56bfd65fb6132e83dd96c98c7e4c653c1cade4..ea8241536f88dedd424176a9b78394d9adf61e57 100644 (file)
@@ -289,6 +289,7 @@ help(const char *progname)
        printf(_("  -D directory    GTM working directory\n"));
        printf(_("  -l filename     GTM server log file name \n"));
        printf(_("  -c              show server status, then exit\n"));
+       printf(_("  -f              force start GTM with starting XID specified by -x option\n"));
        printf(_("  --help          show this help, then exit\n"));
        printf(_("\n"));
        printf(_("Options for Standby mode:\n"));
@@ -344,6 +345,7 @@ main(int argc, char *argv[])
        int                     i;
        GlobalTransactionId next_gxid = InvalidGlobalTransactionId;
        FILE       *ctlf;
+       bool            force_xid = false;
 
        /*
         * Local variable to hold command line options.
@@ -409,7 +411,7 @@ main(int argc, char *argv[])
        /*
         * Parse the command like options and set variables
         */
-       while ((opt = getopt(argc, argv, "ch:n:p:x:D:l:si:q:")) != -1)
+       while ((opt = getopt(argc, argv, "ch:n:p:x:D:l:si:q:f")) != -1)
        {
                switch (opt)
                {
@@ -470,6 +472,10 @@ main(int argc, char *argv[])
                                dest_port = strdup(optarg);
                                break;
 
+                       case 'f':
+                               force_xid = true;
+                               break;
+
                        default:
                                write_stderr("Try \"%s --help\" for more information.\n",
                                                         progname);
@@ -698,7 +704,7 @@ main(int argc, char *argv[])
                }
 
                GTM_RestoreStart(ctlf, &restoreContext);
-               GTM_RestoreTxnInfo(ctlf, next_gxid, &restoreContext);
+               GTM_RestoreTxnInfo(ctlf, next_gxid, &restoreContext, force_xid);
                GTM_RestoreSeqInfo(ctlf, &restoreContext);
                if (ctlf)
                        fclose(ctlf);
@@ -2312,7 +2318,7 @@ GTM_RestoreStart(FILE *ctlf, struct GTM_RestoreContext *context)
 
 void
 GTM_RestoreTxnInfo(FILE *ctlf, GlobalTransactionId next_gxid,
-               struct GTM_RestoreContext *context)
+               struct GTM_RestoreContext *context, bool force_xid)
 {
        GlobalTransactionId saved_gxid;
        GlobalTransactionId saved_global_xmin;
@@ -2371,7 +2377,18 @@ GTM_RestoreTxnInfo(FILE *ctlf, GlobalTransactionId next_gxid,
                        GTMTransactions.gt_recent_global_xmin = saved_gxid;
        }
        else
+       {
+               if (GlobalTransactionIdIsValid(saved_gxid) &&
+                       GlobalTransactionIdPrecedes(next_gxid, saved_gxid) && !force_xid)
+                       ereport(FATAL,
+                                       (EINVAL,
+                                        errmsg("Requested to start GTM with starting xid %d, "
+                                                "which is lower than gxid saved in control file %d. Refusing to start",
+                                                next_gxid, saved_gxid),
+                                        errhint("If you must force start GTM with a lower xid, please"
+                                                " use -f option")));
                GTMTransactions.gt_recent_global_xmin = next_gxid;
+       }
 
        SetNextGlobalTransactionId(next_gxid);
        elog(LOG, "Restoring last GXID to %u\n", next_gxid);
index 9ed35c6cc809737292eb1c69775e08f31e6eb865..d516aceceebfe71d37389c9da88469c08418033c 100644 (file)
@@ -232,7 +232,7 @@ void GTM_WriteRestorePointVersion(FILE *f);
 void GTM_RestoreStart(FILE *ctlf, struct GTM_RestoreContext *context);
 void GTM_SaveTxnInfo(FILE *ctlf);
 void GTM_RestoreTxnInfo(FILE *ctlf, GlobalTransactionId next_gxid,
-               struct GTM_RestoreContext *context);
+               struct GTM_RestoreContext *context, bool force_xid);
 void GTM_BkupBeginTransaction(GTM_IsolationLevel isolevel,
                                                          bool readonly,
                                                          const char *global_sessionid,