summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavan Deolasee2016-04-12 10:45:49 +0000
committerPavan Deolasee2016-10-18 10:05:05 +0000
commitb682953a137a167b4f7e5835961bfcd0b2ef0457 (patch)
treec2329c94b7166b47289df825d77a63819cbf7974
parent6aaf7729ebe1dc402717415823cb557663d4aa76 (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.c2
-rw-r--r--src/gtm/main/main.c23
-rw-r--r--src/include/gtm/gtm_txn.h2
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,