2019-05-07 07:56:49 +08:00
|
|
|
/*
|
2019-05-13 12:53:09 +08:00
|
|
|
* RestoreLoader.h
|
2019-05-07 07:56:49 +08:00
|
|
|
*
|
|
|
|
* This source file is part of the FoundationDB open source project
|
|
|
|
*
|
|
|
|
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
2019-05-13 12:53:09 +08:00
|
|
|
// This file declares the actors used by the RestoreLoader role
|
2019-05-07 07:56:49 +08:00
|
|
|
|
|
|
|
#pragma once
|
2019-05-13 12:53:09 +08:00
|
|
|
#if defined(NO_INTELLISENSE) && !defined(FDBSERVER_RESTORE_LOADER_G_H)
|
2019-08-02 08:00:13 +08:00
|
|
|
#define FDBSERVER_RESTORE_LOADER_G_H
|
|
|
|
#include "fdbserver/RestoreLoader.actor.g.h"
|
2019-05-13 12:53:09 +08:00
|
|
|
#elif !defined(FDBSERVER_RESTORE_LOADER_H)
|
2019-08-02 08:00:13 +08:00
|
|
|
#define FDBSERVER_RESTORE_LOADER_H
|
2019-05-07 07:56:49 +08:00
|
|
|
|
|
|
|
#include <sstream>
|
|
|
|
#include "fdbclient/FDBTypes.h"
|
|
|
|
#include "fdbclient/CommitTransaction.h"
|
|
|
|
#include "fdbrpc/fdbrpc.h"
|
2020-07-11 06:06:34 +08:00
|
|
|
#include "fdbrpc/Stats.h"
|
2019-05-07 07:56:49 +08:00
|
|
|
#include "fdbserver/CoordinationInterface.h"
|
|
|
|
#include "fdbrpc/Locality.h"
|
2019-09-26 15:18:37 +08:00
|
|
|
#include "fdbclient/RestoreWorkerInterface.actor.h"
|
2019-05-10 11:55:44 +08:00
|
|
|
#include "fdbserver/RestoreUtil.h"
|
|
|
|
#include "fdbserver/RestoreCommon.actor.h"
|
|
|
|
#include "fdbserver/RestoreRoleCommon.actor.h"
|
|
|
|
#include "fdbclient/BackupContainer.h"
|
2019-05-07 07:56:49 +08:00
|
|
|
|
2019-05-10 11:55:44 +08:00
|
|
|
#include "flow/actorcompiler.h" // has to be last include
|
|
|
|
|
2020-02-28 12:13:20 +08:00
|
|
|
class LoaderVersionBatchState : RoleVersionBatchState {
|
2020-02-28 12:59:34 +08:00
|
|
|
public:
|
2020-02-28 12:13:20 +08:00
|
|
|
static const int NOT_INIT = 0;
|
|
|
|
static const int INIT = 1;
|
|
|
|
static const int LOAD_FILE = 2;
|
|
|
|
static const int SEND_MUTATIONS = 3;
|
|
|
|
static const int INVALID = 4;
|
|
|
|
|
2020-02-28 12:59:34 +08:00
|
|
|
explicit LoaderVersionBatchState(int newState) {
|
|
|
|
vbState = newState;
|
|
|
|
}
|
2020-02-28 12:13:20 +08:00
|
|
|
|
2020-02-28 13:18:01 +08:00
|
|
|
virtual ~LoaderVersionBatchState() = default;
|
2020-02-28 12:59:56 +08:00
|
|
|
|
2020-02-28 13:18:01 +08:00
|
|
|
virtual void operator=(int newState) { vbState = newState; }
|
2020-02-28 12:59:56 +08:00
|
|
|
|
2020-02-28 13:18:01 +08:00
|
|
|
virtual int get() { return vbState; }
|
2020-02-28 11:23:29 +08:00
|
|
|
};
|
|
|
|
|
2020-01-16 05:39:06 +08:00
|
|
|
struct LoaderBatchData : public ReferenceCounted<LoaderBatchData> {
|
2019-05-28 09:39:30 +08:00
|
|
|
std::map<LoadingParam, Future<Void>> processedFileParams;
|
2019-11-13 08:28:09 +08:00
|
|
|
std::map<LoadingParam, VersionedMutationsMap> kvOpsPerLP; // Buffered kvOps for each loading param
|
2019-05-28 09:39:30 +08:00
|
|
|
|
2020-07-17 06:30:27 +08:00
|
|
|
// rangeToApplier is in controller and loader. Loader uses this to determine which applier a mutation should be sent
|
2019-12-04 04:58:11 +08:00
|
|
|
// Key is the inclusive lower bound of the key range the applier (UID) is responsible for
|
|
|
|
std::map<Key, UID> rangeToApplier;
|
2019-12-03 06:33:31 +08:00
|
|
|
|
2020-07-17 06:30:27 +08:00
|
|
|
// Sampled mutations to be sent back to restore controller
|
2020-08-05 04:35:36 +08:00
|
|
|
std::map<LoadingParam, SampledMutationsVec> sampleMutations;
|
2019-05-10 11:55:44 +08:00
|
|
|
int numSampledMutations; // The total number of mutations received from sampled data.
|
|
|
|
|
2020-02-11 07:06:03 +08:00
|
|
|
Future<Void> pollMetrics;
|
|
|
|
|
2020-02-28 11:23:29 +08:00
|
|
|
LoaderVersionBatchState vbState;
|
|
|
|
|
2020-06-28 06:16:38 +08:00
|
|
|
long loadFileReqs;
|
|
|
|
|
2020-02-10 11:19:32 +08:00
|
|
|
// Status counters
|
|
|
|
struct Counters {
|
|
|
|
CounterCollection cc;
|
|
|
|
Counter loadedRangeBytes, loadedLogBytes, sentBytes;
|
2020-02-12 03:44:53 +08:00
|
|
|
Counter sampledRangeBytes, sampledLogBytes;
|
2020-04-18 06:21:59 +08:00
|
|
|
Counter oldLogMutations;
|
2020-02-10 11:19:32 +08:00
|
|
|
|
|
|
|
Counters(LoaderBatchData* self, UID loaderInterfID, int batchIndex)
|
|
|
|
: cc("LoaderBatch", loaderInterfID.toString() + ":" + std::to_string(batchIndex)),
|
|
|
|
loadedRangeBytes("LoadedRangeBytes", cc), loadedLogBytes("LoadedLogBytes", cc), sentBytes("SentBytes", cc),
|
2020-04-18 06:21:59 +08:00
|
|
|
sampledRangeBytes("SampledRangeBytes", cc), sampledLogBytes("SampledLogBytes", cc),
|
|
|
|
oldLogMutations("OldLogMutations", cc) {}
|
2020-02-10 11:19:32 +08:00
|
|
|
} counters;
|
|
|
|
|
2020-08-19 02:58:57 +08:00
|
|
|
explicit LoaderBatchData(UID nodeID, int batchIndex)
|
|
|
|
: counters(this, nodeID, batchIndex), vbState(LoaderVersionBatchState::NOT_INIT), loadFileReqs(0) {
|
2020-05-02 01:05:33 +08:00
|
|
|
pollMetrics = traceCounters(format("FastRestoreLoaderMetrics%d", batchIndex), nodeID,
|
|
|
|
SERVER_KNOBS->FASTRESTORE_ROLE_LOGGING_DELAY, &counters.cc,
|
|
|
|
nodeID.toString() + "/RestoreLoaderMetrics/" + std::to_string(batchIndex));
|
2020-02-11 09:01:59 +08:00
|
|
|
TraceEvent("FastRestoreLoaderMetricsCreated").detail("Node", nodeID);
|
2020-02-11 07:06:03 +08:00
|
|
|
}
|
2020-02-10 11:19:32 +08:00
|
|
|
|
2020-01-16 05:39:06 +08:00
|
|
|
void reset() {
|
|
|
|
processedFileParams.clear();
|
|
|
|
kvOpsPerLP.clear();
|
|
|
|
sampleMutations.clear();
|
|
|
|
numSampledMutations = 0;
|
|
|
|
rangeToApplier.clear();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2020-02-10 11:19:32 +08:00
|
|
|
using LoaderCounters = LoaderBatchData::Counters;
|
|
|
|
|
2020-01-22 06:49:13 +08:00
|
|
|
struct LoaderBatchStatus : public ReferenceCounted<LoaderBatchStatus> {
|
|
|
|
Optional<Future<Void>> sendAllRanges;
|
|
|
|
Optional<Future<Void>> sendAllLogs;
|
|
|
|
|
|
|
|
void addref() { return ReferenceCounted<LoaderBatchStatus>::addref(); }
|
|
|
|
void delref() { return ReferenceCounted<LoaderBatchStatus>::delref(); }
|
|
|
|
|
2020-08-19 06:49:44 +08:00
|
|
|
std::string toString() const {
|
2020-01-22 06:49:13 +08:00
|
|
|
std::stringstream ss;
|
|
|
|
ss << "sendAllRanges: "
|
|
|
|
<< (!sendAllRanges.present() ? "invalid" : (sendAllRanges.get().isReady() ? "ready" : "notReady"))
|
|
|
|
<< " sendAllLogs: "
|
|
|
|
<< (!sendAllLogs.present() ? "invalid" : (sendAllLogs.get().isReady() ? "ready" : "notReady"));
|
|
|
|
return ss.str();
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2020-08-16 22:38:30 +08:00
|
|
|
// Each request for each loadingParam, so that scheduler can control which requests in which version batch to send first
|
|
|
|
struct RestoreLoaderSchedSendLoadParamRequest {
|
|
|
|
int batchIndex;
|
|
|
|
Promise<Void> toSched;
|
|
|
|
double start;
|
|
|
|
|
2020-08-16 23:13:28 +08:00
|
|
|
explicit RestoreLoaderSchedSendLoadParamRequest(int batchIndex, Promise<Void> toSched, double start)
|
2020-08-16 22:38:30 +08:00
|
|
|
: batchIndex(batchIndex), toSched(toSched), start(start){};
|
|
|
|
RestoreLoaderSchedSendLoadParamRequest() = default;
|
|
|
|
|
2020-08-16 23:19:46 +08:00
|
|
|
bool operator<(RestoreLoaderSchedSendLoadParamRequest const& rhs) const {
|
2020-08-16 22:38:30 +08:00
|
|
|
return batchIndex > rhs.batchIndex || (batchIndex == rhs.batchIndex && start > rhs.start);
|
|
|
|
}
|
2020-08-19 06:49:44 +08:00
|
|
|
|
|
|
|
std::string toString() const {
|
|
|
|
std::stringstream ss;
|
|
|
|
ss << "RestoreLoaderSchedSendLoadParamRequest: "
|
|
|
|
<< " batchIndex:" << batchIndex << " toSchedFutureIsReady:" << toSched.getFuture().isReady()
|
|
|
|
<< " start:" << start;
|
|
|
|
return ss.str();
|
|
|
|
}
|
2020-08-16 22:38:30 +08:00
|
|
|
};
|
|
|
|
|
2020-01-16 05:39:06 +08:00
|
|
|
struct RestoreLoaderData : RestoreRoleData, public ReferenceCounted<RestoreLoaderData> {
|
|
|
|
// buffered data per version batch
|
|
|
|
std::map<int, Reference<LoaderBatchData>> batch;
|
2020-01-22 06:49:13 +08:00
|
|
|
std::map<int, Reference<LoaderBatchStatus>> status;
|
2020-08-05 04:35:36 +08:00
|
|
|
RestoreControllerInterface ci;
|
2020-01-16 05:39:06 +08:00
|
|
|
|
2020-04-16 04:32:52 +08:00
|
|
|
KeyRangeMap<Version> rangeVersions;
|
|
|
|
|
2019-05-10 11:55:44 +08:00
|
|
|
Reference<IBackupContainer> bc; // Backup container is used to read backup files
|
|
|
|
Key bcUrl; // The url used to get the bc
|
|
|
|
|
2020-08-16 09:33:24 +08:00
|
|
|
// Request scheduler
|
|
|
|
std::priority_queue<RestoreLoadFileRequest> loadingQueue; // request queue of loading files
|
|
|
|
std::priority_queue<RestoreSendMutationsToAppliersRequest>
|
|
|
|
sendingQueue; // request queue of sending mutations to appliers
|
2020-08-16 22:38:30 +08:00
|
|
|
std::priority_queue<RestoreLoaderSchedSendLoadParamRequest> sendLoadParamQueue;
|
2020-08-16 09:33:24 +08:00
|
|
|
int finishedLoadingVB; // the max version batch index that finished loading file phase
|
|
|
|
int finishedSendingVB; // the max version batch index that finished sending mutations phase
|
|
|
|
int inflightSendingReqs; // number of sendingMutations requests released
|
2020-08-16 22:38:30 +08:00
|
|
|
int inflightLoadingReqs; // number of load backup file requests released
|
|
|
|
std::map<int, int> inflightSendLoadParamReqs; // key: batchIndex, value: inflightSendLoadParamReqs
|
2020-08-16 09:33:24 +08:00
|
|
|
|
2020-08-25 01:45:46 +08:00
|
|
|
Reference<AsyncVar<bool>> hasPendingRequests; // are there pending requests for loader
|
2020-08-16 12:55:02 +08:00
|
|
|
|
2020-08-16 09:33:24 +08:00
|
|
|
// addActor: add to actorCollection so that when an actor has error, the ActorCollection can catch the error.
|
|
|
|
// addActor is used to create the actorCollection when the RestoreController is created
|
|
|
|
PromiseStream<Future<Void>> addActor;
|
|
|
|
|
2019-05-10 11:55:44 +08:00
|
|
|
void addref() { return ReferenceCounted<RestoreLoaderData>::addref(); }
|
|
|
|
void delref() { return ReferenceCounted<RestoreLoaderData>::delref(); }
|
|
|
|
|
2020-08-16 09:33:24 +08:00
|
|
|
explicit RestoreLoaderData(UID loaderInterfID, int assignedIndex, RestoreControllerInterface ci)
|
2020-08-16 23:13:28 +08:00
|
|
|
: ci(ci), finishedLoadingVB(0), finishedSendingVB(0), inflightSendingReqs(0), inflightLoadingReqs(0) {
|
2019-05-11 07:48:01 +08:00
|
|
|
nodeID = loaderInterfID;
|
2019-05-15 06:04:07 +08:00
|
|
|
nodeIndex = assignedIndex;
|
2019-05-11 07:48:01 +08:00
|
|
|
role = RestoreRole::Loader;
|
2020-08-16 12:55:02 +08:00
|
|
|
hasPendingRequests = Reference<AsyncVar<bool>>(new AsyncVar<bool>(false));
|
2019-05-10 11:55:44 +08:00
|
|
|
}
|
|
|
|
|
2019-07-25 07:59:05 +08:00
|
|
|
~RestoreLoaderData() = default;
|
2019-05-10 11:55:44 +08:00
|
|
|
|
|
|
|
std::string describeNode() {
|
|
|
|
std::stringstream ss;
|
2019-08-02 08:00:13 +08:00
|
|
|
ss << "[Role: Loader] [NodeID:" << nodeID.toString().c_str() << "] [NodeIndex:" << std::to_string(nodeIndex)
|
|
|
|
<< "]";
|
2019-05-10 11:55:44 +08:00
|
|
|
return ss.str();
|
|
|
|
}
|
|
|
|
|
2020-03-02 12:39:56 +08:00
|
|
|
int getVersionBatchState(int batchIndex) final {
|
2020-02-28 11:23:29 +08:00
|
|
|
std::map<int, Reference<LoaderBatchData>>::iterator item = batch.find(batchIndex);
|
2020-07-31 03:10:32 +08:00
|
|
|
if (item == batch.end()) { // Batch has not been initialized when we blindly profile the state
|
2020-02-28 15:45:48 +08:00
|
|
|
return LoaderVersionBatchState::INVALID;
|
|
|
|
} else {
|
|
|
|
return item->second->vbState.get();
|
|
|
|
}
|
2020-02-28 11:23:29 +08:00
|
|
|
}
|
2020-03-02 12:39:56 +08:00
|
|
|
void setVersionBatchState(int batchIndex, int vbState) final {
|
2020-02-28 11:23:29 +08:00
|
|
|
std::map<int, Reference<LoaderBatchData>>::iterator item = batch.find(batchIndex);
|
|
|
|
ASSERT(item != batch.end());
|
2020-02-28 12:59:34 +08:00
|
|
|
item->second->vbState = vbState;
|
2020-02-28 11:23:29 +08:00
|
|
|
}
|
|
|
|
|
2020-01-28 10:13:14 +08:00
|
|
|
void initVersionBatch(int batchIndex) {
|
2020-05-02 01:27:01 +08:00
|
|
|
TraceEvent("FastRestoreLoaderInitVersionBatch", nodeID).detail("BatchIndex", batchIndex);
|
2020-02-10 11:19:32 +08:00
|
|
|
batch[batchIndex] = Reference<LoaderBatchData>(new LoaderBatchData(nodeID, batchIndex));
|
2020-01-22 06:49:13 +08:00
|
|
|
status[batchIndex] = Reference<LoaderBatchStatus>(new LoaderBatchStatus());
|
2019-08-02 08:00:13 +08:00
|
|
|
}
|
2019-05-10 11:55:44 +08:00
|
|
|
|
2020-01-17 08:19:51 +08:00
|
|
|
void resetPerRestoreRequest() {
|
|
|
|
batch.clear();
|
2020-01-22 06:49:13 +08:00
|
|
|
status.clear();
|
2020-05-05 02:31:39 +08:00
|
|
|
finishedBatch = NotifiedVersion(0);
|
2020-01-17 08:19:51 +08:00
|
|
|
}
|
|
|
|
|
2019-05-10 11:55:44 +08:00
|
|
|
void initBackupContainer(Key url) {
|
2019-08-02 08:00:13 +08:00
|
|
|
if (bcUrl == url && bc.isValid()) {
|
2019-05-10 11:55:44 +08:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
bcUrl = url;
|
|
|
|
bc = IBackupContainer::openContainer(url.toString());
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2020-08-05 04:35:36 +08:00
|
|
|
ACTOR Future<Void> restoreLoaderCore(RestoreLoaderInterface loaderInterf, int nodeIndex, Database cx,
|
|
|
|
RestoreControllerInterface ci);
|
2019-05-10 11:55:44 +08:00
|
|
|
|
|
|
|
#include "flow/unactorcompiler.h"
|
2019-09-26 14:19:42 +08:00
|
|
|
#endif
|