mirror of
https://github.com/apple/foundationdb.git
synced 2026-01-25 12:28:19 +00:00
This is the first experimental feature to be deleted in the list published at PR #12400.
There is more code here than I anticipated. It is about 40,000 lines total, of which about three quarters are in dedicated files which I am deleting, and about one quarter is in shared files. That means about 10k lines in shared files, which is the stuff we tend to notice day to day (that plus the test failures on heretofore not-yet-disabled test cases, which I am now deleting).
I ran 3 million simulations, mostly against 692df86 or very similar code (differing by one TraceEvent). This was prior to syncing with upstream/main, which had no conflicts and from which I don't expect problems. The number of failures in these runs was about 8. We looked at them and believe there is a high likelihood that these are existing issues not related to the changes in this PR. More details on these failures can be found in docs linked from here: https://quip-apple.com/MN7gAyXLjgyn
* change Long Term status for unowned features for "scheduled for deletion" where applicable
* Relax wording about scheduled for deletion features
* Delete blob granule feature. WIP. Does not compile.
* more incremental hacking to remove / comment out blob granule related code
* more hacking to remove blob granule related code, e.g. blob manager and blob migrator roles
* delete more blob granule stuff
* more hacking
* more hacking
* more hacking
* More changes to remove blob granule related code. IT COMPILES NOW
* dont try to run AuthzSecurity tests as we have deleted that workload as part of this effort
* delete more stuff that matches, abbreviates, or smells like blob granule related
* EncryptKeyProxy: dont do blobMetadata stuff, because that is not used and support is being removed
* delete more references to blob granule stuff
* SimulationConfig::setEncryptionAtRestMode: always use DISABLED; also disable EncryptKeyProxyTest.toml
* format code
* manual update to bindings/java/src/tests.cmake to remove a deleted file
* fix compile errors. I guess by default I dont build Java bindings
* remove unneeded blob granule functions rather than #if..#endif them out
* remove more code in #if..#endif
* remove more code in #if 0..#endif
* revert changes to fdb_c.h in preparation for marking removed API calls as removed
* rework C API declarations to in preparation for marking blob granule APIs as removed
* deprecate removed glob granule related API functions as of version 740 (and add a comment to request a justification of this convention)
* make progress on broken ctests. E.g. 1) python does not need to do blob granule stuff. 2) authz tests seemingly not needed
* remove blob granule stuff from Java and Python APIs and fix test runner stuff so that ctests pass
* reformat comments to fix compile error. FIXME: why is this error not happening on the default compile commands we use
* hacks all the way down to try to fix the Mac build
* add pointed comment about the perceived pointlessness of the API deprecation scheme embodied in this source file
* really serious about the C++ style comments, arent we
* remove commented-out code from prior iterative efforts
* put back undeleted code in original order
* delete commented-out code
* update feature-status.md to say blob granule is mostly deleted
* upgrade `mostly deleted` to `has been deleted`
372 lines
18 KiB
C++
372 lines
18 KiB
C++
/*
|
|
* ConfigureCommand.actor.cpp
|
|
*
|
|
* This source file is part of the FoundationDB open source project
|
|
*
|
|
* Copyright 2013-2024 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/FlowLineNoise.h"
|
|
#include "fdbcli/fdbcli.actor.h"
|
|
|
|
#include "fdbclient/FDBOptions.g.h"
|
|
#include "fdbclient/IClientApi.h"
|
|
#include "fdbclient/ManagementAPI.actor.h"
|
|
|
|
#include "flow/Arena.h"
|
|
#include "flow/FastRef.h"
|
|
#include "flow/ThreadHelper.actor.h"
|
|
#include "flow/actorcompiler.h" // This must be the last #include.
|
|
|
|
namespace fdb_cli {
|
|
|
|
ACTOR Future<bool> configureCommandActor(Reference<IDatabase> db,
|
|
Database localDb,
|
|
std::vector<StringRef> tokens,
|
|
LineNoise* linenoise,
|
|
Future<Void> warn) {
|
|
state ConfigurationResult result;
|
|
state StatusObject s;
|
|
state int startToken = 1;
|
|
state bool force = false;
|
|
if (tokens.size() < 2)
|
|
result = ConfigurationResult::NO_OPTIONS_PROVIDED;
|
|
else {
|
|
if (tokens[startToken] == "FORCE"_sr) {
|
|
force = true;
|
|
startToken = 2;
|
|
}
|
|
|
|
state Optional<ConfigureAutoResult> conf;
|
|
if (tokens[startToken] == "auto"_sr) {
|
|
// get cluster status
|
|
state Reference<ITransaction> tr = db->createTransaction();
|
|
if (!tr->isValid()) {
|
|
StatusObject _s = wait(StatusClient::statusFetcher(localDb));
|
|
s = _s;
|
|
} else {
|
|
state ThreadFuture<Optional<Value>> statusValueF = tr->get("\xff\xff/status/json"_sr);
|
|
Optional<Value> statusValue = wait(safeThreadFutureToFuture(statusValueF));
|
|
if (!statusValue.present()) {
|
|
fprintf(stderr, "ERROR: Failed to get status json from the cluster\n");
|
|
return false;
|
|
}
|
|
json_spirit::mValue mv;
|
|
json_spirit::read_string(statusValue.get().toString(), mv);
|
|
s = StatusObject(mv.get_obj());
|
|
}
|
|
|
|
if (warn.isValid())
|
|
warn.cancel();
|
|
|
|
conf = parseConfig(s);
|
|
|
|
if (!conf.get().isValid()) {
|
|
printf("Unable to provide advice for the current configuration.\n");
|
|
return false;
|
|
}
|
|
|
|
bool noChanges = conf.get().old_replication == conf.get().auto_replication &&
|
|
conf.get().old_logs == conf.get().auto_logs &&
|
|
conf.get().old_commit_proxies == conf.get().auto_commit_proxies &&
|
|
conf.get().old_grv_proxies == conf.get().auto_grv_proxies &&
|
|
conf.get().old_resolvers == conf.get().auto_resolvers &&
|
|
conf.get().old_processes_with_transaction == conf.get().auto_processes_with_transaction &&
|
|
conf.get().old_machines_with_transaction == conf.get().auto_machines_with_transaction;
|
|
|
|
bool noDesiredChanges = noChanges && conf.get().old_logs == conf.get().desired_logs &&
|
|
conf.get().old_commit_proxies == conf.get().desired_commit_proxies &&
|
|
conf.get().old_grv_proxies == conf.get().desired_grv_proxies &&
|
|
conf.get().old_resolvers == conf.get().desired_resolvers;
|
|
|
|
std::string outputString;
|
|
|
|
outputString += "\nYour cluster has:\n\n";
|
|
outputString += format(" processes %d\n", conf.get().processes);
|
|
outputString += format(" machines %d\n", conf.get().machines);
|
|
|
|
if (noDesiredChanges)
|
|
outputString += "\nConfigure recommends keeping your current configuration:\n\n";
|
|
else if (noChanges)
|
|
outputString +=
|
|
"\nConfigure cannot modify the configuration because some parameters have been set manually:\n\n";
|
|
else
|
|
outputString += "\nConfigure recommends the following changes:\n\n";
|
|
outputString += " ------------------------------------------------------------------- \n";
|
|
outputString += "| parameter | old | new |\n";
|
|
outputString += " ------------------------------------------------------------------- \n";
|
|
outputString += format("| replication | %16s | %16s |\n",
|
|
conf.get().old_replication.c_str(),
|
|
conf.get().auto_replication.c_str());
|
|
outputString +=
|
|
format("| logs | %16d | %16d |", conf.get().old_logs, conf.get().auto_logs);
|
|
outputString += conf.get().auto_logs != conf.get().desired_logs
|
|
? format(" (manually set; would be %d)\n", conf.get().desired_logs)
|
|
: "\n";
|
|
outputString += format("| commit_proxies | %16d | %16d |",
|
|
conf.get().old_commit_proxies,
|
|
conf.get().auto_commit_proxies);
|
|
outputString += conf.get().auto_commit_proxies != conf.get().desired_commit_proxies
|
|
? format(" (manually set; would be %d)\n", conf.get().desired_commit_proxies)
|
|
: "\n";
|
|
outputString += format("| grv_proxies | %16d | %16d |",
|
|
conf.get().old_grv_proxies,
|
|
conf.get().auto_grv_proxies);
|
|
outputString += conf.get().auto_grv_proxies != conf.get().desired_grv_proxies
|
|
? format(" (manually set; would be %d)\n", conf.get().desired_grv_proxies)
|
|
: "\n";
|
|
outputString += format(
|
|
"| resolvers | %16d | %16d |", conf.get().old_resolvers, conf.get().auto_resolvers);
|
|
outputString += conf.get().auto_resolvers != conf.get().desired_resolvers
|
|
? format(" (manually set; would be %d)\n", conf.get().desired_resolvers)
|
|
: "\n";
|
|
outputString += format("| transaction-class processes | %16d | %16d |\n",
|
|
conf.get().old_processes_with_transaction,
|
|
conf.get().auto_processes_with_transaction);
|
|
outputString += format("| transaction-class machines | %16d | %16d |\n",
|
|
conf.get().old_machines_with_transaction,
|
|
conf.get().auto_machines_with_transaction);
|
|
outputString += " ------------------------------------------------------------------- \n\n";
|
|
|
|
std::printf("%s", outputString.c_str());
|
|
|
|
if (noChanges)
|
|
return true;
|
|
|
|
// TODO: disable completion
|
|
Optional<std::string> line = wait(linenoise->read("Would you like to make these changes? [y/n]> "));
|
|
|
|
if (!line.present() || (line.get() != "y" && line.get() != "Y")) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
ConfigurationResult r = wait(ManagementAPI::changeConfig(
|
|
db, std::vector<StringRef>(tokens.begin() + startToken, tokens.end()), conf, force));
|
|
result = r;
|
|
}
|
|
|
|
// Real errors get thrown from makeInterruptable and printed by the catch block in cli(), but
|
|
// there are various results specific to changeConfig() that we need to report:
|
|
bool ret = true;
|
|
switch (result) {
|
|
case ConfigurationResult::NO_OPTIONS_PROVIDED:
|
|
case ConfigurationResult::CONFLICTING_OPTIONS:
|
|
case ConfigurationResult::UNKNOWN_OPTION:
|
|
case ConfigurationResult::INCOMPLETE_CONFIGURATION:
|
|
printUsage("configure"_sr);
|
|
ret = false;
|
|
break;
|
|
case ConfigurationResult::INVALID_CONFIGURATION:
|
|
fprintf(stderr, "ERROR: These changes would make the configuration invalid\n");
|
|
ret = false;
|
|
break;
|
|
case ConfigurationResult::STORAGE_MIGRATION_DISABLED:
|
|
fprintf(stderr,
|
|
"ERROR: Storage engine type cannot be changed because "
|
|
"storage_migration_type=disabled.\n");
|
|
fprintf(stderr,
|
|
"Type `configure perpetual_storage_wiggle=1 storage_migration_type=gradual' to enable gradual "
|
|
"migration with the perpetual wiggle, or `configure "
|
|
"storage_migration_type=aggressive' for aggressive migration.\n");
|
|
ret = false;
|
|
break;
|
|
case ConfigurationResult::DATABASE_ALREADY_CREATED:
|
|
fprintf(stderr, "ERROR: Database already exists! To change configuration, don't say `new'\n");
|
|
ret = false;
|
|
break;
|
|
case ConfigurationResult::DATABASE_CREATED:
|
|
printf("Database created\n");
|
|
break;
|
|
case ConfigurationResult::DATABASE_CREATED_WARN_SHARDED_ROCKSDB_EXPERIMENTAL:
|
|
printf("Database created\n");
|
|
fprintf(
|
|
stderr,
|
|
"WARN: Sharded RocksDB storage engine type is still in experimental stage, not yet production tested.\n");
|
|
break;
|
|
case ConfigurationResult::DATABASE_UNAVAILABLE:
|
|
fprintf(stderr, "ERROR: The database is unavailable\n");
|
|
fprintf(stderr, "Type `configure FORCE <TOKEN...>' to configure without this check\n");
|
|
ret = false;
|
|
break;
|
|
case ConfigurationResult::STORAGE_IN_UNKNOWN_DCID:
|
|
fprintf(stderr, "ERROR: All storage servers must be in one of the known regions\n");
|
|
fprintf(stderr, "Type `configure FORCE <TOKEN...>' to configure without this check\n");
|
|
ret = false;
|
|
break;
|
|
case ConfigurationResult::REGION_NOT_FULLY_REPLICATED:
|
|
fprintf(stderr,
|
|
"ERROR: When usable_regions > 1, all regions with priority >= 0 must be fully replicated "
|
|
"before changing the configuration\n");
|
|
fprintf(stderr, "Type `configure FORCE <TOKEN...>' to configure without this check\n");
|
|
ret = false;
|
|
break;
|
|
case ConfigurationResult::MULTIPLE_ACTIVE_REGIONS:
|
|
fprintf(stderr, "ERROR: When changing usable_regions, only one region can have priority >= 0\n");
|
|
fprintf(stderr, "Type `configure FORCE <TOKEN...>' to configure without this check\n");
|
|
ret = false;
|
|
break;
|
|
case ConfigurationResult::REGIONS_CHANGED:
|
|
fprintf(stderr,
|
|
"ERROR: The region configuration cannot be changed while simultaneously changing usable_regions\n");
|
|
fprintf(stderr, "Type `configure FORCE <TOKEN...>' to configure without this check\n");
|
|
ret = false;
|
|
break;
|
|
case ConfigurationResult::NOT_ENOUGH_WORKERS:
|
|
fprintf(stderr, "ERROR: Not enough processes exist to support the specified configuration\n");
|
|
fprintf(stderr, "Type `configure FORCE <TOKEN...>' to configure without this check\n");
|
|
ret = false;
|
|
break;
|
|
case ConfigurationResult::REGION_REPLICATION_MISMATCH:
|
|
fprintf(stderr, "ERROR: `three_datacenter' replication is incompatible with region configuration\n");
|
|
fprintf(stderr, "Type `configure FORCE <TOKEN...>' to configure without this check\n");
|
|
ret = false;
|
|
break;
|
|
case ConfigurationResult::DCID_MISSING:
|
|
fprintf(stderr, "ERROR: `No storage servers in one of the specified regions\n");
|
|
fprintf(stderr, "Type `configure FORCE <TOKEN...>' to configure without this check\n");
|
|
ret = false;
|
|
break;
|
|
case ConfigurationResult::SUCCESS:
|
|
printf("Configuration changed\n");
|
|
break;
|
|
case ConfigurationResult::LOCKED_NOT_NEW:
|
|
fprintf(stderr, "ERROR: `only new databases can be configured as locked`\n");
|
|
ret = false;
|
|
break;
|
|
case ConfigurationResult::SUCCESS_WARN_PPW_GRADUAL:
|
|
printf("Configuration changed, with warnings\n");
|
|
fprintf(stderr,
|
|
"WARN: To make progress toward the desired storage type with storage_migration_type=gradual, the "
|
|
"Perpetual Wiggle must be enabled.\n");
|
|
fprintf(stderr,
|
|
"Type `configure perpetual_storage_wiggle=1' to enable the perpetual wiggle, or `configure "
|
|
"storage_migration_type=gradual' to set the gradual migration type.\n");
|
|
break;
|
|
case ConfigurationResult::SUCCESS_WARN_SHARDED_ROCKSDB_EXPERIMENTAL:
|
|
printf("Configuration changed\n");
|
|
fprintf(
|
|
stderr,
|
|
"WARN: Sharded RocksDB storage engine type is still in experimental stage, not yet production tested.\n");
|
|
break;
|
|
case ConfigurationResult::DATABASE_IS_REGISTERED:
|
|
fprintf(stderr, "ERROR: A cluster cannot change its tenant mode while part of a metacluster.\n");
|
|
ret = false;
|
|
break;
|
|
case ConfigurationResult::ENCRYPTION_AT_REST_MODE_ALREADY_SET:
|
|
fprintf(stderr, "ERROR: A cluster cannot change its encryption_at_rest state after database creation.\n");
|
|
ret = false;
|
|
break;
|
|
case ConfigurationResult::INVALID_STORAGE_TYPE:
|
|
fprintf(stderr, "ERROR: Invalid storage type for storage or TLog.\n");
|
|
ret = false;
|
|
break;
|
|
default:
|
|
ASSERT(false);
|
|
ret = false;
|
|
};
|
|
return ret;
|
|
}
|
|
|
|
void configureGenerator(const char* text,
|
|
const char* line,
|
|
std::vector<std::string>& lc,
|
|
std::vector<StringRef> const& tokens) {
|
|
const char* opts[] = { "new",
|
|
"single",
|
|
"double",
|
|
"triple",
|
|
"three_data_hall",
|
|
"three_datacenter",
|
|
"ssd",
|
|
"ssd-1",
|
|
"ssd-2",
|
|
"memory",
|
|
"memory-1",
|
|
"memory-2",
|
|
"memory-radixtree",
|
|
"commit_proxies=",
|
|
"grv_proxies=",
|
|
"logs=",
|
|
"resolvers=",
|
|
"perpetual_storage_wiggle=",
|
|
"perpetual_storage_wiggle_locality=",
|
|
// TODO(zhewu): update fdbcli command documentation.
|
|
"perpetual_storage_wiggle_engine=",
|
|
"storage_migration_type=",
|
|
"tenant_mode=",
|
|
"encryption_at_rest_mode=",
|
|
nullptr };
|
|
arrayGenerator(text, line, opts, lc);
|
|
}
|
|
|
|
CommandFactory configureFactory(
|
|
"configure",
|
|
CommandHelp(
|
|
"configure [new|tss]"
|
|
"<single|double|triple|three_data_hall|three_datacenter|ssd|memory|memory-radixtree|proxies=<PROXIES>|"
|
|
"commit_proxies=<COMMIT_PROXIES>|grv_proxies=<GRV_PROXIES>|logs=<LOGS>|resolvers=<RESOLVERS>>*|"
|
|
"count=<TSS_COUNT>|perpetual_storage_wiggle=<WIGGLE_SPEED>|perpetual_storage_wiggle_locality="
|
|
"<<LOCALITY_KEY>:<LOCALITY_VALUE>|0>|storage_migration_type={disabled|gradual|aggressive}"
|
|
"|tenant_mode={disabled|optional_experimental|required_experimental}"
|
|
"|encryption_at_rest_mode={disabled|domain_aware|cluster_aware}"
|
|
"|exclude=<ADDRESS...>",
|
|
"change the database configuration",
|
|
"The `new' option, if present, initializes a new database with the given configuration rather than changing "
|
|
"the configuration of an existing one. When used, both a redundancy mode and a storage engine must be "
|
|
"specified.\n\ntss: when enabled, configures the testing storage server for the cluster instead."
|
|
"When used with new to set up tss for the first time, it requires both a count and a storage engine."
|
|
"To disable the testing storage server, run \"configure tss count=0\"\n\n"
|
|
"Redundancy mode:\n single - one copy of the data. Not fault tolerant.\n double - two copies "
|
|
"of data (survive one failure).\n triple - three copies of data (survive two failures).\n three_data_hall - "
|
|
"See the Admin Guide.\n three_datacenter - See the Admin Guide.\n\nStorage engine:\n ssd - B-Tree storage "
|
|
"engine optimized for solid state disks.\n memory - Durable in-memory storage engine for small "
|
|
"datasets.\n\nproxies=<PROXIES>: Sets the desired number of proxies in the cluster. The proxy role is being "
|
|
"deprecated and split into GRV proxy and Commit proxy, now prefer configure 'grv_proxies' and 'commit_proxies' "
|
|
"separately. Generally we should follow that 'commit_proxies' is three times of 'grv_proxies' and "
|
|
"'grv_proxies' "
|
|
"should be not more than 4. If 'proxies' is specified, it will be converted to 'grv_proxies' and "
|
|
"'commit_proxies'. "
|
|
"Must be at least 2 (1 GRV proxy, 1 Commit proxy), or set to -1 which restores the number of proxies to the "
|
|
"default value.\n\ncommit_proxies=<COMMIT_PROXIES>: Sets the desired number of commit proxies in the cluster. "
|
|
"Must be at least 1, or set to -1 which restores the number of commit proxies to the default "
|
|
"value.\n\ngrv_proxies=<GRV_PROXIES>: Sets the desired number of GRV proxies in the cluster. Must be at least "
|
|
"1, or set to -1 which restores the number of GRV proxies to the default value.\n\nlogs=<LOGS>: Sets the "
|
|
"desired number of log servers in the cluster. Must be at least 1, or set to -1 which restores the number of "
|
|
"logs to the default value.\n\nresolvers=<RESOLVERS>: Sets the desired number of resolvers in the cluster. "
|
|
"Must be at least 1, or set to -1 which restores the number of resolvers to the default value.\n\n"
|
|
"perpetual_storage_wiggle=<WIGGLE_SPEED>: Set the value speed (a.k.a., the number of processes that the Data "
|
|
"Distributor should wiggle at a time). Currently, only 0 and 1 are supported. The value 0 means to disable the "
|
|
"perpetual storage wiggle.\n\n"
|
|
"perpetual_storage_wiggle_locality=<<LOCALITY_KEY>:<LOCALITY_VALUE>|0>: Set the process filter for wiggling. "
|
|
"The processes that match the given locality key and locality value are only wiggled. The value 0 will disable "
|
|
"the locality filter and matches all the processes for wiggling.\n\n"
|
|
"tenant_mode=<disabled|optional_experimental|required_experimental>: Sets the tenant mode for the cluster. If "
|
|
"optional, then transactions can be run with or without specifying tenants. If required, all data must be "
|
|
"accessed using tenants.\n\n"
|
|
"encryption_at_rest_mode=<disabled|domain_aware|cluster_aware>: Sets the cluster encryption data at-rest "
|
|
"support for the "
|
|
"database. The configuration can be updated ONLY at the time of database creation and once set can't be "
|
|
"updated for the lifetime of the database.\n\n"
|
|
"exclude=<ADDRESS...>: Sets the addresses in the format of IP1:port1,IP2:port2 pairs to be excluded during "
|
|
"recruitment. Note this should be only used when the database is unavailable because of the faulty processes "
|
|
"that are blocking the recovery from completion. The number of addresses should be less than the replication "
|
|
"factor to avoid data loss.\n\n"
|
|
|
|
"See the FoundationDB Administration Guide for more information."),
|
|
&configureGenerator);
|
|
|
|
} // namespace fdb_cli
|