Exemplo n.º 1
0
Status Balancer::rebalanceSingleChunk(OperationContext* txn, const ChunkType& chunk) {
    auto migrateStatus = _chunkSelectionPolicy->selectSpecificChunkToMove(txn, chunk);
    if (!migrateStatus.isOK()) {
        return migrateStatus.getStatus();
    }

    auto migrateInfo = std::move(migrateStatus.getValue());
    if (!migrateInfo) {
        LOG(1) << "Unable to find more appropriate location for chunk " << redact(chunk.toString());
        return Status::OK();
    }

    auto balancerConfig = Grid::get(txn)->getBalancerConfiguration();
    Status refreshStatus = balancerConfig->refreshAndCheck(txn);
    if (!refreshStatus.isOK()) {
        return refreshStatus;
    }

    MigrationManager migrationManager;
    auto migrationStatuses = migrationManager.scheduleMigrations(
        txn,
        {MigrationManager::MigrationRequest(std::move(*migrateInfo),
                                            balancerConfig->getMaxChunkSizeBytes(),
                                            balancerConfig->getSecondaryThrottle(),
                                            balancerConfig->waitForDelete())});

    invariant(migrationStatuses.size() == 1);

    auto scopedCMStatus = ScopedChunkManager::getExisting(txn, NamespaceString(chunk.getNS()));
    if (!scopedCMStatus.isOK()) {
        return scopedCMStatus.getStatus();
    }

    auto scopedCM = std::move(scopedCMStatus.getValue());
    ChunkManager* const cm = scopedCM.cm();
    cm->reload(txn);

    return migrationStatuses.begin()->second;
}