Added a new option to bypass unreadable protection in read your writes for calls to get
This commit is contained in:
parent
54ed5de648
commit
709df795c0
|
@ -42,7 +42,7 @@ const RYWIterator::SEGMENT_TYPE RYWIterator::typeMap[12] = {
|
|||
};
|
||||
|
||||
RYWIterator::SEGMENT_TYPE RYWIterator::type() const {
|
||||
if (is_unreadable())
|
||||
if (is_unreadable() && !bypassUnreadable)
|
||||
throw accessed_unreadable();
|
||||
|
||||
return typeMap[writes.type() * 3 + cache.type()];
|
||||
|
@ -72,7 +72,7 @@ ExtStringRef RYWIterator::endKey() {
|
|||
}
|
||||
|
||||
const KeyValueRef* RYWIterator::kv(Arena& arena) {
|
||||
if (is_unreadable())
|
||||
if (is_unreadable() && !bypassUnreadable)
|
||||
throw accessed_unreadable();
|
||||
|
||||
if (writes.is_unmodified_range()) {
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
class RYWIterator {
|
||||
public:
|
||||
RYWIterator(SnapshotCache* snapshotCache, WriteMap* writeMap)
|
||||
: cache(snapshotCache), writes(writeMap), begin_key_cmp(0), end_key_cmp(0) {}
|
||||
: cache(snapshotCache), writes(writeMap), begin_key_cmp(0), end_key_cmp(0), bypassUnreadable(false) {}
|
||||
|
||||
enum SEGMENT_TYPE { UNKNOWN_RANGE, EMPTY_RANGE, KV };
|
||||
static const SEGMENT_TYPE typeMap[12];
|
||||
|
@ -59,6 +59,8 @@ public:
|
|||
|
||||
void skipContiguousBack(KeyRef key);
|
||||
|
||||
void bypassUnreadableProtection() { bypassUnreadable = true; }
|
||||
|
||||
WriteMap::iterator& extractWriteMapIterator();
|
||||
// Really this should return an iterator by value, but for performance it's convenient to actually grab the internal
|
||||
// one. Consider copying the return value if performance isn't critical. If you modify the returned iterator, it
|
||||
|
@ -72,6 +74,7 @@ private:
|
|||
SnapshotCache::iterator cache;
|
||||
WriteMap::iterator writes;
|
||||
KeyValueRef temp;
|
||||
bool bypassUnreadable;
|
||||
|
||||
void updateCmp();
|
||||
};
|
||||
|
|
|
@ -84,6 +84,9 @@ public:
|
|||
static Future<Optional<Value>> read(ReadYourWritesTransaction* ryw, GetValueReq read, Iter* it) {
|
||||
// This overload is required to provide postcondition: it->extractWriteMapIterator().segmentContains(read.key)
|
||||
|
||||
if (ryw->options.bypassUnreadable) {
|
||||
it->bypassUnreadableProtection();
|
||||
}
|
||||
it->skip(read.key);
|
||||
state bool dependent = it->is_dependent();
|
||||
if (it->is_kv()) {
|
||||
|
@ -2237,6 +2240,11 @@ void ReadYourWritesTransaction::setOptionImpl(FDBTransactionOptions::Option opti
|
|||
validateOptionValue(value, false);
|
||||
options.specialKeySpaceChangeConfiguration = true;
|
||||
break;
|
||||
case FDBTransactionOptions::BYPASS_UNREADABLE:
|
||||
validateOptionValue(value, false);
|
||||
TraceEvent("ReadVersionStampValueOptionSet");
|
||||
options.bypassUnreadable = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -42,6 +42,7 @@ struct ReadYourWritesTransactionOptions {
|
|||
double timeoutInSeconds;
|
||||
int maxRetries;
|
||||
int snapshotRywEnabled;
|
||||
bool bypassUnreadable : 1;
|
||||
|
||||
ReadYourWritesTransactionOptions() {}
|
||||
explicit ReadYourWritesTransactionOptions(Transaction const& tr);
|
||||
|
|
|
@ -203,6 +203,7 @@ public:
|
|||
bool is_empty_range() const { return type() == EMPTY_RANGE; }
|
||||
bool is_dependent() const { return false; }
|
||||
bool is_unreadable() const { return false; }
|
||||
void bypassUnreadableProtection() {}
|
||||
|
||||
ExtStringRef beginKey() const {
|
||||
if (offset == 0) {
|
||||
|
|
|
@ -192,6 +192,9 @@ description is not currently required but encouraged.
|
|||
description="Enable tracing for all transactions. This is the default." />
|
||||
<Option name="distributed_transaction_trace_disable" code="601"
|
||||
description="Disable tracing for all transactions." />
|
||||
<Option name="transaction_bypass_unreadable" code="700"
|
||||
description="Allows ``get`` operations to read from sections of keyspace that have become unreadable because of versionstamp operations."
|
||||
defaultFor="1100"/>
|
||||
</Scope>
|
||||
|
||||
<Scope name="TransactionOption">
|
||||
|
@ -284,6 +287,8 @@ description is not currently required but encouraged.
|
|||
description="Adds a parent to the Span of this transaction. Used for transaction tracing. A span can be identified with any 16 bytes"/>
|
||||
<Option name="expensive_clear_cost_estimation_enable" code="1000"
|
||||
description="Asks storage servers for how many bytes a clear key range contains. Otherwise uses the location cache to roughly estimate this." />
|
||||
<Option name="bypass_unreadable" code="1100"
|
||||
description="Allows ``get`` operations to read from sections of keyspace that have become unreadable because of versionstamp operations." />
|
||||
</Scope>
|
||||
|
||||
<!-- The enumeration values matter - do not change them without
|
||||
|
|
|
@ -313,6 +313,10 @@ struct UnreadableWorkload : TestWorkload {
|
|||
state bool snapshot;
|
||||
state KeySelectorRef begin;
|
||||
state KeySelectorRef end;
|
||||
state bool bypassUnreadable = deterministicRandom()->coinflip();
|
||||
if (readVerisonStampValues) {
|
||||
tr.setOption(FDBTransactionOptions::BYPASS_UNREADABLE);
|
||||
}
|
||||
|
||||
setMap[normalKeys.begin] = ValueRef();
|
||||
setMap[normalKeys.end] = ValueRef();
|
||||
|
@ -377,6 +381,9 @@ struct UnreadableWorkload : TestWorkload {
|
|||
setMap = std::map<KeyRef, ValueRef>();
|
||||
unreadableMap = KeyRangeMap<bool>();
|
||||
tr = ReadYourWritesTransaction(cx);
|
||||
if (bypassUnreadable) {
|
||||
tr.setOption(FDBTransactionOptions::BYPASS_UNREADABLE);
|
||||
}
|
||||
arena = Arena();
|
||||
|
||||
setMap[normalKeys.begin] = ValueRef();
|
||||
|
@ -422,6 +429,9 @@ struct UnreadableWorkload : TestWorkload {
|
|||
setMap = std::map<KeyRef, ValueRef>();
|
||||
unreadableMap = KeyRangeMap<bool>();
|
||||
tr = ReadYourWritesTransaction(cx);
|
||||
if (bypassUnreadable) {
|
||||
tr.setOption(FDBTransactionOptions::BYPASS_UNREADABLE);
|
||||
}
|
||||
arena = Arena();
|
||||
|
||||
setMap[normalKeys.begin] = ValueRef();
|
||||
|
@ -441,7 +451,7 @@ struct UnreadableWorkload : TestWorkload {
|
|||
|
||||
if (!value.isError() || value.getError().code() == error_code_accessed_unreadable) {
|
||||
//TraceEvent("RYWT_Get").detail("Key", printable(key)).detail("IsUnreadable", value.isError());
|
||||
if (snapshot) {
|
||||
if (snapshot || bypassUnreadable) {
|
||||
ASSERT(!value.isError());
|
||||
} else {
|
||||
ASSERT(unreadableMap[key] == value.isError());
|
||||
|
@ -451,6 +461,9 @@ struct UnreadableWorkload : TestWorkload {
|
|||
setMap = std::map<KeyRef, ValueRef>();
|
||||
unreadableMap = KeyRangeMap<bool>();
|
||||
tr = ReadYourWritesTransaction(cx);
|
||||
if (bypassUnreadable) {
|
||||
tr.setOption(FDBTransactionOptions::BYPASS_UNREADABLE);
|
||||
}
|
||||
arena = Arena();
|
||||
|
||||
setMap[normalKeys.begin] = ValueRef();
|
||||
|
|
Loading…
Reference in New Issue