Coverage Report

Created: 2026-08-14 10:14

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 <variant>
27
#include <vector>
28
29
#include "cloud/cloud_tablet.h"
30
#include "common/status.h"
31
#include "storage/rowset/rowset_fwd.h"
32
#include "storage/rowset/rowset_meta.h"
33
#include "util/s3_util.h"
34
35
namespace doris {
36
37
class DeleteBitmap;
38
class StreamLoadContext;
39
class CloudTablet;
40
class TabletMeta;
41
class TabletSchema;
42
class TabletMetaPB;
43
class RowsetMeta;
44
45
namespace cloud {
46
47
class FinishTabletJobResponse;
48
class StartTabletJobResponse;
49
class TabletJobInfoPB;
50
class TabletStatsPB;
51
class TabletIndexPB;
52
class HostLevelMSRpcRateLimiters;
53
class MSBackpressureHandler;
54
55
using StorageVaultInfos = std::vector<
56
        std::tuple<std::string, std::variant<S3Conf, HdfsVaultInfo>, StorageVaultPB_PathFormat>>;
57
58
// run tasks in bthread with concurrency and wait until all tasks done
59
// it stops running tasks if there are any tasks return !ok, leaving some tasks untouched
60
// return OK if all tasks successfully done, otherwise return the result of the failed task
61
Status bthread_fork_join(const std::vector<std::function<Status()>>& tasks, int concurrency);
62
63
// An async wrap of `bthread_fork_join` declared previously using promise-future
64
// return OK if fut successfully created, otherwise return error
65
Status bthread_fork_join(std::vector<std::function<Status()>>&& tasks, int concurrency,
66
                         std::future<Status>* fut);
67
68
// Returns the exact actual_code when recognized. An unknown actual_code uses an explicit non-OK
69
// legacy fallback and otherwise fails closed. Responses from a legacy Meta Service use code.
70
// Exposed for unit tests.
71
MetaServiceCode get_response_code(const MetaServiceResponseStatus& status);
72
73
class CloudMetaMgr {
74
public:
75
259
    CloudMetaMgr() = default;
76
    ~CloudMetaMgr() = default;
77
    CloudMetaMgr(const CloudMetaMgr&) = delete;
78
    CloudMetaMgr& operator=(const CloudMetaMgr&) = delete;
79
80
    Status get_tablet_meta(int64_t tablet_id, std::shared_ptr<TabletMeta>* tablet_meta);
81
82
    Status sync_tablet_rowsets(CloudTablet* tablet, const SyncOptions& options = {},
83
                               SyncRowsetStats* sync_stats = nullptr);
84
    Status sync_tablet_rowsets_unlocked(
85
            CloudTablet* tablet, std::unique_lock<bthread::Mutex>& lock /* _sync_meta_lock */,
86
            const SyncOptions& options = {}, SyncRowsetStats* sync_stats = nullptr);
87
88
    Status prepare_rowset(const RowsetMeta& rs_meta, const std::string& job_id, int64_t table_id,
89
                          std::shared_ptr<RowsetMeta>* existed_rs_meta = nullptr);
90
91
    Status commit_rowset(RowsetMeta& rs_meta, const std::string& job_id, int64_t table_id,
92
                         std::shared_ptr<RowsetMeta>* existed_rs_meta = nullptr,
93
                         RowsetMeta* attach_row_binlog = nullptr,
94
                         std::shared_ptr<RowsetMeta>* existed_attach_row_binlog = nullptr);
95
    void cache_committed_rowset(RowsetMetaSharedPtr rs_meta, int64_t expiration_time);
96
97
    Status update_tmp_rowset(const RowsetMeta& rs_meta, int64_t table_id,
98
                             const RowsetMeta* attach_row_binlog = nullptr);
99
100
    Status update_packed_file_info(const std::string& packed_file_path,
101
                                   const cloud::PackedFileInfoPB& packed_file_info,
102
                                   int64_t table_id);
103
104
    Status commit_txn(const StreamLoadContext& ctx, bool is_2pc);
105
106
    Status abort_txn(const StreamLoadContext& ctx);
107
108
    Status precommit_txn(const StreamLoadContext& ctx);
109
110
    /**
111
     * Prepares a restore job for a tablet to meta-service
112
     * Change the state to PREPARED
113
     * PREPARED state means the meta of tablet has been uploaded but not finalized.
114
     */
115
    Status prepare_restore_job(const TabletMetaPB& tablet_meta);
116
117
    /**
118
     * Commits a restore job for a tablet to meta-service
119
     * Change the state from PREPARED to COMMITTED
120
     * COMMITTED state means the meta of tablet has been finalized.
121
     */
122
    Status commit_restore_job(const int64_t tablet_id);
123
124
    /**
125
     * Finish a restore job for a tablet from meta-service
126
     * Change the state to final state.
127
     * If is_completed = true, change the state from COMMITTED to COMPLETED
128
     * If is_completed = false, change the state to from PREPARED/COMMITTED to DROPPED
129
     * COMPLETED state means the job is finished, the restored data should be visible.
130
     * DROPPED state means the job is aborted.
131
     * COMPLETED/DROPPED are the final states, jobs with final states will be recycled.
132
     */
133
    Status finish_restore_job(const int64_t tablet_id, bool is_completed);
134
135
    /**
136
     * Gets storage vault (storage backends) from meta-service
137
     * 
138
     * @param vault_info output param, all storage backends
139
     * @param is_vault_mode output param, true for pure vault mode, false for legacy mode
140
     * @return status
141
     */
142
    Status get_storage_vault_info(StorageVaultInfos* vault_infos, bool* is_vault_mode);
143
144
    Status prepare_tablet_job(const TabletJobInfoPB& job, StartTabletJobResponse* res);
145
146
    Status commit_tablet_job(const TabletJobInfoPB& job, FinishTabletJobResponse* res);
147
148
    Status abort_tablet_job(const TabletJobInfoPB& job);
149
150
    Status lease_tablet_job(const TabletJobInfoPB& job);
151
152
    Status update_delete_bitmap(const CloudTablet& tablet, int64_t lock_id, int64_t initiator,
153
                                DeleteBitmap* delete_bitmap, DeleteBitmap* delete_bitmap_v2,
154
                                std::string rowset_id,
155
                                std::optional<StorageResource> storage_resource,
156
                                int64_t store_version, int64_t table_id, int64_t txn_id = -1,
157
                                bool is_explicit_txn = false, int64_t next_visible_version = -1);
158
159
    Status cloud_update_delete_bitmap_without_lock(
160
            const CloudTablet& tablet, DeleteBitmap* delete_bitmap,
161
            std::map<std::string, int64_t>& rowset_to_versions, int64_t table_id,
162
            int64_t pre_rowset_agg_start_version = 0, int64_t pre_rowset_agg_end_version = 0);
163
164
    Status get_delete_bitmap_update_lock(const CloudTablet& tablet, int64_t lock_id,
165
                                         int64_t initiator);
166
167
    void remove_delete_bitmap_update_lock(int64_t table_id, int64_t lock_id, int64_t initiator,
168
                                          int64_t tablet_id);
169
170
    // Fill version holes by creating empty rowsets for missing versions
171
    Status fill_version_holes(CloudTablet* tablet, int64_t max_version,
172
                              std::unique_lock<BthreadSharedMutex>& wlock);
173
174
    // Create an empty rowset to fill a version hole
175
    Status create_empty_rowset_for_hole(CloudTablet* tablet, int64_t version,
176
                                        RowsetMetaSharedPtr prev_rowset_meta,
177
                                        RowsetSharedPtr* rowset);
178
179
    Status list_snapshot(std::vector<SnapshotInfoPB>& snapshots);
180
    Status get_snapshot_properties(SnapshotSwitchStatus& switch_status,
181
                                   int64_t& max_reserved_snapshots,
182
                                   int64_t& snapshot_interval_seconds);
183
184
    // Get all cluster status for the instance
185
    // Returns cluster_id -> (status, mtime_ms)
186
    // If my_cluster_id is not null, also returns the requesting node's cluster_id
187
    Status get_cluster_status(std::unordered_map<std::string, std::pair<int32_t, int64_t>>* result,
188
                              std::string* my_cluster_id = nullptr);
189
190
1
    void set_host_level_ms_rpc_rate_limiters(HostLevelMSRpcRateLimiters* limiters) {
191
1
        host_level_ms_rpc_rate_limiters_ = limiters;
192
1
    }
193
194
1
    void set_ms_backpressure_handler(MSBackpressureHandler* handler) {
195
1
        ms_backpressure_handler_ = handler;
196
1
    }
197
198
private:
199
    bool sync_tablet_delete_bitmap_by_cache(CloudTablet* tablet, std::ranges::range auto&& rs_metas,
200
                                            DeleteBitmap* delete_bitmap);
201
202
    Status sync_tablet_delete_bitmap(CloudTablet* tablet, int64_t old_max_version,
203
                                     std::ranges::range auto&& rs_metas, const TabletStatsPB& stats,
204
                                     const TabletIndexPB& idx, DeleteBitmap* delete_bitmap,
205
                                     bool full_sync, SyncRowsetStats* sync_stats,
206
                                     int32_t read_version, bool full_sync_v2);
207
    Status _read_tablet_delete_bitmap_v2(CloudTablet* tablet, int64_t old_max_version,
208
                                         std::ranges::range auto&& rs_metas,
209
                                         DeleteBitmap* delete_bitmap, GetDeleteBitmapResponse& res,
210
                                         int64_t& remote_delete_bitmap_bytes, bool full_sync_v2);
211
    Status _log_mow_delete_bitmap(CloudTablet* tablet, GetRowsetResponse& resp,
212
                                  DeleteBitmap& delete_bitmap, int64_t old_max_version,
213
                                  bool full_sync, int32_t read_version);
214
    Status _check_delete_bitmap_v2_correctness(CloudTablet* tablet, GetRowsetRequest& req,
215
                                               GetRowsetResponse& resp, int64_t old_max_version);
216
217
    Status _get_delete_bitmap_from_ms(GetDeleteBitmapRequest& req, GetDeleteBitmapResponse& res);
218
    Status _get_delete_bitmap_from_ms_by_batch(GetDeleteBitmapRequest& req,
219
                                               GetDeleteBitmapResponse& res,
220
                                               int64_t bytes_threadhold);
221
222
    void check_table_size_correctness(RowsetMeta& rs_meta);
223
    int64_t get_segment_file_size(RowsetMeta& rs_meta);
224
    int64_t get_inverted_index_file_size(RowsetMeta& rs_meta);
225
226
    Status do_commit_rowset(RowsetMeta& rs_meta, const std::string& job_id, int64_t table_id,
227
                            std::shared_ptr<RowsetMeta>* existed_rs_meta = nullptr);
228
229
    Status do_update_tmp_rowset(const RowsetMeta& rs_meta, int64_t table_id);
230
231
    HostLevelMSRpcRateLimiters* host_level_ms_rpc_rate_limiters_ {nullptr};
232
    MSBackpressureHandler* ms_backpressure_handler_ {nullptr};
233
};
234
235
} // namespace cloud
236
} // namespace doris