summaryrefslogtreecommitdiff
path: root/src/redis-cli.c
diff options
context:
space:
mode:
authorartix <artix2@gmail.com>2019-02-25 18:14:50 +0100
committerartix <artix2@gmail.com>2019-03-01 17:41:40 +0100
commit5e4dfc5c974463e9df867ff049853f7be3772d6e (patch)
treedd11915b1c9f5dcb410bd82efd298f673e50238a /src/redis-cli.c
parentfb020ab090f6059bc8dbcfae3d333f9997fba5c3 (diff)
downloadredis-5e4dfc5c974463e9df867ff049853f7be3772d6e.tar.gz
Cluster Manager: check cluster before backup
- Prevent cluster backup if cluster has issues and needs to be fixed. This behaviour can be overridden by adding the option '--cluster-ignore-issues'
Diffstat (limited to 'src/redis-cli.c')
-rw-r--r--src/redis-cli.c99
1 files changed, 67 insertions, 32 deletions
diff --git a/src/redis-cli.c b/src/redis-cli.c
index dc4f8e96d..b598a9f48 100644
--- a/src/redis-cli.c
+++ b/src/redis-cli.c
@@ -118,6 +118,7 @@
#define CLUSTER_MANAGER_CMD_FLAG_COPY 1 << 7
#define CLUSTER_MANAGER_CMD_FLAG_COLOR 1 << 8
#define CLUSTER_MANAGER_CMD_FLAG_CHECK_OWNERS 1 << 9
+#define CLUSTER_MANAGER_CMD_FLAG_IGNORE_ISSUES 1 << 10
#define CLUSTER_MANAGER_OPT_GETFRIENDS 1 << 0
#define CLUSTER_MANAGER_OPT_COLD 1 << 1
@@ -1416,6 +1417,9 @@ static int parseOptions(int argc, char **argv) {
} else if (!strcmp(argv[i],"--cluster-yes")) {
config.cluster_manager_command.flags |=
CLUSTER_MANAGER_CMD_FLAG_YES;
+ } else if (!strcmp(argv[i],"--cluster-ignore-issues")) {
+ config.cluster_manager_command.flags |=
+ CLUSTER_MANAGER_CMD_FLAG_IGNORE_ISSUES;
} else if (!strcmp(argv[i],"--cluster-simulate")) {
config.cluster_manager_command.flags |=
CLUSTER_MANAGER_CMD_FLAG_SIMULATE;
@@ -2091,7 +2095,7 @@ clusterManagerCommandDef clusterManagerCommands[] = {
{"import", clusterManagerCommandImport, 1, "host:port",
"from <arg>,copy,replace"},
{"backup", clusterManagerCommandBackup, 2, "host:port backup_directory",
- NULL},
+ "ignore-issues"},
{"help", clusterManagerCommandHelp, 0, NULL, NULL}
};
@@ -2695,6 +2699,45 @@ static sds clusterManagerNodeSlotsString(clusterManagerNode *node) {
return slots;
}
+static sds clusterManagerNodeGetJSON(clusterManagerNode *node) {
+ sds json = sdsempty();
+ sds replicate = sdsempty();
+ if (node->replicate)
+ replicate = sdscatprintf(replicate, "\"%s\"", node->replicate);
+ else
+ replicate = sdscat(replicate, "null");
+ sds slots = clusterManagerNodeSlotsString(node);
+ sds flags = clusterManagerNodeFlagString(node);
+ char *p = slots;
+ while ((p = strchr(p, '-')) != NULL)
+ *(p++) = ',';
+ json = sdscatprintf(json,
+ " {\n"
+ " \"name\": \"%s\",\n"
+ " \"host\": \"%s\",\n"
+ " \"port\": %d,\n"
+ " \"replicate\": %s,\n"
+ " \"slots\": [%s],\n"
+ " \"slots_count\": [%d],\n"
+ " \"flags\": \"%s\",\n"
+ " \"current_epoch\": %llu\n"
+ " }",
+ node->name,
+ node->ip,
+ node->port,
+ replicate,
+ slots,
+ node->slots_count,
+ flags,
+ node->current_epoch
+ );
+ sdsfree(replicate);
+ sdsfree(slots);
+ sdsfree(flags);
+ return json;
+}
+
+
/* -----------------------------------------------------------------------------
* Key space handling
* -------------------------------------------------------------------------- */
@@ -6075,6 +6118,21 @@ static int clusterManagerCommandBackup(int argc, char **argv) {
if (!getClusterHostFromCmdArgs(1, argv, &ip, &port)) goto invalid_args;
clusterManagerNode *refnode = clusterManagerNewNode(ip, port);
if (!clusterManagerLoadInfoFromNode(refnode, 0)) return 0;
+ int ignore_issues = config.cluster_manager_command.flags &
+ CLUSTER_MANAGER_CMD_FLAG_IGNORE_ISSUES;
+ if (!ignore_issues) {
+ success = clusterManagerCheckCluster(0);
+ if (success && cluster_manager.errors &&
+ listLength(cluster_manager.errors) > 0) success = 0;
+ if (!success) {
+ fflush(stdout);
+ clusterManagerLogErr("*** Please fix your cluster problems before "
+ "creating a backup, otherwise invoke the "
+ "backup command with "
+ "--cluster-ignore-issues options\n");
+ return 0;
+ }
+ }
config.cluster_manager_command.backup_dir = argv[1];
/* TODO: check if backup_dir is a valid directory. */
sds json = sdsnew("[\n");
@@ -6086,41 +6144,14 @@ static int clusterManagerCommandBackup(int argc, char **argv) {
if (!first_node) first_node = 1;
else json = sdscat(json, ",\n");
clusterManagerNode *node = ln->value;
- sds replicate = sdsempty();
- if (node->replicate)
- replicate = sdscatprintf(replicate, "\"%s\"", node->replicate);
- else
- replicate = sdscat(replicate, "null");
- sds slots = clusterManagerNodeSlotsString(node);
- sds flags = clusterManagerNodeFlagString(node);
- char *p = slots;
- while ((p = strchr(p, '-')) != NULL)
- *(p++) = ',';
- json = sdscatprintf(json,
- " {\n"
- " \"name\": \"%s\",\n"
- " \"host\": \"%s\",\n"
- " \"port\": %d,\n"
- " \"replicate\": %s,\n"
- " \"slots\": [%s],\n"
- " \"flags\": \"%s\",\n"
- " \"current_epoch\": %llu\n"
- " }",
- node->name,
- node->ip,
- node->port,
- replicate,
- slots,
- flags,
- node->current_epoch
- );
- sdsfree(replicate);
- sdsfree(slots);
- sdsfree(flags);
+ sds node_json = clusterManagerNodeGetJSON(node);
+ json = sdscat(json, node_json);
+ sdsfree(node_json);
if (node->replicate)
continue;
clusterManagerLogInfo(">>> Node %s:%d -> Saving RDB...\n",
node->ip, node->port);
+ fflush(stdout);
getRDB(node);
}
json = sdscat(json, "\n]");
@@ -6140,6 +6171,10 @@ static int clusterManagerCommandBackup(int argc, char **argv) {
cleanup:
sdsfree(json);
sdsfree(jsonpath);
+ if (success) {
+ clusterManagerLogOk("[OK] Backup created into: %s\n",
+ config.cluster_manager_command.backup_dir);
+ } else clusterManagerLogOk("[ERR] Failed to back cluster!\n");
return success;
invalid_args:
fprintf(stderr, CLUSTER_MANAGER_INVALID_HOST_ARG);