@@ -30,49 +30,63 @@ namespace doris::cloud {
3030void internal_get_tablet_stats (MetaServiceCode& code, std::string& msg, Transaction* txn,
3131 const std::string& instance_id, const TabletIndexPB& idx,
3232 TabletStatsPB& stats, TabletStats& detached_stats, bool snapshot) {
33- auto begin_key = stats_tablet_key (
34- {instance_id, idx.table_id (), idx.index_id (), idx.partition_id (), idx.tablet_id ()});
35- auto end_key = stats_tablet_key (
36- {instance_id, idx.table_id (), idx.index_id (), idx.partition_id (), idx.tablet_id () + 1 });
33+ // clang-format off
34+ auto begin_key = stats_tablet_key ({instance_id, idx.table_id (), idx.index_id (), idx.partition_id (), idx.tablet_id ()});
35+ auto begin_key_check = begin_key;
36+ auto end_key = stats_tablet_key ({instance_id, idx.table_id (), idx.index_id (), idx.partition_id (), idx.tablet_id () + 1 });
37+ // clang-format on
38+ std::vector<std::pair<std::string, std::string>> stats_kvs;
39+ stats_kvs.reserve (5 ); // aggregate + data_size + num_rows + num_rowsets + num_segments
40+
3741 std::unique_ptr<RangeGetIterator> it;
38- TxnErrorCode err = txn->get (begin_key, end_key, &it, snapshot);
39- if (err != TxnErrorCode::TXN_OK ) {
40- code = cast_as<ErrCategory::READ >(err);
41- msg = fmt::format (" failed to get tablet stats, err={} tablet_id={}" , err, idx.tablet_id ());
42- return ;
43- }
44- if (!it->has_next ()) {
42+ do {
43+ TxnErrorCode err = txn->get (begin_key, end_key, &it, snapshot);
44+ if (err != TxnErrorCode::TXN_OK ) {
45+ code = cast_as<ErrCategory::READ >(err);
46+ msg = fmt::format (" failed to get tablet stats, err={} tablet_id={}" , err,
47+ idx.tablet_id ());
48+ return ;
49+ }
50+ while (it->has_next ()) {
51+ auto [k, v] = it->next ();
52+ stats_kvs.emplace_back (std::string {k.data (), k.size ()},
53+ std::string {v.data (), v.size ()});
54+ }
55+ begin_key = it->next_begin_key ();
56+ } while (it->more ());
57+
58+ if (stats_kvs.empty ()) {
4559 code = MetaServiceCode::TABLET_NOT_FOUND ;
4660 msg = fmt::format (" tablet stats not found, tablet_id={}" , idx.tablet_id ());
4761 return ;
4862 }
49- auto [k, v] = it->next ();
50- // First key MUST be tablet stats key
51- DCHECK (k == begin_key) << hex (k) << " vs " << hex (begin_key);
63+
64+ auto & [first_stats_key, v] = stats_kvs[0 ];
65+ // First key MUST be tablet stats key, the original non-detached one
66+ DCHECK (first_stats_key == begin_key_check)
67+ << hex (first_stats_key) << " vs " << hex (begin_key_check);
5268 if (!stats.ParseFromArray (v.data (), v.size ())) {
5369 code = MetaServiceCode::PROTOBUF_PARSE_ERR ;
54- msg = fmt::format (" marformed tablet stats value, key={}" , hex (k ));
70+ msg = fmt::format (" marformed tablet stats value, key={}" , hex (first_stats_key ));
5571 return ;
5672 }
5773 // Parse split tablet stats
58- int ret = get_detached_tablet_stats (*it, detached_stats);
74+ int ret = get_detached_tablet_stats (stats_kvs, detached_stats);
75+
5976 if (ret != 0 ) {
6077 code = MetaServiceCode::PROTOBUF_PARSE_ERR ;
61- msg = fmt::format (" marformed splitted tablet stats kv, key={}" , hex (k ));
78+ msg = fmt::format (" marformed splitted tablet stats kv, key={}" , hex (first_stats_key ));
6279 return ;
6380 }
6481}
6582
66- int get_detached_tablet_stats (RangeGetIterator& iter, TabletStats& detached_stats) {
67- while (iter.has_next ()) {
68- auto [k, v] = iter.next ();
69- int64_t val;
70- if (v.size () != sizeof (val)) [[unlikely]] {
71- LOG (WARNING ) << " malformed tablet stats value. key=" << hex (k);
72- return -1 ;
73- }
74-
75- // 0x01 "stats" ${instance_id} "tablet" ${table_id} ${index_id} ${partition_id} ${tablet_id} "data_size"
83+ int get_detached_tablet_stats (const std::vector<std::pair<std::string, std::string>>& stats_kvs,
84+ TabletStats& detached_stats) {
85+ if (stats_kvs.size () != 5 && stats_kvs.size () != 1 ) {
86+ LOG (WARNING ) << " incorrect tablet stats_kvs, it should be 1 or 5 size=" << stats_kvs.size ();
87+ }
88+ for (size_t i = 1 ; i < stats_kvs.size (); ++i) {
89+ std::string_view k (stats_kvs[i].first ), v (stats_kvs[i].second );
7690 k.remove_prefix (1 );
7791 constexpr size_t key_parts = 8 ;
7892 std::vector<std::tuple<std::variant<int64_t , std::string>, int , int >> out;
@@ -84,9 +98,14 @@ int get_detached_tablet_stats(RangeGetIterator& iter, TabletStats& detached_stat
8498 auto * suffix = std::get_if<std::string>(&std::get<0 >(out.back ()));
8599 if (!suffix) [[unlikely]] {
86100 LOG (WARNING ) << " malformed tablet stats key. key=" << hex (k);
87- return -1 ;
101+ return -2 ;
88102 }
89103
104+ int64_t val = 0 ;
105+ if (v.size () != sizeof (val)) [[unlikely]] {
106+ LOG (WARNING ) << " malformed tablet stats value v.size=" << v.size () << " key=" << hex (k);
107+ return -3 ;
108+ }
90109 std::memcpy (&val, v.data (), sizeof (val));
91110 if constexpr (std::endian::native == std::endian::big) {
92111 val = bswap_64 (val);
0 commit comments