Move slots between source and target nodes using MIGRATE. * * Options: * CLUSTER_MANAGER_OPT_VERBOSE -- Print a dot for every moved key. * CLUSTER_MANAGER_OPT_COLD -- Move keys without opening slots / * reconfiguring the nodes. * CLUSTER_MANAGER_OPT_UPDATE -- Update node->slots for source/target nodes. * CLUSTER_MANAGER_OPT_QUIET -- Don't print info mess
| 3920 | * CLUSTER_MANAGER_OPT_QUIET -- Don't print info messages. |
| 3921 | */ |
| 3922 | static int clusterManagerMoveSlot(clusterManagerNode *source, |
| 3923 | clusterManagerNode *target, |
| 3924 | int slot, int opts, char**err) |
| 3925 | { |
| 3926 | if (!(opts & CLUSTER_MANAGER_OPT_QUIET)) { |
| 3927 | printf("Moving slot %d from %s:%d to %s:%d: ", slot, source->ip, |
| 3928 | source->port, target->ip, target->port); |
| 3929 | fflush(stdout); |
| 3930 | } |
| 3931 | if (err != NULL) *err = NULL; |
| 3932 | int pipeline = config.cluster_manager_command.pipeline, |
| 3933 | timeout = config.cluster_manager_command.timeout, |
| 3934 | print_dots = (opts & CLUSTER_MANAGER_OPT_VERBOSE), |
| 3935 | option_cold = (opts & CLUSTER_MANAGER_OPT_COLD), |
| 3936 | success = 1; |
| 3937 | if (!option_cold) { |
| 3938 | success = clusterManagerSetSlot(target, source, slot, |
| 3939 | "importing", err); |
| 3940 | if (!success) return 0; |
| 3941 | success = clusterManagerSetSlot(source, target, slot, |
| 3942 | "migrating", err); |
| 3943 | if (!success) return 0; |
| 3944 | } |
| 3945 | success = clusterManagerMigrateKeysInSlot(source, target, slot, timeout, |
| 3946 | pipeline, print_dots, err); |
| 3947 | if (!(opts & CLUSTER_MANAGER_OPT_QUIET)) printf("\n"); |
| 3948 | if (!success) return 0; |
| 3949 | /* Set the new node as the owner of the slot in all the known nodes. */ |
| 3950 | if (!option_cold) { |
| 3951 | listIter li; |
| 3952 | listNode *ln; |
| 3953 | listRewind(cluster_manager.nodes, &li); |
| 3954 | while ((ln = listNext(&li)) != NULL) { |
| 3955 | clusterManagerNode *n = ln->value; |
| 3956 | if (n->flags & CLUSTER_MANAGER_FLAG_SLAVE) continue; |
| 3957 | redisReply *r = CLUSTER_MANAGER_COMMAND(n, "CLUSTER " |
| 3958 | "SETSLOT %d %s %s", |
| 3959 | slot, "node", |
| 3960 | target->name); |
| 3961 | success = (r != NULL); |
| 3962 | if (!success) return 0; |
| 3963 | if (r->type == REDIS_REPLY_ERROR) { |
| 3964 | success = 0; |
| 3965 | if (err != NULL) { |
| 3966 | *err = zmalloc((r->len + 1) * sizeof(char)); |
| 3967 | strcpy(*err, r->str); |
| 3968 | CLUSTER_MANAGER_PRINT_REPLY_ERROR(n, *err); |
| 3969 | } |
| 3970 | } |
| 3971 | freeReplyObject(r); |
| 3972 | if (!success) return 0; |
| 3973 | } |
| 3974 | } |
| 3975 | /* Update the node logical config */ |
| 3976 | if (opts & CLUSTER_MANAGER_OPT_UPDATE) { |
| 3977 | source->slots[slot] = 0; |
| 3978 | target->slots[slot] = 1; |
| 3979 | } |
no test coverage detected