Skip to content

Commit

Permalink
fix row key not in standard format (#7901) (#7912)
Browse files Browse the repository at this point in the history
close #3099, close #7762
  • Loading branch information
ti-chi-bot authored Aug 9, 2023
1 parent f00dea7 commit 9393dbf
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 15 deletions.
40 changes: 40 additions & 0 deletions dbms/src/Storages/DeltaMerge/RowKeyRange.h
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,46 @@ struct RowKeyValue
{
size_t cursor = 0;
int_value = DB::DecodeInt64(cursor, *value);
if (unlikely(value->size() != sizeof(Int64)))
{
// For int type handle, the standard key enconding format should be t{table_id}_r{handle_value}.
// But TiKV may generate region range keys which are not strictly following the standard format.
// More concretely, the key may be t{table_id}_r{handle_value} + some other bytes.
// We need to adapt the key to the standard format.
// For example, the key may be t100_r1000 + 0x00, we need to adapt it to t100_r1001.
// This is ok, because
// 1) if the key is the start range, then [t100_r1000 + 0x00, xxx) has the same semantics with [t100_r1001, xxx)
// 2) if the key is the end range, then [xxx, t100_r1000 + 0x00) also has the same semantics with [xxx, t100_r1001)
//
// Note if the `int_value` is Int64::max_value,
// it is a value generated by tiflash itself to means +inf()(which is RowKeyValue::INT_HANDLE_MAX_KEY).
// So we can just ignore it.
if (value->size() != sizeof(UInt64) + 1 || value->back() != 0x00)
{
LOG_WARNING(
Logger::get(),
"Meet rowkey {} with unexpected encoding format",
Redact::keyToDebugString(value->data(), value->size()));
}
else
{
if (int_value < std::numeric_limits<Int64>::max())
{
LOG_WARNING(
Logger::get(),
"Meet rowkey {} which has an extra zero suffix",
Redact::keyToDebugString(value->data(), value->size()));
int_value = int_value + 1;
WriteBufferFromOwnString ss;
DB::EncodeInt64(int_value, ss);
value = std::make_shared<String>(ss.releaseStr());
}
else
{
// ignore RowKeyValue::INT_HANDLE_MAX_KEY
}
}
}
}
}

Expand Down
30 changes: 15 additions & 15 deletions dbms/src/Storages/DeltaMerge/tests/gtest_key_range.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -119,21 +119,21 @@ TEST(RowKey, ToNextKeyIntHandle)
/* row_key_column_size */ 1);
EXPECT_EQ(0, compare(next.toRowKeyValueRef(), range.getEnd()));
}
// Note: The following does not work, because {20,00} will be regarded as Key=20 in RowKeyRange::fromRegionRange.
// {
// auto key_end = RecordKVFormat::genRawKey(1, 20);
// key_end.push_back(0);
// auto tikv_key_end = RecordKVFormat::encodeAsTiKVKey(key_end);
// const auto range_keys = std::make_shared<RegionRangeKeys>(
// RecordKVFormat::genKey(1, 0),
// std::move(tikv_key_end));
// const auto range = RowKeyRange::fromRegionRange(
// range_keys,
// /* table_id */ 1,
// /* is_common_handle */ false,
// /* row_key_column_size */ 1);
// EXPECT_EQ(0, compare(next.toRowKeyValueRef(), range.getEnd()));
// }
// Note: {20,00} will be regarded as Key=21 in RowKeyRange::fromRegionRange.
{
auto key_end = RecordKVFormat::genRawKey(1, 20);
key_end.push_back(0);
auto tikv_key_end = RecordKVFormat::encodeAsTiKVKey(key_end);
const auto range_keys = std::make_shared<RegionRangeKeys>(
RecordKVFormat::genKey(1, 0),
std::move(tikv_key_end));
const auto range = RowKeyRange::fromRegionRange(
range_keys,
/* table_id */ 1,
/* is_common_handle */ false,
/* row_key_column_size */ 1);
EXPECT_EQ(0, compare(next.toRowKeyValueRef(), range.getEnd()));
}
}

TEST(RowKey, ToNextKeyCommonHandle)
Expand Down

0 comments on commit 9393dbf

Please sign in to comment.