Fix memory bug in index prefetch code path (#8187)
Same address is being reused for multiple queries incorrectly.
This commit is contained in:
parent
b19f1b5e3b
commit
e9a12b4a1a
|
@ -4129,14 +4129,12 @@ void preprocessMappedKey(Tuple& mappedKeyFormatTuple, std::vector<Optional<Tuple
|
|||
}
|
||||
}
|
||||
|
||||
Key constructMappedKey(KeyValueRef* keyValue,
|
||||
std::vector<Optional<Tuple>>& vec,
|
||||
Tuple& mappedKeyTuple,
|
||||
Tuple& mappedKeyFormatTuple) {
|
||||
Key constructMappedKey(KeyValueRef* keyValue, std::vector<Optional<Tuple>>& vec, Tuple& mappedKeyFormatTuple) {
|
||||
// Lazily parse key and/or value to tuple because they may not need to be a tuple if not used.
|
||||
Optional<Tuple> keyTuple;
|
||||
Optional<Tuple> valueTuple;
|
||||
mappedKeyTuple.clear();
|
||||
Tuple mappedKeyTuple;
|
||||
|
||||
mappedKeyTuple.reserve(vec.size());
|
||||
|
||||
for (int i = 0; i < vec.size(); i++) {
|
||||
|
@ -4183,12 +4181,11 @@ TEST_CASE("/fdbserver/storageserver/constructMappedKey") {
|
|||
Tuple mappedKeyFormatTuple =
|
||||
Tuple::makeTuple("normal"_sr, "{{escaped}}"_sr, "{K[2]}"_sr, "{V[0]}"_sr, "{...}"_sr);
|
||||
|
||||
Tuple mappedKeyTuple;
|
||||
std::vector<Optional<Tuple>> vt;
|
||||
bool isRangeQuery = false;
|
||||
preprocessMappedKey(mappedKeyFormatTuple, vt, isRangeQuery);
|
||||
|
||||
Key mappedKey = constructMappedKey(&kvr, vt, mappedKeyTuple, mappedKeyFormatTuple);
|
||||
Key mappedKey = constructMappedKey(&kvr, vt, mappedKeyFormatTuple);
|
||||
|
||||
Key expectedMappedKey =
|
||||
Tuple::makeTuple("normal"_sr, "{escaped}"_sr, "key-2"_sr, "value-0"_sr).getDataAsStandalone();
|
||||
|
@ -4200,11 +4197,10 @@ TEST_CASE("/fdbserver/storageserver/constructMappedKey") {
|
|||
{
|
||||
Tuple mappedKeyFormatTuple = Tuple::makeTuple("{{{{}}"_sr, "}}"_sr);
|
||||
|
||||
Tuple mappedKeyTuple;
|
||||
std::vector<Optional<Tuple>> vt;
|
||||
bool isRangeQuery = false;
|
||||
preprocessMappedKey(mappedKeyFormatTuple, vt, isRangeQuery);
|
||||
Key mappedKey = constructMappedKey(&kvr, vt, mappedKeyTuple, mappedKeyFormatTuple);
|
||||
Key mappedKey = constructMappedKey(&kvr, vt, mappedKeyFormatTuple);
|
||||
|
||||
Key expectedMappedKey = Tuple::makeTuple("{{}"_sr, "}"_sr).getDataAsStandalone();
|
||||
// std::cout << printable(mappedKey) << " == " << printable(expectedMappedKey) << std::endl;
|
||||
|
@ -4214,11 +4210,10 @@ TEST_CASE("/fdbserver/storageserver/constructMappedKey") {
|
|||
{
|
||||
Tuple mappedKeyFormatTuple = Tuple::makeTuple("{{{{}}"_sr, "}}"_sr);
|
||||
|
||||
Tuple mappedKeyTuple;
|
||||
std::vector<Optional<Tuple>> vt;
|
||||
bool isRangeQuery = false;
|
||||
preprocessMappedKey(mappedKeyFormatTuple, vt, isRangeQuery);
|
||||
Key mappedKey = constructMappedKey(&kvr, vt, mappedKeyTuple, mappedKeyFormatTuple);
|
||||
Key mappedKey = constructMappedKey(&kvr, vt, mappedKeyFormatTuple);
|
||||
|
||||
Key expectedMappedKey = Tuple::makeTuple("{{}"_sr, "}"_sr).getDataAsStandalone();
|
||||
// std::cout << printable(mappedKey) << " == " << printable(expectedMappedKey) << std::endl;
|
||||
|
@ -4229,12 +4224,11 @@ TEST_CASE("/fdbserver/storageserver/constructMappedKey") {
|
|||
Tuple mappedKeyFormatTuple = Tuple::makeTuple("{K[100]}"_sr);
|
||||
state bool throwException = false;
|
||||
try {
|
||||
Tuple mappedKeyTuple;
|
||||
std::vector<Optional<Tuple>> vt;
|
||||
bool isRangeQuery = false;
|
||||
preprocessMappedKey(mappedKeyFormatTuple, vt, isRangeQuery);
|
||||
|
||||
Key mappedKey = constructMappedKey(&kvr, vt, mappedKeyTuple, mappedKeyFormatTuple);
|
||||
Key mappedKey = constructMappedKey(&kvr, vt, mappedKeyFormatTuple);
|
||||
} catch (Error& e) {
|
||||
ASSERT(e.code() == error_code_mapper_bad_index);
|
||||
throwException = true;
|
||||
|
@ -4245,12 +4239,11 @@ TEST_CASE("/fdbserver/storageserver/constructMappedKey") {
|
|||
Tuple mappedKeyFormatTuple = Tuple::makeTuple("{...}"_sr, "last-element"_sr);
|
||||
state bool throwException2 = false;
|
||||
try {
|
||||
Tuple mappedKeyTuple;
|
||||
std::vector<Optional<Tuple>> vt;
|
||||
bool isRangeQuery = false;
|
||||
preprocessMappedKey(mappedKeyFormatTuple, vt, isRangeQuery);
|
||||
|
||||
Key mappedKey = constructMappedKey(&kvr, vt, mappedKeyTuple, mappedKeyFormatTuple);
|
||||
Key mappedKey = constructMappedKey(&kvr, vt, mappedKeyFormatTuple);
|
||||
} catch (Error& e) {
|
||||
ASSERT(e.code() == error_code_mapper_bad_range_decriptor);
|
||||
throwException2 = true;
|
||||
|
@ -4261,12 +4254,11 @@ TEST_CASE("/fdbserver/storageserver/constructMappedKey") {
|
|||
Tuple mappedKeyFormatTuple = Tuple::makeTuple("{K[not-a-number]}"_sr);
|
||||
state bool throwException3 = false;
|
||||
try {
|
||||
Tuple mappedKeyTuple;
|
||||
std::vector<Optional<Tuple>> vt;
|
||||
bool isRangeQuery = false;
|
||||
preprocessMappedKey(mappedKeyFormatTuple, vt, isRangeQuery);
|
||||
|
||||
Key mappedKey = constructMappedKey(&kvr, vt, mappedKeyTuple, mappedKeyFormatTuple);
|
||||
Key mappedKey = constructMappedKey(&kvr, vt, mappedKeyFormatTuple);
|
||||
} catch (Error& e) {
|
||||
ASSERT(e.code() == error_code_mapper_bad_index);
|
||||
throwException3 = true;
|
||||
|
@ -4324,7 +4316,6 @@ ACTOR Future<GetMappedKeyValuesReply> mapKeyValues(StorageServer* data,
|
|||
g_traceBatch.addEvent(
|
||||
"TransactionDebug", pOriginalReq->options.get().debugID.get().first(), "storageserver.mapKeyValues.Start");
|
||||
state Tuple mappedKeyFormatTuple;
|
||||
state Tuple mappedKeyTuple;
|
||||
|
||||
try {
|
||||
mappedKeyFormatTuple = Tuple::unpack(mapper);
|
||||
|
@ -4361,7 +4352,7 @@ ACTOR Future<GetMappedKeyValuesReply> mapKeyValues(StorageServer* data,
|
|||
kvm->value = ""_sr;
|
||||
}
|
||||
|
||||
Key mappedKey = constructMappedKey(it, vt, mappedKeyTuple, mappedKeyFormatTuple);
|
||||
Key mappedKey = constructMappedKey(it, vt, mappedKeyFormatTuple);
|
||||
// Make sure the mappedKey is always available, so that it's good even we want to get key asynchronously.
|
||||
result.arena.dependsOn(mappedKey.arena());
|
||||
|
||||
|
|
Loading…
Reference in New Issue