Cluster: save/restore vars that must persist after recovery.

This fixes issue #1479.
This commit is contained in:
antirez 2014-03-27 14:54:57 +01:00
parent 6dd2dbbd36
commit 7fb14b73ba

View File

@ -121,6 +121,25 @@ int clusterLoadConfig(char *filename) {
argv = sdssplitargs(line,&argc);
if (argv == NULL) goto fmterr;
/* Handle the special "vars" line. Don't pretend it is the last
* line even if it actually is when generated by Redis. */
if (strcasecmp(argv[0],"vars") == 0) {
for (j = 1; j < argc; j += 2) {
if (strcasecmp(argv[j],"currentEpoch") == 0) {
server.cluster->currentEpoch =
strtoull(argv[j+1],NULL,10);
} else if (strcasecmp(argv[j],"last_vote_epoch") == 0) {
server.cluster->last_vote_epoch =
strtoull(argv[j+1],NULL,10);
} else {
redisLog(REDIS_WARNING,
"Skipping unknown cluster config variable '%s'",
argv[j]);
}
}
continue;
}
/* Create this node if it does not exist */
n = clusterLookupNode(argv[0]);
if (!n) {
@ -227,10 +246,13 @@ int clusterLoadConfig(char *filename) {
/* Config sanity check */
redisAssert(server.cluster->myself != NULL);
redisLog(REDIS_NOTICE,"Node configuration loaded, I'm %.40s", myself->name);
/* Set the currentEpoch to the max epoch found in the master.
* FIXME: this should actually be part of the persistent state, as
* documented in the Github issue #1479. */
server.cluster->currentEpoch = clusterGetMaxEpoch();
/* Something that should never happen: currentEpoch smaller than
* the max epoch found in the nodes configuration. However we handle this
* as some form of protection against manual editing of critical files. */
if (clusterGetMaxEpoch() > server.cluster->currentEpoch) {
server.cluster->currentEpoch = clusterGetMaxEpoch();
}
return REDIS_OK;
fmterr:
@ -253,10 +275,18 @@ fmterr:
* bigger we pad our payload with newlines that are anyway ignored and truncate
* the file afterward. */
int clusterSaveConfig(int do_fsync) {
sds ci = clusterGenNodesDescription(REDIS_NODE_HANDSHAKE);
size_t content_size = sdslen(ci);
sds ci;
size_t content_size;
struct stat sb;
int fd;
/* Get the nodes description and concatenate our "vars" directive to
* save currentEpoch and last_vote_epoch. */
ci = clusterGenNodesDescription(REDIS_NODE_HANDSHAKE);
ci = sdscatprintf(ci,"vars currentEpoch %llu last_vote_epoch %llu\n",
(unsigned long long) server.cluster->currentEpoch,
(unsigned long long) server.cluster->last_vote_epoch);
content_size = sdslen(ci);
if ((fd = open(server.cluster_configfile,O_WRONLY|O_CREAT,0644))
== -1) goto err;