be/src/storage/index/index_disk_usage.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 <gen_cpp/olap_common.pb.h> |
21 | | #include <gen_cpp/olap_file.pb.h> |
22 | | |
23 | | #include <cstdint> |
24 | | #include <functional> |
25 | | #include <set> |
26 | | #include <string> |
27 | | #include <string_view> |
28 | | #include <vector> |
29 | | |
30 | | #include "common/status.h" |
31 | | #include "io/fs/file_system.h" |
32 | | #include "io/io_common.h" |
33 | | #include "storage/rowset/rowset_fwd.h" |
34 | | #include "storage/tablet/tablet_schema.h" |
35 | | |
36 | | namespace doris::segment_v2 { |
37 | | |
38 | | enum class IndexDiskUsageStructure : uint8_t { kTerm, kBkd, kAnn, kContainer }; |
39 | | |
40 | | // Physical bytes of one index, or of a container's shared overhead, in one segment. |
41 | | // A component of -1 means it is unknown. |
42 | | struct IndexDiskUsageRecord { |
43 | | int64_t index_id = -1; |
44 | | std::string index_suffix; |
45 | | IndexDiskUsageStructure structure = IndexDiskUsageStructure::kTerm; |
46 | | int64_t total_bytes = 0; |
47 | | int64_t dict_bytes = 0; |
48 | | int64_t posting_bytes = 0; |
49 | | int64_t position_bytes = 0; |
50 | | int64_t stats_bytes = 0; |
51 | | int64_t other_bytes = 0; |
52 | | }; |
53 | | |
54 | | // The sorted names of the files in one local directory, listed on first use and shared by the |
55 | | // segments that live there. |
56 | | class DirectoryFileNames { |
57 | | public: |
58 | | // Sets `names` to the sorted file names in `dir`, which are none when `dir` does not exist. |
59 | | Status list(const std::string& dir, const std::vector<std::string>** names); |
60 | | // How many times a directory was listed. |
61 | 4 | int listings() const { return _listings; } |
62 | | |
63 | | private: |
64 | | std::string _dir; |
65 | | std::vector<std::string> _names; |
66 | | bool _listed = false; |
67 | | int _listings = 0; |
68 | | }; |
69 | | |
70 | | struct IndexDiskUsageOptions { |
71 | | // Scan SNII dictionary blocks to split positions out of postings. |
72 | | bool position_detail = false; |
73 | | // Empty means all indexes. |
74 | | std::set<int64_t> index_ids; |
75 | | // Returns an error once the query is cancelled. Called before each segment and each SNII |
76 | | // dictionary block; unset means the work cannot be cancelled. |
77 | | std::function<Status()> check_cancelled; |
78 | | // The query context passed to every index file read, so the file cache accounts these reads |
79 | | // to the query. Unset means the default read behavior. |
80 | | const io::IOContext* io_ctx = nullptr; |
81 | | // The listing of the directory that holds the segments of one tablet. Unset means each |
82 | | // segment that needs a listing lists the directory itself. |
83 | | DirectoryFileNames* directory_files = nullptr; |
84 | | }; |
85 | | |
86 | | enum class IndexDiskUsageLevel : uint8_t { kTablet, kRowset, kSegment }; |
87 | | |
88 | | // A record tagged with the rowset and segment it was collected from. |
89 | | struct IndexDiskUsageRow { |
90 | | std::string rowset_id; |
91 | | int32_t segment_id = -1; |
92 | | int64_t segment_count = 0; |
93 | | int64_t row_count = 0; |
94 | | InvertedIndexStorageFormatPB format = InvertedIndexStorageFormatPB::V2; |
95 | | IndexDiskUsageRecord record; |
96 | | }; |
97 | | |
98 | | // Merges rows of the same index, format and structure within the granularity of `level`. |
99 | | // Merged rows keep first-appearance order; a component unknown in any input stays unknown. |
100 | | std::vector<IndexDiskUsageRow> aggregate_index_disk_usage(std::vector<IndexDiskUsageRow> rows, |
101 | | IndexDiskUsageLevel level); |
102 | | |
103 | | // Adds a CLucene sub-file to the component it belongs to. BKD and ANN sub-files only count toward |
104 | | // the total and mark the record with their structure. |
105 | | void classify_clucene_file(std::string_view name, int64_t length, IndexDiskUsageRecord* record); |
106 | | |
107 | | // Reads the index file metadata of one segment and reports the bytes of each index. |
108 | | class IndexDiskUsageCollector { |
109 | | public: |
110 | | // `index_file_info` holds the index file sizes persisted in the rowset meta. Without them the |
111 | | // file sizes are requested from the filesystem. |
112 | | IndexDiskUsageCollector(io::FileSystemSPtr fs, std::string index_path_prefix, |
113 | | TabletSchemaSPtr schema, InvertedIndexStorageFormatPB format, |
114 | | int64_t tablet_id, |
115 | | InvertedIndexFileInfo index_file_info = InvertedIndexFileInfo()); |
116 | | |
117 | | // Appends one record per index, plus a container record for a shared file when no index |
118 | | // filter is given. |
119 | | Status collect(const IndexDiskUsageOptions& options, std::vector<IndexDiskUsageRecord>* out); |
120 | | |
121 | | private: |
122 | | Status _collect_v1(const IndexDiskUsageOptions& options, |
123 | | std::vector<IndexDiskUsageRecord>* out); |
124 | | Status _collect_compound(const IndexDiskUsageOptions& options, |
125 | | std::vector<IndexDiskUsageRecord>* out); |
126 | | Status _collect_snii(const IndexDiskUsageOptions& options, |
127 | | std::vector<IndexDiskUsageRecord>* out); |
128 | | |
129 | | io::FileSystemSPtr _fs; |
130 | | std::string _index_path_prefix; |
131 | | TabletSchemaSPtr _schema; |
132 | | InvertedIndexStorageFormatPB _format; |
133 | | int64_t _tablet_id; |
134 | | InvertedIndexFileInfo _index_file_info; |
135 | | }; |
136 | | |
137 | | // Returns the schema index that describes the physical index `(index_id, suffix)`, or nullptr |
138 | | // when the index no longer exists in `schema`. |
139 | | const TabletIndex* resolve_disk_usage_index(const TabletSchema& schema, int64_t index_id, |
140 | | std::string_view suffix); |
141 | | |
142 | | // Appends one row per index record of every segment in `rowset`. |
143 | | Status collect_rowset_index_disk_usage(const RowsetSharedPtr& rowset, |
144 | | const IndexDiskUsageOptions& options, int64_t tablet_id, |
145 | | std::vector<IndexDiskUsageRow>* rows); |
146 | | |
147 | | } // namespace doris::segment_v2 |