summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPavan Deolasee2016-02-04 13:33:34 +0000
committerPavan Deolasee2016-10-18 09:48:14 +0000
commit076dae8ff2a956ecffb1588c9735a92bc0bca09c (patch)
treec920bb2295b7939b828a3e538d494364b3159828
parent83bcfb83b82ff1112611b43b5f8ccf771377bcab (diff)
If we don't find GTM control file on startup, look for the temporary control
file and use that. While updating the control file, GTM first writes updated content to a temp file, then deletes the old file and renames the temp to the control file. But in a rare situation, its possible that GTM may exit before renaming the temp file. In such cases, we should use the temp file after renaming it to the orignal file. More improvements in this area are necessary. P.S. This commit gets distinction to be the first commit, pushed from 41000 feet in the air ;-)
-rw-r--r--src/bin/initgtm/initgtm.c26
-rw-r--r--src/gtm/main/main.c42
-rw-r--r--src/include/gtm/gtm.h5
3 files changed, 71 insertions, 2 deletions
diff --git a/src/bin/initgtm/initgtm.c b/src/bin/initgtm/initgtm.c
index f78f1f5d17..7e1d002e52 100644
--- a/src/bin/initgtm/initgtm.c
+++ b/src/bin/initgtm/initgtm.c
@@ -35,6 +35,7 @@
#include "miscadmin.h"
#include "postgres.h"
+#include "gtm/gtm.h"
/*
* these values are passed in by makefile defines
@@ -87,6 +88,7 @@ static void set_input(char **dest, char *filename);
static void check_input(char *path);
static void set_null_conf(void);
static void setup_config(void);
+static void setup_control(void);
static void trapsig(int signum);
static void check_ok(void);
static void usage(const char *progname);
@@ -547,6 +549,27 @@ setup_config(void)
check_ok();
}
+/*
+ * set up all the control file
+ */
+static void
+setup_control(void)
+{
+ char path[MAXPGPATH];
+ char *controlline = NULL;
+
+ if (!is_gtm)
+ return;
+
+ fputs(_("creating control file ... "), stdout);
+ fflush(stdout);
+
+ snprintf(path, sizeof(path), "%s/gtm.control", pg_data);
+ writefile(path, &controlline);
+ chmod(path, S_IRUSR | S_IWUSR);
+
+ check_ok();
+}
/*
* signal handler in case we are interrupted.
@@ -1084,6 +1107,9 @@ main(int argc, char *argv[])
/* Now create all the text config files */
setup_config();
+ /* Now create the control file */
+ setup_control();
+
/* Get directory specification used to start this executable */
strcpy(bin_dir, argv[0]);
get_parent_directory(bin_dir);
diff --git a/src/gtm/main/main.c b/src/gtm/main/main.c
index d122591f32..123350029e 100644
--- a/src/gtm/main/main.c
+++ b/src/gtm/main/main.c
@@ -59,7 +59,6 @@ extern char *optarg;
#define GTM_MAX_PATH 1024
#define GTM_DEFAULT_HOSTNAME "*"
#define GTM_DEFAULT_PORT 6666
-#define GTM_CONTROL_FILE "gtm.control"
#define GTM_PID_FILE "gtm.pid"
#define GTM_LOG_FILE "gtm.log"
@@ -658,6 +657,47 @@ main(int argc, char *argv[])
GTM_MutexLockAcquire(&control_lock);
ctlf = fopen(GTMControlFile, "r");
+
+ /*
+ * When the GTMControlFile file is updated, we first write the updated
+ * contents to a GTMControlFileTmp, delete the original GTMControlFile
+ * and then rename the GTMControlFileTmp file to GTMControlFile
+ *
+ * In a rare situation, the GTMControlFile may get deleted, but the
+ * GTMControlFileTmp may not get renamed. If we don't find the
+ * GTMControlFile file, then look for the GTMControlFileTmp file. If
+ * none exists, then its an error condition and we must not start.
+ */
+ if (ctlf == NULL)
+ {
+ switch (errno)
+ {
+ case ENOENT:
+ elog(WARNING, "%s not found, now looking for %s",
+ GTMControlFile, GTMControlFileTmp);
+ break;
+ default:
+ elog(ERROR, "Could not open %s, errno %d - aborting GTM start",
+ GTMControlFile, errno);
+ }
+ ctlf = fopen(GTMControlFileTmp, "r");
+ if (ctlf == NULL)
+ elog(ERROR, "Could not open %s, errno %d - aborting GTM start",
+ GTMControlFileTmp, errno);
+
+ /*
+ * Ok, so the GTMControlFileTmp exists. Just rename it to the
+ * GTMControlFile and open again with the new name
+ */
+ elog(WARNING, "Renaming %s to %s", GTMControlFileTmp,
+ GTMControlFile);
+ fclose(ctlf);
+ rename(GTMControlFileTmp, GTMControlFile);
+ ctlf = fopen(GTMControlFile, "r");
+ if (ctlf == NULL)
+ elog(ERROR, "Could not open %s, errno %d - aborting GTM start",
+ GTMControlFile, errno);
+ }
GTM_RestoreTxnInfo(ctlf, next_gxid);
GTM_RestoreSeqInfo(ctlf);
if (ctlf)
diff --git a/src/include/gtm/gtm.h b/src/include/gtm/gtm.h
index 30580abd3b..887e65025d 100644
--- a/src/include/gtm/gtm.h
+++ b/src/include/gtm/gtm.h
@@ -92,7 +92,7 @@ GTM_ThreadInfo *GTM_ThreadCreate(GTM_ConnectionInfo *conninfo,
GTM_ThreadInfo * GTM_GetThreadInfo(GTM_ThreadID thrid);
#ifdef XCP
extern void SaveControlInfo(void);
-#define CONTROL_INTERVAL 1000
+#define CONTROL_INTERVAL 50000
#endif
/*
@@ -145,4 +145,7 @@ extern GTM_ThreadID TopMostThreadID;
(!GTM_CLIENT_ID_LT(a, b) && !GTM_CLIENT_ID_EQ(a, b))
#define GTM_CLIENT_ID_NEXT(a) \
((((a) + 1) == UINT32_MAX) ? 1 : ((a) + 1))
+
+#define GTM_CONTROL_FILE "gtm.control"
+
#endif