Server processes send unknown_tenant responses back to clients, which is meant to be retried after updating the tenant cache. Fix bug where key selectors could be truncated after applying the tenant prefix.
This commit is contained in:
parent
72a34945ce
commit
3ae98189af
|
@ -76,7 +76,8 @@ extern "C" DLLEXPORT fdb_bool_t fdb_error_predicate(int predicate_test, fdb_erro
|
|||
return code == error_code_not_committed || code == error_code_transaction_too_old ||
|
||||
code == error_code_future_version || code == error_code_database_locked ||
|
||||
code == error_code_proxy_memory_limit_exceeded || code == error_code_batch_transaction_throttled ||
|
||||
code == error_code_process_behind || code == error_code_tag_throttled;
|
||||
code == error_code_process_behind || code == error_code_tag_throttled ||
|
||||
code == error_code_unknown_tenant;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -160,6 +160,20 @@ FoundationDB may return the following error codes from API functions. If you nee
|
|||
| special_keys_api_failure | 2117| Api call through special keys failed. For more information, read the |
|
||||
| | | ``0xff0xff/error_message`` key |
|
||||
+-----------------------------------------------+-----+--------------------------------------------------------------------------------+
|
||||
| tenant_name_required | 2130| Tenant name must be specified to access data in the cluster |
|
||||
+-----------------------------------------------+-----+--------------------------------------------------------------------------------+
|
||||
| tenant_not_found | 2131| Tenant does not exist |
|
||||
+-----------------------------------------------+-----+--------------------------------------------------------------------------------+
|
||||
| tenant_already_exists | 2132| A tenant with the given name already exists |
|
||||
+-----------------------------------------------+-----+--------------------------------------------------------------------------------+
|
||||
| tenant_not_empty | 2133| Cannot delete a non-empty tenant |
|
||||
+-----------------------------------------------+-----+--------------------------------------------------------------------------------+
|
||||
| invalid_tenant_name | 2134| Tenant name cannot begin with \xff |
|
||||
+-----------------------------------------------+-----+--------------------------------------------------------------------------------+
|
||||
| tenant_prefix_allocator_conflict | 2135| The database already has keys stored at the prefix allocated for the tenant |
|
||||
+-----------------------------------------------+-----+--------------------------------------------------------------------------------+
|
||||
| tenants_disabled | 2136| Tenants have been disabled in the cluster |
|
||||
+-----------------------------------------------+-----+--------------------------------------------------------------------------------+
|
||||
| api_version_unset | 2200| API version is not set |
|
||||
+-----------------------------------------------+-----+--------------------------------------------------------------------------------+
|
||||
| api_version_already_set | 2201| API version may be set only once |
|
||||
|
|
|
@ -52,6 +52,10 @@ void KeySelectorRef::setKey(KeyRef const& key) {
|
|||
this->key = key;
|
||||
}
|
||||
|
||||
void KeySelectorRef::setKeyUnlimited(KeyRef const& key) {
|
||||
this->key = key;
|
||||
}
|
||||
|
||||
std::string KeySelectorRef::toString() const {
|
||||
if (offset > 0) {
|
||||
if (orEqual)
|
||||
|
|
|
@ -550,6 +550,7 @@ public:
|
|||
KeyRef getKey() const { return key; }
|
||||
|
||||
void setKey(KeyRef const& key);
|
||||
void setKeyUnlimited(KeyRef const& key);
|
||||
|
||||
std::string toString() const;
|
||||
|
||||
|
|
|
@ -419,12 +419,12 @@ ErrorOr<Optional<TenantMapEntry>> getTenantEntry(ProxyCommitData* commitData,
|
|||
auto itr = view.find(tenant.get());
|
||||
if (itr == view.end()) {
|
||||
if (commitVersion != latestVersion) {
|
||||
TraceEvent(SevWarn, "CommitProxyTenantNotFound", commitData->dbgid)
|
||||
TraceEvent(SevWarn, "CommitProxyUnknownTenant", commitData->dbgid)
|
||||
.detail("Tenant", tenant.get())
|
||||
.detail("Version", commitVersion);
|
||||
}
|
||||
|
||||
return tenant_not_found();
|
||||
return unknown_tenant();
|
||||
} else if (tenantId.present() && tenantId.get() != itr->id) {
|
||||
if (commitVersion != latestVersion) {
|
||||
TraceEvent(SevWarn, "CommitProxyTenantIdMismatch", commitData->dbgid)
|
||||
|
@ -434,7 +434,7 @@ ErrorOr<Optional<TenantMapEntry>> getTenantEntry(ProxyCommitData* commitData,
|
|||
.detail("Version", commitVersion);
|
||||
}
|
||||
|
||||
return tenant_not_found();
|
||||
return unknown_tenant();
|
||||
}
|
||||
|
||||
return ErrorOr<Optional<TenantMapEntry>>(Optional<TenantMapEntry>(*itr));
|
||||
|
|
|
@ -87,7 +87,7 @@ bool canReplyWith(Error e) {
|
|||
case error_code_unknown_change_feed:
|
||||
case error_code_server_overloaded:
|
||||
case error_code_tenant_name_required:
|
||||
case error_code_tenant_not_found:
|
||||
case error_code_unknown_tenant:
|
||||
// getRangeAndMap related exceptions that are not retriable:
|
||||
case error_code_mapper_bad_index:
|
||||
case error_code_mapper_no_such_key:
|
||||
|
@ -1377,15 +1377,15 @@ Optional<TenantMapEntry> StorageServer::getTenantEntry(Version version, TenantIn
|
|||
auto view = tenantMap.at(version);
|
||||
auto itr = view.find(tenantInfo.name.get());
|
||||
if (itr == view.end()) {
|
||||
TraceEvent(SevWarn, "StorageTenantNotFound", thisServerID).detail("Tenant", tenantInfo.name).backtrace();
|
||||
throw tenant_not_found();
|
||||
TraceEvent(SevWarn, "StorageUnknownTenant", thisServerID).detail("Tenant", tenantInfo.name).backtrace();
|
||||
throw unknown_tenant();
|
||||
} else if (itr->id != tenantInfo.tenantId) {
|
||||
TraceEvent(SevWarn, "StorageTenantIdMismatch", thisServerID)
|
||||
.detail("Tenant", tenantInfo.name)
|
||||
.detail("TenantId", tenantInfo.tenantId)
|
||||
.detail("ExistingId", itr->id)
|
||||
.backtrace();
|
||||
throw tenant_not_found();
|
||||
throw unknown_tenant();
|
||||
}
|
||||
|
||||
return *itr;
|
||||
|
@ -2636,10 +2636,8 @@ ACTOR Future<Void> getKeyValuesQ(StorageServer* data, GetKeyValuesRequest req)
|
|||
Optional<TenantMapEntry> entry = data->getTenantEntry(version, req.tenantInfo);
|
||||
state Optional<Key> tenantPrefix = entry.map<Key>([](TenantMapEntry e) { return e.prefix; });
|
||||
if (tenantPrefix.present()) {
|
||||
req.begin = KeySelectorRef(
|
||||
req.begin.getKey().withPrefix(tenantPrefix.get(), req.arena), req.begin.orEqual, req.begin.offset);
|
||||
req.end = KeySelectorRef(
|
||||
req.end.getKey().withPrefix(tenantPrefix.get(), req.arena), req.end.orEqual, req.end.offset);
|
||||
req.begin.setKeyUnlimited(req.begin.getKey().withPrefix(tenantPrefix.get(), req.arena));
|
||||
req.end.setKeyUnlimited(req.end.getKey().withPrefix(tenantPrefix.get(), req.arena));
|
||||
}
|
||||
|
||||
state uint64_t changeCounter = data->shardChangeCounter;
|
||||
|
@ -3145,10 +3143,8 @@ ACTOR Future<Void> getKeyValuesAndFlatMapQ(StorageServer* data, GetKeyValuesAndF
|
|||
Optional<TenantMapEntry> entry = data->getTenantEntry(req.version, req.tenantInfo);
|
||||
state Optional<Key> tenantPrefix = entry.map<Key>([](TenantMapEntry e) { return e.prefix; });
|
||||
if (tenantPrefix.present()) {
|
||||
req.begin = KeySelectorRef(
|
||||
req.begin.getKey().withPrefix(tenantPrefix.get(), req.arena), req.begin.orEqual, req.begin.offset);
|
||||
req.end = KeySelectorRef(
|
||||
req.end.getKey().withPrefix(tenantPrefix.get(), req.arena), req.end.orEqual, req.end.offset);
|
||||
req.begin.setKeyUnlimited(req.begin.getKey().withPrefix(tenantPrefix.get(), req.arena));
|
||||
req.end.setKeyUnlimited(req.end.getKey().withPrefix(tenantPrefix.get(), req.arena));
|
||||
}
|
||||
|
||||
state uint64_t changeCounter = data->shardChangeCounter;
|
||||
|
@ -3358,10 +3354,8 @@ ACTOR Future<Void> getKeyValuesStreamQ(StorageServer* data, GetKeyValuesStreamRe
|
|||
Optional<TenantMapEntry> entry = data->getTenantEntry(version, req.tenantInfo);
|
||||
state Optional<Key> tenantPrefix = entry.map<Key>([](TenantMapEntry e) { return e.prefix; });
|
||||
if (tenantPrefix.present()) {
|
||||
req.begin = KeySelectorRef(
|
||||
req.begin.getKey().withPrefix(tenantPrefix.get(), req.arena), req.begin.orEqual, req.begin.offset);
|
||||
req.end = KeySelectorRef(
|
||||
req.end.getKey().withPrefix(tenantPrefix.get(), req.arena), req.end.orEqual, req.end.offset);
|
||||
req.begin.setKeyUnlimited(req.begin.getKey().withPrefix(tenantPrefix.get(), req.arena));
|
||||
req.end.setKeyUnlimited(req.end.getKey().withPrefix(tenantPrefix.get(), req.arena));
|
||||
}
|
||||
|
||||
state uint64_t changeCounter = data->shardChangeCounter;
|
||||
|
@ -3551,8 +3545,7 @@ ACTOR Future<Void> getKeyQ(StorageServer* data, GetKeyRequest req) {
|
|||
|
||||
state Optional<TenantMapEntry> tenantEntry = data->getTenantEntry(version, req.tenantInfo);
|
||||
if (tenantEntry.present()) {
|
||||
req.sel = KeySelectorRef(
|
||||
req.sel.getKey().withPrefix(tenantEntry.get().prefix, req.arena), req.sel.orEqual, req.sel.offset);
|
||||
req.sel.setKeyUnlimited(req.sel.getKey().withPrefix(tenantEntry.get().prefix, req.arena));
|
||||
}
|
||||
state uint64_t changeCounter = data->shardChangeCounter;
|
||||
|
||||
|
|
|
@ -199,12 +199,13 @@ ERROR( client_lib_not_available, 2121, "Client library exists, but is not availa
|
|||
ERROR( client_lib_invalid_binary, 2122, "Invalid client library binary." )
|
||||
|
||||
ERROR( tenant_name_required, 2130, "Tenant name must be specified to access data in the cluster" )
|
||||
ERROR( tenant_not_found, 2131, "Tenant not found on the cluster" )
|
||||
ERROR( tenant_not_found, 2131, "Tenant does not exist" )
|
||||
ERROR( tenant_already_exists, 2132, "A tenant with the given name already exists" )
|
||||
ERROR( tenant_not_empty, 2133, "Cannot delete a non-empty tenant" )
|
||||
ERROR( invalid_tenant_name, 2134, "Tenant name cannot begin with \\xff");
|
||||
ERROR( tenant_prefix_allocator_conflict, 2135, "The database already has keys stored at the prefix allocated for the tenant");
|
||||
ERROR( tenants_disabled, 2136, "Tenants have been disabled in the cluster");
|
||||
ERROR( unknown_tenant, 2137, "Tenant is not available from this server")
|
||||
|
||||
// 2200 - errors from bindings and official APIs
|
||||
ERROR( api_version_unset, 2200, "API version is not set" )
|
||||
|
|
Loading…
Reference in New Issue