]>
Commit | Line | Data |
---|---|---|
7c673cae | 1 | // Copyright (c) 2011-present, Facebook, Inc. All rights reserved. |
11fdf7f2 TL |
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). | |
7c673cae FG |
5 | |
6 | #include "db/event_helpers.h" | |
7 | ||
1e59de90 TL |
8 | #include "rocksdb/convenience.h" |
9 | #include "rocksdb/listener.h" | |
10 | #include "rocksdb/utilities/customizable_util.h" | |
11 | ||
f67539c2 | 12 | namespace ROCKSDB_NAMESPACE { |
1e59de90 TL |
13 | #ifndef ROCKSDB_LITE |
14 | Status EventListener::CreateFromString(const ConfigOptions& config_options, | |
15 | const std::string& id, | |
16 | std::shared_ptr<EventListener>* result) { | |
17 | return LoadSharedObject<EventListener>(config_options, id, nullptr, result); | |
18 | } | |
19 | #endif // ROCKSDB_LITE | |
7c673cae FG |
20 | |
21 | namespace { | |
11fdf7f2 | 22 | template <class T> |
7c673cae FG |
23 | inline T SafeDivide(T a, T b) { |
24 | return b == 0 ? 0 : a / b; | |
25 | } | |
1e59de90 | 26 | } // anonymous namespace |
7c673cae FG |
27 | |
28 | void EventHelpers::AppendCurrentTime(JSONWriter* jwriter) { | |
29 | *jwriter << "time_micros" | |
30 | << std::chrono::duration_cast<std::chrono::microseconds>( | |
11fdf7f2 TL |
31 | std::chrono::system_clock::now().time_since_epoch()) |
32 | .count(); | |
7c673cae FG |
33 | } |
34 | ||
35 | #ifndef ROCKSDB_LITE | |
36 | void EventHelpers::NotifyTableFileCreationStarted( | |
37 | const std::vector<std::shared_ptr<EventListener>>& listeners, | |
38 | const std::string& db_name, const std::string& cf_name, | |
39 | const std::string& file_path, int job_id, TableFileCreationReason reason) { | |
1e59de90 TL |
40 | if (listeners.empty()) { |
41 | return; | |
42 | } | |
7c673cae FG |
43 | TableFileCreationBriefInfo info; |
44 | info.db_name = db_name; | |
45 | info.cf_name = cf_name; | |
46 | info.file_path = file_path; | |
47 | info.job_id = job_id; | |
48 | info.reason = reason; | |
49 | for (auto& listener : listeners) { | |
50 | listener->OnTableFileCreationStarted(info); | |
51 | } | |
52 | } | |
53 | #endif // !ROCKSDB_LITE | |
54 | ||
11fdf7f2 TL |
55 | void EventHelpers::NotifyOnBackgroundError( |
56 | const std::vector<std::shared_ptr<EventListener>>& listeners, | |
57 | BackgroundErrorReason reason, Status* bg_error, InstrumentedMutex* db_mutex, | |
58 | bool* auto_recovery) { | |
59 | #ifndef ROCKSDB_LITE | |
1e59de90 | 60 | if (listeners.empty()) { |
11fdf7f2 TL |
61 | return; |
62 | } | |
63 | db_mutex->AssertHeld(); | |
64 | // release lock while notifying events | |
65 | db_mutex->Unlock(); | |
66 | for (auto& listener : listeners) { | |
67 | listener->OnBackgroundError(reason, bg_error); | |
20effc67 | 68 | bg_error->PermitUncheckedError(); |
11fdf7f2 TL |
69 | if (*auto_recovery) { |
70 | listener->OnErrorRecoveryBegin(reason, *bg_error, auto_recovery); | |
71 | } | |
72 | } | |
73 | db_mutex->Lock(); | |
74 | #else | |
75 | (void)listeners; | |
76 | (void)reason; | |
77 | (void)bg_error; | |
78 | (void)db_mutex; | |
79 | (void)auto_recovery; | |
80 | #endif // ROCKSDB_LITE | |
81 | } | |
82 | ||
7c673cae FG |
83 | void EventHelpers::LogAndNotifyTableFileCreationFinished( |
84 | EventLogger* event_logger, | |
85 | const std::vector<std::shared_ptr<EventListener>>& listeners, | |
86 | const std::string& db_name, const std::string& cf_name, | |
87 | const std::string& file_path, int job_id, const FileDescriptor& fd, | |
f67539c2 | 88 | uint64_t oldest_blob_file_number, const TableProperties& table_properties, |
20effc67 TL |
89 | TableFileCreationReason reason, const Status& s, |
90 | const std::string& file_checksum, | |
91 | const std::string& file_checksum_func_name) { | |
7c673cae FG |
92 | if (s.ok() && event_logger) { |
93 | JSONWriter jwriter; | |
94 | AppendCurrentTime(&jwriter); | |
95 | jwriter << "cf_name" << cf_name << "job" << job_id << "event" | |
96 | << "table_file_creation" | |
97 | << "file_number" << fd.GetNumber() << "file_size" | |
1e59de90 TL |
98 | << fd.GetFileSize() << "file_checksum" |
99 | << Slice(file_checksum).ToString(true) << "file_checksum_func_name" | |
100 | << file_checksum_func_name << "smallest_seqno" << fd.smallest_seqno | |
101 | << "largest_seqno" << fd.largest_seqno; | |
7c673cae FG |
102 | |
103 | // table_properties | |
104 | { | |
105 | jwriter << "table_properties"; | |
106 | jwriter.StartObject(); | |
107 | ||
108 | // basic properties: | |
109 | jwriter << "data_size" << table_properties.data_size << "index_size" | |
f67539c2 TL |
110 | << table_properties.index_size << "index_partitions" |
111 | << table_properties.index_partitions << "top_level_index_size" | |
112 | << table_properties.top_level_index_size | |
113 | << "index_key_is_user_key" | |
114 | << table_properties.index_key_is_user_key | |
115 | << "index_value_is_delta_encoded" | |
116 | << table_properties.index_value_is_delta_encoded << "filter_size" | |
7c673cae FG |
117 | << table_properties.filter_size << "raw_key_size" |
118 | << table_properties.raw_key_size << "raw_average_key_size" | |
119 | << SafeDivide(table_properties.raw_key_size, | |
120 | table_properties.num_entries) | |
121 | << "raw_value_size" << table_properties.raw_value_size | |
122 | << "raw_average_value_size" | |
123 | << SafeDivide(table_properties.raw_value_size, | |
124 | table_properties.num_entries) | |
125 | << "num_data_blocks" << table_properties.num_data_blocks | |
126 | << "num_entries" << table_properties.num_entries | |
1e59de90 | 127 | << "num_filter_entries" << table_properties.num_filter_entries |
f67539c2 TL |
128 | << "num_deletions" << table_properties.num_deletions |
129 | << "num_merge_operands" << table_properties.num_merge_operands | |
130 | << "num_range_deletions" << table_properties.num_range_deletions | |
131 | << "format_version" << table_properties.format_version | |
132 | << "fixed_key_len" << table_properties.fixed_key_len | |
133 | << "filter_policy" << table_properties.filter_policy_name | |
134 | << "column_family_name" << table_properties.column_family_name | |
135 | << "column_family_id" << table_properties.column_family_id | |
136 | << "comparator" << table_properties.comparator_name | |
137 | << "merge_operator" << table_properties.merge_operator_name | |
138 | << "prefix_extractor_name" | |
139 | << table_properties.prefix_extractor_name << "property_collectors" | |
140 | << table_properties.property_collectors_names << "compression" | |
141 | << table_properties.compression_name << "compression_options" | |
142 | << table_properties.compression_options << "creation_time" | |
143 | << table_properties.creation_time << "oldest_key_time" | |
144 | << table_properties.oldest_key_time << "file_creation_time" | |
1e59de90 TL |
145 | << table_properties.file_creation_time |
146 | << "slow_compression_estimated_data_size" | |
147 | << table_properties.slow_compression_estimated_data_size | |
148 | << "fast_compression_estimated_data_size" | |
149 | << table_properties.fast_compression_estimated_data_size | |
150 | << "db_id" << table_properties.db_id << "db_session_id" | |
151 | << table_properties.db_session_id << "orig_file_number" | |
152 | << table_properties.orig_file_number << "seqno_to_time_mapping"; | |
153 | ||
154 | if (table_properties.seqno_to_time_mapping.empty()) { | |
155 | jwriter << "N/A"; | |
156 | } else { | |
157 | SeqnoToTimeMapping tmp; | |
158 | Status status = tmp.Add(table_properties.seqno_to_time_mapping); | |
159 | if (status.ok()) { | |
160 | jwriter << tmp.ToHumanString(); | |
161 | } else { | |
162 | jwriter << "Invalid"; | |
163 | } | |
164 | } | |
7c673cae FG |
165 | |
166 | // user collected properties | |
167 | for (const auto& prop : table_properties.readable_properties) { | |
168 | jwriter << prop.first << prop.second; | |
169 | } | |
170 | jwriter.EndObject(); | |
171 | } | |
f67539c2 TL |
172 | |
173 | if (oldest_blob_file_number != kInvalidBlobFileNumber) { | |
174 | jwriter << "oldest_blob_file_number" << oldest_blob_file_number; | |
175 | } | |
176 | ||
7c673cae FG |
177 | jwriter.EndObject(); |
178 | ||
179 | event_logger->Log(jwriter); | |
180 | } | |
181 | ||
182 | #ifndef ROCKSDB_LITE | |
1e59de90 | 183 | if (listeners.empty()) { |
7c673cae FG |
184 | return; |
185 | } | |
186 | TableFileCreationInfo info; | |
187 | info.db_name = db_name; | |
188 | info.cf_name = cf_name; | |
189 | info.file_path = file_path; | |
190 | info.file_size = fd.file_size; | |
191 | info.job_id = job_id; | |
192 | info.table_properties = table_properties; | |
193 | info.reason = reason; | |
194 | info.status = s; | |
20effc67 TL |
195 | info.file_checksum = file_checksum; |
196 | info.file_checksum_func_name = file_checksum_func_name; | |
7c673cae FG |
197 | for (auto& listener : listeners) { |
198 | listener->OnTableFileCreated(info); | |
199 | } | |
20effc67 | 200 | info.status.PermitUncheckedError(); |
11fdf7f2 TL |
201 | #else |
202 | (void)listeners; | |
203 | (void)db_name; | |
204 | (void)cf_name; | |
205 | (void)file_path; | |
206 | (void)reason; | |
7c673cae FG |
207 | #endif // !ROCKSDB_LITE |
208 | } | |
209 | ||
210 | void EventHelpers::LogAndNotifyTableFileDeletion( | |
11fdf7f2 TL |
211 | EventLogger* event_logger, int job_id, uint64_t file_number, |
212 | const std::string& file_path, const Status& status, | |
213 | const std::string& dbname, | |
7c673cae | 214 | const std::vector<std::shared_ptr<EventListener>>& listeners) { |
7c673cae FG |
215 | JSONWriter jwriter; |
216 | AppendCurrentTime(&jwriter); | |
217 | ||
11fdf7f2 TL |
218 | jwriter << "job" << job_id << "event" |
219 | << "table_file_deletion" | |
7c673cae FG |
220 | << "file_number" << file_number; |
221 | if (!status.ok()) { | |
222 | jwriter << "status" << status.ToString(); | |
223 | } | |
224 | ||
225 | jwriter.EndObject(); | |
226 | ||
227 | event_logger->Log(jwriter); | |
228 | ||
229 | #ifndef ROCKSDB_LITE | |
1e59de90 TL |
230 | if (listeners.empty()) { |
231 | return; | |
232 | } | |
7c673cae FG |
233 | TableFileDeletionInfo info; |
234 | info.db_name = dbname; | |
235 | info.job_id = job_id; | |
236 | info.file_path = file_path; | |
237 | info.status = status; | |
238 | for (auto& listener : listeners) { | |
239 | listener->OnTableFileDeleted(info); | |
240 | } | |
20effc67 | 241 | info.status.PermitUncheckedError(); |
11fdf7f2 TL |
242 | #else |
243 | (void)file_path; | |
244 | (void)dbname; | |
245 | (void)listeners; | |
7c673cae FG |
246 | #endif // !ROCKSDB_LITE |
247 | } | |
248 | ||
1e59de90 | 249 | void EventHelpers::NotifyOnErrorRecoveryEnd( |
11fdf7f2 | 250 | const std::vector<std::shared_ptr<EventListener>>& listeners, |
1e59de90 TL |
251 | const Status& old_bg_error, const Status& new_bg_error, |
252 | InstrumentedMutex* db_mutex) { | |
11fdf7f2 | 253 | #ifndef ROCKSDB_LITE |
1e59de90 TL |
254 | if (!listeners.empty()) { |
255 | db_mutex->AssertHeld(); | |
256 | // release lock while notifying events | |
257 | db_mutex->Unlock(); | |
258 | for (auto& listener : listeners) { | |
259 | BackgroundErrorRecoveryInfo info; | |
260 | info.old_bg_error = old_bg_error; | |
261 | info.new_bg_error = new_bg_error; | |
262 | listener->OnErrorRecoveryCompleted(old_bg_error); | |
263 | listener->OnErrorRecoveryEnd(info); | |
264 | info.old_bg_error.PermitUncheckedError(); | |
265 | info.new_bg_error.PermitUncheckedError(); | |
266 | } | |
267 | db_mutex->Lock(); | |
11fdf7f2 | 268 | } |
11fdf7f2 TL |
269 | #else |
270 | (void)listeners; | |
271 | (void)old_bg_error; | |
1e59de90 | 272 | (void)new_bg_error; |
11fdf7f2 TL |
273 | (void)db_mutex; |
274 | #endif // ROCKSDB_LITE | |
275 | } | |
276 | ||
1e59de90 TL |
277 | #ifndef ROCKSDB_LITE |
278 | void EventHelpers::NotifyBlobFileCreationStarted( | |
279 | const std::vector<std::shared_ptr<EventListener>>& listeners, | |
280 | const std::string& db_name, const std::string& cf_name, | |
281 | const std::string& file_path, int job_id, | |
282 | BlobFileCreationReason creation_reason) { | |
283 | if (listeners.empty()) { | |
284 | return; | |
285 | } | |
286 | BlobFileCreationBriefInfo info(db_name, cf_name, file_path, job_id, | |
287 | creation_reason); | |
288 | for (const auto& listener : listeners) { | |
289 | listener->OnBlobFileCreationStarted(info); | |
290 | } | |
291 | } | |
292 | #endif // !ROCKSDB_LITE | |
293 | ||
294 | void EventHelpers::LogAndNotifyBlobFileCreationFinished( | |
295 | EventLogger* event_logger, | |
296 | const std::vector<std::shared_ptr<EventListener>>& listeners, | |
297 | const std::string& db_name, const std::string& cf_name, | |
298 | const std::string& file_path, int job_id, uint64_t file_number, | |
299 | BlobFileCreationReason creation_reason, const Status& s, | |
300 | const std::string& file_checksum, | |
301 | const std::string& file_checksum_func_name, uint64_t total_blob_count, | |
302 | uint64_t total_blob_bytes) { | |
303 | if (s.ok() && event_logger) { | |
304 | JSONWriter jwriter; | |
305 | AppendCurrentTime(&jwriter); | |
306 | jwriter << "cf_name" << cf_name << "job" << job_id << "event" | |
307 | << "blob_file_creation" | |
308 | << "file_number" << file_number << "total_blob_count" | |
309 | << total_blob_count << "total_blob_bytes" << total_blob_bytes | |
310 | << "file_checksum" << file_checksum << "file_checksum_func_name" | |
311 | << file_checksum_func_name << "status" << s.ToString(); | |
312 | ||
313 | jwriter.EndObject(); | |
314 | event_logger->Log(jwriter); | |
315 | } | |
316 | ||
317 | #ifndef ROCKSDB_LITE | |
318 | if (listeners.empty()) { | |
319 | return; | |
320 | } | |
321 | BlobFileCreationInfo info(db_name, cf_name, file_path, job_id, | |
322 | creation_reason, total_blob_count, total_blob_bytes, | |
323 | s, file_checksum, file_checksum_func_name); | |
324 | for (const auto& listener : listeners) { | |
325 | listener->OnBlobFileCreated(info); | |
326 | } | |
327 | info.status.PermitUncheckedError(); | |
328 | #else | |
329 | (void)listeners; | |
330 | (void)db_name; | |
331 | (void)file_path; | |
332 | (void)creation_reason; | |
333 | #endif | |
334 | } | |
335 | ||
336 | void EventHelpers::LogAndNotifyBlobFileDeletion( | |
337 | EventLogger* event_logger, | |
338 | const std::vector<std::shared_ptr<EventListener>>& listeners, int job_id, | |
339 | uint64_t file_number, const std::string& file_path, const Status& status, | |
340 | const std::string& dbname) { | |
341 | if (event_logger) { | |
342 | JSONWriter jwriter; | |
343 | AppendCurrentTime(&jwriter); | |
344 | ||
345 | jwriter << "job" << job_id << "event" | |
346 | << "blob_file_deletion" | |
347 | << "file_number" << file_number; | |
348 | if (!status.ok()) { | |
349 | jwriter << "status" << status.ToString(); | |
350 | } | |
351 | ||
352 | jwriter.EndObject(); | |
353 | event_logger->Log(jwriter); | |
354 | } | |
355 | #ifndef ROCKSDB_LITE | |
356 | if (listeners.empty()) { | |
357 | return; | |
358 | } | |
359 | BlobFileDeletionInfo info(dbname, file_path, job_id, status); | |
360 | for (const auto& listener : listeners) { | |
361 | listener->OnBlobFileDeleted(info); | |
362 | } | |
363 | info.status.PermitUncheckedError(); | |
364 | #else | |
365 | (void)listeners; | |
366 | (void)dbname; | |
367 | (void)file_path; | |
368 | #endif // !ROCKSDB_LITE | |
369 | } | |
370 | ||
f67539c2 | 371 | } // namespace ROCKSDB_NAMESPACE |