internal_stats.h 18.5 KB
Newer Older
1
//  Copyright (c) 2011-present, Facebook, Inc.  All rights reserved.
I
Igor Canadi 已提交
2 3 4 5 6 7 8 9 10 11
//  This source code is licensed under the BSD-style license found in the
//  LICENSE file in the root directory of this source tree. An additional grant
//  of patent rights can be found in the PATENTS file in the same directory.
//
// 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
#include <map>
I
Igor Canadi 已提交
13
#include <string>
14 15 16
#include <vector>

#include "db/version_set.h"
I
Igor Canadi 已提交
17

18 19
class ColumnFamilyData;

I
Igor Canadi 已提交
20
namespace rocksdb {
21 22

class MemTableList;
23
class DBImpl;
24

25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
// 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);
45 46
  bool (InternalStats::*handle_map)(
      std::map<std::string, double>* compaction_stats);
47 48
};

49
extern const DBPropertyInfo* GetPropertyInfo(const Slice& property);
50 51

#ifndef ROCKSDB_LITE
52 53 54 55
enum class LevelStatType {
  INVALID = 0,
  NUM_FILES,
  COMPACTED_FILES,
56
  SIZE_BYTES,
57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
  SCORE,
  READ_GB,
  RN_GB,
  RNP1_GB,
  WRITE_GB,
  W_NEW_GB,
  MOVED_GB,
  WRITE_AMP,
  READ_MBPS,
  WRITE_MBPS,
  COMP_SEC,
  COMP_COUNT,
  AVG_SEC,
  KEY_IN,
  KEY_DROP,
  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;
};

I
Igor Canadi 已提交
82 83
class InternalStats {
 public:
84 85
  static const std::map<LevelStatType, LevelStat> compaction_level_stats;

86
  enum InternalCFStatsType {
87 88
    LEVEL0_SLOWDOWN_TOTAL,
    LEVEL0_SLOWDOWN_WITH_COMPACTION,
I
Igor Canadi 已提交
89
    MEMTABLE_COMPACTION,
90
    MEMTABLE_SLOWDOWN,
91 92
    LEVEL0_NUM_FILES_TOTAL,
    LEVEL0_NUM_FILES_WITH_COMPACTION,
93
    SOFT_PENDING_COMPACTION_BYTES_LIMIT,
94
    HARD_PENDING_COMPACTION_BYTES_LIMIT,
I
Igor Canadi 已提交
95
    WRITE_STALLS_ENUM_MAX,
96
    BYTES_FLUSHED,
97
    BYTES_INGESTED_ADD_FILE,
98 99 100
    INGESTED_NUM_FILES_TOTAL,
    INGESTED_LEVEL0_NUM_FILES_TOTAL,
    INGESTED_NUM_KEYS_TOTAL,
101
    INTERNAL_CF_STATS_ENUM_MAX,
I
Igor Canadi 已提交
102 103
  };

104 105 106 107
  enum InternalDBStatsType {
    WAL_FILE_BYTES,
    WAL_FILE_SYNCED,
    BYTES_WRITTEN,
S
sdong 已提交
108
    NUMBER_KEYS_WRITTEN,
109 110 111
    WRITE_DONE_BY_OTHER,
    WRITE_DONE_BY_SELF,
    WRITE_WITH_WAL,
S
sdong 已提交
112
    WRITE_STALL_MICROS,
113 114 115
    INTERNAL_DB_STATS_ENUM_MAX,
  };

116
  InternalStats(int num_levels, Env* env, ColumnFamilyData* cfd)
117 118 119
      : db_stats_{},
        cf_stats_value_{},
        cf_stats_count_{},
120
        comp_stats_(num_levels),
121
        file_read_latency_(num_levels),
122
        bg_error_count_(0),
I
Igor Canadi 已提交
123 124
        number_levels_(num_levels),
        env_(env),
125
        cfd_(cfd),
126
        started_at_(env->NowMicros()) {}
I
Igor Canadi 已提交
127

128
  // Per level compaction stats.  comp_stats_[level] stores the stats for
I
Igor Canadi 已提交
129 130 131 132
  // compactions that produced data for the specified "level".
  struct CompactionStats {
    uint64_t micros;

133 134
    // The number of bytes read from all non-output levels
    uint64_t bytes_read_non_output_levels;
I
Igor Canadi 已提交
135

136 137
    // The number of bytes read from the compaction output level.
    uint64_t bytes_read_output_level;
I
Igor Canadi 已提交
138

139
    // Total number of bytes written during compaction
140
    uint64_t bytes_written;
I
Igor Canadi 已提交
141

142
    // Total number of bytes moved to the output level
143 144
    uint64_t bytes_moved;

145 146
    // The number of compaction input files in all non-output levels.
    int num_input_files_in_non_output_levels;
I
Igor Canadi 已提交
147

148 149
    // The number of compaction input files in the output level.
    int num_input_files_in_output_level;
I
Igor Canadi 已提交
150

151 152
    // The number of compaction output files.
    int num_output_files;
I
Igor Canadi 已提交
153

154
    // Total incoming entries during compaction between levels N and N+1
S
sdong 已提交
155
    uint64_t num_input_records;
156 157 158

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

I
Igor Canadi 已提交
161 162 163
    // Number of compactions done
    int count;

I
Igor Canadi 已提交
164
    explicit CompactionStats(int _count = 0)
I
Igor Canadi 已提交
165
        : micros(0),
166 167
          bytes_read_non_output_levels(0),
          bytes_read_output_level(0),
I
Igor Canadi 已提交
168
          bytes_written(0),
169
          bytes_moved(0),
170 171 172
          num_input_files_in_non_output_levels(0),
          num_input_files_in_output_level(0),
          num_output_files(0),
173 174
          num_input_records(0),
          num_dropped_records(0),
I
Igor Canadi 已提交
175
          count(_count) {}
I
Igor Canadi 已提交
176

177 178
    explicit CompactionStats(const CompactionStats& c)
        : micros(c.micros),
179 180
          bytes_read_non_output_levels(c.bytes_read_non_output_levels),
          bytes_read_output_level(c.bytes_read_output_level),
181
          bytes_written(c.bytes_written),
182
          bytes_moved(c.bytes_moved),
183 184 185 186 187
          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),
188 189
          num_input_records(c.num_input_records),
          num_dropped_records(c.num_dropped_records),
190 191
          count(c.count) {}

I
Igor Canadi 已提交
192 193
    void Add(const CompactionStats& c) {
      this->micros += c.micros;
194 195
      this->bytes_read_non_output_levels += c.bytes_read_non_output_levels;
      this->bytes_read_output_level += c.bytes_read_output_level;
I
Igor Canadi 已提交
196
      this->bytes_written += c.bytes_written;
197
      this->bytes_moved += c.bytes_moved;
198 199 200 201 202
      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;
203 204
      this->num_input_records += c.num_input_records;
      this->num_dropped_records += c.num_dropped_records;
L
Lei Jin 已提交
205
      this->count += c.count;
I
Igor Canadi 已提交
206
    }
207 208 209

    void Subtract(const CompactionStats& c) {
      this->micros -= c.micros;
210 211
      this->bytes_read_non_output_levels -= c.bytes_read_non_output_levels;
      this->bytes_read_output_level -= c.bytes_read_output_level;
212
      this->bytes_written -= c.bytes_written;
213
      this->bytes_moved -= c.bytes_moved;
214 215 216 217 218
      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;
219 220
      this->num_input_records -= c.num_input_records;
      this->num_dropped_records -= c.num_dropped_records;
221 222
      this->count -= c.count;
    }
I
Igor Canadi 已提交
223 224 225
  };

  void AddCompactionStats(int level, const CompactionStats& stats) {
226
    comp_stats_[level].Add(stats);
I
Igor Canadi 已提交
227 228
  }

229 230 231 232
  void IncBytesMoved(int level, uint64_t amount) {
    comp_stats_[level].bytes_moved += amount;
  }

233 234 235
  void AddCFStats(InternalCFStatsType type, uint64_t value) {
    cf_stats_value_[type] += value;
    ++cf_stats_count_[type];
I
Igor Canadi 已提交
236 237
  }

238
  void AddDBStats(InternalDBStatsType type, uint64_t value) {
239 240 241 242 243 244 245
    auto& v = db_stats_[type];
    v.store(v.load(std::memory_order_relaxed) + value,
            std::memory_order_relaxed);
  }

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

248 249 250 251
  HistogramImpl* GetFileReadHist(int level) {
    return &file_read_latency_[level];
  }

252 253 254 255
  uint64_t GetBackgroundErrorCount() const { return bg_error_count_; }

  uint64_t BumpAndGetBackgroundErrorCount() { return ++bg_error_count_; }

256 257 258
  bool GetStringProperty(const DBPropertyInfo& property_info,
                         const Slice& property, std::string* value);

259 260 261 262
  bool GetMapProperty(const DBPropertyInfo& property_info,
                      const Slice& property,
                      std::map<std::string, double>* value);

263 264
  bool GetIntProperty(const DBPropertyInfo& property_info, uint64_t* value,
                      DBImpl* db);
I
Igor Canadi 已提交
265

266 267
  bool GetIntPropertyOutOfMutex(const DBPropertyInfo& property_info,
                                Version* version, uint64_t* value);
268

269 270 271
  // Store a mapping from the user-facing DB::Properties string to our
  // DBPropertyInfo struct used internally for retrieving properties.
  static const std::unordered_map<std::string, DBPropertyInfo> ppt_name_to_info;
272

I
Igor Canadi 已提交
273
 private:
274
  void DumpDBStats(std::string* value);
275
  void DumpCFMapStats(std::map<std::string, double>* cf_stats);
276
  void DumpCFMapStats(
277 278
      std::map<int, std::map<LevelStatType, double>>* level_stats,
      CompactionStats* compaction_stats_sum);
279
  void DumpCFStats(std::string* value);
280 281
  void DumpCFStatsNoFileHistogram(std::string* value);
  void DumpCFFileHistogram(std::string* value);
282 283

  // Per-DB stats
284
  std::atomic<uint64_t> db_stats_[INTERNAL_DB_STATS_ENUM_MAX];
285
  // Per-ColumnFamily stats
286 287
  uint64_t cf_stats_value_[INTERNAL_CF_STATS_ENUM_MAX];
  uint64_t cf_stats_count_[INTERNAL_CF_STATS_ENUM_MAX];
288 289
  // Per-ColumnFamily/level compaction stats
  std::vector<CompactionStats> comp_stats_;
290
  std::vector<HistogramImpl> file_read_latency_;
I
Igor Canadi 已提交
291 292

  // Used to compute per-interval statistics
293 294 295
  struct CFStatsSnapshot {
    // ColumnFamily-level stats
    CompactionStats comp_stats;
296
    uint64_t ingest_bytes_flush;      // Bytes written to L0 (Flush)
297
    uint64_t stall_count;             // Stall count
298 299 300 301 302
    // 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;
303

304 305 306 307 308 309
    // 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

310 311
    CFStatsSnapshot()
        : comp_stats(0),
312
          ingest_bytes_flush(0),
313 314 315 316
          stall_count(0),
          compact_bytes_write(0),
          compact_bytes_read(0),
          compact_micros(0),
317 318 319 320 321
          seconds_up(0),
          ingest_bytes_addfile(0),
          ingest_files_addfile(0),
          ingest_l0_files_addfile(0),
          ingest_keys_addfile(0) {}
322 323 324 325 326 327 328 329
  } 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 已提交
330 331
    // These count the number of writes processed by the calling thread or
    // another thread.
332 333
    uint64_t write_other;
    uint64_t write_self;
S
sdong 已提交
334 335 336 337 338
    // 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 已提交
339 340
    // Total time writes delayed by stalls.
    uint64_t write_stall_micros;
341 342 343 344 345 346 347 348 349
    double seconds_up;

    DBStatsSnapshot()
        : ingest_bytes(0),
          wal_bytes(0),
          wal_synced(0),
          write_with_wal(0),
          write_other(0),
          write_self(0),
350
          num_keys_written(0),
S
sdong 已提交
351
          write_stall_micros(0),
352 353
          seconds_up(0) {}
  } db_stats_snapshot_;
I
Igor Canadi 已提交
354

355 356 357
  // 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);
358
  bool HandleCompressionRatioAtLevelPrefix(std::string* value, Slice suffix);
359 360
  bool HandleLevelStats(std::string* value, Slice suffix);
  bool HandleStats(std::string* value, Slice suffix);
361
  bool HandleCFMapStats(std::map<std::string, double>* compaction_stats);
362
  bool HandleCFStats(std::string* value, Slice suffix);
363 364
  bool HandleCFStatsNoFileHistogram(std::string* value, Slice suffix);
  bool HandleCFFileHistogram(std::string* value, Slice suffix);
365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395
  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);
  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);
  bool HandleNumLiveVersions(uint64_t* value, DBImpl* db, Version* version);
396 397
  bool HandleCurrentSuperVersionNumber(uint64_t* value, DBImpl* db,
                                       Version* version);
398 399 400 401 402 403 404 405 406 407
  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);
  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);
408
  bool HandleMinLogNumberToKeep(uint64_t* value, DBImpl* db, Version* version);
409 410 411
  bool HandleActualDelayedWriteRate(uint64_t* value, DBImpl* db,
                                    Version* version);
  bool HandleIsWriteStopped(uint64_t* value, DBImpl* db, Version* version);
412

413 414 415 416 417 418 419
  // 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_;

420
  const int number_levels_;
I
Igor Canadi 已提交
421
  Env* env_;
422
  ColumnFamilyData* cfd_;
423
  const uint64_t started_at_;
I
Igor Canadi 已提交
424 425
};

426 427 428 429 430
#else

class InternalStats {
 public:
  enum InternalCFStatsType {
431 432
    LEVEL0_SLOWDOWN_TOTAL,
    LEVEL0_SLOWDOWN_WITH_COMPACTION,
433
    MEMTABLE_COMPACTION,
434
    MEMTABLE_SLOWDOWN,
435 436
    LEVEL0_NUM_FILES_TOTAL,
    LEVEL0_NUM_FILES_WITH_COMPACTION,
437
    SOFT_PENDING_COMPACTION_BYTES_LIMIT,
438
    HARD_PENDING_COMPACTION_BYTES_LIMIT,
439 440
    WRITE_STALLS_ENUM_MAX,
    BYTES_FLUSHED,
441
    BYTES_INGESTED_ADD_FILE,
442 443 444
    INGESTED_NUM_FILES_TOTAL,
    INGESTED_LEVEL0_NUM_FILES_TOTAL,
    INGESTED_NUM_KEYS_TOTAL,
445 446 447 448 449 450 451 452 453 454 455
    INTERNAL_CF_STATS_ENUM_MAX,
  };

  enum InternalDBStatsType {
    WAL_FILE_BYTES,
    WAL_FILE_SYNCED,
    BYTES_WRITTEN,
    NUMBER_KEYS_WRITTEN,
    WRITE_DONE_BY_OTHER,
    WRITE_DONE_BY_SELF,
    WRITE_WITH_WAL,
S
sdong 已提交
456
    WRITE_STALL_MICROS,
457 458 459 460 461 462 463
    INTERNAL_DB_STATS_ENUM_MAX,
  };

  InternalStats(int num_levels, Env* env, ColumnFamilyData* cfd) {}

  struct CompactionStats {
    uint64_t micros;
464 465
    uint64_t bytes_read_non_output_levels;
    uint64_t bytes_read_output_level;
466
    uint64_t bytes_written;
467
    uint64_t bytes_moved;
468 469 470
    int num_input_files_in_non_output_levels;
    int num_input_files_in_output_level;
    int num_output_files;
471 472 473 474 475 476 477 478 479 480 481 482 483 484 485
    uint64_t num_input_records;
    uint64_t num_dropped_records;
    int count;

    explicit CompactionStats(int _count = 0) {}

    explicit CompactionStats(const CompactionStats& c) {}

    void Add(const CompactionStats& c) {}

    void Subtract(const CompactionStats& c) {}
  };

  void AddCompactionStats(int level, const CompactionStats& stats) {}

486 487
  void IncBytesMoved(int level, uint64_t amount) {}

488 489 490 491
  void AddCFStats(InternalCFStatsType type, uint64_t value) {}

  void AddDBStats(InternalDBStatsType type, uint64_t value) {}

492 493
  HistogramImpl* GetFileReadHist(int level) { return nullptr; }

494 495 496 497
  uint64_t GetBackgroundErrorCount() const { return 0; }

  uint64_t BumpAndGetBackgroundErrorCount() { return 0; }

498 499 500 501
  bool GetStringProperty(const DBPropertyInfo& property_info,
                         const Slice& property, std::string* value) {
    return false;
  }
502

503 504 505 506 507 508
  bool GetMapProperty(const DBPropertyInfo& property_info,
                      const Slice& property,
                      std::map<std::string, double>* value) {
    return false;
  }

509 510 511 512
  bool GetIntProperty(const DBPropertyInfo& property_info, uint64_t* value,
                      DBImpl* db) const {
    return false;
  }
513

514 515 516 517
  bool GetIntPropertyOutOfMutex(const DBPropertyInfo& property_info,
                                Version* version, uint64_t* value) const {
    return false;
  }
518 519 520
};
#endif  // !ROCKSDB_LITE

I
Igor Canadi 已提交
521
}  // namespace rocksdb