Coverage Report

Created: 2026-10-20 18:03

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
be/src/storage/storage_engine.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
18
#pragma once
19
20
#include <butil/macros.h>
21
#include <bvar/bvar.h>
22
#include <gen_cpp/Types_types.h>
23
#include <gen_cpp/internal_service.pb.h>
24
#include <gen_cpp/olap_file.pb.h>
25
26
#include <atomic>
27
#include <condition_variable>
28
#include <cstdint>
29
#include <ctime>
30
#include <map>
31
#include <memory>
32
#include <mutex>
33
#include <set>
34
#include <shared_mutex>
35
#include <string>
36
#include <unordered_map>
37
#include <unordered_set>
38
#include <vector>
39
40
#include "agent/task_worker_pool.h"
41
#include "common/config.h"
42
#include "common/status.h"
43
#include "runtime/heartbeat_flags.h"
44
#include "storage/adaptive_thread_pool_controller.h"
45
#include "storage/compaction/compaction_permit_limiter.h"
46
#include "storage/compaction_task_types.h"
47
#include "storage/delete/calc_delete_bitmap_executor.h"
48
#include "storage/olap_common.h"
49
#include "storage/options.h"
50
#include "storage/rowset/pending_rowset_helper.h"
51
#include "storage/rowset/rowset_fwd.h"
52
#include "storage/segment/segment.h"
53
#include "storage/tablet/tablet_fwd.h"
54
#include "storage/task/index_builder.h"
55
#include "util/countdown_latch.h"
56
57
namespace doris {
58
59
class DataDir;
60
class EngineTask;
61
class MemTableFlushExecutor;
62
class SegcompactionWorker;
63
class BaseCompaction;
64
class CumulativeCompaction;
65
class CumulativeCompactionPolicy;
66
class StreamLoadRecorder;
67
class TCloneReq;
68
class TCreateTabletReq;
69
class TabletManager;
70
class Thread;
71
class ThreadPool;
72
class TxnManager;
73
class ReportWorker;
74
class CreateTabletRRIdxCache;
75
struct DirInfo;
76
class SnapshotManager;
77
class WorkloadGroup;
78
79
using SegCompactionCandidates = std::vector<segment_v2::SegmentSharedPtr>;
80
using SegCompactionCandidatesSharedPtr = std::shared_ptr<SegCompactionCandidates>;
81
using CumuCompactionPolicyTable =
82
        std::unordered_map<std::string_view, std::shared_ptr<CumulativeCompactionPolicy>>;
83
84
class StorageEngine;
85
class CloudStorageEngine;
86
87
extern bvar::Status<int64_t> g_max_rowsets_with_useless_delete_bitmap;
88
extern bvar::Status<int64_t> g_max_rowsets_with_useless_delete_bitmap_version;
89
90
// StorageEngine singleton to manage all Table pointers.
91
// Providing add/drop/get operations.
92
// StorageEngine instance doesn't own the Table resources, just hold the pointer,
93
// allocation/deallocation must be done outside.
94
class BaseStorageEngine {
95
protected:
96
    enum class Type : uint8_t {
97
        LOCAL, // Shared-nothing integrated compute and storage architecture
98
        CLOUD, // Separating compute and storage architecture
99
    };
100
    Type _type;
101
102
public:
103
    BaseStorageEngine(Type type, const UniqueId& backend_uid);
104
    virtual ~BaseStorageEngine();
105
106
    StorageEngine& to_local();
107
    CloudStorageEngine& to_cloud();
108
109
    virtual Status open() = 0;
110
    virtual void stop() = 0;
111
    virtual bool stopped() = 0;
112
113
    // start all background threads. This should be call after env is ready.
114
    virtual Status start_bg_threads(std::shared_ptr<WorkloadGroup> wg_sptr = nullptr) = 0;
115
116
    /* Parameters:
117
     * - tablet_id: the id of tablet to get
118
     * - sync_stats: the stats of sync rowset
119
     * - force_use_only_cached: whether only use cached tablet meta
120
     * - cache_on_miss: whether cache the tablet meta when missing in cache
121
     */
122
    virtual Result<BaseTabletSPtr> get_tablet(int64_t tablet_id,
123
                                              SyncRowsetStats* sync_stats = nullptr,
124
                                              bool force_use_only_cached = false,
125
                                              bool cache_on_miss = true) = 0;
126
127
    virtual Status get_tablet_meta(int64_t tablet_id, TabletMetaSharedPtr* tablet_meta,
128
                                   bool force_use_only_cached = false) = 0;
129
130
    void register_row_binlog_tablet(const BaseTabletSPtr& tablet);
131
    // Catalog discovery refreshes cached Cloud metadata too, including tablets with no recent reads.
132
    Status submit_row_binlog_ttl(int64_t tablet_id, bool refresh_cloud_meta = false);
133
134
    void register_report_listener(ReportWorker* listener);
135
    void deregister_report_listener(ReportWorker* listener);
136
    void notify_listeners();
137
    bool notify_listener(std::string_view name);
138
139
0
    void set_heartbeat_flags(HeartbeatFlags* heartbeat_flags) {
140
0
        _heartbeat_flags = heartbeat_flags;
141
0
    }
142
    virtual Status set_cluster_id(int32_t cluster_id) = 0;
143
0
    int32_t effective_cluster_id() const { return _effective_cluster_id; }
144
145
    RowsetId next_rowset_id();
146
147
30
    MemTableFlushExecutor* memtable_flush_executor() { return _memtable_flush_executor.get(); }
148
8
    AdaptiveThreadPoolController* adaptive_thread_controller() {
149
8
        return &_adaptive_thread_controller;
150
8
    }
151
62
    CalcDeleteBitmapExecutor* calc_delete_bitmap_executor() {
152
62
        return _calc_delete_bitmap_executor.get();
153
62
    }
154
155
48
    CalcDeleteBitmapExecutor* calc_delete_bitmap_executor_for_load() {
156
48
        return _calc_delete_bitmap_executor_for_load.get();
157
48
    }
158
159
    int64_t memory_limitation_bytes_per_thread_for_schema_change() const;
160
161
0
    int get_disk_num() { return _disk_num; }
162
163
    Status init_stream_load_recorder(const std::string& stream_load_record_path);
164
165
0
    const std::shared_ptr<StreamLoadRecorder>& get_stream_load_recorder() {
166
0
        return _stream_load_recorder;
167
0
    }
168
169
protected:
170
    void _start_adaptive_thread_controller();
171
    void _gc_expired_id_file_map();
172
    void _gc_expired_id_file_map_thread_callback();
173
    bool _should_delay_large_task();
174
175
    int32_t _effective_cluster_id = -1;
176
    HeartbeatFlags* _heartbeat_flags = nullptr;
177
178
    // For task, tablet and disk report
179
    std::mutex _report_mtx;
180
    std::vector<ReportWorker*> _report_listeners;
181
182
    std::unique_ptr<RowsetIdGenerator> _rowset_id_generator;
183
    std::unique_ptr<MemTableFlushExecutor> _memtable_flush_executor;
184
    AdaptiveThreadPoolController _adaptive_thread_controller;
185
    std::unique_ptr<CalcDeleteBitmapExecutor> _calc_delete_bitmap_executor;
186
    std::unique_ptr<CalcDeleteBitmapExecutor> _calc_delete_bitmap_executor_for_load;
187
    CountDownLatch _stop_background_threads_latch;
188
189
    Status _start_row_binlog_ttl_scanner();
190
    void _stop_row_binlog_ttl_scanner();
191
    std::mutex _row_binlog_ttl_mutex;
192
    std::map<int64_t, std::weak_ptr<BaseTablet>> _row_binlog_ttl_tablets;
193
    std::unordered_set<int64_t> _row_binlog_ttl_pending;
194
    std::unique_ptr<ThreadPool> _row_binlog_ttl_prepare_pool;
195
    std::shared_ptr<Thread> _row_binlog_ttl_scan_thread;
196
197
    std::shared_ptr<Thread> _id_file_map_gc_thread;
198
199
    int64_t _memory_limitation_bytes_for_schema_change;
200
201
    int _disk_num {-1};
202
203
    std::shared_ptr<StreamLoadRecorder> _stream_load_recorder;
204
205
    std::shared_ptr<bvar::Status<size_t>> _tablet_max_delete_bitmap_score_metrics;
206
    std::shared_ptr<bvar::Status<size_t>> _tablet_max_base_rowset_delete_bitmap_score_metrics;
207
208
    std::unique_ptr<ThreadPool> _base_compaction_thread_pool;
209
    std::unique_ptr<ThreadPool> _cumu_compaction_thread_pool;
210
    std::unique_ptr<ThreadPool> _binlog_compaction_thread_pool;
211
    int _cumu_compaction_thread_pool_used_threads {0};
212
    int _cumu_compaction_thread_pool_small_tasks_running {0};
213
};
214
215
class CompactionSubmitRegistry {
216
    using TabletSet = std::unordered_set<TabletSharedPtr>;
217
    using Registry = std::map<DataDir*, TabletSet>;
218
219
public:
220
768
    CompactionSubmitRegistry() = default;
221
    CompactionSubmitRegistry(CompactionSubmitRegistry&& r);
222
223
    // create a snapshot for current registry, operations to the snapshot can be lock-free.
224
    CompactionSubmitRegistry create_snapshot();
225
226
    void reset(const std::vector<DataDir*>& stores);
227
228
    uint32_t count_executing_compaction(DataDir* dir, CompactionType compaction_type);
229
    uint32_t count_executing_cumu_and_base(DataDir* dir);
230
231
    bool has_compaction_task(DataDir* dir, CompactionType compaction_type);
232
233
    bool insert(TabletSharedPtr tablet, CompactionType compaction_type);
234
235
    void remove(TabletSharedPtr tablet, CompactionType compaction_type,
236
                std::function<void()> wakeup_cb);
237
238
    void jsonfy_compaction_status(std::string* result);
239
240
    std::vector<TabletCompactionContext> pick_topn_tablets_for_compaction(
241
            TabletManager* tablet_mgr, DataDir* data_dir, CompactionType compaction_type,
242
            const CumuCompactionPolicyTable& cumu_compaction_policies,
243
            CompactionScoreStats* disk_score_stats);
244
245
private:
246
    TabletSet& _get_tablet_set(DataDir* dir, CompactionType compaction_type);
247
248
    std::mutex _tablet_submitted_compaction_mutex;
249
    Registry _tablet_submitted_cumu_compaction;
250
    Registry _tablet_submitted_base_compaction;
251
    Registry _tablet_submitted_full_compaction;
252
    Registry _tablet_submitted_binlog_compaction;
253
};
254
255
class StorageEngine final : public BaseStorageEngine {
256
public:
257
    StorageEngine(const EngineOptions& options);
258
    ~StorageEngine() override;
259
260
    Status open() override;
261
262
    Status create_tablet(const TCreateTabletReq& request, RuntimeProfile* profile);
263
264
    /* Parameters:
265
     * - tablet_id: the id of tablet to get
266
     * - sync_stats: the stats of sync rowset
267
     * - force_use_only_cached: whether only use cached tablet meta
268
     * - cache_on_miss: whether cache the tablet meta when missing in cache
269
     */
270
    Result<BaseTabletSPtr> get_tablet(int64_t tablet_id, SyncRowsetStats* sync_stats = nullptr,
271
                                      bool force_use_only_cached = false,
272
                                      bool cache_on_miss = true) override;
273
274
    Status get_tablet_meta(int64_t tablet_id, TabletMetaSharedPtr* tablet_meta,
275
                           bool force_use_only_cached = false) override;
276
277
    void clear_transaction_task(const TTransactionId transaction_id);
278
    void clear_transaction_task(const TTransactionId transaction_id,
279
                                const std::vector<TPartitionId>& partition_ids);
280
281
    std::vector<DataDir*> get_stores(bool include_unused = false);
282
283
    // get all info of root_path
284
    Status get_all_data_dir_info(std::vector<DataDirInfo>* data_dir_infos, bool need_update);
285
286
    static int64_t get_file_or_directory_size(const std::string& file_path);
287
288
    // get root path for creating tablet. The returned vector of root path should be round robin,
289
    // for avoiding that all the tablet would be deployed one disk.
290
    std::vector<DataDir*> get_stores_for_create_tablet(int64_t partition_id,
291
                                                       TStorageMedium::type storage_medium);
292
293
    DataDir* get_store(const std::string& path);
294
295
0
    uint32_t available_storage_medium_type_count() const {
296
0
        return _available_storage_medium_type_count;
297
0
    }
298
299
    Status set_cluster_id(int32_t cluster_id) override;
300
301
    void start_delete_unused_rowset();
302
    void add_unused_rowset(RowsetSharedPtr rowset);
303
    using DeleteBitmapKeyRanges =
304
            std::vector<std::tuple<DeleteBitmap::BitmapKey, DeleteBitmap::BitmapKey>>;
305
    void add_unused_delete_bitmap_key_ranges(int64_t tablet_id,
306
                                             const std::vector<RowsetId>& rowsets,
307
                                             const DeleteBitmapKeyRanges& key_ranges);
308
309
    // Obtain shard path for new tablet.
310
    //
311
    // @param [out] shard_path choose an available root_path to clone new tablet
312
    // @return error code
313
    Status obtain_shard_path(TStorageMedium::type storage_medium, int64_t path_hash,
314
                             std::string* shared_path, DataDir** store, int64_t partition_id);
315
316
    // Load new tablet to make it effective.
317
    //
318
    // @param [in] root_path specify root path of new tablet
319
    // @param [in] request specify new tablet info
320
    // @param [in] restore whether we're restoring a tablet from trash
321
    // @return OK if load tablet success
322
    Status load_header(const std::string& shard_path, const TCloneReq& request,
323
                       bool restore = false);
324
325
2.47k
    TabletManager* tablet_manager() { return _tablet_manager.get(); }
326
205
    TxnManager* txn_manager() { return _txn_manager.get(); }
327
15
    SnapshotManager* snapshot_mgr() { return _snapshot_mgr.get(); }
328
    // Rowset garbage collection helpers
329
    bool check_rowset_id_in_unused_rowsets(const RowsetId& rowset_id);
330
585
    PendingRowsetSet& pending_local_rowsets() { return _pending_local_rowsets; }
331
5
    PendingRowsetSet& pending_remote_rowsets() { return _pending_remote_rowsets; }
332
    PendingRowsetGuard add_pending_rowset(const RowsetWriterContext& ctx);
333
334
0
    RowsetTypePB default_rowset_type() const {
335
0
        if (_heartbeat_flags != nullptr && _heartbeat_flags->is_set_default_rowset_type_to_beta()) {
336
0
            return BETA_ROWSET;
337
0
        }
338
0
        return _default_rowset_type;
339
0
    }
340
341
    Status start_bg_threads(std::shared_ptr<WorkloadGroup> wg_sptr = nullptr) override;
342
343
    // clear trash and snapshot file
344
    // option: update disk usage after sweep
345
    Status start_trash_sweep(double* usage, bool ignore_guard = false);
346
347
    // Must call stop() before storage_engine is deconstructed
348
    void stop() override;
349
350
    void get_tablet_rowset_versions(const PGetTabletVersionsRequest* request,
351
                                    PGetTabletVersionsResponse* response);
352
353
    bool get_peers_replica_backends(int64_t tablet_id, std::vector<TBackend>* backends);
354
355
0
    const std::shared_ptr<StreamLoadRecorder>& get_stream_load_recorder() {
356
0
        return _stream_load_recorder;
357
0
    }
358
359
    void get_compaction_status_json(std::string* result);
360
361
    Status submit_compaction_task(TabletSharedPtr tablet, CompactionType compaction_type,
362
                                  bool force, bool eager = true,
363
                                  TriggerMethod trigger_method = TriggerMethod::AUTO);
364
    Status submit_seg_compaction_task(std::shared_ptr<SegcompactionWorker> worker,
365
                                      SegCompactionCandidatesSharedPtr segments);
366
367
0
    ThreadPool* tablet_publish_txn_thread_pool() { return _tablet_publish_txn_thread_pool.get(); }
368
7.58k
    bool stopped() override { return _stopped; }
369
370
    Status process_index_change_task(const TAlterInvertedIndexReq& reqest);
371
372
    void gc_binlogs(const std::unordered_map<int64_t, int64_t>& gc_tablet_infos);
373
374
    void add_async_publish_task(int64_t partition_id, int64_t tablet_id, int64_t publish_version,
375
                                int64_t transaction_id, bool is_recover, int64_t commit_tso);
376
    int64_t get_pending_publish_min_version(int64_t tablet_id);
377
378
    bool add_broken_path(std::string path);
379
    bool remove_broken_path(std::string path);
380
381
11
    std::set<std::string> get_broken_paths() { return _broken_paths; }
382
383
    Status submit_clone_task(Tablet* tablet, int64_t version);
384
385
    std::unordered_map<int64_t, std::unique_ptr<TaskWorkerPoolIf>>* workers;
386
387
17
    int64_t get_compaction_num_per_round() const { return _compaction_num_per_round; }
388
389
#ifdef BE_TEST
390
    std::vector<TabletSharedPtr> generate_compaction_tasks_for_test(
391
5
            CompactionType compaction_type, std::vector<DataDir*>& data_dirs, bool check_score) {
392
5
        auto tablet_contexts = _generate_compaction_tasks(compaction_type, data_dirs, check_score);
393
5
        std::vector<TabletSharedPtr> tablets;
394
5
        tablets.reserve(tablet_contexts.size());
395
5
        for (auto& context : tablet_contexts) {
396
3
            tablets.emplace_back(std::move(context.tablet));
397
3
        }
398
5
        return tablets;
399
5
    }
400
401
1
    CompactionSubmitRegistry& compaction_submit_registry_for_test() {
402
1
        return _compaction_submit_registry;
403
1
    }
404
#endif
405
406
private:
407
    // Instance should be inited from `static open()`
408
    // MUST NOT be called in other circumstances.
409
    Status _open();
410
411
    Status _init_store_map();
412
413
    void _update_storage_medium_type_count();
414
415
    // Some check methods
416
    Status _check_file_descriptor_number();
417
    Status _check_all_root_path_cluster_id();
418
    Status _judge_and_update_effective_cluster_id(int32_t cluster_id);
419
420
    void _exit_if_too_many_disks_are_failed();
421
422
    void _clean_unused_txns();
423
424
    void _clean_unused_rowset_metas();
425
426
    void _clean_unused_binlog_metas();
427
428
    void _clean_unused_delete_bitmap();
429
430
    void _clean_unused_pending_publish_info();
431
432
    void _clean_unused_partial_update_info();
433
434
    Status _do_sweep(const std::string& scan_root, const time_t& local_tm_now,
435
                     const int32_t expire);
436
437
    // All these xxx_callback() functions are for Background threads
438
    // unused rowset monitor thread
439
    void _unused_rowset_monitor_thread_callback();
440
441
    // garbage sweep thread process function. clear snapshot and trash folder
442
    void _garbage_sweeper_thread_callback();
443
444
    // delete tablet with io error process function
445
    void _disk_stat_monitor_thread_callback();
446
447
    // path gc process function
448
    void _path_gc_thread_callback(DataDir* data_dir);
449
450
    void _tablet_path_check_callback();
451
452
    void _tablet_checkpoint_callback(const std::vector<DataDir*>& data_dirs);
453
454
    // parse the default rowset type config to RowsetTypePB
455
    void _parse_default_rowset_type();
456
457
    // Disk status monitoring. Monitoring unused_flag Road King's new corresponding root_path unused flag,
458
    // When the unused mark is detected, the corresponding table information is deleted from the memory, and the disk data does not move.
459
    // When the disk status is unusable, but the unused logo is not _push_tablet_into_submitted_compactiondetected, you need to download it from root_path
460
    // Reload the data.
461
    void _start_disk_stat_monitor();
462
463
    void _compaction_tasks_producer_callback();
464
    void _binlog_compaction_tasks_producer_callback();
465
466
    std::vector<TabletCompactionContext> _generate_compaction_tasks(
467
            CompactionType compaction_type, std::vector<DataDir*>& data_dirs, bool check_score);
468
    void _update_cumulative_compaction_policy();
469
    CumuCompactionPolicyTable _snapshot_cumulative_compaction_policy();
470
    std::shared_ptr<CumulativeCompactionPolicy> _get_cumulative_compaction_policy(
471
            std::string_view compaction_policy);
472
473
    void _pop_tablet_from_submitted_compaction(TabletSharedPtr tablet,
474
                                               CompactionType compaction_type);
475
476
    Status _submit_compaction_task(TabletSharedPtr tablet, CompactionType compaction_type,
477
                                   bool force, TriggerMethod trigger_method = TriggerMethod::AUTO);
478
479
    void _handle_compaction(TabletSharedPtr tablet, std::shared_ptr<CompactionMixin> compaction,
480
                            CompactionType compaction_type, int64_t permits, bool force,
481
                            int64_t compaction_id = 0);
482
483
    void _adjust_compaction_thread_num();
484
485
    void _cooldown_tasks_producer_callback();
486
    void _remove_unused_remote_files_callback();
487
    void do_remove_unused_remote_files();
488
    void _cold_data_compaction_producer_callback();
489
    void _handle_cold_data_compaction(TabletSharedPtr tablet);
490
    void _follow_cooldown_meta(TabletSharedPtr tablet);
491
492
    Status _handle_seg_compaction(std::shared_ptr<SegcompactionWorker> worker,
493
                                  SegCompactionCandidatesSharedPtr segments,
494
                                  uint64_t submission_time);
495
496
    Status _handle_index_change(IndexBuilderSharedPtr index_builder);
497
498
    void _gc_binlogs(int64_t tablet_id, int64_t version);
499
500
    void _async_publish_callback();
501
502
    void _process_async_publish();
503
504
    Status _persist_broken_paths();
505
506
    bool _increase_low_priority_task_nums(DataDir* dir);
507
508
    void _decrease_low_priority_task_nums(DataDir* dir);
509
510
    void _get_candidate_stores(TStorageMedium::type storage_medium,
511
                               std::vector<DirInfo>& dir_infos);
512
513
    int _get_and_set_next_disk_index(int64_t partition_id, TStorageMedium::type storage_medium);
514
515
    int32_t _auto_get_interval_by_disk_capacity(DataDir* data_dir);
516
517
    void _check_tablet_delete_bitmap_score_callback();
518
519
private:
520
    EngineOptions _options;
521
    std::mutex _store_lock;
522
    std::mutex _trash_sweep_lock;
523
    std::map<std::string, std::unique_ptr<DataDir>> _store_map;
524
    std::set<std::string> _broken_paths;
525
    std::mutex _broken_paths_mutex;
526
527
    uint32_t _available_storage_medium_type_count;
528
529
    bool _is_all_cluster_id_exist;
530
531
    std::atomic_bool _stopped {false};
532
533
    std::mutex _gc_mutex;
534
    std::unordered_map<RowsetId, RowsetSharedPtr> _unused_rowsets;
535
    // tablet_id, unused_rowsets, [start_version, end_version]
536
    std::vector<std::tuple<int64_t, std::vector<RowsetId>, DeleteBitmapKeyRanges>>
537
            _unused_delete_bitmap;
538
    PendingRowsetSet _pending_local_rowsets;
539
    PendingRowsetSet _pending_remote_rowsets;
540
541
    std::shared_ptr<Thread> _unused_rowset_monitor_thread;
542
    // thread to monitor snapshot expiry
543
    std::shared_ptr<Thread> _garbage_sweeper_thread;
544
    // thread to monitor disk stat
545
    std::shared_ptr<Thread> _disk_stat_monitor_thread;
546
    // thread to produce both base and cumulative compaction tasks
547
    std::shared_ptr<Thread> _compaction_tasks_producer_thread;
548
    std::shared_ptr<Thread> _binlog_compaction_tasks_producer_thread;
549
    std::shared_ptr<Thread> _cache_clean_thread;
550
    // threads to clean all file descriptor not actively in use
551
    std::vector<std::shared_ptr<Thread>> _path_gc_threads;
552
    // thread to produce tablet checkpoint tasks
553
    std::shared_ptr<Thread> _tablet_checkpoint_tasks_producer_thread;
554
    // thread to check tablet path
555
    std::shared_ptr<Thread> _tablet_path_check_thread;
556
    // thread to clean tablet lookup cache
557
    std::shared_ptr<Thread> _lookup_cache_clean_thread;
558
559
    std::mutex _engine_task_mutex;
560
561
    std::unique_ptr<TabletManager> _tablet_manager;
562
    std::unique_ptr<TxnManager> _txn_manager;
563
564
    // Used to control the migration from segment_v1 to segment_v2, can be deleted in futrue.
565
    // Type of new loaded data
566
    RowsetTypePB _default_rowset_type;
567
568
    std::unique_ptr<ThreadPool> _seg_compaction_thread_pool;
569
    std::unique_ptr<ThreadPool> _cold_data_compaction_thread_pool;
570
571
    std::unique_ptr<ThreadPool> _tablet_publish_txn_thread_pool;
572
573
    std::unique_ptr<ThreadPool> _tablet_meta_checkpoint_thread_pool;
574
575
    CompactionPermitLimiter _permit_limiter;
576
577
    CompactionSubmitRegistry _compaction_submit_registry;
578
579
    std::mutex _low_priority_task_nums_mutex;
580
    std::unordered_map<DataDir*, int32_t> _low_priority_task_nums;
581
582
    std::atomic<int32_t> _wakeup_producer_flag {0};
583
584
    std::mutex _compaction_producer_sleep_mutex;
585
    std::condition_variable _compaction_producer_sleep_cv;
586
587
    // we use unordered_map to store all cumulative compaction policy sharded ptr
588
    std::mutex _cumulative_compaction_policy_mtx;
589
    CumuCompactionPolicyTable _cumulative_compaction_policies;
590
591
    std::shared_ptr<Thread> _cooldown_tasks_producer_thread;
592
    std::shared_ptr<Thread> _remove_unused_remote_files_thread;
593
    std::shared_ptr<Thread> _cold_data_compaction_producer_thread;
594
595
    std::shared_ptr<Thread> _cache_file_cleaner_tasks_producer_thread;
596
597
    std::unique_ptr<PriorityThreadPool> _cooldown_thread_pool;
598
599
    std::mutex _running_cooldown_mutex;
600
    std::unordered_set<int64_t> _running_cooldown_tablets;
601
602
    std::mutex _cold_compaction_tablet_submitted_mtx;
603
    std::unordered_set<int64_t> _cold_compaction_tablet_submitted;
604
605
    std::mutex _cumu_compaction_delay_mtx;
606
607
    // tablet_id, publish_version, transaction_id, partition_id, commit_tso
608
    std::map<int64_t, std::map<int64_t, std::tuple<int64_t, int64_t, int64_t>>>
609
            _async_publish_tasks;
610
    // aync publish for discontinuous versions of merge_on_write table
611
    std::shared_ptr<Thread> _async_publish_thread;
612
    std::shared_mutex _async_publish_lock;
613
614
    std::atomic<bool> _need_clean_trash {false};
615
616
    // next index for create tablet
617
    std::map<TStorageMedium::type, int> _last_use_index;
618
619
    std::unique_ptr<CreateTabletRRIdxCache> _create_tablet_idx_lru_cache;
620
621
    std::unique_ptr<SnapshotManager> _snapshot_mgr;
622
623
    // thread to check tablet delete bitmap count tasks
624
    std::shared_ptr<Thread> _check_delete_bitmap_score_thread;
625
626
    int64_t _last_get_peers_replica_backends_time_ms {0};
627
628
    int64_t _compaction_num_per_round {1};
629
};
630
631
// lru cache for create tabelt round robin in disks
632
// key: partitionId_medium
633
// value: index
634
class CreateTabletRRIdxCache : public LRUCachePolicy {
635
public:
636
    // get key, delimiter with DELIMITER '-'
637
150
    static std::string get_key(int64_t partition_id, TStorageMedium::type medium) {
638
150
        return fmt::format("{}-{}", partition_id, medium);
639
150
    }
640
641
    // -1 not found key in lru
642
    int get_index(const std::string& key);
643
644
    void set_index(const std::string& key, int next_idx);
645
646
    class CacheValue : public LRUCacheValueBase {
647
    public:
648
        int idx = 0;
649
    };
650
651
    CreateTabletRRIdxCache(size_t capacity)
652
763
            : LRUCachePolicy(CachePolicy::CacheType::CREATE_TABLET_RR_IDX_CACHE, capacity,
653
763
                             LRUCacheType::NUMBER,
654
763
                             /*stale_sweep_time_s*/ 30 * 60, /*num shards*/ 1,
655
763
                             /*element count capacity */ 0,
656
763
                             /*enable prune*/ true, /*is lru-k*/ false) {}
657
};
658
659
struct DirInfo {
660
    DataDir* data_dir;
661
662
    double usage = 0;
663
    int available_level = 0;
664
665
10
    bool operator<(const DirInfo& other) const {
666
10
        if (available_level != other.available_level) {
667
0
            return available_level < other.available_level;
668
0
        }
669
10
        return data_dir->path_hash() < other.data_dir->path_hash();
670
10
    }
671
};
672
673
} // namespace doris