Add read conflict for metadata txs that aren't lock-aware

This commit is contained in:
Andrew Noyes 2020-08-20 02:52:37 +00:00
parent bc5da1f6d7
commit 9cf3041393
3 changed files with 14 additions and 2 deletions

View File

@ -589,6 +589,7 @@ std::pair<MetricNameRef, KeyRef> decodeMetricConfKey( KeyRef const& prefix, KeyR
const KeyRef maxUIDKey = LiteralStringRef("\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff\xff");
const KeyRef databaseLockedKey = LiteralStringRef("\xff/dbLocked");
const KeyRef databaseLockedKeyEnd = LiteralStringRef("\xff/dbLocked\x00");
const KeyRef metadataVersionKey = LiteralStringRef("\xff/metadataVersion");
const KeyRef metadataVersionKeyEnd = LiteralStringRef("\xff/metadataVersion\x00");
const KeyRef metadataVersionRequiredValue = LiteralStringRef("\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00");

View File

@ -268,6 +268,7 @@ extern const KeyRef metricConfPrefix;
extern const KeyRef maxUIDKey;
extern const KeyRef databaseLockedKey;
extern const KeyRef databaseLockedKeyEnd;
extern const KeyRef metadataVersionKey;
extern const KeyRef metadataVersionKeyEnd;
extern const KeyRef metadataVersionRequiredValue;

View File

@ -345,7 +345,8 @@ struct ResolutionRequestBuilder {
return *out;
}
void addTransaction(CommitTransactionRef& trIn, int transactionNumberInBatch) {
void addTransaction(CommitTransactionRequest& trRequest, int transactionNumberInBatch) {
auto& trIn = trRequest.transaction;
// SOMEDAY: There are a couple of unnecessary O( # resolvers ) steps here
outTr.assign(requests.size(), NULL);
ASSERT( transactionNumberInBatch >= 0 && transactionNumberInBatch < 32768 );
@ -363,6 +364,15 @@ struct ResolutionRequestBuilder {
getOutTransaction(0, trIn.read_snapshot).mutations.push_back(requests[0].arena, m);
}
}
if (isTXNStateTransaction && !trRequest.isLockAware()) {
// This mitigates https://github.com/apple/foundationdb/issues/3647.
// Since this transaction is not lock aware, \xff/dbLocked must not
// have been set at this transaction's read snapshot. If that
// changes by commit time, then it won't commit on any proxy because
// of a conflict.
trIn.read_conflict_ranges.push_back_deep(trRequest.arena,
KeyRangeRef(databaseLockedKey, databaseLockedKeyEnd));
}
for(auto& r : trIn.read_conflict_ranges) {
auto ranges = self->keyResolvers.intersectingRanges( r );
std::set<int> resolvers;
@ -587,7 +597,7 @@ ACTOR Future<Void> commitBatch(
int conflictRangeCount = 0;
state int64_t maxTransactionBytes = 0;
for (int t = 0; t<trs.size(); t++) {
requests.addTransaction(trs[t].transaction, t);
requests.addTransaction(trs[t], t);
conflictRangeCount += trs[t].transaction.read_conflict_ranges.size() + trs[t].transaction.write_conflict_ranges.size();
//TraceEvent("MPTransactionDump", self->dbgid).detail("Snapshot", trs[t].transaction.read_snapshot);
//for(auto& m : trs[t].transaction.mutations)