Fix memory bug in index prefetch code path (#8187)

Same address is being reused for multiple queries incorrectly.
This commit is contained in:
Hao Fu 2022-09-15 13:18:37 -07:00 committed by GitHub
parent b19f1b5e3b
commit e9a12b4a1a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 10 additions and 19 deletions

View File

@ -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());