1 // Copyright (c) 2011-present, Facebook, Inc. All rights reserved.
2 // This source code is licensed under both the GPLv2 (found in the
3 // COPYING file in the root directory) and Apache 2.0 License
4 // (found in the LICENSE.Apache file in the root directory).
16 #include "rocksdb/env.h"
17 #include "rocksdb/trace_reader_writer.h"
18 #include "rocksdb/write_batch.h"
19 #include "util/trace_replay.h"
26 enum TraceOperationType
: int {
34 kIteratorSeekForPrev
= 7,
46 struct TypeCorrelation
{
53 uint64_t access_count
;
55 uint64_t succ_count
; // current only used to count Get if key found
58 std::vector
<TypeCorrelation
> v_correlation
;
61 class AnalyzerOptions
{
63 std::vector
<std::vector
<int>> correlation_map
;
64 std::vector
<std::pair
<int, int>> correlation_list
;
70 void SparseCorrelationInput(const std::string
& in_str
);
73 // Note that, for the variable names in the trace_analyzer,
74 // Starting with 'a_' means the variable is used for 'accessed_keys'.
75 // Starting with 'w_' means it is used for 'the whole key space'.
76 // Ending with '_f' means a file write or reader pointer.
77 // For example, 'a_count' means 'accessed_keys_count',
78 // 'w_key_f' means 'whole_key_space_file'.
84 uint64_t a_succ_count
;
86 uint64_t a_key_size_sqsum
;
87 uint64_t a_key_size_sum
;
89 uint64_t a_value_size_sqsum
;
90 uint64_t a_value_size_sum
;
94 std::map
<std::string
, StatsUnit
> a_key_stats
;
95 std::map
<uint64_t, uint64_t> a_count_stats
;
96 std::map
<uint64_t, uint64_t> a_key_size_stats
;
97 std::map
<uint64_t, uint64_t> a_value_size_stats
;
98 std::map
<uint32_t, uint32_t> a_qps_stats
;
99 std::map
<uint32_t, std::map
<std::string
, uint32_t>> a_qps_prefix_stats
;
100 std::priority_queue
<std::pair
<uint64_t, std::string
>,
101 std::vector
<std::pair
<uint64_t, std::string
>>,
102 std::greater
<std::pair
<uint64_t, std::string
>>>
104 std::priority_queue
<std::pair
<uint64_t, std::string
>,
105 std::vector
<std::pair
<uint64_t, std::string
>>,
106 std::greater
<std::pair
<uint64_t, std::string
>>>
108 std::priority_queue
<std::pair
<double, std::string
>,
109 std::vector
<std::pair
<double, std::string
>>,
110 std::greater
<std::pair
<double, std::string
>>>
112 std::priority_queue
<std::pair
<uint32_t, uint32_t>,
113 std::vector
<std::pair
<uint32_t, uint32_t>>,
114 std::greater
<std::pair
<uint32_t, uint32_t>>>
116 std::list
<TraceUnit
> time_series
;
117 std::vector
<std::pair
<uint64_t, uint64_t>> correlation_output
;
119 std::unique_ptr
<rocksdb::WritableFile
> time_series_f
;
120 std::unique_ptr
<rocksdb::WritableFile
> a_key_f
;
121 std::unique_ptr
<rocksdb::WritableFile
> a_count_dist_f
;
122 std::unique_ptr
<rocksdb::WritableFile
> a_prefix_cut_f
;
123 std::unique_ptr
<rocksdb::WritableFile
> a_value_size_f
;
124 std::unique_ptr
<rocksdb::WritableFile
> a_qps_f
;
125 std::unique_ptr
<rocksdb::WritableFile
> a_top_qps_prefix_f
;
126 std::unique_ptr
<rocksdb::WritableFile
> w_key_f
;
127 std::unique_ptr
<rocksdb::WritableFile
> w_prefix_cut_f
;
131 TraceStats(const TraceStats
&) = delete;
132 TraceStats
& operator=(const TraceStats
&) = delete;
133 TraceStats(TraceStats
&&) = default;
134 TraceStats
& operator=(TraceStats
&&) = default;
138 std::string type_name
;
141 uint64_t total_access
;
142 uint64_t total_succ_access
;
143 std::map
<uint32_t, TraceStats
> stats
;
144 TypeUnit() = default;
145 ~TypeUnit() = default;
146 TypeUnit(const TypeUnit
&) = delete;
147 TypeUnit
& operator=(const TypeUnit
&) = delete;
148 TypeUnit(TypeUnit
&&) = default;
149 TypeUnit
& operator=(TypeUnit
&&) = default;
154 uint64_t w_count
; // total keys in this cf if we use the whole key space
155 uint64_t a_count
; // the total keys in this cf that are accessed
156 std::map
<uint64_t, uint64_t> w_key_size_stats
; // whole key space key size
160 class TraceAnalyzer
{
162 TraceAnalyzer(std::string
& trace_path
, std::string
& output_path
,
163 AnalyzerOptions _analyzer_opts
);
166 Status
PrepareProcessing();
168 Status
StartProcessing();
170 Status
MakeStatistics();
172 Status
ReProcessing();
174 Status
EndProcessing();
176 Status
WriteTraceUnit(TraceUnit
& unit
);
178 // The trace processing functions for different type
179 Status
HandleGet(uint32_t column_family_id
, const std::string
& key
,
180 const uint64_t& ts
, const uint32_t& get_ret
);
181 Status
HandlePut(uint32_t column_family_id
, const Slice
& key
,
183 Status
HandleDelete(uint32_t column_family_id
, const Slice
& key
);
184 Status
HandleSingleDelete(uint32_t column_family_id
, const Slice
& key
);
185 Status
HandleDeleteRange(uint32_t column_family_id
, const Slice
& begin_key
,
186 const Slice
& end_key
);
187 Status
HandleMerge(uint32_t column_family_id
, const Slice
& key
,
189 Status
HandleIter(uint32_t column_family_id
, const std::string
& key
,
190 const uint64_t& ts
, TraceType
& trace_type
);
191 std::vector
<TypeUnit
>& GetTaVector() { return ta_
; }
195 EnvOptions env_options_
;
196 std::unique_ptr
<TraceReader
> trace_reader_
;
200 std::string trace_name_
;
201 std::string output_path_
;
202 AnalyzerOptions analyzer_opts_
;
203 uint64_t total_requests_
;
204 uint64_t total_access_keys_
;
205 uint64_t total_gets_
;
206 uint64_t total_writes_
;
207 uint64_t begin_time_
;
209 uint64_t time_series_start_
;
210 std::unique_ptr
<rocksdb::WritableFile
> trace_sequence_f_
; // readable trace
211 std::unique_ptr
<rocksdb::WritableFile
> qps_f_
; // overall qps
212 std::unique_ptr
<rocksdb::SequentialFile
> wkey_input_f_
;
213 std::vector
<TypeUnit
> ta_
; // The main statistic collecting data structure
214 std::map
<uint32_t, CfUnit
> cfs_
; // All the cf_id appears in this trace;
215 std::vector
<uint32_t> qps_peak_
;
216 std::vector
<double> qps_ave_
;
218 Status
ReadTraceHeader(Trace
* header
);
219 Status
ReadTraceFooter(Trace
* footer
);
220 Status
ReadTraceRecord(Trace
* trace
);
221 Status
KeyStatsInsertion(const uint32_t& type
, const uint32_t& cf_id
,
222 const std::string
& key
, const size_t value_size
,
224 Status
StatsUnitCorrelationUpdate(StatsUnit
& unit
, const uint32_t& type
,
225 const uint64_t& ts
, const std::string
& key
);
226 Status
OpenStatsOutputFiles(const std::string
& type
, TraceStats
& new_stats
);
227 Status
CreateOutputFile(const std::string
& type
, const std::string
& cf_name
,
228 const std::string
& ending
,
229 std::unique_ptr
<rocksdb::WritableFile
>* f_ptr
);
230 void CloseOutputFiles();
232 void PrintStatistics();
233 Status
TraceUnitWriter(std::unique_ptr
<rocksdb::WritableFile
>& f_ptr
,
235 Status
WriteTraceSequence(const uint32_t& type
, const uint32_t& cf_id
,
236 const std::string
& key
, const size_t value_size
,
238 Status
MakeStatisticKeyStatsOrPrefix(TraceStats
& stats
);
239 Status
MakeStatisticCorrelation(TraceStats
& stats
, StatsUnit
& unit
);
240 Status
MakeStatisticQPS();
243 // write bach handler to be used for WriteBache iterator
244 // when processing the write trace
245 class TraceWriteHandler
: public WriteBatch::Handler
{
247 TraceWriteHandler() { ta_ptr
= nullptr; }
248 explicit TraceWriteHandler(TraceAnalyzer
* _ta_ptr
) { ta_ptr
= _ta_ptr
; }
249 ~TraceWriteHandler() {}
251 virtual Status
PutCF(uint32_t column_family_id
, const Slice
& key
,
252 const Slice
& value
) override
{
253 return ta_ptr
->HandlePut(column_family_id
, key
, value
);
255 virtual Status
DeleteCF(uint32_t column_family_id
,
256 const Slice
& key
) override
{
257 return ta_ptr
->HandleDelete(column_family_id
, key
);
259 virtual Status
SingleDeleteCF(uint32_t column_family_id
,
260 const Slice
& key
) override
{
261 return ta_ptr
->HandleSingleDelete(column_family_id
, key
);
263 virtual Status
DeleteRangeCF(uint32_t column_family_id
,
264 const Slice
& begin_key
,
265 const Slice
& end_key
) override
{
266 return ta_ptr
->HandleDeleteRange(column_family_id
, begin_key
, end_key
);
268 virtual Status
MergeCF(uint32_t column_family_id
, const Slice
& key
,
269 const Slice
& value
) override
{
270 return ta_ptr
->HandleMerge(column_family_id
, key
, value
);
274 TraceAnalyzer
* ta_ptr
;
277 int trace_analyzer_tool(int argc
, char** argv
);
279 } // namespace rocksdb
281 #endif // ROCKSDB_LITE