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 |