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,
|
isBackward,
|
||||||
version);
|
version);
|
||||||
|
|
||||||
if (trState->tenant().present() && useTenant) {
|
if (trState->tenant().present() && useTenant && trState->tenantId == TenantInfo::INVALID_TENANT) {
|
||||||
return map(f, [trState](const KeyRangeLocationInfo& locationInfo) {
|
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;
|
return locationInfo;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@ -3132,10 +3134,12 @@ Future<std::vector<KeyRangeLocationInfo>> getKeyRangeLocations(Reference<Transac
|
|||||||
trState->useProvisionalProxies,
|
trState->useProvisionalProxies,
|
||||||
version);
|
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) {
|
return map(f, [trState](const std::vector<KeyRangeLocationInfo>& locationInfo) {
|
||||||
ASSERT(!locationInfo.empty());
|
ASSERT(!locationInfo.empty());
|
||||||
trState->tenantId = locationInfo[0].tenantEntry.id;
|
if (trState->tenantId == TenantInfo::INVALID_TENANT) {
|
||||||
|
trState->tenantId = locationInfo[0].tenantEntry.id;
|
||||||
|
}
|
||||||
return locationInfo;
|
return locationInfo;
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
@ -5972,6 +5976,7 @@ ACTOR static Future<Void> commitDummyTransaction(Reference<TransactionState> trS
|
|||||||
tr.trState->options = trState->options;
|
tr.trState->options = trState->options;
|
||||||
tr.trState->taskID = trState->taskID;
|
tr.trState->taskID = trState->taskID;
|
||||||
tr.trState->authToken = trState->authToken;
|
tr.trState->authToken = trState->authToken;
|
||||||
|
tr.trState->tenantId = trState->tenantId;
|
||||||
if (!trState->hasTenant()) {
|
if (!trState->hasTenant()) {
|
||||||
tr.setOption(FDBTransactionOptions::RAW_ACCESS);
|
tr.setOption(FDBTransactionOptions::RAW_ACCESS);
|
||||||
} else {
|
} else {
|
||||||
@ -5985,6 +5990,10 @@ ACTOR static Future<Void> commitDummyTransaction(Reference<TransactionState> trS
|
|||||||
wait(tr.commit());
|
wait(tr.commit());
|
||||||
return Void();
|
return Void();
|
||||||
} catch (Error& e) {
|
} 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")
|
TraceEvent("CommitDummyTransactionError")
|
||||||
.errorUnsuppressed(e)
|
.errorUnsuppressed(e)
|
||||||
.detail("Key", range.begin)
|
.detail("Key", range.begin)
|
||||||
@ -6157,19 +6166,17 @@ ACTOR static Future<Void> tryCommit(Reference<TransactionState> trState,
|
|||||||
}
|
}
|
||||||
|
|
||||||
state Key tenantPrefix;
|
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,
|
KeyRangeLocationInfo locationInfo = wait(getKeyLocation(trState,
|
||||||
""_sr,
|
""_sr,
|
||||||
&StorageServerInterface::getValue,
|
&StorageServerInterface::getValue,
|
||||||
Reverse::False,
|
Reverse::False,
|
||||||
UseTenant::True,
|
UseTenant::True,
|
||||||
req.transaction.read_snapshot));
|
req.transaction.read_snapshot));
|
||||||
// skipApplyTenantPrefix is set only in the context of a commitDummyTransaction()
|
applyTenantPrefix(req, locationInfo.tenantEntry.prefix);
|
||||||
// (see member declaration)
|
tenantPrefixPrepended = TenantPrefixPrepended::True;
|
||||||
if (!trState->skipApplyTenantPrefix) {
|
|
||||||
applyTenantPrefix(req, locationInfo.tenantEntry.prefix);
|
|
||||||
tenantPrefixPrepended = TenantPrefixPrepended::True;
|
|
||||||
}
|
|
||||||
tenantPrefix = locationInfo.tenantEntry.prefix;
|
tenantPrefix = locationInfo.tenantEntry.prefix;
|
||||||
}
|
}
|
||||||
CODE_PROBE(trState->skipApplyTenantPrefix, "Tenant prefix prepend skipped for dummy transaction");
|
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,
|
self->trState->useProvisionalProxies,
|
||||||
Reverse::False,
|
Reverse::False,
|
||||||
latestVersion));
|
latestVersion));
|
||||||
self->trState->tenantId = l.tenantEntry.id;
|
if (self->trState->tenantId == TenantInfo::INVALID_TENANT) {
|
||||||
|
self->trState->tenantId = l.tenantEntry.id;
|
||||||
|
}
|
||||||
return l.tenantEntry;
|
return l.tenantEntry;
|
||||||
} else {
|
} 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;
|
return cachedLocationInfo.get().tenantEntry;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -283,16 +283,20 @@ bool verifyTenantPrefix(ProxyCommitData* const commitData, const CommitTransacti
|
|||||||
if (!m.param1.startsWith(tenantPrefix)) {
|
if (!m.param1.startsWith(tenantPrefix)) {
|
||||||
TraceEvent(SevWarnAlways, "TenantPrefixMismatch")
|
TraceEvent(SevWarnAlways, "TenantPrefixMismatch")
|
||||||
.suppressFor(60)
|
.suppressFor(60)
|
||||||
.detail("Prefix", tenantPrefix.toHexString())
|
.detail("Tenant", req.tenantInfo.name)
|
||||||
.detail("Key", m.param1.toHexString());
|
.detail("TenantID", req.tenantInfo.tenantId)
|
||||||
|
.detail("Prefix", tenantPrefix)
|
||||||
|
.detail("Key", m.param1);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m.type == MutationRef::ClearRange && !m.param2.startsWith(tenantPrefix)) {
|
if (m.type == MutationRef::ClearRange && !m.param2.startsWith(tenantPrefix)) {
|
||||||
TraceEvent(SevWarnAlways, "TenantClearRangePrefixMismatch")
|
TraceEvent(SevWarnAlways, "TenantClearRangePrefixMismatch")
|
||||||
.suppressFor(60)
|
.suppressFor(60)
|
||||||
.detail("Prefix", tenantPrefix.toHexString())
|
.detail("Tenant", req.tenantInfo.name)
|
||||||
.detail("Key", m.param2.toHexString());
|
.detail("TenantID", req.tenantInfo.tenantId)
|
||||||
|
.detail("Prefix", tenantPrefix)
|
||||||
|
.detail("Key", m.param2);
|
||||||
return false;
|
return false;
|
||||||
} else if (m.type == MutationRef::SetVersionstampedKey) {
|
} else if (m.type == MutationRef::SetVersionstampedKey) {
|
||||||
ASSERT(m.param1.size() >= 4);
|
ASSERT(m.param1.size() >= 4);
|
||||||
@ -301,8 +305,10 @@ bool verifyTenantPrefix(ProxyCommitData* const commitData, const CommitTransacti
|
|||||||
if (*offset < tenantPrefix.size()) {
|
if (*offset < tenantPrefix.size()) {
|
||||||
TraceEvent(SevWarnAlways, "TenantVersionstampInvalidOffset")
|
TraceEvent(SevWarnAlways, "TenantVersionstampInvalidOffset")
|
||||||
.suppressFor(60)
|
.suppressFor(60)
|
||||||
.detail("Prefix", tenantPrefix.toHexString())
|
.detail("Tenant", req.tenantInfo.name)
|
||||||
.detail("Key", m.param1.toHexString())
|
.detail("TenantID", req.tenantInfo.tenantId)
|
||||||
|
.detail("Prefix", tenantPrefix)
|
||||||
|
.detail("Key", m.param1)
|
||||||
.detail("Offset", *offset);
|
.detail("Offset", *offset);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@ -315,9 +321,11 @@ bool verifyTenantPrefix(ProxyCommitData* const commitData, const CommitTransacti
|
|||||||
(!rc.begin.startsWith(tenantPrefix) || !rc.end.startsWith(tenantPrefix))) {
|
(!rc.begin.startsWith(tenantPrefix) || !rc.end.startsWith(tenantPrefix))) {
|
||||||
TraceEvent(SevWarnAlways, "TenantReadConflictPrefixMismatch")
|
TraceEvent(SevWarnAlways, "TenantReadConflictPrefixMismatch")
|
||||||
.suppressFor(60)
|
.suppressFor(60)
|
||||||
.detail("Prefix", tenantPrefix.toHexString())
|
.detail("Tenant", req.tenantInfo.name)
|
||||||
.detail("BeginKey", rc.begin.toHexString())
|
.detail("TenantID", req.tenantInfo.tenantId)
|
||||||
.detail("EndKey", rc.end.toHexString());
|
.detail("Prefix", tenantPrefix)
|
||||||
|
.detail("BeginKey", rc.begin)
|
||||||
|
.detail("EndKey", rc.end);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -327,9 +335,11 @@ bool verifyTenantPrefix(ProxyCommitData* const commitData, const CommitTransacti
|
|||||||
(!wc.begin.startsWith(tenantPrefix) || !wc.end.startsWith(tenantPrefix))) {
|
(!wc.begin.startsWith(tenantPrefix) || !wc.end.startsWith(tenantPrefix))) {
|
||||||
TraceEvent(SevWarnAlways, "TenantWriteConflictPrefixMismatch")
|
TraceEvent(SevWarnAlways, "TenantWriteConflictPrefixMismatch")
|
||||||
.suppressFor(60)
|
.suppressFor(60)
|
||||||
.detail("Prefix", tenantPrefix.toHexString())
|
.detail("Tenant", req.tenantInfo.name)
|
||||||
.detail("BeginKey", wc.begin.toHexString())
|
.detail("TenantID", req.tenantInfo.tenantId)
|
||||||
.detail("EndKey", wc.end.toHexString());
|
.detail("Prefix", tenantPrefix)
|
||||||
|
.detail("BeginKey", wc.begin)
|
||||||
|
.detail("EndKey", wc.end);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user