Add getlocation and getall fdbcli debug commands

getlocation: returns the SS list for a key
getall: returns both the SS list and values on the SS for a key
This commit is contained in:
Jingyu Zhou 2023-06-05 16:53:37 -07:00
parent c510510391
commit 614686f737
4 changed files with 127 additions and 3 deletions

View File

@ -0,0 +1,93 @@
/*
* DebugCommands.actor.cpp
*
* This source file is part of the FoundationDB open source project
*
* Copyright 2013-2023 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.
*/
#include "fdbcli/fdbcli.actor.h"
#include "fdbclient/NativeAPI.actor.h"
namespace fdb_cli {
// The command is used to get all storage server addresses for a given key.
ACTOR Future<bool> getLocationCommandActor(Database cx, std::vector<StringRef> tokens, Version version) {
if (tokens.size() != 2) {
printf("getlocation <KEY>\n"
"fetch the storage server address for a given key.\n"
"Displays the addresses of storage servers, or `not found' if location is not found.");
return false;
}
KeyRangeLocationInfo loc = wait(getKeyLocation_internal(
cx, {}, tokens[1], SpanID(), Optional<UID>(), UseProvisionalProxies::False, Reverse::False, version));
if (loc.locations) {
printf("version is %ld\n", version);
printf("`%s' is at:\n", printable(tokens[1]).c_str());
auto locations = loc.locations->locations();
for (int i = 0; locations && i < locations->size(); i++) {
printf(" %s\n", locations->getInterface(i).address().toString().c_str());
}
} else {
printf("`%s': location not found\n", printable(tokens[1]).c_str());
}
return true;
}
// hidden commands, no help text for now
CommandFactory getLocationCommandFactory("getlocation");
// The command is used to get values from all storage servers that have the given key.
ACTOR Future<bool> getallCommandActor(Database cx, std::vector<StringRef> tokens, Version version) {
if (tokens.size() != 2) {
printf("getall <KEY>\n"
"fetch values from all storage servers that have the given key.\n"
"Displays the value and the addresses of storage servers, or `not found' if key is not found.");
return false;
}
KeyRangeLocationInfo loc = wait(getKeyLocation_internal(
cx, {}, tokens[1], SpanID(), Optional<UID>(), UseProvisionalProxies::False, Reverse::False, version));
if (loc.locations) {
printf("version is %ld\n", version);
printf("`%s' is at:\n", printable(tokens[1]).c_str());
state Reference<LocationInfo::Locations> locations = loc.locations->locations();
state std::vector<Future<GetValueReply>> replies;
for (int i = 0; locations && i < locations->size(); i++) {
GetValueRequest req({}, {}, tokens[1], version, {}, {}, {});
replies.push_back(locations->get(i, &StorageServerInterface::getValue).getReply(req));
}
wait(waitForAll(replies));
for (int i = 0; i < replies.size(); i++) {
std::string ssi = locations->getInterface(i).address().toString();
if (replies[i].isError()) {
fprintf(stderr, "ERROR: %s %s\n", ssi.c_str(), replies[i].getError().what());
} else {
Optional<Value> v = replies[i].get().value;
printf(" %s %s\n", ssi.c_str(), v.present() ? printable(v.get()).c_str() : "(not found)");
}
}
} else {
printf("`%s': location not found\n", printable(tokens[1]).c_str());
}
return true;
}
// hidden commands, no help text for now
CommandFactory getallCommandFactory("getall");
} // namespace fdb_cli

View File

@ -1194,7 +1194,6 @@ ACTOR Future<int> cli(CLIOptions opt, LineNoise* plinenoise, Reference<ClusterCo
}
state bool is_error = false;
state Future<Void> warn;
loop {
if (warn.isValid())
@ -1618,6 +1617,24 @@ ACTOR Future<int> cli(CLIOptions opt, LineNoise* plinenoise, Reference<ClusterCo
continue;
}
if (tokencmp(tokens[0], "getlocation")) {
Version _v = wait(makeInterruptable(
safeThreadFutureToFuture(getTransaction(db, tenant, tr, options, intrans)->getReadVersion())));
bool _result = wait(makeInterruptable(getLocationCommandActor(localDb, tokens, _v)));
if (!_result)
is_error = true;
continue;
}
if (tokencmp(tokens[0], "getall")) {
Version _v = wait(makeInterruptable(
safeThreadFutureToFuture(getTransaction(db, tenant, tr, options, intrans)->getReadVersion())));
bool _result = wait(makeInterruptable(getallCommandActor(localDb, tokens, _v)));
if (!_result)
is_error = true;
continue;
}
if (tokencmp(tokens[0], "getversion")) {
if (tokens.size() != 1) {
printUsage(tokens[0]);

View File

@ -291,6 +291,10 @@ ACTOR Future<bool> idempotencyIdsCommandActor(Database cx, std::vector<StringRef
// rangeconfig command
ACTOR Future<bool> rangeConfigCommandActor(Database cx, std::vector<StringRef> tokens);
// debug commands: getlocation, getall
ACTOR Future<bool> getLocationCommandActor(Database cx, std::vector<StringRef> tokens, Version version);
ACTOR Future<bool> getallCommandActor(Database cx, std::vector<StringRef> tokens, Version version);
} // namespace fdb_cli
#include "flow/unactorcompiler.h"

View File

@ -19,8 +19,6 @@
*/
#pragma once
#include "flow/IRandom.h"
#include "fdbclient/Tracing.h"
#if defined(NO_INTELLISENSE) && !defined(FDBCLIENT_NATIVEAPI_ACTOR_G_H)
#define FDBCLIENT_NATIVEAPI_ACTOR_G_H
#include "fdbclient/NativeAPI.actor.g.h"
@ -31,6 +29,7 @@
#include "flow/flow.h"
#include "flow/WipedString.h"
#include "flow/TDMetric.actor.h"
#include "flow/IRandom.h"
#include "fdbclient/FDBTypes.h"
#include "fdbclient/CommitProxyInterface.h"
#include "fdbclient/ClientBooleanParams.h"
@ -39,6 +38,7 @@
#include "fdbclient/ClusterInterface.h"
#include "fdbclient/ClientLogEvents.h"
#include "fdbclient/KeyRangeMap.h"
#include "fdbclient/Tracing.h"
#include "flow/actorcompiler.h" // has to be last include
// CLIENT_BUGGIFY should be used to randomly introduce failures at run time (like BUGGIFY but for client side testing)
@ -683,5 +683,15 @@ namespace NativeAPI {
ACTOR Future<std::vector<std::pair<StorageServerInterface, ProcessClass>>> getServerListAndProcessClasses(
Transaction* tr);
}
ACTOR Future<KeyRangeLocationInfo> getKeyLocation_internal(Database cx,
Optional<TenantName> tenant,
Key key,
SpanID spanID,
Optional<UID> debugID,
UseProvisionalProxies useProvisionalProxies,
Reverse isBackward,
Version version);
#include "flow/unactorcompiler.h"
#endif