| 1446 | enum DispatchState { SKIP = 0, DONE = 1, NOT_DONE_MIN = 2 }; |
| 1447 | |
| 1448 | ACTOR static Future<Void> _execute(Database cx, |
| 1449 | Reference<TaskBucket> taskBucket, |
| 1450 | Reference<FutureBucket> futureBucket, |
| 1451 | Reference<Task> task) { |
| 1452 | state Reference<FlowLock> lock(new FlowLock(CLIENT_KNOBS->BACKUP_LOCK_BYTES)); |
| 1453 | wait(checkTaskVersion(cx, task, name, version)); |
| 1454 | |
| 1455 | state double startTime = timer(); |
| 1456 | state Reference<ReadYourWritesTransaction> tr(new ReadYourWritesTransaction(cx)); |
| 1457 | |
| 1458 | // The shard map will use 3 values classes. Exactly SKIP, exactly DONE, then any number >= NOT_DONE_MIN which |
| 1459 | // will mean not done. This is to enable an efficient coalesce() call to squash adjacent ranges which are not |
| 1460 | // yet finished to enable efficiently finding random database shards which are not done. |
| 1461 | state int notDoneSequence = NOT_DONE_MIN; |
| 1462 | state KeyRangeMap<int> shardMap(notDoneSequence++, normalKeys.end); |
| 1463 | state Key beginKey = normalKeys.begin; |
| 1464 | |
| 1465 | // Read all shard boundaries and add them to the map |
| 1466 | loop { |
| 1467 | try { |
| 1468 | tr->setOption(FDBTransactionOptions::ACCESS_SYSTEM_KEYS); |
| 1469 | tr->setOption(FDBTransactionOptions::LOCK_AWARE); |
| 1470 | |
| 1471 | state Future<Standalone<VectorRef<KeyRef>>> shardBoundaries = |
| 1472 | getBlockOfShards(tr, beginKey, normalKeys.end, CLIENT_KNOBS->TOO_MANY); |
| 1473 | wait(success(shardBoundaries) && taskBucket->keepRunning(tr, task)); |
| 1474 | |
| 1475 | if (shardBoundaries.get().size() == 0) |
| 1476 | break; |
| 1477 | |
| 1478 | for (auto& boundary : shardBoundaries.get()) { |
| 1479 | shardMap.rawInsert(boundary, notDoneSequence++); |
| 1480 | } |
| 1481 | |
| 1482 | beginKey = keyAfter(shardBoundaries.get().back()); |
| 1483 | tr->reset(); |
| 1484 | } catch (Error& e) { |
| 1485 | wait(tr->onError(e)); |
| 1486 | } |
| 1487 | } |
| 1488 | |
| 1489 | // Read required stuff from backup config |
| 1490 | state BackupConfig config(task); |