This function is responsible to decide if this replica should be migrated * to a different (orphaned) master. It is called by the clusterCron() function * only if: * * 1) We are a slave node. * 2) It was detected that there is at least one orphaned master in * the cluster. * 3) We are a slave of one of the masters with the greatest number of * slaves. * * This checks are performed
| 3330 | * Additional conditions for migration are examined inside the function. |
| 3331 | */ |
| 3332 | void clusterHandleSlaveMigration(int max_slaves) { |
| 3333 | int j, okslaves = 0; |
| 3334 | clusterNode *mymaster = myself->slaveof, *target = NULL, *candidate = NULL; |
| 3335 | dictIterator *di; |
| 3336 | dictEntry *de; |
| 3337 | |
| 3338 | /* Step 1: Don't migrate if the cluster state is not ok. */ |
| 3339 | if (server.cluster->state != CLUSTER_OK) return; |
| 3340 | |
| 3341 | /* Step 2: Don't migrate if my master will not be left with at least |
| 3342 | * 'migration-barrier' slaves after my migration. */ |
| 3343 | if (mymaster == NULL) return; |
| 3344 | for (j = 0; j < mymaster->numslaves; j++) |
| 3345 | if (!nodeFailed(mymaster->slaves[j]) && |
| 3346 | !nodeTimedOut(mymaster->slaves[j])) okslaves++; |
| 3347 | if (okslaves <= server.cluster_migration_barrier) return; |
| 3348 | |
| 3349 | /* Step 3: Identify a candidate for migration, and check if among the |
| 3350 | * masters with the greatest number of ok slaves, I'm the one with the |
| 3351 | * smallest node ID (the "candidate slave"). |
| 3352 | * |
| 3353 | * Note: this means that eventually a replica migration will occur |
| 3354 | * since slaves that are reachable again always have their FAIL flag |
| 3355 | * cleared, so eventually there must be a candidate. At the same time |
| 3356 | * this does not mean that there are no race conditions possible (two |
| 3357 | * slaves migrating at the same time), but this is unlikely to |
| 3358 | * happen, and harmless when happens. */ |
| 3359 | candidate = myself; |
| 3360 | di = dictGetSafeIterator(server.cluster->nodes); |
| 3361 | while((de = dictNext(di)) != NULL) { |
| 3362 | clusterNode *node = dictGetVal(de); |
| 3363 | int okslaves = 0, is_orphaned = 1; |
| 3364 | |
| 3365 | /* We want to migrate only if this master is working, orphaned, and |
| 3366 | * used to have slaves or if failed over a master that had slaves |
| 3367 | * (MIGRATE_TO flag). This way we only migrate to instances that were |
| 3368 | * supposed to have replicas. */ |
| 3369 | if (nodeIsSlave(node) || nodeFailed(node)) is_orphaned = 0; |
| 3370 | if (!(node->flags & CLUSTER_NODE_MIGRATE_TO)) is_orphaned = 0; |
| 3371 | |
| 3372 | /* Check number of working slaves. */ |
| 3373 | if (nodeIsMaster(node)) okslaves = clusterCountNonFailingSlaves(node); |
| 3374 | if (okslaves > 0) is_orphaned = 0; |
| 3375 | |
| 3376 | if (is_orphaned) { |
| 3377 | if (!target && node->numslots > 0) target = node; |
| 3378 | |
| 3379 | /* Track the starting time of the orphaned condition for this |
| 3380 | * master. */ |
| 3381 | if (!node->orphaned_time) node->orphaned_time = mstime(); |
| 3382 | } else { |
| 3383 | node->orphaned_time = 0; |
| 3384 | } |
| 3385 | |
| 3386 | /* Check if I'm the slave candidate for the migration: attached |
| 3387 | * to a master with the maximum number of slaves and with the smallest |
| 3388 | * node ID. */ |
| 3389 | if (okslaves == max_slaves) { |
no test coverage detected