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
| 3531 | * CLUSTER_MANAGER_OPT_QUIET -- Don't print info messages. |
| 3532 | */ |
| 3533 | int clusterManagerMoveSlot(clusterManagerNode *source, |
| 3534 | clusterManagerNode *target, |
| 3535 | int slot, int opts, char**err) |
| 3536 | { |
| 3537 | if (!(opts & CLUSTER_MANAGER_OPT_QUIET)) { |
| 3538 | printf("Moving slot %d from %s:%d to %s:%d: ", slot, source->ip, |
| 3539 | source->port, target->ip, target->port); |
| 3540 | fflush(stdout); |
| 3541 | } |
| 3542 | if (err != NULL) *err = NULL; |
| 3543 | int pipeline = config.cluster_manager_command.pipeline, |
| 3544 | timeout = config.cluster_manager_command.timeout, |
| 3545 | print_dots = (opts & CLUSTER_MANAGER_OPT_VERBOSE), |
| 3546 | option_cold = (opts & CLUSTER_MANAGER_OPT_COLD), |
| 3547 | success = 1; |
| 3548 | if (!option_cold) { |
| 3549 | success = clusterManagerSetSlot(target, source, slot, |
| 3550 | "importing", err); |
| 3551 | if (!success) return 0; |
| 3552 | success = clusterManagerSetSlot(source, target, slot, |
| 3553 | "migrating", err); |
| 3554 | if (!success) return 0; |
| 3555 | } |
| 3556 | success = clusterManagerMigrateKeysInSlot(source, target, slot, timeout, |
| 3557 | pipeline, print_dots, err); |
| 3558 | if (!(opts & CLUSTER_MANAGER_OPT_QUIET)) printf("\n"); |
| 3559 | if (!success) return 0; |
| 3560 | /* Set the new node as the owner of the slot in all the known nodes. */ |
| 3561 | if (!option_cold) { |
| 3562 | listIter li; |
| 3563 | listNode *ln; |
| 3564 | listRewind(cluster_manager.nodes, &li); |
| 3565 | while ((ln = listNext(&li)) != NULL) { |
| 3566 | clusterManagerNode *n = ln->value; |
| 3567 | if (n->flags & CLUSTER_MANAGER_FLAG_SLAVE) continue; |
| 3568 | redisReply *r = CLUSTER_MANAGER_COMMAND(n, "CLUSTER " |
| 3569 | "SETSLOT %d %s %s", |
| 3570 | slot, "node", |
| 3571 | target->name); |
| 3572 | success = (r != NULL); |
| 3573 | if (!success) return 0; |
| 3574 | if (r->type == REDIS_REPLY_ERROR) { |
| 3575 | success = 0; |
| 3576 | if (err != NULL) { |
| 3577 | *err = zmalloc((r->len + 1) * sizeof(char), MALLOC_LOCAL); |
| 3578 | strcpy(*err, r->str); |
| 3579 | CLUSTER_MANAGER_PRINT_REPLY_ERROR(n, *err); |
| 3580 | } |
| 3581 | } |
| 3582 | freeReplyObject(r); |
| 3583 | if (!success) return 0; |
| 3584 | } |
| 3585 | } |
| 3586 | /* Update the node logical config */ |
| 3587 | if (opts & CLUSTER_MANAGER_OPT_UPDATE) { |
| 3588 | source->slots[slot] = 0; |
| 3589 | target->slots[slot] = 1; |
| 3590 | } |
no test coverage detected