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 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481
  // For use with CacheEntryStatsCollector
  struct CacheEntryRoleStats {
    uint64_t cache_capacity = 0;
    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:
482
    UnorderedMap<Cache::DeleterFn, CacheEntryRole> role_map_;
483 484 485
    uint64_t GetLastDurationMicros() const;
  };

S
Siying Dong 已提交
486
  void Clear() {
487
    for (int i = 0; i < kIntStatsNumMax; i++) {
S
Siying Dong 已提交
488 489 490 491 492 493 494 495 496
      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();
    }
497
    per_key_placement_comp_stats_.Clear();
S
Siying Dong 已提交
498 499 500
    for (auto& h : file_read_latency_) {
      h.Clear();
    }
501
    blob_file_read_latency_.Clear();
S
Siying Dong 已提交
502 503 504
    cf_stats_snapshot_.Clear();
    db_stats_snapshot_.Clear();
    bg_error_count_ = 0;
505
    started_at_ = clock_->NowMicros();
S
Siying Dong 已提交
506 507
  }

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

514 515 516 517 518 519 520 521 522
  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);
    }
  }

523 524 525 526
  void IncBytesMoved(int level, uint64_t amount) {
    comp_stats_[level].bytes_moved += amount;
  }

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

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

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

547 548 549 550
  HistogramImpl* GetFileReadHist(int level) {
    return &file_read_latency_[level];
  }

551 552
  HistogramImpl* GetBlobFileReadHist() { return &blob_file_read_latency_; }

553 554 555 556
  uint64_t GetBackgroundErrorCount() const { return bg_error_count_; }

  uint64_t BumpAndGetBackgroundErrorCount() { return ++bg_error_count_; }

557 558 559
  bool GetStringProperty(const DBPropertyInfo& property_info,
                         const Slice& property, std::string* value);

560 561
  bool GetMapProperty(const DBPropertyInfo& property_info,
                      const Slice& property,
562
                      std::map<std::string, std::string>* value);
563

564 565
  bool GetIntProperty(const DBPropertyInfo& property_info, uint64_t* value,
                      DBImpl* db);
I
Igor Canadi 已提交
566

567 568
  bool GetIntPropertyOutOfMutex(const DBPropertyInfo& property_info,
                                Version* version, uint64_t* value);
569

570 571 572 573 574 575 576
  // 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);

577 578
  const uint64_t* TEST_GetCFStatsValue() const { return cf_stats_value_; }

579 580 581 582
  const std::vector<CompactionStats>& TEST_GetCompactionStats() const {
    return comp_stats_;
  }

583 584 585 586
  const CompactionStats& TEST_GetPerKeyPlacementCompactionStats() const {
    return per_key_placement_comp_stats_;
  }

587
  void TEST_GetCacheEntryRoleStats(CacheEntryRoleStats* stats, bool foreground);
588

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

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

608 609
  Cache* GetBlockCacheForStats();
  Cache* GetBlobCacheForStats();
610

611
  // Per-DB stats
612
  std::atomic<uint64_t> db_stats_[kIntStatsNumMax];
613
  // Per-ColumnFamily stats
614 615
  uint64_t cf_stats_value_[INTERNAL_CF_STATS_ENUM_MAX];
  uint64_t cf_stats_count_[INTERNAL_CF_STATS_ENUM_MAX];
616 617 618 619 620
  // 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.
621 622
  std::shared_ptr<CacheEntryStatsCollector<CacheEntryRoleStats>>
      cache_entry_stats_collector_;
623 624
  // Per-ColumnFamily/level compaction stats
  std::vector<CompactionStats> comp_stats_;
625
  std::vector<CompactionStats> comp_stats_by_pri_;
626
  CompactionStats per_key_placement_comp_stats_;
627
  std::vector<HistogramImpl> file_read_latency_;
628
  HistogramImpl blob_file_read_latency_;
I
Igor Canadi 已提交
629 630

  // Used to compute per-interval statistics
631 632 633
  struct CFStatsSnapshot {
    // ColumnFamily-level stats
    CompactionStats comp_stats;
634
    uint64_t ingest_bytes_flush;      // Bytes written to L0 (Flush)
635
    uint64_t stall_count;             // Stall count
636 637 638 639 640
    // 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;
641

642 643 644 645 646 647
    // 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

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

    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;
    }
673 674 675 676 677 678 679 680
  } 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 已提交
681 682
    // These count the number of writes processed by the calling thread or
    // another thread.
683 684
    uint64_t write_other;
    uint64_t write_self;
S
sdong 已提交
685 686 687 688 689
    // 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 已提交
690 691
    // Total time writes delayed by stalls.
    uint64_t write_stall_micros;
692 693 694 695 696 697 698 699 700
    double seconds_up;

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

    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;
    }
716
  } db_stats_snapshot_;
I
Igor Canadi 已提交
717

718 719 720
  // 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);
721
  bool HandleCompressionRatioAtLevelPrefix(std::string* value, Slice suffix);
722 723
  bool HandleLevelStats(std::string* value, Slice suffix);
  bool HandleStats(std::string* value, Slice suffix);
724 725
  bool HandleCFMapStats(std::map<std::string, std::string>* compaction_stats,
                        Slice suffix);
726
  bool HandleCFStats(std::string* value, Slice suffix);
727 728
  bool HandleCFStatsNoFileHistogram(std::string* value, Slice suffix);
  bool HandleCFFileHistogram(std::string* value, Slice suffix);
729 730
  bool HandleDBMapStats(std::map<std::string, std::string>* compaction_stats,
                        Slice suffix);
731 732 733 734
  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);
735 736 737 738
  bool HandleAggregatedTablePropertiesMap(
      std::map<std::string, std::string>* values, Slice suffix);
  bool HandleAggregatedTablePropertiesAtLevelMap(
      std::map<std::string, std::string>* values, Slice suffix);
739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764
  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);
765 766
  bool HandleOldestSnapshotSequence(uint64_t* value, DBImpl* db,
                                    Version* version);
767
  bool HandleNumLiveVersions(uint64_t* value, DBImpl* db, Version* version);
768 769
  bool HandleCurrentSuperVersionNumber(uint64_t* value, DBImpl* db,
                                       Version* version);
770 771 772 773
  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);
774
  bool HandleLiveSstFilesSize(uint64_t* value, DBImpl* db, Version* version);
775 776 777 778 779 780
  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);
781
  bool HandleMinLogNumberToKeep(uint64_t* value, DBImpl* db, Version* version);
782 783
  bool HandleMinObsoleteSstNumberToKeep(uint64_t* value, DBImpl* db,
                                        Version* version);
784 785 786
  bool HandleActualDelayedWriteRate(uint64_t* value, DBImpl* db,
                                    Version* version);
  bool HandleIsWriteStopped(uint64_t* value, DBImpl* db, Version* version);
Y
Yi Wu 已提交
787 788
  bool HandleEstimateOldestKeyTime(uint64_t* value, DBImpl* db,
                                   Version* version);
Y
Yi Wu 已提交
789 790 791 792
  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);
793 794 795
  bool HandleBlockCacheEntryStats(std::string* value, Slice suffix);
  bool HandleBlockCacheEntryStatsMap(std::map<std::string, std::string>* values,
                                     Slice suffix);
796
  bool HandleLiveSstFilesSizeAtTemperature(std::string* value, Slice suffix);
797 798 799 800
  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);
801 802
  bool HandleLiveBlobFileGarbageSize(uint64_t* value, DBImpl* db,
                                     Version* version);
803 804 805 806
  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);
807

808 809 810 811 812 813 814
  // 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_;

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

821 822 823 824 825
#else

class InternalStats {
 public:
  enum InternalCFStatsType {
826 827 828 829 830 831 832 833
    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,
834 835
    WRITE_STALLS_ENUM_MAX,
    BYTES_FLUSHED,
836
    BYTES_INGESTED_ADD_FILE,
837 838 839
    INGESTED_NUM_FILES_TOTAL,
    INGESTED_LEVEL0_NUM_FILES_TOTAL,
    INGESTED_NUM_KEYS_TOTAL,
840 841 842 843
    INTERNAL_CF_STATS_ENUM_MAX,
  };

  enum InternalDBStatsType {
844 845 846 847 848 849 850 851 852
    kIntStatsWalFileBytes,
    kIntStatsWalFileSynced,
    kIntStatsBytesWritten,
    kIntStatsNumKeysWritten,
    kIntStatsWriteDoneByOther,
    kIntStatsWriteDoneBySelf,
    kIntStatsWriteWithWal,
    kIntStatsWriteStallMicros,
    kIntStatsNumMax,
853 854
  };

855
  InternalStats(int /*num_levels*/, SystemClock* /*clock*/,
856
                ColumnFamilyData* /*cfd*/) {}
857

858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874
  // 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;
    }
  };

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

893 894
    explicit CompactionStats() {}

895
    explicit CompactionStats(CompactionReason /*reason*/, int /*c*/) {}
896

897
    explicit CompactionStats(const CompactionStats& /*c*/) {}
898

899
    void Add(const CompactionStats& /*c*/) {}
900

901 902
    void Add(const CompactionOutputsStats& /*c*/) {}

903
    void Subtract(const CompactionStats& /*c*/) {}
904 905
  };

906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926
  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*/){};
  };

927 928
  void AddCompactionStats(int /*level*/, Env::Priority /*thread_pri*/,
                          const CompactionStats& /*stats*/) {}
929

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

933
  void IncBytesMoved(int /*level*/, uint64_t /*amount*/) {}
934

935
  void AddCFStats(InternalCFStatsType /*type*/, uint64_t /*value*/) {}
936

937 938
  void AddDBStats(InternalDBStatsType /*type*/, uint64_t /*value*/,
                  bool /*concurrent */ = false) {}
939

940
  HistogramImpl* GetFileReadHist(int /*level*/) { return nullptr; }
941

942 943
  HistogramImpl* GetBlobFileReadHist() { return nullptr; }

944 945 946 947
  uint64_t GetBackgroundErrorCount() const { return 0; }

  uint64_t BumpAndGetBackgroundErrorCount() { return 0; }

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

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

959 960
  bool GetIntProperty(const DBPropertyInfo& /*property_info*/, uint64_t* /*value*/,
                      DBImpl* /*db*/) const {
961 962
    return false;
  }
963

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

971
}  // namespace ROCKSDB_NAMESPACE