mirror of
https://github.com/apple/foundationdb.git
synced 2025-05-14 01:42:37 +08:00
Transactions could change tenant ID part way through. The dummy transaction could set a new tenant ID but use the old tenant prefix.
This commit is contained in:
parent
eeefb12f14
commit
ea76eb2beb
@ -2992,9 +2992,11 @@ Future<KeyRangeLocationInfo> getKeyLocation(Reference<TransactionState> trState,
|
||||
isBackward,
|
||||
version);
|
||||
|
||||
if (trState->tenant().present() && useTenant) {
|
||||
if (trState->tenant().present() && useTenant && trState->tenantId == TenantInfo::INVALID_TENANT) {
|
||||
return map(f, [trState](const KeyRangeLocationInfo& locationInfo) {
|
||||
trState->tenantId = locationInfo.tenantEntry.id;
|
||||
if (trState->tenantId == TenantInfo::INVALID_TENANT) {
|
||||
trState->tenantId = locationInfo.tenantEntry.id;
|
||||
}
|
||||
return locationInfo;
|
||||
});
|
||||
} else {
|
||||
@ -3132,10 +3134,12 @@ Future<std::vector<KeyRangeLocationInfo>> getKeyRangeLocations(Reference<Transac
|
||||
trState->useProvisionalProxies,
|
||||
version);
|
||||
|
||||
if (trState->tenant().present() && useTenant) {
|
||||
if (trState->tenant().present() && useTenant && trState->tenantId == TenantInfo::INVALID_TENANT) {
|
||||
return map(f, [trState](const std::vector<KeyRangeLocationInfo>& locationInfo) {
|
||||
ASSERT(!locationInfo.empty());
|
||||
trState->tenantId = locationInfo[0].tenantEntry.id;
|
||||
if (trState->tenantId == TenantInfo::INVALID_TENANT) {
|
||||
trState->tenantId = locationInfo[0].tenantEntry.id;
|
||||
}
|
||||
return locationInfo;
|
||||
});
|
||||
} else {
|
||||
@ -5972,6 +5976,7 @@ ACTOR static Future<Void> commitDummyTransaction(Reference<TransactionState> trS
|
||||
tr.trState->options = trState->options;
|
||||
tr.trState->taskID = trState->taskID;
|
||||
tr.trState->authToken = trState->authToken;
|
||||
tr.trState->tenantId = trState->tenantId;
|
||||
if (!trState->hasTenant()) {
|
||||
tr.setOption(FDBTransactionOptions::RAW_ACCESS);
|
||||
} else {
|
||||
@ -5985,6 +5990,10 @@ ACTOR static Future<Void> commitDummyTransaction(Reference<TransactionState> trS
|
||||
wait(tr.commit());
|
||||
return Void();
|
||||
} catch (Error& e) {
|
||||
// If the tenant is gone, then our original transaction won't be able to commit
|
||||
if (e.code() == error_code_unknown_tenant) {
|
||||
return Void();
|
||||
}
|
||||
TraceEvent("CommitDummyTransactionError")
|
||||
.errorUnsuppressed(e)
|
||||
.detail("Key", range.begin)
|
||||
@ -6157,19 +6166,17 @@ ACTOR static Future<Void> tryCommit(Reference<TransactionState> trState,
|
||||
}
|
||||
|
||||
state Key tenantPrefix;
|
||||
if (trState->tenant().present()) {
|
||||
// skipApplyTenantPrefix is set only in the context of a commitDummyTransaction()
|
||||
// (see member declaration)
|
||||
if (trState->tenant().present() && !trState->skipApplyTenantPrefix) {
|
||||
KeyRangeLocationInfo locationInfo = wait(getKeyLocation(trState,
|
||||
""_sr,
|
||||
&StorageServerInterface::getValue,
|
||||
Reverse::False,
|
||||
UseTenant::True,
|
||||
req.transaction.read_snapshot));
|
||||
// skipApplyTenantPrefix is set only in the context of a commitDummyTransaction()
|
||||
// (see member declaration)
|
||||
if (!trState->skipApplyTenantPrefix) {
|
||||
applyTenantPrefix(req, locationInfo.tenantEntry.prefix);
|
||||
tenantPrefixPrepended = TenantPrefixPrepended::True;
|
||||
}
|
||||
applyTenantPrefix(req, locationInfo.tenantEntry.prefix);
|
||||
tenantPrefixPrepended = TenantPrefixPrepended::True;
|
||||
tenantPrefix = locationInfo.tenantEntry.prefix;
|
||||
}
|
||||
CODE_PROBE(trState->skipApplyTenantPrefix, "Tenant prefix prepend skipped for dummy transaction");
|
||||
@ -7621,10 +7628,14 @@ ACTOR Future<TenantMapEntry> blobGranuleGetTenantEntry(Transaction* self, Key ra
|
||||
self->trState->useProvisionalProxies,
|
||||
Reverse::False,
|
||||
latestVersion));
|
||||
self->trState->tenantId = l.tenantEntry.id;
|
||||
if (self->trState->tenantId == TenantInfo::INVALID_TENANT) {
|
||||
self->trState->tenantId = l.tenantEntry.id;
|
||||
}
|
||||
return l.tenantEntry;
|
||||
} else {
|
||||
self->trState->tenantId = cachedLocationInfo.get().tenantEntry.id;
|
||||
if (self->trState->tenantId == TenantInfo::INVALID_TENANT) {
|
||||
self->trState->tenantId = cachedLocationInfo.get().tenantEntry.id;
|
||||
}
|
||||
return cachedLocationInfo.get().tenantEntry;
|
||||
}
|
||||
}
|
||||
|
@ -283,16 +283,20 @@ bool verifyTenantPrefix(ProxyCommitData* const commitData, const CommitTransacti
|
||||
if (!m.param1.startsWith(tenantPrefix)) {
|
||||
TraceEvent(SevWarnAlways, "TenantPrefixMismatch")
|
||||
.suppressFor(60)
|
||||
.detail("Prefix", tenantPrefix.toHexString())
|
||||
.detail("Key", m.param1.toHexString());
|
||||
.detail("Tenant", req.tenantInfo.name)
|
||||
.detail("TenantID", req.tenantInfo.tenantId)
|
||||
.detail("Prefix", tenantPrefix)
|
||||
.detail("Key", m.param1);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (m.type == MutationRef::ClearRange && !m.param2.startsWith(tenantPrefix)) {
|
||||
TraceEvent(SevWarnAlways, "TenantClearRangePrefixMismatch")
|
||||
.suppressFor(60)
|
||||
.detail("Prefix", tenantPrefix.toHexString())
|
||||
.detail("Key", m.param2.toHexString());
|
||||
.detail("Tenant", req.tenantInfo.name)
|
||||
.detail("TenantID", req.tenantInfo.tenantId)
|
||||
.detail("Prefix", tenantPrefix)
|
||||
.detail("Key", m.param2);
|
||||
return false;
|
||||
} else if (m.type == MutationRef::SetVersionstampedKey) {
|
||||
ASSERT(m.param1.size() >= 4);
|
||||
@ -301,8 +305,10 @@ bool verifyTenantPrefix(ProxyCommitData* const commitData, const CommitTransacti
|
||||
if (*offset < tenantPrefix.size()) {
|
||||
TraceEvent(SevWarnAlways, "TenantVersionstampInvalidOffset")
|
||||
.suppressFor(60)
|
||||
.detail("Prefix", tenantPrefix.toHexString())
|
||||
.detail("Key", m.param1.toHexString())
|
||||
.detail("Tenant", req.tenantInfo.name)
|
||||
.detail("TenantID", req.tenantInfo.tenantId)
|
||||
.detail("Prefix", tenantPrefix)
|
||||
.detail("Key", m.param1)
|
||||
.detail("Offset", *offset);
|
||||
return false;
|
||||
}
|
||||
@ -315,9 +321,11 @@ bool verifyTenantPrefix(ProxyCommitData* const commitData, const CommitTransacti
|
||||
(!rc.begin.startsWith(tenantPrefix) || !rc.end.startsWith(tenantPrefix))) {
|
||||
TraceEvent(SevWarnAlways, "TenantReadConflictPrefixMismatch")
|
||||
.suppressFor(60)
|
||||
.detail("Prefix", tenantPrefix.toHexString())
|
||||
.detail("BeginKey", rc.begin.toHexString())
|
||||
.detail("EndKey", rc.end.toHexString());
|
||||
.detail("Tenant", req.tenantInfo.name)
|
||||
.detail("TenantID", req.tenantInfo.tenantId)
|
||||
.detail("Prefix", tenantPrefix)
|
||||
.detail("BeginKey", rc.begin)
|
||||
.detail("EndKey", rc.end);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@ -327,9 +335,11 @@ bool verifyTenantPrefix(ProxyCommitData* const commitData, const CommitTransacti
|
||||
(!wc.begin.startsWith(tenantPrefix) || !wc.end.startsWith(tenantPrefix))) {
|
||||
TraceEvent(SevWarnAlways, "TenantWriteConflictPrefixMismatch")
|
||||
.suppressFor(60)
|
||||
.detail("Prefix", tenantPrefix.toHexString())
|
||||
.detail("BeginKey", wc.begin.toHexString())
|
||||
.detail("EndKey", wc.end.toHexString());
|
||||
.detail("Tenant", req.tenantInfo.name)
|
||||
.detail("TenantID", req.tenantInfo.tenantId)
|
||||
.detail("Prefix", tenantPrefix)
|
||||
.detail("BeginKey", wc.begin)
|
||||
.detail("EndKey", wc.end);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user