internal_stats.h 35.2 KB
Newer Older
1
//  Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
S
Siying Dong 已提交
2 3 4
//  This source code is licensed under both the GPLv2 (found in the
//  COPYING file in the root directory) and Apache 2.0 License
//  (found in the LICENSE.Apache file in the root directory).
I
Igor Canadi 已提交
5 6 7 8 9 10 11
//
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file. See the AUTHORS file for names of contributors.
//

#pragma once
12

13
#include <map>
14
#include <memory>
I
Igor Canadi 已提交
15
#include <string>
16 17
#include <vector>

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"
I
Igor Canadi 已提交
22

23
namespace ROCKSDB_NAMESPACE {
24

25 26
template <class Stats>
class CacheEntryStatsCollector;
27
class DBImpl;
S
Siying Dong 已提交
28
class MemTableList;
29

30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49
// Config for retrieving a property's value.
struct DBPropertyInfo {
  bool need_out_of_mutex;

  // gcc had an internal error for initializing union of pointer-to-member-
  // functions. Workaround is to populate exactly one of the following function
  // pointers with a non-nullptr value.

  // @param value Value-result argument for storing the property's string value
  // @param suffix Argument portion of the property. For example, suffix would
  //      be "5" for the property "rocksdb.num-files-at-level5". So far, only
  //      certain string properties take an argument.
  bool (InternalStats::*handle_string)(std::string* value, Slice suffix);

  // @param value Value-result argument for storing the property's uint64 value
  // @param db Many of the int properties rely on DBImpl methods.
  // @param version Version is needed in case the property is retrieved without
  //      holding db mutex, which is only supported for int properties.
  bool (InternalStats::*handle_int)(uint64_t* value, DBImpl* db,
                                    Version* version);
50 51

  // @param props Map of general properties to populate
52 53 54
  // @param suffix Argument portion of the property. (see handle_string)
  bool (InternalStats::*handle_map)(std::map<std::string, std::string>* props,
                                    Slice suffix);
55 56 57 58

  // handle the string type properties rely on DBImpl methods
  // @param value Value-result argument for storing the property's string value
  bool (DBImpl::*handle_string_dbimpl)(std::string* value);
59 60
};

61
extern const DBPropertyInfo* GetPropertyInfo(const Slice& property);
62 63

#ifndef ROCKSDB_LITE
T
Tomas Kolda 已提交
64
#undef SCORE
65 66 67 68
enum class LevelStatType {
  INVALID = 0,
  NUM_FILES,
  COMPACTED_FILES,
69
  SIZE_BYTES,
70 71 72 73 74 75 76 77 78 79 80
  SCORE,
  READ_GB,
  RN_GB,
  RNP1_GB,
  WRITE_GB,
  W_NEW_GB,
  MOVED_GB,
  WRITE_AMP,
  READ_MBPS,
  WRITE_MBPS,
  COMP_SEC,
81
  COMP_CPU_SEC,
82 83 84 85
  COMP_COUNT,
  AVG_SEC,
  KEY_IN,
  KEY_DROP,
86
  R_BLOB_GB,
87
  W_BLOB_GB,
88 89 90 91 92 93 94 95 96 97
  TOTAL  // total number of types
};

struct LevelStat {
  // This what will be L?.property_name in the flat map returned to the user
  std::string property_name;
  // This will be what we will print in the header in the cli
  std::string header_name;
};

98 99 100 101 102
struct DBStatInfo {
  // This what will be property_name in the flat map returned to the user
  std::string property_name;
};

I
Igor Canadi 已提交
103 104
class InternalStats {
 public:
105 106
  static const std::map<LevelStatType, LevelStat> compaction_level_stats;

107
  enum InternalCFStatsType {
108 109 110 111 112 113 114 115
    L0_FILE_COUNT_LIMIT_SLOWDOWNS,
    LOCKED_L0_FILE_COUNT_LIMIT_SLOWDOWNS,
    MEMTABLE_LIMIT_STOPS,
    MEMTABLE_LIMIT_SLOWDOWNS,
    L0_FILE_COUNT_LIMIT_STOPS,
    LOCKED_L0_FILE_COUNT_LIMIT_STOPS,
    PENDING_COMPACTION_BYTES_LIMIT_SLOWDOWNS,
    PENDING_COMPACTION_BYTES_LIMIT_STOPS,
I
Igor Canadi 已提交
116
    WRITE_STALLS_ENUM_MAX,
117
    BYTES_FLUSHED,
118
    BYTES_INGESTED_ADD_FILE,
119 120 121
    INGESTED_NUM_FILES_TOTAL,
    INGESTED_LEVEL0_NUM_FILES_TOTAL,
    INGESTED_NUM_KEYS_TOTAL,
122
    INTERNAL_CF_STATS_ENUM_MAX,
I
Igor Canadi 已提交
123 124
  };

125
  enum InternalDBStatsType {
126 127 128 129 130 131 132 133 134
    kIntStatsWalFileBytes,
    kIntStatsWalFileSynced,
    kIntStatsBytesWritten,
    kIntStatsNumKeysWritten,
    kIntStatsWriteDoneByOther,
    kIntStatsWriteDoneBySelf,
    kIntStatsWriteWithWal,
    kIntStatsWriteStallMicros,
    kIntStatsNumMax,
135 136
  };

137 138
  static const std::map<InternalDBStatsType, DBStatInfo> db_stats_type_to_info;

139
  InternalStats(int num_levels, SystemClock* clock, ColumnFamilyData* cfd);
I
Igor Canadi 已提交
140

141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157
  // Per level compaction stats
  struct CompactionOutputsStats {
    uint64_t num_output_records = 0;
    uint64_t bytes_written = 0;
    uint64_t bytes_written_blob = 0;
    uint64_t num_output_files = 0;
    uint64_t num_output_files_blob = 0;

    void Add(const CompactionOutputsStats& stats) {
      this->num_output_records += stats.num_output_records;
      this->bytes_written += stats.bytes_written;
      this->bytes_written_blob += stats.bytes_written_blob;
      this->num_output_files += stats.num_output_files;
      this->num_output_files_blob += stats.num_output_files_blob;
    }
  };

158
  // Per level compaction stats.  comp_stats_[level] stores the stats for
I
Igor Canadi 已提交
159 160 161
  // compactions that produced data for the specified "level".
  struct CompactionStats {
    uint64_t micros;
162
    uint64_t cpu_micros;
I
Igor Canadi 已提交
163

164
    // The number of bytes read from all non-output levels (table files)
165
    uint64_t bytes_read_non_output_levels;
I
Igor Canadi 已提交
166

167
    // The number of bytes read from the compaction output level (table files)
168
    uint64_t bytes_read_output_level;
I
Igor Canadi 已提交
169

170 171 172
    // The number of bytes read from blob files
    uint64_t bytes_read_blob;

173
    // Total number of bytes written to table files during compaction
174
    uint64_t bytes_written;
I
Igor Canadi 已提交
175

176 177 178 179
    // Total number of bytes written to blob files during compaction
    uint64_t bytes_written_blob;

    // Total number of bytes moved to the output level (table files)
180 181
    uint64_t bytes_moved;

182 183
    // The number of compaction input files in all non-output levels (table
    // files)
184
    int num_input_files_in_non_output_levels;
I
Igor Canadi 已提交
185

186
    // The number of compaction input files in the output level (table files)
187
    int num_input_files_in_output_level;
I
Igor Canadi 已提交
188

189
    // The number of compaction output files (table files)
190
    int num_output_files;
I
Igor Canadi 已提交
191

192 193 194
    // The number of compaction output files (blob files)
    int num_output_files_blob;

195
    // Total incoming entries during compaction between levels N and N+1
S
sdong 已提交
196
    uint64_t num_input_records;
197 198

    // Accumulated diff number of entries
199
    // (num input entries - num output entries) for compaction levels N and N+1
S
sdong 已提交
200
    uint64_t num_dropped_records;
201

202 203 204
    // Total output entries from compaction
    uint64_t num_output_records;

I
Igor Canadi 已提交
205 206 207
    // Number of compactions done
    int count;

208
    // Number of compactions done per CompactionReason
209
    int counts[static_cast<int>(CompactionReason::kNumOfReasons)]{};
210 211 212

    explicit CompactionStats()
        : micros(0),
213
          cpu_micros(0),
214 215
          bytes_read_non_output_levels(0),
          bytes_read_output_level(0),
216
          bytes_read_blob(0),
217
          bytes_written(0),
218
          bytes_written_blob(0),
219 220 221 222
          bytes_moved(0),
          num_input_files_in_non_output_levels(0),
          num_input_files_in_output_level(0),
          num_output_files(0),
223
          num_output_files_blob(0),
224 225
          num_input_records(0),
          num_dropped_records(0),
226
          num_output_records(0),
227 228 229 230 231 232 233 234
          count(0) {
      int num_of_reasons = static_cast<int>(CompactionReason::kNumOfReasons);
      for (int i = 0; i < num_of_reasons; i++) {
        counts[i] = 0;
      }
    }

    explicit CompactionStats(CompactionReason reason, int c)
I
Igor Canadi 已提交
235
        : micros(0),
236
          cpu_micros(0),
237 238
          bytes_read_non_output_levels(0),
          bytes_read_output_level(0),
239
          bytes_read_blob(0),
I
Igor Canadi 已提交
240
          bytes_written(0),
241
          bytes_written_blob(0),
242
          bytes_moved(0),
243 244 245
          num_input_files_in_non_output_levels(0),
          num_input_files_in_output_level(0),
          num_output_files(0),
246
          num_output_files_blob(0),
247 248
          num_input_records(0),
          num_dropped_records(0),
249
          num_output_records(0),
250 251 252 253 254 255 256 257 258 259 260 261
          count(c) {
      int num_of_reasons = static_cast<int>(CompactionReason::kNumOfReasons);
      for (int i = 0; i < num_of_reasons; i++) {
        counts[i] = 0;
      }
      int r = static_cast<int>(reason);
      if (r >= 0 && r < num_of_reasons) {
        counts[r] = c;
      } else {
        count = 0;
      }
    }
I
Igor Canadi 已提交
262

263
    CompactionStats(const CompactionStats& c)
264
        : micros(c.micros),
265
          cpu_micros(c.cpu_micros),
266 267
          bytes_read_non_output_levels(c.bytes_read_non_output_levels),
          bytes_read_output_level(c.bytes_read_output_level),
268
          bytes_read_blob(c.bytes_read_blob),
269
          bytes_written(c.bytes_written),
270
          bytes_written_blob(c.bytes_written_blob),
271
          bytes_moved(c.bytes_moved),
272 273
          num_input_files_in_non_output_levels(
              c.num_input_files_in_non_output_levels),
274
          num_input_files_in_output_level(c.num_input_files_in_output_level),
275
          num_output_files(c.num_output_files),
276
          num_output_files_blob(c.num_output_files_blob),
277 278
          num_input_records(c.num_input_records),
          num_dropped_records(c.num_dropped_records),
279
          num_output_records(c.num_output_records),
280 281 282 283 284 285
          count(c.count) {
      int num_of_reasons = static_cast<int>(CompactionReason::kNumOfReasons);
      for (int i = 0; i < num_of_reasons; i++) {
        counts[i] = c.counts[i];
      }
    }
286

287 288 289 290 291
    CompactionStats& operator=(const CompactionStats& c) {
      micros = c.micros;
      cpu_micros = c.cpu_micros;
      bytes_read_non_output_levels = c.bytes_read_non_output_levels;
      bytes_read_output_level = c.bytes_read_output_level;
292
      bytes_read_blob = c.bytes_read_blob;
293
      bytes_written = c.bytes_written;
294
      bytes_written_blob = c.bytes_written_blob;
295 296 297 298 299
      bytes_moved = c.bytes_moved;
      num_input_files_in_non_output_levels =
          c.num_input_files_in_non_output_levels;
      num_input_files_in_output_level = c.num_input_files_in_output_level;
      num_output_files = c.num_output_files;
300
      num_output_files_blob = c.num_output_files_blob;
301 302
      num_input_records = c.num_input_records;
      num_dropped_records = c.num_dropped_records;
303
      num_output_records = c.num_output_records;
304 305 306 307 308 309 310 311 312
      count = c.count;

      int num_of_reasons = static_cast<int>(CompactionReason::kNumOfReasons);
      for (int i = 0; i < num_of_reasons; i++) {
        counts[i] = c.counts[i];
      }
      return *this;
    }

S
Siying Dong 已提交
313 314
    void Clear() {
      this->micros = 0;
315
      this->cpu_micros = 0;
S
Siying Dong 已提交
316 317
      this->bytes_read_non_output_levels = 0;
      this->bytes_read_output_level = 0;
318
      this->bytes_read_blob = 0;
S
Siying Dong 已提交
319
      this->bytes_written = 0;
320
      this->bytes_written_blob = 0;
S
Siying Dong 已提交
321 322 323 324
      this->bytes_moved = 0;
      this->num_input_files_in_non_output_levels = 0;
      this->num_input_files_in_output_level = 0;
      this->num_output_files = 0;
325
      this->num_output_files_blob = 0;
S
Siying Dong 已提交
326 327
      this->num_input_records = 0;
      this->num_dropped_records = 0;
328
      this->num_output_records = 0;
S
Siying Dong 已提交
329
      this->count = 0;
330 331 332 333
      int num_of_reasons = static_cast<int>(CompactionReason::kNumOfReasons);
      for (int i = 0; i < num_of_reasons; i++) {
        counts[i] = 0;
      }
S
Siying Dong 已提交
334 335
    }

I
Igor Canadi 已提交
336 337
    void Add(const CompactionStats& c) {
      this->micros += c.micros;
338
      this->cpu_micros += c.cpu_micros;
339 340
      this->bytes_read_non_output_levels += c.bytes_read_non_output_levels;
      this->bytes_read_output_level += c.bytes_read_output_level;
341
      this->bytes_read_blob += c.bytes_read_blob;
I
Igor Canadi 已提交
342
      this->bytes_written += c.bytes_written;
343
      this->bytes_written_blob += c.bytes_written_blob;
344
      this->bytes_moved += c.bytes_moved;
345 346 347 348 349
      this->num_input_files_in_non_output_levels +=
          c.num_input_files_in_non_output_levels;
      this->num_input_files_in_output_level +=
          c.num_input_files_in_output_level;
      this->num_output_files += c.num_output_files;
350
      this->num_output_files_blob += c.num_output_files_blob;
351 352
      this->num_input_records += c.num_input_records;
      this->num_dropped_records += c.num_dropped_records;
353
      this->num_output_records += c.num_output_records;
L
Lei Jin 已提交
354
      this->count += c.count;
355 356 357 358
      int num_of_reasons = static_cast<int>(CompactionReason::kNumOfReasons);
      for (int i = 0; i< num_of_reasons; i++) {
        counts[i] += c.counts[i];
      }
I
Igor Canadi 已提交
359
    }
360

361 362 363 364 365 366 367 368 369
    void Add(const CompactionOutputsStats& stats) {
      this->num_output_files += static_cast<int>(stats.num_output_files);
      this->num_output_records += stats.num_output_records;
      this->bytes_written += stats.bytes_written;
      this->bytes_written_blob += stats.bytes_written_blob;
      this->num_output_files_blob +=
          static_cast<int>(stats.num_output_files_blob);
    }

370 371
    void Subtract(const CompactionStats& c) {
      this->micros -= c.micros;
372
      this->cpu_micros -= c.cpu_micros;
373 374
      this->bytes_read_non_output_levels -= c.bytes_read_non_output_levels;
      this->bytes_read_output_level -= c.bytes_read_output_level;
375
      this->bytes_read_blob -= c.bytes_read_blob;
376
      this->bytes_written -= c.bytes_written;
377
      this->bytes_written_blob -= c.bytes_written_blob;
378
      this->bytes_moved -= c.bytes_moved;
379 380 381 382 383
      this->num_input_files_in_non_output_levels -=
          c.num_input_files_in_non_output_levels;
      this->num_input_files_in_output_level -=
          c.num_input_files_in_output_level;
      this->num_output_files -= c.num_output_files;
384
      this->num_output_files_blob -= c.num_output_files_blob;
385 386
      this->num_input_records -= c.num_input_records;
      this->num_dropped_records -= c.num_dropped_records;
387
      this->num_output_records -= c.num_output_records;
388
      this->count -= c.count;
389 390 391 392
      int num_of_reasons = static_cast<int>(CompactionReason::kNumOfReasons);
      for (int i = 0; i < num_of_reasons; i++) {
        counts[i] -= c.counts[i];
      }
393
    }
394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450

    void ResetCompactionReason(CompactionReason reason) {
      int num_of_reasons = static_cast<int>(CompactionReason::kNumOfReasons);
      assert(count == 1);  // only support update one compaction reason
      for (int i = 0; i < num_of_reasons; i++) {
        counts[i] = 0;
      }
      int r = static_cast<int>(reason);
      assert(r >= 0 && r < num_of_reasons);
      counts[r] = 1;
    }
  };

  // Compaction stats, for per_key_placement compaction, it includes 2 levels
  // stats: the last level and the penultimate level.
  struct CompactionStatsFull {
    // the stats for the target primary output level
    CompactionStats stats;

    // stats for penultimate level output if exist
    bool has_penultimate_level_output = false;
    CompactionStats penultimate_level_stats;

    explicit CompactionStatsFull() : stats(), penultimate_level_stats() {}

    explicit CompactionStatsFull(CompactionReason reason, int c)
        : stats(reason, c), penultimate_level_stats(reason, c){};

    uint64_t TotalBytesWritten() const {
      uint64_t bytes_written = stats.bytes_written + stats.bytes_written_blob;
      if (has_penultimate_level_output) {
        bytes_written += penultimate_level_stats.bytes_written +
                         penultimate_level_stats.bytes_written_blob;
      }
      return bytes_written;
    }

    uint64_t DroppedRecords() {
      uint64_t output_records = stats.num_output_records;
      if (has_penultimate_level_output) {
        output_records += penultimate_level_stats.num_output_records;
      }
      if (stats.num_input_records > output_records) {
        return stats.num_input_records - output_records;
      }
      return 0;
    }

    void SetMicros(uint64_t val) {
      stats.micros = val;
      penultimate_level_stats.micros = val;
    }

    void AddCpuMicros(uint64_t val) {
      stats.cpu_micros += val;
      penultimate_level_stats.cpu_micros += val;
    }
I
Igor Canadi 已提交
451 452
  };

453 454 455
  // For use with CacheEntryStatsCollector
  struct CacheEntryRoleStats {
    uint64_t cache_capacity = 0;
456 457 458
    uint64_t cache_usage = 0;
    size_t table_size = 0;
    size_t occupancy = 0;
459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484
    std::string cache_id;
    std::array<uint64_t, kNumCacheEntryRoles> total_charges;
    std::array<size_t, kNumCacheEntryRoles> entry_counts;
    uint32_t collection_count = 0;
    uint32_t copies_of_last_collection = 0;
    uint64_t last_start_time_micros_ = 0;
    uint64_t last_end_time_micros_ = 0;

    void Clear() {
      // Wipe everything except collection_count
      uint32_t saved_collection_count = collection_count;
      *this = CacheEntryRoleStats();
      collection_count = saved_collection_count;
    }

    void BeginCollection(Cache*, SystemClock*, uint64_t start_time_micros);
    std::function<void(const Slice&, void*, size_t, Cache::DeleterFn)>
    GetEntryCallback();
    void EndCollection(Cache*, SystemClock*, uint64_t end_time_micros);
    void SkippedCollection();

    std::string ToString(SystemClock* clock) const;
    void ToMap(std::map<std::string, std::string>* values,
               SystemClock* clock) const;

   private:
485
    UnorderedMap<Cache::DeleterFn, CacheEntryRole> role_map_;
486 487 488
    uint64_t GetLastDurationMicros() const;
  };

S
Siying Dong 已提交
489
  void Clear() {
490
    for (int i = 0; i < kIntStatsNumMax; i++) {
S
Siying Dong 已提交
491 492 493 494 495 496 497 498 499
      db_stats_[i].store(0);
    }
    for (int i = 0; i < INTERNAL_CF_STATS_ENUM_MAX; i++) {
      cf_stats_count_[i] = 0;
      cf_stats_value_[i] = 0;
    }
    for (auto& comp_stat : comp_stats_) {
      comp_stat.Clear();
    }
500
    per_key_placement_comp_stats_.Clear();
S
Siying Dong 已提交
501 502 503
    for (auto& h : file_read_latency_) {
      h.Clear();
    }
504
    blob_file_read_latency_.Clear();
S
Siying Dong 已提交
505 506 507
    cf_stats_snapshot_.Clear();
    db_stats_snapshot_.Clear();
    bg_error_count_ = 0;
508
    started_at_ = clock_->NowMicros();
S
Siying Dong 已提交
509 510
  }

511 512
  void AddCompactionStats(int level, Env::Priority thread_pri,
                          const CompactionStats& stats) {
513
    comp_stats_[level].Add(stats);
514
    comp_stats_by_pri_[thread_pri].Add(stats);
I
Igor Canadi 已提交
515 516
  }

517 518 519 520 521 522 523 524 525
  void AddCompactionStats(int level, Env::Priority thread_pri,
                          const CompactionStatsFull& comp_stats_full) {
    AddCompactionStats(level, thread_pri, comp_stats_full.stats);
    if (comp_stats_full.has_penultimate_level_output) {
      per_key_placement_comp_stats_.Add(
          comp_stats_full.penultimate_level_stats);
    }
  }

526 527 528 529
  void IncBytesMoved(int level, uint64_t amount) {
    comp_stats_[level].bytes_moved += amount;
  }

530 531 532
  void AddCFStats(InternalCFStatsType type, uint64_t value) {
    cf_stats_value_[type] += value;
    ++cf_stats_count_[type];
I
Igor Canadi 已提交
533 534
  }

535 536
  void AddDBStats(InternalDBStatsType type, uint64_t value,
                  bool concurrent = false) {
537
    auto& v = db_stats_[type];
538 539 540 541 542 543
    if (concurrent) {
      v.fetch_add(value, std::memory_order_relaxed);
    } else {
      v.store(v.load(std::memory_order_relaxed) + value,
              std::memory_order_relaxed);
    }
544 545 546 547
  }

  uint64_t GetDBStats(InternalDBStatsType type) {
    return db_stats_[type].load(std::memory_order_relaxed);
I
Igor Canadi 已提交
548 549
  }

550 551 552 553
  HistogramImpl* GetFileReadHist(int level) {
    return &file_read_latency_[level];
  }

554 555
  HistogramImpl* GetBlobFileReadHist() { return &blob_file_read_latency_; }

556 557 558 559
  uint64_t GetBackgroundErrorCount() const { return bg_error_count_; }

  uint64_t BumpAndGetBackgroundErrorCount() { return ++bg_error_count_; }

560 561 562
  bool GetStringProperty(const DBPropertyInfo& property_info,
                         const Slice& property, std::string* value);

563 564
  bool GetMapProperty(const DBPropertyInfo& property_info,
                      const Slice& property,
565
                      std::map<std::string, std::string>* value);
566

567 568
  bool GetIntProperty(const DBPropertyInfo& property_info, uint64_t* value,
                      DBImpl* db);
I
Igor Canadi 已提交
569

570 571
  bool GetIntPropertyOutOfMutex(const DBPropertyInfo& property_info,
                                Version* version, uint64_t* value);
572

573 574 575 576 577 578 579
  // Unless there is a recent enough collection of the stats, collect and
  // saved new cache entry stats. If `foreground`, require data to be more
  // recent to skip re-collection.
  //
  // This should only be called while NOT holding the DB mutex.
  void CollectCacheEntryStats(bool foreground);

580 581
  const uint64_t* TEST_GetCFStatsValue() const { return cf_stats_value_; }

582 583 584 585
  const std::vector<CompactionStats>& TEST_GetCompactionStats() const {
    return comp_stats_;
  }

586 587 588 589
  const CompactionStats& TEST_GetPerKeyPlacementCompactionStats() const {
    return per_key_placement_comp_stats_;
  }

590
  void TEST_GetCacheEntryRoleStats(CacheEntryRoleStats* stats, bool foreground);
591

592 593
  // Store a mapping from the user-facing DB::Properties string to our
  // DBPropertyInfo struct used internally for retrieving properties.
594
  static const UnorderedMap<std::string, DBPropertyInfo> ppt_name_to_info;
595

I
Igor Canadi 已提交
596
 private:
597
  void DumpDBMapStats(std::map<std::string, std::string>* db_stats);
598
  void DumpDBStats(std::string* value);
599
  void DumpCFMapStats(std::map<std::string, std::string>* cf_stats);
600
  void DumpCFMapStats(
601
      const VersionStorageInfo* vstorage,
602 603
      std::map<int, std::map<LevelStatType, double>>* level_stats,
      CompactionStats* compaction_stats_sum);
604 605
  void DumpCFMapStatsByPriority(
      std::map<int, std::map<LevelStatType, double>>* priorities_stats);
606
  void DumpCFMapStatsIOStalls(std::map<std::string, std::string>* cf_stats);
607
  void DumpCFStats(std::string* value);
608 609
  void DumpCFStatsNoFileHistogram(std::string* value);
  void DumpCFFileHistogram(std::string* value);
610

611 612
  Cache* GetBlockCacheForStats();
  Cache* GetBlobCacheForStats();
613

614
  // Per-DB stats
615
  std::atomic<uint64_t> db_stats_[kIntStatsNumMax];
616
  // Per-ColumnFamily stats
617 618
  uint64_t cf_stats_value_[INTERNAL_CF_STATS_ENUM_MAX];
  uint64_t cf_stats_count_[INTERNAL_CF_STATS_ENUM_MAX];
619 620 621 622 623
  // Initialize/reference the collector in constructor so that we don't need
  // additional synchronization in InternalStats, relying on synchronization
  // in CacheEntryStatsCollector::GetStats. This collector is pinned in cache
  // (through a shared_ptr) so that it does not get immediately ejected from
  // a full cache, which would force a re-scan on the next GetStats.
624 625
  std::shared_ptr<CacheEntryStatsCollector<CacheEntryRoleStats>>
      cache_entry_stats_collector_;
626 627
  // Per-ColumnFamily/level compaction stats
  std::vector<CompactionStats> comp_stats_;
628
  std::vector<CompactionStats> comp_stats_by_pri_;
629
  CompactionStats per_key_placement_comp_stats_;
630
  std::vector<HistogramImpl> file_read_latency_;
631
  HistogramImpl blob_file_read_latency_;
I
Igor Canadi 已提交
632 633

  // Used to compute per-interval statistics
634 635 636
  struct CFStatsSnapshot {
    // ColumnFamily-level stats
    CompactionStats comp_stats;
637
    uint64_t ingest_bytes_flush;      // Bytes written to L0 (Flush)
638
    uint64_t stall_count;             // Stall count
639 640 641 642 643
    // Stats from compaction jobs - bytes written, bytes read, duration.
    uint64_t compact_bytes_write;
    uint64_t compact_bytes_read;
    uint64_t compact_micros;
    double seconds_up;
644

645 646 647 648 649 650
    // AddFile specific stats
    uint64_t ingest_bytes_addfile;     // Total Bytes ingested
    uint64_t ingest_files_addfile;     // Total number of files ingested
    uint64_t ingest_l0_files_addfile;  // Total number of files ingested to L0
    uint64_t ingest_keys_addfile;      // Total number of keys ingested

651
    CFStatsSnapshot()
652
        : ingest_bytes_flush(0),
653 654 655 656
          stall_count(0),
          compact_bytes_write(0),
          compact_bytes_read(0),
          compact_micros(0),
657 658 659 660 661
          seconds_up(0),
          ingest_bytes_addfile(0),
          ingest_files_addfile(0),
          ingest_l0_files_addfile(0),
          ingest_keys_addfile(0) {}
S
Siying Dong 已提交
662 663 664 665 666 667 668 669 670 671 672 673 674 675

    void Clear() {
      comp_stats.Clear();
      ingest_bytes_flush = 0;
      stall_count = 0;
      compact_bytes_write = 0;
      compact_bytes_read = 0;
      compact_micros = 0;
      seconds_up = 0;
      ingest_bytes_addfile = 0;
      ingest_files_addfile = 0;
      ingest_l0_files_addfile = 0;
      ingest_keys_addfile = 0;
    }
676 677 678 679 680 681 682 683
  } cf_stats_snapshot_;

  struct DBStatsSnapshot {
    // DB-level stats
    uint64_t ingest_bytes;            // Bytes written by user
    uint64_t wal_bytes;               // Bytes written to WAL
    uint64_t wal_synced;              // Number of times WAL is synced
    uint64_t write_with_wal;          // Number of writes that request WAL
I
Igor Canadi 已提交
684 685
    // These count the number of writes processed by the calling thread or
    // another thread.
686 687
    uint64_t write_other;
    uint64_t write_self;
S
sdong 已提交
688 689 690 691 692
    // Total number of keys written. write_self and write_other measure number
    // of write requests written, Each of the write request can contain updates
    // to multiple keys. num_keys_written is total number of keys updated by all
    // those writes.
    uint64_t num_keys_written;
S
sdong 已提交
693 694
    // Total time writes delayed by stalls.
    uint64_t write_stall_micros;
695 696 697 698 699 700 701 702 703
    double seconds_up;

    DBStatsSnapshot()
        : ingest_bytes(0),
          wal_bytes(0),
          wal_synced(0),
          write_with_wal(0),
          write_other(0),
          write_self(0),
704
          num_keys_written(0),
S
sdong 已提交
705
          write_stall_micros(0),
706
          seconds_up(0) {}
S
Siying Dong 已提交
707 708 709 710 711 712 713 714 715 716 717 718

    void Clear() {
      ingest_bytes = 0;
      wal_bytes = 0;
      wal_synced = 0;
      write_with_wal = 0;
      write_other = 0;
      write_self = 0;
      num_keys_written = 0;
      write_stall_micros = 0;
      seconds_up = 0;
    }
719
  } db_stats_snapshot_;
I
Igor Canadi 已提交
720

721 722 723
  // Handler functions for getting property values. They use "value" as a value-
  // result argument, and return true upon successfully setting "value".
  bool HandleNumFilesAtLevel(std::string* value, Slice suffix);
724
  bool HandleCompressionRatioAtLevelPrefix(std::string* value, Slice suffix);
725 726
  bool HandleLevelStats(std::string* value, Slice suffix);
  bool HandleStats(std::string* value, Slice suffix);
727 728
  bool HandleCFMapStats(std::map<std::string, std::string>* compaction_stats,
                        Slice suffix);
729
  bool HandleCFStats(std::string* value, Slice suffix);
730 731
  bool HandleCFStatsNoFileHistogram(std::string* value, Slice suffix);
  bool HandleCFFileHistogram(std::string* value, Slice suffix);
732 733
  bool HandleDBMapStats(std::map<std::string, std::string>* compaction_stats,
                        Slice suffix);
734 735 736 737
  bool HandleDBStats(std::string* value, Slice suffix);
  bool HandleSsTables(std::string* value, Slice suffix);
  bool HandleAggregatedTableProperties(std::string* value, Slice suffix);
  bool HandleAggregatedTablePropertiesAtLevel(std::string* value, Slice suffix);
738 739 740 741
  bool HandleAggregatedTablePropertiesMap(
      std::map<std::string, std::string>* values, Slice suffix);
  bool HandleAggregatedTablePropertiesAtLevelMap(
      std::map<std::string, std::string>* values, Slice suffix);
742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767
  bool HandleNumImmutableMemTable(uint64_t* value, DBImpl* db,
                                  Version* version);
  bool HandleNumImmutableMemTableFlushed(uint64_t* value, DBImpl* db,
                                         Version* version);
  bool HandleMemTableFlushPending(uint64_t* value, DBImpl* db,
                                  Version* version);
  bool HandleNumRunningFlushes(uint64_t* value, DBImpl* db, Version* version);
  bool HandleCompactionPending(uint64_t* value, DBImpl* db, Version* version);
  bool HandleNumRunningCompactions(uint64_t* value, DBImpl* db,
                                   Version* version);
  bool HandleBackgroundErrors(uint64_t* value, DBImpl* db, Version* version);
  bool HandleCurSizeActiveMemTable(uint64_t* value, DBImpl* db,
                                   Version* version);
  bool HandleCurSizeAllMemTables(uint64_t* value, DBImpl* db, Version* version);
  bool HandleSizeAllMemTables(uint64_t* value, DBImpl* db, Version* version);
  bool HandleNumEntriesActiveMemTable(uint64_t* value, DBImpl* db,
                                      Version* version);
  bool HandleNumEntriesImmMemTables(uint64_t* value, DBImpl* db,
                                    Version* version);
  bool HandleNumDeletesActiveMemTable(uint64_t* value, DBImpl* db,
                                      Version* version);
  bool HandleNumDeletesImmMemTables(uint64_t* value, DBImpl* db,
                                    Version* version);
  bool HandleEstimateNumKeys(uint64_t* value, DBImpl* db, Version* version);
  bool HandleNumSnapshots(uint64_t* value, DBImpl* db, Version* version);
  bool HandleOldestSnapshotTime(uint64_t* value, DBImpl* db, Version* version);
768 769
  bool HandleOldestSnapshotSequence(uint64_t* value, DBImpl* db,
                                    Version* version);
770
  bool HandleNumLiveVersions(uint64_t* value, DBImpl* db, Version* version);
771 772
  bool HandleCurrentSuperVersionNumber(uint64_t* value, DBImpl* db,
                                       Version* version);
773 774 775 776
  bool HandleIsFileDeletionsEnabled(uint64_t* value, DBImpl* db,
                                    Version* version);
  bool HandleBaseLevel(uint64_t* value, DBImpl* db, Version* version);
  bool HandleTotalSstFilesSize(uint64_t* value, DBImpl* db, Version* version);
777
  bool HandleLiveSstFilesSize(uint64_t* value, DBImpl* db, Version* version);
778 779 780 781 782 783
  bool HandleEstimatePendingCompactionBytes(uint64_t* value, DBImpl* db,
                                            Version* version);
  bool HandleEstimateTableReadersMem(uint64_t* value, DBImpl* db,
                                     Version* version);
  bool HandleEstimateLiveDataSize(uint64_t* value, DBImpl* db,
                                  Version* version);
784
  bool HandleMinLogNumberToKeep(uint64_t* value, DBImpl* db, Version* version);
785 786
  bool HandleMinObsoleteSstNumberToKeep(uint64_t* value, DBImpl* db,
                                        Version* version);
787 788 789
  bool HandleActualDelayedWriteRate(uint64_t* value, DBImpl* db,
                                    Version* version);
  bool HandleIsWriteStopped(uint64_t* value, DBImpl* db, Version* version);
Y
Yi Wu 已提交
790 791
  bool HandleEstimateOldestKeyTime(uint64_t* value, DBImpl* db,
                                   Version* version);
Y
Yi Wu 已提交
792 793 794 795
  bool HandleBlockCacheCapacity(uint64_t* value, DBImpl* db, Version* version);
  bool HandleBlockCacheUsage(uint64_t* value, DBImpl* db, Version* version);
  bool HandleBlockCachePinnedUsage(uint64_t* value, DBImpl* db,
                                   Version* version);
796 797 798
  bool HandleBlockCacheEntryStats(std::string* value, Slice suffix);
  bool HandleBlockCacheEntryStatsMap(std::map<std::string, std::string>* values,
                                     Slice suffix);
799
  bool HandleLiveSstFilesSizeAtTemperature(std::string* value, Slice suffix);
800 801 802 803
  bool HandleNumBlobFiles(uint64_t* value, DBImpl* db, Version* version);
  bool HandleBlobStats(std::string* value, Slice suffix);
  bool HandleTotalBlobFileSize(uint64_t* value, DBImpl* db, Version* version);
  bool HandleLiveBlobFileSize(uint64_t* value, DBImpl* db, Version* version);
804 805
  bool HandleLiveBlobFileGarbageSize(uint64_t* value, DBImpl* db,
                                     Version* version);
806 807 808 809
  bool HandleBlobCacheCapacity(uint64_t* value, DBImpl* db, Version* version);
  bool HandleBlobCacheUsage(uint64_t* value, DBImpl* db, Version* version);
  bool HandleBlobCachePinnedUsage(uint64_t* value, DBImpl* db,
                                  Version* version);
810

811 812 813 814 815 816 817
  // Total number of background errors encountered. Every time a flush task
  // or compaction task fails, this counter is incremented. The failure can
  // be caused by any possible reason, including file system errors, out of
  // resources, or input file corruption. Failing when retrying the same flush
  // or compaction will cause the counter to increase too.
  uint64_t bg_error_count_;

818
  const int number_levels_;
819
  SystemClock* clock_;
820
  ColumnFamilyData* cfd_;
S
Siying Dong 已提交
821
  uint64_t started_at_;
I
Igor Canadi 已提交
822 823
};

824 825 826 827 828
#else

class InternalStats {
 public:
  enum InternalCFStatsType {
829 830 831 832 833 834 835 836
    L0_FILE_COUNT_LIMIT_SLOWDOWNS,
    LOCKED_L0_FILE_COUNT_LIMIT_SLOWDOWNS,
    MEMTABLE_LIMIT_STOPS,
    MEMTABLE_LIMIT_SLOWDOWNS,
    L0_FILE_COUNT_LIMIT_STOPS,
    LOCKED_L0_FILE_COUNT_LIMIT_STOPS,
    PENDING_COMPACTION_BYTES_LIMIT_SLOWDOWNS,
    PENDING_COMPACTION_BYTES_LIMIT_STOPS,
837 838
    WRITE_STALLS_ENUM_MAX,
    BYTES_FLUSHED,
839
    BYTES_INGESTED_ADD_FILE,
840 841 842
    INGESTED_NUM_FILES_TOTAL,
    INGESTED_LEVEL0_NUM_FILES_TOTAL,
    INGESTED_NUM_KEYS_TOTAL,
843 844 845 846
    INTERNAL_CF_STATS_ENUM_MAX,
  };

  enum InternalDBStatsType {
847 848 849 850 851 852 853 854 855
    kIntStatsWalFileBytes,
    kIntStatsWalFileSynced,
    kIntStatsBytesWritten,
    kIntStatsNumKeysWritten,
    kIntStatsWriteDoneByOther,
    kIntStatsWriteDoneBySelf,
    kIntStatsWriteWithWal,
    kIntStatsWriteStallMicros,
    kIntStatsNumMax,
856 857
  };

858
  InternalStats(int /*num_levels*/, SystemClock* /*clock*/,
859
                ColumnFamilyData* /*cfd*/) {}
860

861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877
  // Per level compaction stats
  struct CompactionOutputsStats {
    uint64_t num_output_records = 0;
    uint64_t bytes_written = 0;
    uint64_t bytes_written_blob = 0;
    uint64_t num_output_files = 0;
    uint64_t num_output_files_blob = 0;

    void Add(const CompactionOutputsStats& stats) {
      this->num_output_records += stats.num_output_records;
      this->bytes_written += stats.bytes_written;
      this->bytes_written_blob += stats.bytes_written_blob;
      this->num_output_files += stats.num_output_files;
      this->num_output_files_blob += stats.num_output_files_blob;
    }
  };

878 879
  struct CompactionStats {
    uint64_t micros;
880
    uint64_t cpu_micros;
881 882
    uint64_t bytes_read_non_output_levels;
    uint64_t bytes_read_output_level;
883
    uint64_t bytes_read_blob;
884
    uint64_t bytes_written;
885
    uint64_t bytes_written_blob;
886
    uint64_t bytes_moved;
887 888 889
    int num_input_files_in_non_output_levels;
    int num_input_files_in_output_level;
    int num_output_files;
890
    int num_output_files_blob;
891 892
    uint64_t num_input_records;
    uint64_t num_dropped_records;
893
    uint64_t num_output_records;
894 895
    int count;

896 897
    explicit CompactionStats() {}

898
    explicit CompactionStats(CompactionReason /*reason*/, int /*c*/) {}
899

900
    explicit CompactionStats(const CompactionStats& /*c*/) {}
901

902
    void Add(const CompactionStats& /*c*/) {}
903

904 905
    void Add(const CompactionOutputsStats& /*c*/) {}

906
    void Subtract(const CompactionStats& /*c*/) {}
907 908
  };

909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927 928 929
  struct CompactionStatsFull {
    // the stats for the target primary output level (per level stats)
    CompactionStats stats;

    // stats for output_to_penultimate_level level (per level stats)
    bool has_penultimate_level_output = false;
    CompactionStats penultimate_level_stats;

    explicit CompactionStatsFull(){};

    explicit CompactionStatsFull(CompactionReason /*reason*/, int /*c*/){};

    uint64_t TotalBytesWritten() const { return 0; }

    uint64_t DroppedRecords() { return 0; }

    void SetMicros(uint64_t /*val*/){};

    void AddCpuMicros(uint64_t /*val*/){};
  };

930 931
  void AddCompactionStats(int /*level*/, Env::Priority /*thread_pri*/,
                          const CompactionStats& /*stats*/) {}
932

933 934 935
  void AddCompactionStats(int /*level*/, Env::Priority /*thread_pri*/,
                          const CompactionStatsFull& /*unmerged_stats*/) {}

936
  void IncBytesMoved(int /*level*/, uint64_t /*amount*/) {}
937

938
  void AddCFStats(InternalCFStatsType /*type*/, uint64_t /*value*/) {}
939

940 941
  void AddDBStats(InternalDBStatsType /*type*/, uint64_t /*value*/,
                  bool /*concurrent */ = false) {}
942

943
  HistogramImpl* GetFileReadHist(int /*level*/) { return nullptr; }
944

945 946
  HistogramImpl* GetBlobFileReadHist() { return nullptr; }

947 948 949 950
  uint64_t GetBackgroundErrorCount() const { return 0; }

  uint64_t BumpAndGetBackgroundErrorCount() { return 0; }

951 952
  bool GetStringProperty(const DBPropertyInfo& /*property_info*/,
                         const Slice& /*property*/, std::string* /*value*/) {
953 954
    return false;
  }
955

956 957 958
  bool GetMapProperty(const DBPropertyInfo& /*property_info*/,
                      const Slice& /*property*/,
                      std::map<std::string, std::string>* /*value*/) {
959 960 961
    return false;
  }

962 963
  bool GetIntProperty(const DBPropertyInfo& /*property_info*/, uint64_t* /*value*/,
                      DBImpl* /*db*/) const {
964 965
    return false;
  }
966

967 968
  bool GetIntPropertyOutOfMutex(const DBPropertyInfo& /*property_info*/,
                                Version* /*version*/, uint64_t* /*value*/) const {
969 970
    return false;
  }
971 972 973
};
#endif  // !ROCKSDB_LITE

974
}  // namespace ROCKSDB_NAMESPACE