Coverage Report

Created: 2024-07-27 06:53

/src/rocksdb/db/internal_stats.h
Line
Count
Source (jump to first uncovered line)
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).
5
//
6
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
7
// Use of this source code is governed by a BSD-style license that can be
8
// found in the LICENSE file. See the AUTHORS file for names of contributors.
9
//
10
11
#pragma once
12
13
#include <map>
14
#include <memory>
15
#include <string>
16
#include <vector>
17
18
#include "cache/cache_entry_roles.h"
19
#include "db/version_set.h"
20
#include "rocksdb/system_clock.h"
21
#include "util/hash_containers.h"
22
23
namespace ROCKSDB_NAMESPACE {
24
25
template <class Stats>
26
class CacheEntryStatsCollector;
27
class DBImpl;
28
class MemTableList;
29
30
// Config for retrieving a property's value.
31
struct DBPropertyInfo {
32
  bool need_out_of_mutex;
33
34
  // gcc had an internal error for initializing union of pointer-to-member-
35
  // functions. Workaround is to populate exactly one of the following function
36
  // pointers with a non-nullptr value.
37
38
  // @param value Value-result argument for storing the property's string value
39
  // @param suffix Argument portion of the property. For example, suffix would
40
  //      be "5" for the property "rocksdb.num-files-at-level5". So far, only
41
  //      certain string properties take an argument.
42
  bool (InternalStats::*handle_string)(std::string* value, Slice suffix);
43
44
  // @param value Value-result argument for storing the property's uint64 value
45
  // @param db Many of the int properties rely on DBImpl methods.
46
  // @param version Version is needed in case the property is retrieved without
47
  //      holding db mutex, which is only supported for int properties.
48
  bool (InternalStats::*handle_int)(uint64_t* value, DBImpl* db,
49
                                    Version* version);
50
51
  // @param props Map of general properties to populate
52
  // @param suffix Argument portion of the property. (see handle_string)
53
  bool (InternalStats::*handle_map)(std::map<std::string, std::string>* props,
54
                                    Slice suffix);
55
56
  // handle the string type properties rely on DBImpl methods
57
  // @param value Value-result argument for storing the property's string value
58
  bool (DBImpl::*handle_string_dbimpl)(std::string* value);
59
};
60
61
const DBPropertyInfo* GetPropertyInfo(const Slice& property);
62
63
#undef SCORE
64
enum class LevelStatType {
65
  INVALID = 0,
66
  NUM_FILES,
67
  COMPACTED_FILES,
68
  SIZE_BYTES,
69
  SCORE,
70
  READ_GB,
71
  RN_GB,
72
  RNP1_GB,
73
  WRITE_GB,
74
  W_NEW_GB,
75
  MOVED_GB,
76
  WRITE_AMP,
77
  READ_MBPS,
78
  WRITE_MBPS,
79
  COMP_SEC,
80
  COMP_CPU_SEC,
81
  COMP_COUNT,
82
  AVG_SEC,
83
  KEY_IN,
84
  KEY_DROP,
85
  R_BLOB_GB,
86
  W_BLOB_GB,
87
  TOTAL  // total number of types
88
};
89
90
struct LevelStat {
91
  // This what will be L?.property_name in the flat map returned to the user
92
  std::string property_name;
93
  // This will be what we will print in the header in the cli
94
  std::string header_name;
95
};
96
97
struct DBStatInfo {
98
  // This what will be property_name in the flat map returned to the user
99
  std::string property_name;
100
};
101
102
class InternalStats {
103
 public:
104
  static const std::map<LevelStatType, LevelStat> compaction_level_stats;
105
106
  enum InternalCFStatsType {
107
    MEMTABLE_LIMIT_DELAYS,
108
    MEMTABLE_LIMIT_STOPS,
109
    L0_FILE_COUNT_LIMIT_DELAYS,
110
    L0_FILE_COUNT_LIMIT_STOPS,
111
    PENDING_COMPACTION_BYTES_LIMIT_DELAYS,
112
    PENDING_COMPACTION_BYTES_LIMIT_STOPS,
113
    // Write slowdown caused by l0 file count limit while there is ongoing L0
114
    // compaction
115
    L0_FILE_COUNT_LIMIT_DELAYS_WITH_ONGOING_COMPACTION,
116
    // Write stop caused by l0 file count limit while there is ongoing L0
117
    // compaction
118
    L0_FILE_COUNT_LIMIT_STOPS_WITH_ONGOING_COMPACTION,
119
    WRITE_STALLS_ENUM_MAX,
120
    // End of all write stall stats
121
    BYTES_FLUSHED,
122
    BYTES_INGESTED_ADD_FILE,
123
    INGESTED_NUM_FILES_TOTAL,
124
    INGESTED_LEVEL0_NUM_FILES_TOTAL,
125
    INGESTED_NUM_KEYS_TOTAL,
126
    INTERNAL_CF_STATS_ENUM_MAX,
127
  };
128
129
  enum InternalDBStatsType {
130
    kIntStatsWalFileBytes,
131
    kIntStatsWalFileSynced,
132
    kIntStatsBytesWritten,
133
    kIntStatsNumKeysWritten,
134
    kIntStatsWriteDoneByOther,
135
    kIntStatsWriteDoneBySelf,
136
    kIntStatsWriteWithWal,
137
    // TODO(hx235): Currently `kIntStatsWriteStallMicros` only measures
138
    // "delayed" time of CF-scope write stalls, not including the "stopped" time
139
    // nor any DB-scope write stalls (e.g, ones triggered by
140
    // `WriteBufferManager`).
141
    //
142
    // However, the word "write stall" includes both "delayed" and "stopped"
143
    // (see `WriteStallCondition`) and DB-scope writes stalls (see
144
    // `WriteStallCause`).
145
    //
146
    // So we should improve, rename or clarify it
147
    kIntStatsWriteStallMicros,
148
    kIntStatsWriteBufferManagerLimitStopsCounts,
149
    kIntStatsNumMax,
150
  };
151
152
  static const std::map<InternalDBStatsType, DBStatInfo> db_stats_type_to_info;
153
154
  InternalStats(int num_levels, SystemClock* clock, ColumnFamilyData* cfd);
155
156
  // Per level compaction stats
157
  struct CompactionOutputsStats {
158
    uint64_t num_output_records = 0;
159
    uint64_t bytes_written = 0;
160
    uint64_t bytes_written_blob = 0;
161
    uint64_t num_output_files = 0;
162
    uint64_t num_output_files_blob = 0;
163
164
0
    void Add(const CompactionOutputsStats& stats) {
165
0
      this->num_output_records += stats.num_output_records;
166
0
      this->bytes_written += stats.bytes_written;
167
0
      this->bytes_written_blob += stats.bytes_written_blob;
168
0
      this->num_output_files += stats.num_output_files;
169
0
      this->num_output_files_blob += stats.num_output_files_blob;
170
0
    }
171
  };
172
173
  // Per level compaction stats.  comp_stats_[level] stores the stats for
174
  // compactions that produced data for the specified "level".
175
  struct CompactionStats {
176
    uint64_t micros;
177
    uint64_t cpu_micros;
178
179
    // The number of bytes read from all non-output levels (table files)
180
    uint64_t bytes_read_non_output_levels;
181
182
    // The number of bytes read from the compaction output level (table files)
183
    uint64_t bytes_read_output_level;
184
185
    // The number of bytes read from blob files
186
    uint64_t bytes_read_blob;
187
188
    // Total number of bytes written to table files during compaction
189
    uint64_t bytes_written;
190
191
    // Total number of bytes written to blob files during compaction
192
    uint64_t bytes_written_blob;
193
194
    // Total number of bytes moved to the output level (table files)
195
    uint64_t bytes_moved;
196
197
    // The number of compaction input files in all non-output levels (table
198
    // files)
199
    int num_input_files_in_non_output_levels;
200
201
    // The number of compaction input files in the output level (table files)
202
    int num_input_files_in_output_level;
203
204
    // The number of compaction output files (table files)
205
    int num_output_files;
206
207
    // The number of compaction output files (blob files)
208
    int num_output_files_blob;
209
210
    // Total incoming entries during compaction between levels N and N+1
211
    uint64_t num_input_records;
212
213
    // Accumulated diff number of entries
214
    // (num input entries - num output entries) for compaction levels N and N+1
215
    uint64_t num_dropped_records;
216
217
    // Total output entries from compaction
218
    uint64_t num_output_records;
219
220
    // Number of compactions done
221
    int count;
222
223
    // Number of compactions done per CompactionReason
224
    int counts[static_cast<int>(CompactionReason::kNumOfReasons)]{};
225
226
    explicit CompactionStats()
227
        : micros(0),
228
          cpu_micros(0),
229
          bytes_read_non_output_levels(0),
230
          bytes_read_output_level(0),
231
          bytes_read_blob(0),
232
          bytes_written(0),
233
          bytes_written_blob(0),
234
          bytes_moved(0),
235
          num_input_files_in_non_output_levels(0),
236
          num_input_files_in_output_level(0),
237
          num_output_files(0),
238
          num_output_files_blob(0),
239
          num_input_records(0),
240
          num_dropped_records(0),
241
          num_output_records(0),
242
505k
          count(0) {
243
505k
      int num_of_reasons = static_cast<int>(CompactionReason::kNumOfReasons);
244
10.6M
      for (int i = 0; i < num_of_reasons; i++) {
245
10.1M
        counts[i] = 0;
246
10.1M
      }
247
505k
    }
248
249
    explicit CompactionStats(CompactionReason reason, int c)
250
        : micros(0),
251
          cpu_micros(0),
252
          bytes_read_non_output_levels(0),
253
          bytes_read_output_level(0),
254
          bytes_read_blob(0),
255
          bytes_written(0),
256
          bytes_written_blob(0),
257
          bytes_moved(0),
258
          num_input_files_in_non_output_levels(0),
259
          num_input_files_in_output_level(0),
260
          num_output_files(0),
261
          num_output_files_blob(0),
262
          num_input_records(0),
263
          num_dropped_records(0),
264
          num_output_records(0),
265
13.8k
          count(c) {
266
13.8k
      int num_of_reasons = static_cast<int>(CompactionReason::kNumOfReasons);
267
289k
      for (int i = 0; i < num_of_reasons; i++) {
268
276k
        counts[i] = 0;
269
276k
      }
270
13.8k
      int r = static_cast<int>(reason);
271
13.8k
      if (r >= 0 && r < num_of_reasons) {
272
13.8k
        counts[r] = c;
273
13.8k
      } else {
274
0
        count = 0;
275
0
      }
276
13.8k
    }
277
278
    CompactionStats(const CompactionStats& c)
279
        : micros(c.micros),
280
          cpu_micros(c.cpu_micros),
281
          bytes_read_non_output_levels(c.bytes_read_non_output_levels),
282
          bytes_read_output_level(c.bytes_read_output_level),
283
          bytes_read_blob(c.bytes_read_blob),
284
          bytes_written(c.bytes_written),
285
          bytes_written_blob(c.bytes_written_blob),
286
          bytes_moved(c.bytes_moved),
287
          num_input_files_in_non_output_levels(
288
              c.num_input_files_in_non_output_levels),
289
          num_input_files_in_output_level(c.num_input_files_in_output_level),
290
          num_output_files(c.num_output_files),
291
          num_output_files_blob(c.num_output_files_blob),
292
          num_input_records(c.num_input_records),
293
          num_dropped_records(c.num_dropped_records),
294
          num_output_records(c.num_output_records),
295
134
          count(c.count) {
296
134
      int num_of_reasons = static_cast<int>(CompactionReason::kNumOfReasons);
297
2.81k
      for (int i = 0; i < num_of_reasons; i++) {
298
2.68k
        counts[i] = c.counts[i];
299
2.68k
      }
300
134
    }
301
302
134
    CompactionStats& operator=(const CompactionStats& c) {
303
134
      micros = c.micros;
304
134
      cpu_micros = c.cpu_micros;
305
134
      bytes_read_non_output_levels = c.bytes_read_non_output_levels;
306
134
      bytes_read_output_level = c.bytes_read_output_level;
307
134
      bytes_read_blob = c.bytes_read_blob;
308
134
      bytes_written = c.bytes_written;
309
134
      bytes_written_blob = c.bytes_written_blob;
310
134
      bytes_moved = c.bytes_moved;
311
134
      num_input_files_in_non_output_levels =
312
134
          c.num_input_files_in_non_output_levels;
313
134
      num_input_files_in_output_level = c.num_input_files_in_output_level;
314
134
      num_output_files = c.num_output_files;
315
134
      num_output_files_blob = c.num_output_files_blob;
316
134
      num_input_records = c.num_input_records;
317
134
      num_dropped_records = c.num_dropped_records;
318
134
      num_output_records = c.num_output_records;
319
134
      count = c.count;
320
321
134
      int num_of_reasons = static_cast<int>(CompactionReason::kNumOfReasons);
322
2.81k
      for (int i = 0; i < num_of_reasons; i++) {
323
2.68k
        counts[i] = c.counts[i];
324
2.68k
      }
325
134
      return *this;
326
134
    }
327
328
0
    void Clear() {
329
0
      this->micros = 0;
330
0
      this->cpu_micros = 0;
331
0
      this->bytes_read_non_output_levels = 0;
332
0
      this->bytes_read_output_level = 0;
333
0
      this->bytes_read_blob = 0;
334
0
      this->bytes_written = 0;
335
0
      this->bytes_written_blob = 0;
336
0
      this->bytes_moved = 0;
337
0
      this->num_input_files_in_non_output_levels = 0;
338
0
      this->num_input_files_in_output_level = 0;
339
0
      this->num_output_files = 0;
340
0
      this->num_output_files_blob = 0;
341
0
      this->num_input_records = 0;
342
0
      this->num_dropped_records = 0;
343
0
      this->num_output_records = 0;
344
0
      this->count = 0;
345
0
      int num_of_reasons = static_cast<int>(CompactionReason::kNumOfReasons);
346
0
      for (int i = 0; i < num_of_reasons; i++) {
347
0
        counts[i] = 0;
348
0
      }
349
0
    }
350
351
23.3k
    void Add(const CompactionStats& c) {
352
23.3k
      this->micros += c.micros;
353
23.3k
      this->cpu_micros += c.cpu_micros;
354
23.3k
      this->bytes_read_non_output_levels += c.bytes_read_non_output_levels;
355
23.3k
      this->bytes_read_output_level += c.bytes_read_output_level;
356
23.3k
      this->bytes_read_blob += c.bytes_read_blob;
357
23.3k
      this->bytes_written += c.bytes_written;
358
23.3k
      this->bytes_written_blob += c.bytes_written_blob;
359
23.3k
      this->bytes_moved += c.bytes_moved;
360
23.3k
      this->num_input_files_in_non_output_levels +=
361
23.3k
          c.num_input_files_in_non_output_levels;
362
23.3k
      this->num_input_files_in_output_level +=
363
23.3k
          c.num_input_files_in_output_level;
364
23.3k
      this->num_output_files += c.num_output_files;
365
23.3k
      this->num_output_files_blob += c.num_output_files_blob;
366
23.3k
      this->num_input_records += c.num_input_records;
367
23.3k
      this->num_dropped_records += c.num_dropped_records;
368
23.3k
      this->num_output_records += c.num_output_records;
369
23.3k
      this->count += c.count;
370
23.3k
      int num_of_reasons = static_cast<int>(CompactionReason::kNumOfReasons);
371
489k
      for (int i = 0; i < num_of_reasons; i++) {
372
466k
        counts[i] += c.counts[i];
373
466k
      }
374
23.3k
    }
375
376
2.16k
    void Add(const CompactionOutputsStats& stats) {
377
2.16k
      this->num_output_files += static_cast<int>(stats.num_output_files);
378
2.16k
      this->num_output_records += stats.num_output_records;
379
2.16k
      this->bytes_written += stats.bytes_written;
380
2.16k
      this->bytes_written_blob += stats.bytes_written_blob;
381
2.16k
      this->num_output_files_blob +=
382
2.16k
          static_cast<int>(stats.num_output_files_blob);
383
2.16k
    }
384
385
134
    void Subtract(const CompactionStats& c) {
386
134
      this->micros -= c.micros;
387
134
      this->cpu_micros -= c.cpu_micros;
388
134
      this->bytes_read_non_output_levels -= c.bytes_read_non_output_levels;
389
134
      this->bytes_read_output_level -= c.bytes_read_output_level;
390
134
      this->bytes_read_blob -= c.bytes_read_blob;
391
134
      this->bytes_written -= c.bytes_written;
392
134
      this->bytes_written_blob -= c.bytes_written_blob;
393
134
      this->bytes_moved -= c.bytes_moved;
394
134
      this->num_input_files_in_non_output_levels -=
395
134
          c.num_input_files_in_non_output_levels;
396
134
      this->num_input_files_in_output_level -=
397
134
          c.num_input_files_in_output_level;
398
134
      this->num_output_files -= c.num_output_files;
399
134
      this->num_output_files_blob -= c.num_output_files_blob;
400
134
      this->num_input_records -= c.num_input_records;
401
134
      this->num_dropped_records -= c.num_dropped_records;
402
134
      this->num_output_records -= c.num_output_records;
403
134
      this->count -= c.count;
404
134
      int num_of_reasons = static_cast<int>(CompactionReason::kNumOfReasons);
405
2.81k
      for (int i = 0; i < num_of_reasons; i++) {
406
2.68k
        counts[i] -= c.counts[i];
407
2.68k
      }
408
134
    }
409
410
0
    void ResetCompactionReason(CompactionReason reason) {
411
0
      int num_of_reasons = static_cast<int>(CompactionReason::kNumOfReasons);
412
0
      assert(count == 1);  // only support update one compaction reason
413
0
      for (int i = 0; i < num_of_reasons; i++) {
414
0
        counts[i] = 0;
415
0
      }
416
0
      int r = static_cast<int>(reason);
417
0
      assert(r >= 0 && r < num_of_reasons);
418
0
      counts[r] = 1;
419
0
    }
420
  };
421
422
  // Compaction stats, for per_key_placement compaction, it includes 2 levels
423
  // stats: the last level and the penultimate level.
424
  struct CompactionStatsFull {
425
    // the stats for the target primary output level
426
    CompactionStats stats;
427
428
    // stats for penultimate level output if exist
429
    bool has_penultimate_level_output = false;
430
    CompactionStats penultimate_level_stats;
431
432
0
    explicit CompactionStatsFull() : stats(), penultimate_level_stats() {}
433
434
    explicit CompactionStatsFull(CompactionReason reason, int c)
435
2.16k
        : stats(reason, c), penultimate_level_stats(reason, c) {}
436
437
1.45k
    uint64_t TotalBytesWritten() const {
438
1.45k
      uint64_t bytes_written = stats.bytes_written + stats.bytes_written_blob;
439
1.45k
      if (has_penultimate_level_output) {
440
0
        bytes_written += penultimate_level_stats.bytes_written +
441
0
                         penultimate_level_stats.bytes_written_blob;
442
0
      }
443
1.45k
      return bytes_written;
444
1.45k
    }
445
446
2.16k
    uint64_t DroppedRecords() {
447
2.16k
      uint64_t output_records = stats.num_output_records;
448
2.16k
      if (has_penultimate_level_output) {
449
0
        output_records += penultimate_level_stats.num_output_records;
450
0
      }
451
2.16k
      if (stats.num_input_records > output_records) {
452
1.69k
        return stats.num_input_records - output_records;
453
1.69k
      }
454
475
      return 0;
455
2.16k
    }
456
457
2.16k
    void SetMicros(uint64_t val) {
458
2.16k
      stats.micros = val;
459
2.16k
      penultimate_level_stats.micros = val;
460
2.16k
    }
461
462
2.16k
    void AddCpuMicros(uint64_t val) {
463
2.16k
      stats.cpu_micros += val;
464
2.16k
      penultimate_level_stats.cpu_micros += val;
465
2.16k
    }
466
  };
467
468
  // For use with CacheEntryStatsCollector
469
  struct CacheEntryRoleStats {
470
    uint64_t cache_capacity = 0;
471
    uint64_t cache_usage = 0;
472
    size_t table_size = 0;
473
    size_t occupancy = 0;
474
    std::string cache_id;
475
    std::array<uint64_t, kNumCacheEntryRoles> total_charges;
476
    std::array<size_t, kNumCacheEntryRoles> entry_counts;
477
    uint32_t collection_count = 0;
478
    uint32_t copies_of_last_collection = 0;
479
    uint64_t last_start_time_micros_ = 0;
480
    uint64_t last_end_time_micros_ = 0;
481
    uint32_t hash_seed = 0;
482
483
134
    void Clear() {
484
      // Wipe everything except collection_count
485
134
      uint32_t saved_collection_count = collection_count;
486
134
      *this = CacheEntryRoleStats();
487
134
      collection_count = saved_collection_count;
488
134
    }
489
490
    void BeginCollection(Cache*, SystemClock*, uint64_t start_time_micros);
491
    std::function<void(const Slice& key, Cache::ObjectPtr value, size_t charge,
492
                       const Cache::CacheItemHelper* helper)>
493
    GetEntryCallback();
494
    void EndCollection(Cache*, SystemClock*, uint64_t end_time_micros);
495
    void SkippedCollection();
496
497
    std::string ToString(SystemClock* clock) const;
498
    void ToMap(std::map<std::string, std::string>* values,
499
               SystemClock* clock) const;
500
501
   private:
502
    uint64_t GetLastDurationMicros() const;
503
  };
504
505
0
  void Clear() {
506
0
    for (int i = 0; i < kIntStatsNumMax; i++) {
507
0
      db_stats_[i].store(0);
508
0
    }
509
0
    for (int i = 0; i < INTERNAL_CF_STATS_ENUM_MAX; i++) {
510
0
      cf_stats_count_[i] = 0;
511
0
      cf_stats_value_[i] = 0;
512
0
    }
513
0
    for (auto& comp_stat : comp_stats_) {
514
0
      comp_stat.Clear();
515
0
    }
516
0
    per_key_placement_comp_stats_.Clear();
517
0
    for (auto& h : file_read_latency_) {
518
0
      h.Clear();
519
0
    }
520
0
    blob_file_read_latency_.Clear();
521
0
    cf_stats_snapshot_.Clear();
522
0
    db_stats_snapshot_.Clear();
523
0
    bg_error_count_ = 0;
524
0
    started_at_ = clock_->NowMicros();
525
0
    has_cf_change_since_dump_ = true;
526
0
  }
527
528
  void AddCompactionStats(int level, Env::Priority thread_pri,
529
11.6k
                          const CompactionStats& stats) {
530
11.6k
    comp_stats_[level].Add(stats);
531
11.6k
    comp_stats_by_pri_[thread_pri].Add(stats);
532
11.6k
  }
533
534
  void AddCompactionStats(int level, Env::Priority thread_pri,
535
2.16k
                          const CompactionStatsFull& comp_stats_full) {
536
2.16k
    AddCompactionStats(level, thread_pri, comp_stats_full.stats);
537
2.16k
    if (comp_stats_full.has_penultimate_level_output) {
538
0
      per_key_placement_comp_stats_.Add(
539
0
          comp_stats_full.penultimate_level_stats);
540
0
    }
541
2.16k
  }
542
543
1.21k
  void IncBytesMoved(int level, uint64_t amount) {
544
1.21k
    comp_stats_[level].bytes_moved += amount;
545
1.21k
  }
546
547
9.47k
  void AddCFStats(InternalCFStatsType type, uint64_t value) {
548
9.47k
    has_cf_change_since_dump_ = true;
549
9.47k
    cf_stats_value_[type] += value;
550
9.47k
    ++cf_stats_count_[type];
551
9.47k
  }
552
553
  void AddDBStats(InternalDBStatsType type, uint64_t value,
554
6.91M
                  bool concurrent = false) {
555
6.91M
    auto& v = db_stats_[type];
556
6.91M
    if (concurrent) {
557
0
      v.fetch_add(value, std::memory_order_relaxed);
558
6.91M
    } else {
559
6.91M
      v.store(v.load(std::memory_order_relaxed) + value,
560
6.91M
              std::memory_order_relaxed);
561
6.91M
    }
562
6.91M
  }
563
564
792
  uint64_t GetDBStats(InternalDBStatsType type) {
565
792
    return db_stats_[type].load(std::memory_order_relaxed);
566
792
  }
567
568
65.8k
  HistogramImpl* GetFileReadHist(int level) {
569
65.8k
    return &file_read_latency_[level];
570
65.8k
  }
571
572
38.8k
  HistogramImpl* GetBlobFileReadHist() { return &blob_file_read_latency_; }
573
574
0
  uint64_t GetBackgroundErrorCount() const { return bg_error_count_; }
575
576
0
  uint64_t BumpAndGetBackgroundErrorCount() { return ++bg_error_count_; }
577
578
  bool GetStringProperty(const DBPropertyInfo& property_info,
579
                         const Slice& property, std::string* value);
580
581
  bool GetMapProperty(const DBPropertyInfo& property_info,
582
                      const Slice& property,
583
                      std::map<std::string, std::string>* value);
584
585
  bool GetIntProperty(const DBPropertyInfo& property_info, uint64_t* value,
586
                      DBImpl* db);
587
588
  bool GetIntPropertyOutOfMutex(const DBPropertyInfo& property_info,
589
                                Version* version, uint64_t* value);
590
591
  // Unless there is a recent enough collection of the stats, collect and
592
  // saved new cache entry stats. If `foreground`, require data to be more
593
  // recent to skip re-collection.
594
  //
595
  // This should only be called while NOT holding the DB mutex.
596
  void CollectCacheEntryStats(bool foreground);
597
598
0
  const uint64_t* TEST_GetCFStatsValue() const { return cf_stats_value_; }
599
600
0
  const std::vector<CompactionStats>& TEST_GetCompactionStats() const {
601
0
    return comp_stats_;
602
0
  }
603
604
0
  const CompactionStats& TEST_GetPerKeyPlacementCompactionStats() const {
605
0
    return per_key_placement_comp_stats_;
606
0
  }
607
608
  void TEST_GetCacheEntryRoleStats(CacheEntryRoleStats* stats, bool foreground);
609
610
  // Store a mapping from the user-facing DB::Properties string to our
611
  // DBPropertyInfo struct used internally for retrieving properties.
612
  static const UnorderedMap<std::string, DBPropertyInfo> ppt_name_to_info;
613
614
  static const std::string kPeriodicCFStats;
615
616
 private:
617
  void DumpDBMapStats(std::map<std::string, std::string>* db_stats);
618
  void DumpDBStats(std::string* value);
619
620
  void DumpDBMapStatsWriteStall(std::map<std::string, std::string>* value);
621
  void DumpDBStatsWriteStall(std::string* value);
622
623
  void DumpCFMapStats(std::map<std::string, std::string>* cf_stats);
624
  void DumpCFMapStats(
625
      const VersionStorageInfo* vstorage,
626
      std::map<int, std::map<LevelStatType, double>>* level_stats,
627
      CompactionStats* compaction_stats_sum);
628
  void DumpCFMapStatsByPriority(
629
      std::map<int, std::map<LevelStatType, double>>* priorities_stats);
630
  void DumpCFStats(std::string* value);
631
  // if is_periodic = true, it is an internal call by RocksDB periodically to
632
  // dump the status.
633
  void DumpCFStatsNoFileHistogram(bool is_periodic, std::string* value);
634
  // if is_periodic = true, it is an internal call by RocksDB periodically to
635
  // dump the status.
636
  void DumpCFFileHistogram(std::string* value);
637
638
  void DumpCFMapStatsWriteStall(std::map<std::string, std::string>* value);
639
  void DumpCFStatsWriteStall(std::string* value,
640
                             uint64_t* total_stall_count = nullptr);
641
642
  Cache* GetBlockCacheForStats();
643
  Cache* GetBlobCacheForStats();
644
645
  // Per-DB stats
646
  std::atomic<uint64_t> db_stats_[kIntStatsNumMax];
647
  // Per-ColumnFamily stats
648
  uint64_t cf_stats_value_[INTERNAL_CF_STATS_ENUM_MAX];
649
  uint64_t cf_stats_count_[INTERNAL_CF_STATS_ENUM_MAX];
650
  // Initialize/reference the collector in constructor so that we don't need
651
  // additional synchronization in InternalStats, relying on synchronization
652
  // in CacheEntryStatsCollector::GetStats. This collector is pinned in cache
653
  // (through a shared_ptr) so that it does not get immediately ejected from
654
  // a full cache, which would force a re-scan on the next GetStats.
655
  std::shared_ptr<CacheEntryStatsCollector<CacheEntryRoleStats>>
656
      cache_entry_stats_collector_;
657
  // Per-ColumnFamily/level compaction stats
658
  std::vector<CompactionStats> comp_stats_;
659
  std::vector<CompactionStats> comp_stats_by_pri_;
660
  CompactionStats per_key_placement_comp_stats_;
661
  std::vector<HistogramImpl> file_read_latency_;
662
  HistogramImpl blob_file_read_latency_;
663
  bool has_cf_change_since_dump_;
664
  // How many periods of no change since the last time stats are dumped for
665
  // a periodic dump.
666
  int no_cf_change_period_since_dump_ = 0;
667
  uint64_t last_histogram_num = std::numeric_limits<uint64_t>::max();
668
  static const int kMaxNoChangePeriodSinceDump;
669
670
  // Used to compute per-interval statistics
671
  struct CFStatsSnapshot {
672
    // ColumnFamily-level stats
673
    CompactionStats comp_stats;
674
    uint64_t ingest_bytes_flush;  // Bytes written to L0 (Flush)
675
    uint64_t stall_count;         // Total counts of CF-scope write stalls
676
    // Stats from compaction jobs - bytes written, bytes read, duration.
677
    uint64_t compact_bytes_write;
678
    uint64_t compact_bytes_read;
679
    uint64_t compact_micros;
680
    double seconds_up;
681
682
    // AddFile specific stats
683
    uint64_t ingest_bytes_addfile;     // Total Bytes ingested
684
    uint64_t ingest_files_addfile;     // Total number of files ingested
685
    uint64_t ingest_l0_files_addfile;  // Total number of files ingested to L0
686
    uint64_t ingest_keys_addfile;      // Total number of keys ingested
687
688
    CFStatsSnapshot()
689
        : ingest_bytes_flush(0),
690
          stall_count(0),
691
          compact_bytes_write(0),
692
          compact_bytes_read(0),
693
          compact_micros(0),
694
          seconds_up(0),
695
          ingest_bytes_addfile(0),
696
          ingest_files_addfile(0),
697
          ingest_l0_files_addfile(0),
698
38.8k
          ingest_keys_addfile(0) {}
699
700
0
    void Clear() {
701
0
      comp_stats.Clear();
702
0
      ingest_bytes_flush = 0;
703
0
      stall_count = 0;
704
0
      compact_bytes_write = 0;
705
0
      compact_bytes_read = 0;
706
0
      compact_micros = 0;
707
0
      seconds_up = 0;
708
0
      ingest_bytes_addfile = 0;
709
0
      ingest_files_addfile = 0;
710
0
      ingest_l0_files_addfile = 0;
711
0
      ingest_keys_addfile = 0;
712
0
    }
713
  } cf_stats_snapshot_;
714
715
  struct DBStatsSnapshot {
716
    // DB-level stats
717
    uint64_t ingest_bytes;    // Bytes written by user
718
    uint64_t wal_bytes;       // Bytes written to WAL
719
    uint64_t wal_synced;      // Number of times WAL is synced
720
    uint64_t write_with_wal;  // Number of writes that request WAL
721
    // These count the number of writes processed by the calling thread or
722
    // another thread.
723
    uint64_t write_other;
724
    uint64_t write_self;
725
    // Total number of keys written. write_self and write_other measure number
726
    // of write requests written, Each of the write request can contain updates
727
    // to multiple keys. num_keys_written is total number of keys updated by all
728
    // those writes.
729
    uint64_t num_keys_written;
730
    // Total time writes delayed by stalls.
731
    uint64_t write_stall_micros;
732
    double seconds_up;
733
734
    DBStatsSnapshot()
735
        : ingest_bytes(0),
736
          wal_bytes(0),
737
          wal_synced(0),
738
          write_with_wal(0),
739
          write_other(0),
740
          write_self(0),
741
          num_keys_written(0),
742
          write_stall_micros(0),
743
38.8k
          seconds_up(0) {}
744
745
0
    void Clear() {
746
0
      ingest_bytes = 0;
747
0
      wal_bytes = 0;
748
0
      wal_synced = 0;
749
0
      write_with_wal = 0;
750
0
      write_other = 0;
751
0
      write_self = 0;
752
0
      num_keys_written = 0;
753
0
      write_stall_micros = 0;
754
0
      seconds_up = 0;
755
0
    }
756
  } db_stats_snapshot_;
757
758
  // Handler functions for getting property values. They use "value" as a value-
759
  // result argument, and return true upon successfully setting "value".
760
  bool HandleNumFilesAtLevel(std::string* value, Slice suffix);
761
  bool HandleCompressionRatioAtLevelPrefix(std::string* value, Slice suffix);
762
  bool HandleLevelStats(std::string* value, Slice suffix);
763
  bool HandleStats(std::string* value, Slice suffix);
764
  bool HandleCFMapStats(std::map<std::string, std::string>* compaction_stats,
765
                        Slice suffix);
766
  bool HandleCFStats(std::string* value, Slice suffix);
767
  bool HandleCFStatsNoFileHistogram(std::string* value, Slice suffix);
768
  bool HandleCFFileHistogram(std::string* value, Slice suffix);
769
  bool HandleCFStatsPeriodic(std::string* value, Slice suffix);
770
  bool HandleCFWriteStallStats(std::string* value, Slice suffix);
771
  bool HandleCFWriteStallStatsMap(std::map<std::string, std::string>* values,
772
                                  Slice suffix);
773
  bool HandleDBMapStats(std::map<std::string, std::string>* compaction_stats,
774
                        Slice suffix);
775
  bool HandleDBStats(std::string* value, Slice suffix);
776
  bool HandleDBWriteStallStats(std::string* value, Slice suffix);
777
  bool HandleDBWriteStallStatsMap(std::map<std::string, std::string>* values,
778
                                  Slice suffix);
779
  bool HandleSsTables(std::string* value, Slice suffix);
780
  bool HandleAggregatedTableProperties(std::string* value, Slice suffix);
781
  bool HandleAggregatedTablePropertiesAtLevel(std::string* value, Slice suffix);
782
  bool HandleAggregatedTablePropertiesMap(
783
      std::map<std::string, std::string>* values, Slice suffix);
784
  bool HandleAggregatedTablePropertiesAtLevelMap(
785
      std::map<std::string, std::string>* values, Slice suffix);
786
  bool HandleNumImmutableMemTable(uint64_t* value, DBImpl* db,
787
                                  Version* version);
788
  bool HandleNumImmutableMemTableFlushed(uint64_t* value, DBImpl* db,
789
                                         Version* version);
790
  bool HandleMemTableFlushPending(uint64_t* value, DBImpl* db,
791
                                  Version* version);
792
  bool HandleNumRunningFlushes(uint64_t* value, DBImpl* db, Version* version);
793
  bool HandleCompactionPending(uint64_t* value, DBImpl* db, Version* version);
794
  bool HandleNumRunningCompactions(uint64_t* value, DBImpl* db,
795
                                   Version* version);
796
  bool HandleBackgroundErrors(uint64_t* value, DBImpl* db, Version* version);
797
  bool HandleCurSizeActiveMemTable(uint64_t* value, DBImpl* db,
798
                                   Version* version);
799
  bool HandleCurSizeAllMemTables(uint64_t* value, DBImpl* db, Version* version);
800
  bool HandleSizeAllMemTables(uint64_t* value, DBImpl* db, Version* version);
801
  bool HandleNumEntriesActiveMemTable(uint64_t* value, DBImpl* db,
802
                                      Version* version);
803
  bool HandleNumEntriesImmMemTables(uint64_t* value, DBImpl* db,
804
                                    Version* version);
805
  bool HandleNumDeletesActiveMemTable(uint64_t* value, DBImpl* db,
806
                                      Version* version);
807
  bool HandleNumDeletesImmMemTables(uint64_t* value, DBImpl* db,
808
                                    Version* version);
809
  bool HandleEstimateNumKeys(uint64_t* value, DBImpl* db, Version* version);
810
  bool HandleNumSnapshots(uint64_t* value, DBImpl* db, Version* version);
811
  bool HandleOldestSnapshotTime(uint64_t* value, DBImpl* db, Version* version);
812
  bool HandleOldestSnapshotSequence(uint64_t* value, DBImpl* db,
813
                                    Version* version);
814
  bool HandleNumLiveVersions(uint64_t* value, DBImpl* db, Version* version);
815
  bool HandleCurrentSuperVersionNumber(uint64_t* value, DBImpl* db,
816
                                       Version* version);
817
  bool HandleIsFileDeletionsEnabled(uint64_t* value, DBImpl* db,
818
                                    Version* version);
819
  bool HandleBaseLevel(uint64_t* value, DBImpl* db, Version* version);
820
  bool HandleTotalSstFilesSize(uint64_t* value, DBImpl* db, Version* version);
821
  bool HandleLiveSstFilesSize(uint64_t* value, DBImpl* db, Version* version);
822
  bool HandleObsoleteSstFilesSize(uint64_t* value, DBImpl* db,
823
                                  Version* version);
824
  bool HandleEstimatePendingCompactionBytes(uint64_t* value, DBImpl* db,
825
                                            Version* version);
826
  bool HandleEstimateTableReadersMem(uint64_t* value, DBImpl* db,
827
                                     Version* version);
828
  bool HandleEstimateLiveDataSize(uint64_t* value, DBImpl* db,
829
                                  Version* version);
830
  bool HandleMinLogNumberToKeep(uint64_t* value, DBImpl* db, Version* version);
831
  bool HandleMinObsoleteSstNumberToKeep(uint64_t* value, DBImpl* db,
832
                                        Version* version);
833
  bool HandleActualDelayedWriteRate(uint64_t* value, DBImpl* db,
834
                                    Version* version);
835
  bool HandleIsWriteStopped(uint64_t* value, DBImpl* db, Version* version);
836
  bool HandleEstimateOldestKeyTime(uint64_t* value, DBImpl* db,
837
                                   Version* version);
838
  bool HandleBlockCacheCapacity(uint64_t* value, DBImpl* db, Version* version);
839
  bool HandleBlockCacheUsage(uint64_t* value, DBImpl* db, Version* version);
840
  bool HandleBlockCachePinnedUsage(uint64_t* value, DBImpl* db,
841
                                   Version* version);
842
  bool HandleBlockCacheEntryStatsInternal(std::string* value, bool fast);
843
  bool HandleBlockCacheEntryStatsMapInternal(
844
      std::map<std::string, std::string>* values, bool fast);
845
  bool HandleBlockCacheEntryStats(std::string* value, Slice suffix);
846
  bool HandleBlockCacheEntryStatsMap(std::map<std::string, std::string>* values,
847
                                     Slice suffix);
848
  bool HandleFastBlockCacheEntryStats(std::string* value, Slice suffix);
849
  bool HandleFastBlockCacheEntryStatsMap(
850
      std::map<std::string, std::string>* values, Slice suffix);
851
  bool HandleLiveSstFilesSizeAtTemperature(std::string* value, Slice suffix);
852
  bool HandleNumBlobFiles(uint64_t* value, DBImpl* db, Version* version);
853
  bool HandleBlobStats(std::string* value, Slice suffix);
854
  bool HandleTotalBlobFileSize(uint64_t* value, DBImpl* db, Version* version);
855
  bool HandleLiveBlobFileSize(uint64_t* value, DBImpl* db, Version* version);
856
  bool HandleLiveBlobFileGarbageSize(uint64_t* value, DBImpl* db,
857
                                     Version* version);
858
  bool HandleBlobCacheCapacity(uint64_t* value, DBImpl* db, Version* version);
859
  bool HandleBlobCacheUsage(uint64_t* value, DBImpl* db, Version* version);
860
  bool HandleBlobCachePinnedUsage(uint64_t* value, DBImpl* db,
861
                                  Version* version);
862
863
  // Total number of background errors encountered. Every time a flush task
864
  // or compaction task fails, this counter is incremented. The failure can
865
  // be caused by any possible reason, including file system errors, out of
866
  // resources, or input file corruption. Failing when retrying the same flush
867
  // or compaction will cause the counter to increase too.
868
  uint64_t bg_error_count_;
869
870
  const int number_levels_;
871
  SystemClock* clock_;
872
  ColumnFamilyData* cfd_;
873
  uint64_t started_at_;
874
};
875
876
// IntPropertyAggregator aggregates an integer property across all column
877
// families.
878
class IntPropertyAggregator {
879
 public:
880
0
  IntPropertyAggregator() {}
881
0
  virtual ~IntPropertyAggregator() {}
882
883
  IntPropertyAggregator(const IntPropertyAggregator&) = delete;
884
  void operator=(const IntPropertyAggregator&) = delete;
885
886
  // Add a column family's property value to the aggregator.
887
  virtual void Add(ColumnFamilyData* cfd, uint64_t value) = 0;
888
889
  // Get the aggregated value.
890
  virtual uint64_t Aggregate() const = 0;
891
};
892
893
std::unique_ptr<IntPropertyAggregator> CreateIntPropertyAggregator(
894
    const Slice& property);
895
896
}  // namespace ROCKSDB_NAMESPACE