Coverage Report

Created: 2026-09-09 14:27

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/cloud/cloud_meta_mgr.h
Line
Count
Source
1
// Licensed to the Apache Software Foundation (ASF) under one
2
// or more contributor license agreements.  See the NOTICE file
3
// distributed with this work for additional information
4
// regarding copyright ownership.  The ASF licenses this file
5
// to you under the Apache License, Version 2.0 (the
6
// "License"); you may not use this file except in compliance
7
// with the License.  You may obtain a copy of the License at
8
//
9
//   http://www.apache.org/licenses/LICENSE-2.0
10
//
11
// Unless required by applicable law or agreed to in writing,
12
// software distributed under the License is distributed on an
13
// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14
// KIND, either express or implied.  See the License for the
15
// specific language governing permissions and limitations
16
// under the License.
17
#pragma once
18
19
#include <gen_cpp/olap_file.pb.h>
20
21
#include <future>
22
#include <memory>
23
#include <ranges>
24
#include <string>
25
#include <tuple>
26
#include <unordered_map>
27
#include <utility>
28
#include <variant>
29
#include <vector>
30
31
#include "cloud/cloud_tablet.h"
32
#include "common/status.h"
33
#include "storage/rowset/rowset_fwd.h"
34
#include "storage/rowset/rowset_meta.h"
35
#include "util/s3_util.h"
36
37
namespace doris {
38
39
class DeleteBitmap;
40
class StreamLoadContext;
41
class CloudTablet;
42
class CloudTabletMgr;
43
class TabletMeta;
44
class TabletSchema;
45
class TabletMetaPB;
46
class RowsetMeta;
47
48
namespace cloud {
49
50
class FinishTabletJobResponse;
51
class CommitTxnResponse;
52
class ClusterPB;
53
class GetClusterStatusResponse;
54
class StartTabletJobResponse;
55
class TabletJobInfoPB;
56
class TabletStatsPB;
57
class TabletIndexPB;
58
class HostLevelMSRpcRateLimiters;
59
class MSBackpressureHandler;
60
61
using StorageVaultInfos = std::vector<
62
        std::tuple<std::string, std::variant<S3Conf, HdfsVaultInfo>, StorageVaultPB_PathFormat>>;
63
64
// run tasks in bthread with concurrency and wait until all tasks done
65
// it stops running tasks if there are any tasks return !ok, leaving some tasks untouched
66
// return OK if all tasks successfully done, otherwise return the result of the failed task
67
Status bthread_fork_join(const std::vector<std::function<Status()>>& tasks, int concurrency);
68
69
// An async wrap of `bthread_fork_join` declared previously using promise-future
70
// return OK if fut successfully created, otherwise return error
71
Status bthread_fork_join(std::vector<std::function<Status()>>&& tasks, int concurrency,
72
                         std::future<Status>* fut);
73
74
// Returns the exact actual_code when recognized. An unknown actual_code uses an explicit non-OK
75
// legacy fallback and otherwise fails closed. Responses from a legacy Meta Service use code.
76
// Exposed for unit tests.
77
MetaServiceCode get_response_code(const MetaServiceResponseStatus& status);
78
79
// Decodes the raw status and generic cluster generations in milliseconds, plus whether the status
80
// generation can initialize a takeover timer. Raw values are retained for exact token comparison.
81
std::tuple<int64_t, int64_t, bool> get_cluster_status_mtime(const ClusterPB& cluster);
82
83
// Validates and decodes a cluster-status response. When requester identity was requested, an empty
84
// identity is an incomplete response and leaves both outputs unchanged so callers keep their last
85
// known-good cache.
86
Status decode_cluster_status_response(
87
        const GetClusterStatusResponse& response,
88
        std::unordered_map<std::string, std::tuple<int32_t, int64_t, int64_t, bool>>* result,
89
        std::string* my_cluster_id);
90
91
// Applies owner updates returned by a successful commit to tablets already cached on this BE.
92
// Exposed as a separate operation so direct-BE commit handling can be tested without an RPC.
93
void consume_commit_owner_updates(CloudTabletMgr& tablet_mgr, const CommitTxnResponse& response);
94
// Applies owner updates for successful commits and for a 2PC duplicate-visible replay whose first
95
// response was lost, while preserving the existing RPC error returned to the caller.
96
void consume_commit_owner_updates_after_commit(CloudTabletMgr& tablet_mgr,
97
                                               const Status& commit_status, bool is_2pc,
98
                                               const CommitTxnResponse& response);
99
100
class CloudMetaMgr {
101
public:
102
301
    CloudMetaMgr() = default;
103
    ~CloudMetaMgr() = default;
104
    CloudMetaMgr(const CloudMetaMgr&) = delete;
105
    CloudMetaMgr& operator=(const CloudMetaMgr&) = delete;
106
107
    Status get_tablet_meta(int64_t tablet_id, std::shared_ptr<TabletMeta>* tablet_meta);
108
109
    Status sync_tablet_rowsets(CloudTablet* tablet, const SyncOptions& options = {},
110
                               SyncRowsetStats* sync_stats = nullptr);
111
    Status sync_tablet_rowsets_unlocked(
112
            CloudTablet* tablet, std::unique_lock<bthread::Mutex>& lock /* _sync_meta_lock */,
113
            const SyncOptions& options = {}, SyncRowsetStats* sync_stats = nullptr);
114
115
    Status prepare_rowset(const RowsetMeta& rs_meta, const std::string& job_id, int64_t table_id,
116
                          std::shared_ptr<RowsetMeta>* existed_rs_meta = nullptr);
117
118
    Status commit_rowset(RowsetMeta& rs_meta, const std::string& job_id, int64_t table_id,
119
                         std::shared_ptr<RowsetMeta>* existed_rs_meta = nullptr,
120
                         RowsetMeta* attach_row_binlog = nullptr,
121
                         std::shared_ptr<RowsetMeta>* existed_attach_row_binlog = nullptr);
122
    void cache_committed_rowset(RowsetMetaSharedPtr rs_meta, int64_t expiration_time);
123
124
    Status update_tmp_rowset(const RowsetMeta& rs_meta, int64_t table_id,
125
                             const RowsetMeta* attach_row_binlog = nullptr);
126
127
    Status update_packed_file_info(const std::string& packed_file_path,
128
                                   const cloud::PackedFileInfoPB& packed_file_info,
129
                                   int64_t table_id);
130
131
    Status commit_txn(const StreamLoadContext& ctx, bool is_2pc);
132
133
    Status abort_txn(const StreamLoadContext& ctx);
134
135
    Status precommit_txn(const StreamLoadContext& ctx);
136
137
    /**
138
     * Prepares a restore job for a tablet to meta-service
139
     * Change the state to PREPARED
140
     * PREPARED state means the meta of tablet has been uploaded but not finalized.
141
     */
142
    Status prepare_restore_job(const TabletMetaPB& tablet_meta);
143
144
    /**
145
     * Commits a restore job for a tablet to meta-service
146
     * Change the state from PREPARED to COMMITTED
147
     * COMMITTED state means the meta of tablet has been finalized.
148
     */
149
    Status commit_restore_job(const int64_t tablet_id);
150
151
    /**
152
     * Finish a restore job for a tablet from meta-service
153
     * Change the state to final state.
154
     * If is_completed = true, change the state from COMMITTED to COMPLETED
155
     * If is_completed = false, change the state to from PREPARED/COMMITTED to DROPPED
156
     * COMPLETED state means the job is finished, the restored data should be visible.
157
     * DROPPED state means the job is aborted.
158
     * COMPLETED/DROPPED are the final states, jobs with final states will be recycled.
159
     */
160
    Status finish_restore_job(const int64_t tablet_id, bool is_completed);
161
162
    /**
163
     * Gets storage vault (storage backends) from meta-service
164
     * 
165
     * @param vault_info output param, all storage backends
166
     * @param is_vault_mode output param, true for pure vault mode, false for legacy mode
167
     * @return status
168
     */
169
    Status get_storage_vault_info(StorageVaultInfos* vault_infos, bool* is_vault_mode);
170
171
    Status prepare_tablet_job(const TabletJobInfoPB& job, StartTabletJobResponse* res);
172
173
    Status commit_tablet_job(const TabletJobInfoPB& job, FinishTabletJobResponse* res);
174
175
    Status abort_tablet_job(const TabletJobInfoPB& job);
176
177
    Status lease_tablet_job(const TabletJobInfoPB& job);
178
179
    Status update_delete_bitmap(const CloudTablet& tablet, int64_t lock_id, int64_t initiator,
180
                                DeleteBitmap* delete_bitmap, DeleteBitmap* delete_bitmap_v2,
181
                                std::string rowset_id,
182
                                std::optional<StorageResource> storage_resource,
183
                                int64_t store_version, int64_t table_id, int64_t txn_id = -1,
184
                                bool is_explicit_txn = false, int64_t next_visible_version = -1);
185
186
    Status cloud_update_delete_bitmap_without_lock(
187
            const CloudTablet& tablet, DeleteBitmap* delete_bitmap,
188
            std::map<std::string, int64_t>& rowset_to_versions, int64_t table_id,
189
            int64_t pre_rowset_agg_start_version = 0, int64_t pre_rowset_agg_end_version = 0);
190
191
    Status get_delete_bitmap_update_lock(const CloudTablet& tablet, int64_t lock_id,
192
                                         int64_t initiator);
193
194
    void remove_delete_bitmap_update_lock(int64_t table_id, int64_t lock_id, int64_t initiator,
195
                                          int64_t tablet_id);
196
197
    // Fill version holes by creating empty rowsets for missing versions
198
    Status fill_version_holes(CloudTablet* tablet, int64_t max_version,
199
                              std::unique_lock<BthreadSharedMutex>& wlock);
200
201
    // Create an empty rowset to fill a version hole
202
    Status create_empty_rowset_for_hole(CloudTablet* tablet, int64_t version,
203
                                        RowsetMetaSharedPtr prev_rowset_meta,
204
                                        RowsetSharedPtr* rowset);
205
206
    Status list_snapshot(std::vector<SnapshotInfoPB>& snapshots);
207
    Status get_snapshot_properties(SnapshotSwitchStatus& switch_status,
208
                                   int64_t& max_reserved_snapshots,
209
                                   int64_t& snapshot_interval_seconds);
210
211
    // Get all cluster status for the instance
212
    // Returns cluster_id -> (status, status_mtime_ms, generic_mtime_ms, status_mtime_trusted)
213
    // If my_cluster_id is not null, also returns the requesting node's cluster_id
214
    Status get_cluster_status(
215
            std::unordered_map<std::string, std::tuple<int32_t, int64_t, int64_t, bool>>* result,
216
            std::string* my_cluster_id = nullptr);
217
218
0
    void set_host_level_ms_rpc_rate_limiters(HostLevelMSRpcRateLimiters* limiters) {
219
0
        host_level_ms_rpc_rate_limiters_ = limiters;
220
0
    }
221
222
0
    void set_ms_backpressure_handler(MSBackpressureHandler* handler) {
223
0
        ms_backpressure_handler_ = handler;
224
0
    }
225
226
private:
227
    bool sync_tablet_delete_bitmap_by_cache(CloudTablet* tablet, std::ranges::range auto&& rs_metas,
228
                                            DeleteBitmap* delete_bitmap);
229
230
    Status sync_tablet_delete_bitmap(CloudTablet* tablet, int64_t old_max_version,
231
                                     std::ranges::range auto&& rs_metas, const TabletStatsPB& stats,
232
                                     const TabletIndexPB& idx, DeleteBitmap* delete_bitmap,
233
                                     bool full_sync, SyncRowsetStats* sync_stats,
234
                                     int32_t read_version, bool full_sync_v2);
235
    Status _read_tablet_delete_bitmap_v2(CloudTablet* tablet, int64_t old_max_version,
236
                                         std::ranges::range auto&& rs_metas,
237
                                         DeleteBitmap* delete_bitmap, GetDeleteBitmapResponse& res,
238
                                         int64_t& remote_delete_bitmap_bytes, bool full_sync_v2);
239
    Status _log_mow_delete_bitmap(CloudTablet* tablet, GetRowsetResponse& resp,
240
                                  DeleteBitmap& delete_bitmap, int64_t old_max_version,
241
                                  bool full_sync, int32_t read_version);
242
    Status _check_delete_bitmap_v2_correctness(CloudTablet* tablet, GetRowsetRequest& req,
243
                                               GetRowsetResponse& resp, int64_t old_max_version);
244
245
    Status _get_delete_bitmap_from_ms(GetDeleteBitmapRequest& req, GetDeleteBitmapResponse& res);
246
    Status _get_delete_bitmap_from_ms_by_batch(GetDeleteBitmapRequest& req,
247
                                               GetDeleteBitmapResponse& res,
248
                                               int64_t bytes_threadhold);
249
250
    void check_table_size_correctness(RowsetMeta& rs_meta);
251
    int64_t get_segment_file_size(RowsetMeta& rs_meta);
252
    int64_t get_inverted_index_file_size(RowsetMeta& rs_meta);
253
254
    Status do_commit_rowset(RowsetMeta& rs_meta, const std::string& job_id, int64_t table_id,
255
                            std::shared_ptr<RowsetMeta>* existed_rs_meta = nullptr);
256
257
    Status do_update_tmp_rowset(const RowsetMeta& rs_meta, int64_t table_id);
258
259
    HostLevelMSRpcRateLimiters* host_level_ms_rpc_rate_limiters_ {nullptr};
260
    MSBackpressureHandler* ms_backpressure_handler_ {nullptr};
261
};
262
263
} // namespace cloud
264
} // namespace doris