When updating watches after a database switch, lookup the tenant again to get the ID on the new cluster. Update the switching test to set up tenants properly.

This commit is contained in:
A.J. Beamon 2022-09-30 14:36:49 -07:00
parent 201eac77cf
commit 53593c77ac
3 changed files with 67 additions and 15 deletions

View File

@ -3632,6 +3632,9 @@ ACTOR Future<Version> watchValue(Database cx, Reference<const WatchParameters> p
parameters->useProvisionalProxies,
Reverse::False,
parameters->version));
if (parameters->tenant.tenantId != locationInfo.tenantEntry.id) {
throw tenant_not_found();
}
try {
state Optional<UID> watchValueID = Optional<UID>();
@ -5305,6 +5308,44 @@ Future<TenantInfo> populateAndGetTenant(Reference<TransactionState> trState, Key
}
}
// Restarts a watch after a database switch
ACTOR Future<Void> restartWatch(Database cx,
TenantInfo tenantInfo,
Key key,
Optional<Value> value,
TagSet tags,
SpanContext spanContext,
TaskPriority taskID,
Optional<UID> debugID,
UseProvisionalProxies useProvisionalProxies) {
// The ID of the tenant may be different on the cluster that we switched to, so obtain the new ID
if (tenantInfo.name.present()) {
state KeyRangeLocationInfo locationInfo = wait(getKeyLocation(cx,
tenantInfo,
key,
&StorageServerInterface::watchValue,
spanContext,
debugID,
useProvisionalProxies,
Reverse::False,
latestVersion));
tenantInfo.tenantId = locationInfo.tenantEntry.id;
}
wait(watchValueMap(cx->minAcceptableReadVersion,
tenantInfo,
key,
value,
cx,
tags,
spanContext,
taskID,
debugID,
useProvisionalProxies));
return Void();
}
// FIXME: This seems pretty horrible. Now a Database can't die until all of its watches do...
ACTOR Future<Void> watch(Reference<Watch> watch,
Database cx,
@ -5332,16 +5373,15 @@ ACTOR Future<Void> watch(Reference<Watch> watch,
when(wait(cx->connectionFileChanged())) {
CODE_PROBE(true, "Recreated a watch after switch");
cx->clearWatchMetadata();
watch->watchFuture = watchValueMap(cx->minAcceptableReadVersion,
tenantInfo,
watch->key,
watch->value,
cx,
tags,
spanContext,
taskID,
debugID,
useProvisionalProxies);
watch->watchFuture = restartWatch(cx,
tenantInfo,
watch->key,
watch->value,
tags,
spanContext,
taskID,
debugID,
useProvisionalProxies);
}
}
}

View File

@ -21,6 +21,7 @@
#include "fdbclient/ClusterConnectionMemoryRecord.h"
#include "fdbclient/ManagementAPI.actor.h"
#include "fdbclient/RunTransaction.actor.h"
#include "fdbclient/TenantManagement.actor.h"
#include "fdbrpc/simulator.h"
#include "fdbserver/workloads/workloads.actor.h"
#include "flow/ApiVersion.h"
@ -39,9 +40,7 @@ struct DifferentClustersSameRVWorkload : TestWorkload {
DifferentClustersSameRVWorkload(WorkloadContext const& wcx) : TestWorkload(wcx) {
ASSERT(g_simulator->extraDatabases.size() == 1);
auto extraFile =
makeReference<ClusterConnectionMemoryRecord>(ClusterConnectionString(g_simulator->extraDatabases[0]));
extraDB = Database::createDatabase(extraFile, ApiVersion::LATEST_VERSION);
extraDB = Database::createSimulatedExtraDatabase(g_simulator->extraDatabases[0], wcx.defaultTenant);
testDuration = getOption(options, "testDuration"_sr, 100.0);
switchAfter = getOption(options, "switchAfter"_sr, 50.0);
keyToRead = getOption(options, "keyToRead"_sr, "someKey"_sr);
@ -50,13 +49,27 @@ struct DifferentClustersSameRVWorkload : TestWorkload {
std::string description() const override { return "DifferentClustersSameRV"; }
Future<Void> setup(Database const& cx) override { return Void(); }
Future<Void> setup(Database const& cx) override {
if (clientId != 0) {
return Void();
}
return _setup(cx, this);
}
ACTOR static Future<Void> _setup(Database cx, DifferentClustersSameRVWorkload* self) {
if (self->extraDB->defaultTenant.present()) {
wait(success(TenantAPI::createTenant(self->extraDB.getReference(), self->extraDB->defaultTenant.get())));
}
return Void();
}
Future<Void> start(Database const& cx) override {
if (clientId != 0) {
return Void();
}
auto switchConnFileDb = Database::createDatabase(cx->getConnectionRecord(), -1);
switchConnFileDb->defaultTenant = cx->defaultTenant;
originalDB = cx;
std::vector<Future<Void>> clients = { readerClientSeparateDBs(cx, this),
doSwitch(switchConnFileDb, this),

View File

@ -1,6 +1,5 @@
[configuration]
extraDatabaseMode = 'Single'
allowDefaultTenant = false
[[test]]
testTitle = 'DifferentClustersSameRV'