From 7956bd581ab5fbabe8803dde69900460f0c37844 Mon Sep 17 00:00:00 2001 From: yi-xmu Date: Mon, 5 Jan 2026 17:20:40 +0800 Subject: [PATCH] Fix slice split 1. Only need to split slice when post ckpt size is greater than the current size of the slice and greater than the slice upper bound. 2. For non snapshot read, there is no need to return the deleted keys from the data store. --- .../data_store_service_client_closure.cpp | 25 ++++++++++++++----- tx_service/include/cc/template_cc_map.h | 6 ++++- tx_service/src/cc/local_cc_shards.cpp | 5 +++- 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/store_handler/data_store_service_client_closure.cpp b/store_handler/data_store_service_client_closure.cpp index efc27dce..2c3c8fe4 100644 --- a/store_handler/data_store_service_client_closure.cpp +++ b/store_handler/data_store_service_client_closure.cpp @@ -1276,11 +1276,17 @@ void LoadRangeSliceCallback(void *data, std::string key_str, value_str; uint64_t ts, ttl; + uint64_t snapshot_ts = fill_store_slice_req->SnapshotTs(); for (uint32_t i = 0; i < items_size; i++) { scan_next_closure->GetItem(i, key_str, value_str, ts, ttl); txservice::TxKey key = catalog_factory->CreateTxKey(key_str.data(), key_str.size()); + if (i == items_size - 1) + { + fill_store_slice_req->kv_start_key_ = + std::string_view(key.Data(), key.Size()); + } std::unique_ptr record = catalog_factory->CreateTxRecord(); bool is_deleted = false; @@ -1308,18 +1314,25 @@ void LoadRangeSliceCallback(void *data, std::abort(); } + if ((snapshot_ts == 0 && is_deleted) || + (snapshot_ts > 0 && snapshot_ts > ts)) + { + // if it is not a snapshot read, there is no need to return + // deleted keys. + // If it is a snapshot read and the latest version is newer than + // snapshot read ts, we need to backfill deleted key since there + // might be visible archive version of this key for snapshot ts. + // The caller will decide if reading archive table is necessary + // based on the deleted key version. + continue; + } + if (!is_deleted) { record->Deserialize(value_str.data(), offset); } } - if (i == items_size - 1) - { - fill_store_slice_req->kv_start_key_ = - std::string_view(key.Data(), key.Size()); - } - fill_store_slice_req->AddDataItem( std::move(key), std::move(record), ts, is_deleted); } diff --git a/tx_service/include/cc/template_cc_map.h b/tx_service/include/cc/template_cc_map.h index 6af998f4..d69b400c 100644 --- a/tx_service/include/cc/template_cc_map.h +++ b/tx_service/include/cc/template_cc_map.h @@ -5421,7 +5421,11 @@ class TemplateCcMap : public CcMap range_ptr->FindSlice(slice_key); assert(slice->PostCkptSize() != UINT64_MAX); - return slice->PostCkptSize() > StoreSlice::slice_upper_bound; + // Only need to split the slice when the post ckpt size of the slice + // is greater than the current size and greater than the slice upper + // bound. + return (slice->PostCkptSize() > StoreSlice::slice_upper_bound && + slice->PostCkptSize() > slice->Size()); }; const KeyT *const req_start_key = req.start_key_ != nullptr diff --git a/tx_service/src/cc/local_cc_shards.cpp b/tx_service/src/cc/local_cc_shards.cpp index 9e0414fe..94054024 100644 --- a/tx_service/src/cc/local_cc_shards.cpp +++ b/tx_service/src/cc/local_cc_shards.cpp @@ -5462,8 +5462,11 @@ void LocalCcShards::UpdateSlices(const TableName &table_name, : false; uint64_t slice_post_ckpt_size = curr_slice->PostCkptSize(); + // If post ckpt size of the slice is less than or equal to the current + // size, there is no need to split the slice. if (slice_post_ckpt_size == UINT64_MAX || - slice_post_ckpt_size <= StoreSlice::slice_upper_bound) + slice_post_ckpt_size <= StoreSlice::slice_upper_bound || + slice_post_ckpt_size <= curr_slice->Size()) { // Case 1: There is no unpersisted data in the current slice, so no // need to split the slice. Only to migrate this data from the old