diff options
author | Pavan Deolasee | 2016-04-12 10:45:49 +0000 |
---|---|---|
committer | Pavan Deolasee | 2016-10-18 10:05:05 +0000 |
commit | b682953a137a167b4f7e5835961bfcd0b2ef0457 (patch) | |
tree | c2329c94b7166b47289df825d77a63819cbf7974 | |
parent | 6aaf7729ebe1dc402717415823cb557663d4aa76 (diff) |
Add check against accidental start of GTM with an XID lower than what it's
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)
-rw-r--r-- | src/gtm/main/gtm_standby.c | 2 | ||||
-rw-r--r-- | src/gtm/main/main.c | 23 | ||||
-rw-r--r-- | src/include/gtm/gtm_txn.h | 2 |
3 files changed, 22 insertions, 5 deletions
diff --git a/src/gtm/main/gtm_standby.c b/src/gtm/main/gtm_standby.c index 141495d7a0..5c8a6a4979 100644 --- a/src/gtm/main/gtm_standby.c +++ b/src/gtm/main/gtm_standby.c @@ -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; diff --git a/src/gtm/main/main.c b/src/gtm/main/main.c index 3f56bfd65f..ea8241536f 100644 --- a/src/gtm/main/main.c +++ b/src/gtm/main/main.c @@ -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); diff --git a/src/include/gtm/gtm_txn.h b/src/include/gtm/gtm_txn.h index 9ed35c6cc8..d516acecee 100644 --- a/src/include/gtm/gtm_txn.h +++ b/src/include/gtm/gtm_txn.h @@ -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, |