internal_stats.h 15.7 KB
Newer Older
I
Igor Canadi 已提交
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
//  Copyright (c) 2013, Facebook, Inc.  All rights reserved.
//  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
#include "db/version_set.h"

#include <vector>
#include <string>

17 18
class ColumnFamilyData;

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

class MemTableList;
22
class DBImpl;
23

24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43
// 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);
44 45
};

46
extern const DBPropertyInfo* GetPropertyInfo(const Slice& property);
47 48

#ifndef ROCKSDB_LITE
I
Igor Canadi 已提交
49 50
class InternalStats {
 public:
51
  enum InternalCFStatsType {
52 53
    LEVEL0_SLOWDOWN_TOTAL,
    LEVEL0_SLOWDOWN_WITH_COMPACTION,
I
Igor Canadi 已提交
54
    MEMTABLE_COMPACTION,
55
    MEMTABLE_SLOWDOWN,
56 57
    LEVEL0_NUM_FILES_TOTAL,
    LEVEL0_NUM_FILES_WITH_COMPACTION,
58
    SOFT_PENDING_COMPACTION_BYTES_LIMIT,
59
    HARD_PENDING_COMPACTION_BYTES_LIMIT,
I
Igor Canadi 已提交
60
    WRITE_STALLS_ENUM_MAX,
61 62
    BYTES_FLUSHED,
    INTERNAL_CF_STATS_ENUM_MAX,
I
Igor Canadi 已提交
63 64
  };

65 66 67 68
  enum InternalDBStatsType {
    WAL_FILE_BYTES,
    WAL_FILE_SYNCED,
    BYTES_WRITTEN,
S
sdong 已提交
69
    NUMBER_KEYS_WRITTEN,
70 71 72
    WRITE_DONE_BY_OTHER,
    WRITE_DONE_BY_SELF,
    WRITE_WITH_WAL,
S
sdong 已提交
73
    WRITE_STALL_MICROS,
74 75 76
    INTERNAL_DB_STATS_ENUM_MAX,
  };

77
  InternalStats(int num_levels, Env* env, ColumnFamilyData* cfd)
78 79 80
      : db_stats_{},
        cf_stats_value_{},
        cf_stats_count_{},
81
        comp_stats_(num_levels),
82
        file_read_latency_(num_levels),
83
        bg_error_count_(0),
I
Igor Canadi 已提交
84 85
        number_levels_(num_levels),
        env_(env),
86
        cfd_(cfd),
87
        started_at_(env->NowMicros()) {}
I
Igor Canadi 已提交
88

89
  // Per level compaction stats.  comp_stats_[level] stores the stats for
I
Igor Canadi 已提交
90 91 92 93
  // compactions that produced data for the specified "level".
  struct CompactionStats {
    uint64_t micros;

94 95
    // The number of bytes read from all non-output levels
    uint64_t bytes_read_non_output_levels;
I
Igor Canadi 已提交
96

97 98
    // The number of bytes read from the compaction output level.
    uint64_t bytes_read_output_level;
I
Igor Canadi 已提交
99

100
    // Total number of bytes written during compaction
101
    uint64_t bytes_written;
I
Igor Canadi 已提交
102

103
    // Total number of bytes moved to the output level
104 105
    uint64_t bytes_moved;

106 107
    // The number of compaction input files in all non-output levels.
    int num_input_files_in_non_output_levels;
I
Igor Canadi 已提交
108

109 110
    // The number of compaction input files in the output level.
    int num_input_files_in_output_level;
I
Igor Canadi 已提交
111

112 113
    // The number of compaction output files.
    int num_output_files;
I
Igor Canadi 已提交
114

115
    // Total incoming entries during compaction between levels N and N+1
S
sdong 已提交
116
    uint64_t num_input_records;
117 118 119

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

I
Igor Canadi 已提交
122 123 124
    // Number of compactions done
    int count;

I
Igor Canadi 已提交
125
    explicit CompactionStats(int _count = 0)
I
Igor Canadi 已提交
126
        : micros(0),
127 128
          bytes_read_non_output_levels(0),
          bytes_read_output_level(0),
I
Igor Canadi 已提交
129
          bytes_written(0),
130
          bytes_moved(0),
131 132 133
          num_input_files_in_non_output_levels(0),
          num_input_files_in_output_level(0),
          num_output_files(0),
134 135
          num_input_records(0),
          num_dropped_records(0),
I
Igor Canadi 已提交
136
          count(_count) {}
I
Igor Canadi 已提交
137

138 139
    explicit CompactionStats(const CompactionStats& c)
        : micros(c.micros),
140 141
          bytes_read_non_output_levels(c.bytes_read_non_output_levels),
          bytes_read_output_level(c.bytes_read_output_level),
142
          bytes_written(c.bytes_written),
143
          bytes_moved(c.bytes_moved),
144 145 146 147 148
          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),
149 150
          num_input_records(c.num_input_records),
          num_dropped_records(c.num_dropped_records),
151 152
          count(c.count) {}

I
Igor Canadi 已提交
153 154
    void Add(const CompactionStats& c) {
      this->micros += c.micros;
155 156
      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 已提交
157
      this->bytes_written += c.bytes_written;
158
      this->bytes_moved += c.bytes_moved;
159 160 161 162 163
      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;
164 165
      this->num_input_records += c.num_input_records;
      this->num_dropped_records += c.num_dropped_records;
L
Lei Jin 已提交
166
      this->count += c.count;
I
Igor Canadi 已提交
167
    }
168 169 170

    void Subtract(const CompactionStats& c) {
      this->micros -= c.micros;
171 172
      this->bytes_read_non_output_levels -= c.bytes_read_non_output_levels;
      this->bytes_read_output_level -= c.bytes_read_output_level;
173
      this->bytes_written -= c.bytes_written;
174
      this->bytes_moved -= c.bytes_moved;
175 176 177 178 179
      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;
180 181
      this->num_input_records -= c.num_input_records;
      this->num_dropped_records -= c.num_dropped_records;
182 183
      this->count -= c.count;
    }
I
Igor Canadi 已提交
184 185 186
  };

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

190 191 192 193
  void IncBytesMoved(int level, uint64_t amount) {
    comp_stats_[level].bytes_moved += amount;
  }

194 195 196
  void AddCFStats(InternalCFStatsType type, uint64_t value) {
    cf_stats_value_[type] += value;
    ++cf_stats_count_[type];
I
Igor Canadi 已提交
197 198
  }

199
  void AddDBStats(InternalDBStatsType type, uint64_t value) {
200 201 202 203 204 205 206
    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 已提交
207 208
  }

209 210 211 212
  HistogramImpl* GetFileReadHist(int level) {
    return &file_read_latency_[level];
  }

213 214 215 216
  uint64_t GetBackgroundErrorCount() const { return bg_error_count_; }

  uint64_t BumpAndGetBackgroundErrorCount() { return ++bg_error_count_; }

217 218 219 220 221
  bool GetStringProperty(const DBPropertyInfo& property_info,
                         const Slice& property, std::string* value);

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

223 224
  bool GetIntPropertyOutOfMutex(const DBPropertyInfo& property_info,
                                Version* version, uint64_t* value);
225

226 227 228
  // 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;
229

I
Igor Canadi 已提交
230
 private:
231
  void DumpDBStats(std::string* value);
232
  void DumpCFStats(std::string* value);
233 234

  // Per-DB stats
235
  std::atomic<uint64_t> db_stats_[INTERNAL_DB_STATS_ENUM_MAX];
236
  // Per-ColumnFamily stats
237 238
  uint64_t cf_stats_value_[INTERNAL_CF_STATS_ENUM_MAX];
  uint64_t cf_stats_count_[INTERNAL_CF_STATS_ENUM_MAX];
239 240
  // Per-ColumnFamily/level compaction stats
  std::vector<CompactionStats> comp_stats_;
241
  std::vector<HistogramImpl> file_read_latency_;
I
Igor Canadi 已提交
242 243

  // Used to compute per-interval statistics
244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261
  struct CFStatsSnapshot {
    // ColumnFamily-level stats
    CompactionStats comp_stats;
    uint64_t ingest_bytes;            // Bytes written to L0
    uint64_t stall_count;             // Stall count

    CFStatsSnapshot()
        : comp_stats(0),
          ingest_bytes(0),
          stall_count(0) {}
  } 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 已提交
262 263
    // These count the number of writes processed by the calling thread or
    // another thread.
264 265
    uint64_t write_other;
    uint64_t write_self;
266 267 268 269
    // Stats from compaction jobs - bytes written, bytes read, duration.
    uint64_t compact_bytes_write;
    uint64_t compact_bytes_read;
    uint64_t compact_micros;
S
sdong 已提交
270 271 272 273 274
    // 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 已提交
275 276
    // Total time writes delayed by stalls.
    uint64_t write_stall_micros;
277 278 279 280 281 282 283 284 285
    double seconds_up;

    DBStatsSnapshot()
        : ingest_bytes(0),
          wal_bytes(0),
          wal_synced(0),
          write_with_wal(0),
          write_other(0),
          write_self(0),
286 287 288
          compact_bytes_write(0),
          compact_bytes_read(0),
          compact_micros(0),
289
          num_keys_written(0),
S
sdong 已提交
290
          write_stall_micros(0),
291 292
          seconds_up(0) {}
  } db_stats_snapshot_;
I
Igor Canadi 已提交
293

294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341
  // 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);
  bool HandleLevelStats(std::string* value, Slice suffix);
  bool HandleStats(std::string* value, Slice suffix);
  bool HandleCFStats(std::string* value, Slice suffix);
  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);
  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);

342 343 344 345 346 347 348
  // 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_;

349
  const int number_levels_;
I
Igor Canadi 已提交
350
  Env* env_;
351
  ColumnFamilyData* cfd_;
352
  const uint64_t started_at_;
I
Igor Canadi 已提交
353 354
};

355 356 357 358 359
#else

class InternalStats {
 public:
  enum InternalCFStatsType {
360 361
    LEVEL0_SLOWDOWN_TOTAL,
    LEVEL0_SLOWDOWN_WITH_COMPACTION,
362
    MEMTABLE_COMPACTION,
363
    MEMTABLE_SLOWDOWN,
364 365
    LEVEL0_NUM_FILES_TOTAL,
    LEVEL0_NUM_FILES_WITH_COMPACTION,
366
    SOFT_PENDING_COMPACTION_BYTES_LIMIT,
367
    HARD_PENDING_COMPACTION_BYTES_LIMIT,
368 369 370 371 372 373 374 375 376 377 378 379 380
    WRITE_STALLS_ENUM_MAX,
    BYTES_FLUSHED,
    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 已提交
381
    WRITE_STALL_MICROS,
382 383 384 385 386 387 388
    INTERNAL_DB_STATS_ENUM_MAX,
  };

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

  struct CompactionStats {
    uint64_t micros;
389 390
    uint64_t bytes_read_non_output_levels;
    uint64_t bytes_read_output_level;
391
    uint64_t bytes_written;
392
    uint64_t bytes_moved;
393 394 395
    int num_input_files_in_non_output_levels;
    int num_input_files_in_output_level;
    int num_output_files;
396 397 398 399 400 401 402 403 404 405 406 407 408 409 410
    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) {}

411 412
  void IncBytesMoved(int level, uint64_t amount) {}

413 414 415 416
  void AddCFStats(InternalCFStatsType type, uint64_t value) {}

  void AddDBStats(InternalDBStatsType type, uint64_t value) {}

417 418
  HistogramImpl* GetFileReadHist(int level) { return nullptr; }

419 420 421 422
  uint64_t GetBackgroundErrorCount() const { return 0; }

  uint64_t BumpAndGetBackgroundErrorCount() { return 0; }

423 424 425 426
  bool GetStringProperty(const DBPropertyInfo& property_info,
                         const Slice& property, std::string* value) {
    return false;
  }
427

428 429 430 431
  bool GetIntProperty(const DBPropertyInfo& property_info, uint64_t* value,
                      DBImpl* db) const {
    return false;
  }
432

433 434 435 436
  bool GetIntPropertyOutOfMutex(const DBPropertyInfo& property_info,
                                Version* version, uint64_t* value) const {
    return false;
  }
437 438 439
};
#endif  // !ROCKSDB_LITE

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