YugabyteDB (2.13.1.0-b60, 21121d69985fbf76aa6958d8f04a9bfa936293b5)

Coverage Report

Created: 2022-03-22 16:43

/Users/deen/code/yugabyte-db/src/yb/rocksdb/db/internal_stats.cc
Line
Count
Source (jump to first uncovered line)
1
//  This source code is licensed under the BSD-style license found in the
2
//  LICENSE file in the root directory of this source tree. An additional grant
3
//  of patent rights can be found in the PATENTS file in the same directory.
4
//
5
// The following only applies to changes made to this file as part of YugaByte development.
6
//
7
// Portions Copyright (c) YugaByte, Inc.
8
//
9
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
10
// in compliance with the License.  You may obtain a copy of the License at
11
//
12
// http://www.apache.org/licenses/LICENSE-2.0
13
//
14
// Unless required by applicable law or agreed to in writing, software distributed under the License
15
// is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
16
// or implied.  See the License for the specific language governing permissions and limitations
17
// under the License.
18
//
19
// Copyright (c) 2011 The LevelDB Authors. All rights reserved.
20
// Use of this source code is governed by a BSD-style license that can be
21
// found in the LICENSE file. See the AUTHORS file for names of contributors.
22
23
#include "yb/rocksdb/db/internal_stats.h"
24
25
#ifndef __STDC_FORMAT_MACROS
26
#define __STDC_FORMAT_MACROS
27
#endif
28
29
#include <inttypes.h>
30
#include <string>
31
#include <algorithm>
32
#include <utility>
33
#include <vector>
34
35
#include "yb/rocksdb/db/column_family.h"
36
#include "yb/rocksdb/db/compaction_picker.h"
37
#include "yb/rocksdb/db/db_impl.h"
38
#include "yb/rocksdb/db/version_set.h"
39
#include "yb/rocksdb/util/histogram.h"
40
#include "yb/rocksdb/util/logging.h"
41
42
#include "yb/util/string_util.h"
43
44
namespace rocksdb {
45
46
#ifndef ROCKSDB_LITE
47
namespace {
48
const double kMB = 1048576.0;
49
const double kGB = kMB * 1024;
50
const double kMicrosInSec = 1000000.0;
51
52
0
void PrintLevelStatsHeader(char* buf, size_t len, const std::string& cf_name) {
53
0
  snprintf(
54
0
      buf, len,
55
0
      "\n** Compaction Stats [%s] **\n"
56
0
      "Level    Files   Size(MB) Score Read(GB)  Rn(GB) Rnp1(GB) "
57
0
      "Write(GB) Wnew(GB) Moved(GB) W-Amp Rd(MB/s) Wr(MB/s) "
58
0
      "Comp(sec) Comp(cnt) Avg(sec) KeyIn KeyDrop\n"
59
0
      "--------------------------------------------------------------------"
60
0
      "-----------------------------------------------------------"
61
0
      "--------------------------------------\n",
62
0
      cf_name.c_str());
63
0
}
64
65
void PrintLevelStats(char* buf, size_t len, const std::string& name,
66
  int num_files, int being_compacted, double total_file_size,
67
  double score, double w_amp,
68
0
  const InternalStats::CompactionStats& stats) {
69
0
  uint64_t bytes_read =
70
0
      stats.bytes_read_non_output_levels + stats.bytes_read_output_level;
71
0
  int64_t bytes_new =
72
0
      stats.bytes_written - stats.bytes_read_output_level;
73
0
  double elapsed = (stats.micros + 1) / kMicrosInSec;
74
0
  std::string num_input_records = NumberToHumanString(stats.num_input_records);
75
0
  std::string num_dropped_records =
76
0
      NumberToHumanString(stats.num_dropped_records);
77
78
0
  snprintf(buf, len,
79
0
           "%4s %6d/%-3d %8.2f %5.1f " /* Level, Files, Size(MB), Score */
80
0
           "%8.1f "                    /* Read(GB) */
81
0
           "%7.1f "                    /* Rn(GB) */
82
0
           "%8.1f "                    /* Rnp1(GB) */
83
0
           "%9.1f "                    /* Write(GB) */
84
0
           "%8.1f "                    /* Wnew(GB) */
85
0
           "%9.1f "                    /* Moved(GB) */
86
0
           "%5.1f "                    /* W-Amp */
87
0
           "%8.1f "                    /* Rd(MB/s) */
88
0
           "%8.1f "                    /* Wr(MB/s) */
89
0
           "%9.0f "                    /* Comp(sec) */
90
0
           "%9d "                      /* Comp(cnt) */
91
0
           "%8.3f "                    /* Avg(sec) */
92
0
           "%7s "   /* KeyIn */
93
0
           "%6s\n", /* KeyDrop */
94
0
           name.c_str(),
95
0
           num_files, being_compacted, total_file_size / kMB, score,
96
0
           bytes_read / kGB, stats.bytes_read_non_output_levels / kGB,
97
0
           stats.bytes_read_output_level / kGB, stats.bytes_written / kGB,
98
0
           bytes_new / kGB, stats.bytes_moved / kGB, w_amp,
99
0
           bytes_read / kMB / elapsed, stats.bytes_written / kMB / elapsed,
100
0
           stats.micros / kMicrosInSec, stats.count,
101
0
           stats.count == 0 ? 0 : stats.micros / kMicrosInSec / stats.count,
102
0
           num_input_records.c_str(), num_dropped_records.c_str());
103
0
}
104
105
// Assumes that trailing numbers represent an optional argument. This requires
106
// property names to not end with numbers.
107
21.1k
std::pair<Slice, Slice> GetPropertyNameAndArg(const Slice& property) {
108
21.1k
  Slice name = property, arg = property;
109
21.1k
  size_t sfx_len = 0;
110
40.9k
  while (sfx_len < property.size() &&
111
40.9k
         isdigit(property[property.size() - sfx_len - 1])) {
112
19.8k
    ++sfx_len;
113
19.8k
  }
114
21.1k
  name.remove_suffix(sfx_len);
115
21.1k
  arg.remove_prefix(property.size() - sfx_len);
116
21.1k
  return {name, arg};
117
21.1k
}
118
}  // anonymous namespace
119
120
static const std::string rocksdb_prefix = "rocksdb.";
121
122
static const std::string num_files_at_level_prefix = "num-files-at-level";
123
static const std::string allstats = "stats";
124
static const std::string sstables = "sstables";
125
static const std::string cfstats = "cfstats";
126
static const std::string dbstats = "dbstats";
127
static const std::string levelstats = "levelstats";
128
static const std::string num_immutable_mem_table = "num-immutable-mem-table";
129
static const std::string num_immutable_mem_table_flushed =
130
    "num-immutable-mem-table-flushed";
131
static const std::string mem_table_flush_pending = "mem-table-flush-pending";
132
static const std::string compaction_pending = "compaction-pending";
133
static const std::string background_errors = "background-errors";
134
static const std::string cur_size_active_mem_table =
135
                          "cur-size-active-mem-table";
136
static const std::string cur_size_all_mem_tables = "cur-size-all-mem-tables";
137
static const std::string size_all_mem_tables = "size-all-mem-tables";
138
static const std::string num_entries_active_mem_table =
139
                          "num-entries-active-mem-table";
140
static const std::string num_entries_imm_mem_tables =
141
                          "num-entries-imm-mem-tables";
142
static const std::string num_deletes_active_mem_table =
143
                          "num-deletes-active-mem-table";
144
static const std::string num_deletes_imm_mem_tables =
145
                          "num-deletes-imm-mem-tables";
146
static const std::string estimate_num_keys = "estimate-num-keys";
147
static const std::string estimate_table_readers_mem =
148
                          "estimate-table-readers-mem";
149
static const std::string is_file_deletions_enabled =
150
                          "is-file-deletions-enabled";
151
static const std::string num_snapshots = "num-snapshots";
152
static const std::string oldest_snapshot_time = "oldest-snapshot-time";
153
static const std::string num_live_versions = "num-live-versions";
154
static const std::string current_version_number =
155
    "current-super-version-number";
156
static const std::string estimate_live_data_size = "estimate-live-data-size";
157
static const std::string base_level = "base-level";
158
static const std::string total_sst_files_size = "total-sst-files-size";
159
static const std::string estimate_pending_comp_bytes =
160
    "estimate-pending-compaction-bytes";
161
static const std::string aggregated_table_properties =
162
    "aggregated-table-properties";
163
static const std::string aggregated_table_properties_at_level =
164
    aggregated_table_properties + "-at-level";
165
static const std::string num_running_compactions = "num-running-compactions";
166
static const std::string num_running_flushes = "num-running-flushes";
167
168
const std::string DB::Properties::kNumFilesAtLevelPrefix =
169
                      rocksdb_prefix + num_files_at_level_prefix;
170
const std::string DB::Properties::kStats = rocksdb_prefix + allstats;
171
const std::string DB::Properties::kSSTables = rocksdb_prefix + sstables;
172
const std::string DB::Properties::kCFStats = rocksdb_prefix + cfstats;
173
const std::string DB::Properties::kDBStats = rocksdb_prefix + dbstats;
174
const std::string DB::Properties::kLevelStats = rocksdb_prefix + levelstats;
175
const std::string DB::Properties::kNumImmutableMemTable =
176
                      rocksdb_prefix + num_immutable_mem_table;
177
const std::string DB::Properties::kNumImmutableMemTableFlushed =
178
    rocksdb_prefix + num_immutable_mem_table_flushed;
179
const std::string DB::Properties::kMemTableFlushPending =
180
                      rocksdb_prefix + mem_table_flush_pending;
181
const std::string DB::Properties::kCompactionPending =
182
                      rocksdb_prefix + compaction_pending;
183
const std::string DB::Properties::kNumRunningCompactions =
184
    rocksdb_prefix + num_running_compactions;
185
const std::string DB::Properties::kNumRunningFlushes =
186
    rocksdb_prefix + num_running_flushes;
187
const std::string DB::Properties::kBackgroundErrors =
188
                      rocksdb_prefix + background_errors;
189
const std::string DB::Properties::kCurSizeActiveMemTable =
190
                      rocksdb_prefix + cur_size_active_mem_table;
191
const std::string DB::Properties::kCurSizeAllMemTables =
192
    rocksdb_prefix + cur_size_all_mem_tables;
193
const std::string DB::Properties::kSizeAllMemTables =
194
    rocksdb_prefix + size_all_mem_tables;
195
const std::string DB::Properties::kNumEntriesActiveMemTable =
196
                      rocksdb_prefix + num_entries_active_mem_table;
197
const std::string DB::Properties::kNumEntriesImmMemTables =
198
                      rocksdb_prefix + num_entries_imm_mem_tables;
199
const std::string DB::Properties::kNumDeletesActiveMemTable =
200
                      rocksdb_prefix + num_deletes_active_mem_table;
201
const std::string DB::Properties::kNumDeletesImmMemTables =
202
                      rocksdb_prefix + num_deletes_imm_mem_tables;
203
const std::string DB::Properties::kEstimateNumKeys =
204
                      rocksdb_prefix + estimate_num_keys;
205
const std::string DB::Properties::kEstimateTableReadersMem =
206
                      rocksdb_prefix + estimate_table_readers_mem;
207
const std::string DB::Properties::kIsFileDeletionsEnabled =
208
                      rocksdb_prefix + is_file_deletions_enabled;
209
const std::string DB::Properties::kNumSnapshots =
210
                      rocksdb_prefix + num_snapshots;
211
const std::string DB::Properties::kOldestSnapshotTime =
212
                      rocksdb_prefix + oldest_snapshot_time;
213
const std::string DB::Properties::kNumLiveVersions =
214
                      rocksdb_prefix + num_live_versions;
215
const std::string DB::Properties::kCurrentSuperVersionNumber =
216
    rocksdb_prefix + current_version_number;
217
const std::string DB::Properties::kEstimateLiveDataSize =
218
                      rocksdb_prefix + estimate_live_data_size;
219
const std::string DB::Properties::kTotalSstFilesSize =
220
                      rocksdb_prefix + total_sst_files_size;
221
const std::string DB::Properties::kBaseLevel = rocksdb_prefix + base_level;
222
const std::string DB::Properties::kEstimatePendingCompactionBytes =
223
    rocksdb_prefix + estimate_pending_comp_bytes;
224
const std::string DB::Properties::kAggregatedTableProperties =
225
    rocksdb_prefix + aggregated_table_properties;
226
const std::string DB::Properties::kAggregatedTablePropertiesAtLevel =
227
    rocksdb_prefix + aggregated_table_properties_at_level;
228
229
const std::unordered_map<std::string,
230
                         DBPropertyInfo> InternalStats::ppt_name_to_info = {
231
    {DB::Properties::kNumFilesAtLevelPrefix,
232
     {false, &InternalStats::HandleNumFilesAtLevel, nullptr}},
233
    {DB::Properties::kLevelStats,
234
     {false, &InternalStats::HandleLevelStats, nullptr}},
235
    {DB::Properties::kStats, {false, &InternalStats::HandleStats, nullptr}},
236
    {DB::Properties::kCFStats, {false, &InternalStats::HandleCFStats, nullptr}},
237
    {DB::Properties::kDBStats, {false, &InternalStats::HandleDBStats, nullptr}},
238
    {DB::Properties::kSSTables,
239
     {false, &InternalStats::HandleSsTables, nullptr}},
240
    {DB::Properties::kAggregatedTableProperties,
241
     {false, &InternalStats::HandleAggregatedTableProperties, nullptr}},
242
    {DB::Properties::kAggregatedTablePropertiesAtLevel,
243
     {false, &InternalStats::HandleAggregatedTablePropertiesAtLevel, nullptr}},
244
    {DB::Properties::kNumImmutableMemTable,
245
     {false, nullptr, &InternalStats::HandleNumImmutableMemTable}},
246
    {DB::Properties::kNumImmutableMemTableFlushed,
247
     {false, nullptr, &InternalStats::HandleNumImmutableMemTableFlushed}},
248
    {DB::Properties::kMemTableFlushPending,
249
     {false, nullptr, &InternalStats::HandleMemTableFlushPending}},
250
    {DB::Properties::kCompactionPending,
251
     {false, nullptr, &InternalStats::HandleCompactionPending}},
252
    {DB::Properties::kBackgroundErrors,
253
     {false, nullptr, &InternalStats::HandleBackgroundErrors}},
254
    {DB::Properties::kCurSizeActiveMemTable,
255
     {false, nullptr, &InternalStats::HandleCurSizeActiveMemTable}},
256
    {DB::Properties::kCurSizeAllMemTables,
257
     {false, nullptr, &InternalStats::HandleCurSizeAllMemTables}},
258
    {DB::Properties::kSizeAllMemTables,
259
     {false, nullptr, &InternalStats::HandleSizeAllMemTables}},
260
    {DB::Properties::kNumEntriesActiveMemTable,
261
     {false, nullptr, &InternalStats::HandleNumEntriesActiveMemTable}},
262
    {DB::Properties::kNumEntriesImmMemTables,
263
     {false, nullptr, &InternalStats::HandleNumEntriesImmMemTables}},
264
    {DB::Properties::kNumDeletesActiveMemTable,
265
     {false, nullptr, &InternalStats::HandleNumDeletesActiveMemTable}},
266
    {DB::Properties::kNumDeletesImmMemTables,
267
     {false, nullptr, &InternalStats::HandleNumDeletesImmMemTables}},
268
    {DB::Properties::kEstimateNumKeys,
269
     {false, nullptr, &InternalStats::HandleEstimateNumKeys}},
270
    {DB::Properties::kEstimateTableReadersMem,
271
     {true, nullptr, &InternalStats::HandleEstimateTableReadersMem}},
272
    {DB::Properties::kIsFileDeletionsEnabled,
273
     {false, nullptr, &InternalStats::HandleIsFileDeletionsEnabled}},
274
    {DB::Properties::kNumSnapshots,
275
     {false, nullptr, &InternalStats::HandleNumSnapshots}},
276
    {DB::Properties::kOldestSnapshotTime,
277
     {false, nullptr, &InternalStats::HandleOldestSnapshotTime}},
278
    {DB::Properties::kNumLiveVersions,
279
     {false, nullptr, &InternalStats::HandleNumLiveVersions}},
280
    {DB::Properties::kCurrentSuperVersionNumber,
281
     {false, nullptr, &InternalStats::HandleCurrentSuperVersionNumber}},
282
    {DB::Properties::kEstimateLiveDataSize,
283
     {true, nullptr, &InternalStats::HandleEstimateLiveDataSize}},
284
    {DB::Properties::kBaseLevel,
285
     {false, nullptr, &InternalStats::HandleBaseLevel}},
286
    {DB::Properties::kTotalSstFilesSize,
287
     {false, nullptr, &InternalStats::HandleTotalSstFilesSize}},
288
    {DB::Properties::kEstimatePendingCompactionBytes,
289
     {false, nullptr, &InternalStats::HandleEstimatePendingCompactionBytes}},
290
    {DB::Properties::kNumRunningFlushes,
291
     {false, nullptr, &InternalStats::HandleNumRunningFlushes}},
292
    {DB::Properties::kNumRunningCompactions,
293
     {false, nullptr, &InternalStats::HandleNumRunningCompactions}},
294
};
295
296
11.0k
const DBPropertyInfo* GetPropertyInfo(const Slice& property) {
297
11.0k
  std::string ppt_name = GetPropertyNameAndArg(property).first.ToString();
298
11.0k
  auto ppt_info_iter = InternalStats::ppt_name_to_info.find(ppt_name);
299
11.0k
  if (ppt_info_iter == InternalStats::ppt_name_to_info.end()) {
300
0
    return nullptr;
301
0
  }
302
11.0k
  return &ppt_info_iter->second;
303
11.0k
}
304
305
InternalStats::InternalStats(int num_levels, Env* env, ColumnFamilyData* cfd)
306
    : db_stats_{},
307
      cf_stats_value_{},
308
      cf_stats_count_{},
309
      comp_stats_(num_levels),
310
      file_read_latency_(num_levels),
311
      bg_error_count_(0),
312
      number_levels_(num_levels),
313
      env_(env),
314
      cfd_(cfd),
315
442k
      started_at_(env->NowMicros()) {}
316
317
402k
InternalStats::~InternalStats() = default;
318
319
28.8M
HistogramImpl* InternalStats::GetFileReadHist(int level) {
320
28.8M
  return &file_read_latency_[level];
321
28.8M
}
322
323
bool InternalStats::GetStringProperty(const DBPropertyInfo& property_info,
324
                                      const Slice& property,
325
10.0k
                                      std::string* value) {
326
10.0k
  assert(value != nullptr);
327
0
  assert(property_info.handle_string != nullptr);
328
0
  Slice arg = GetPropertyNameAndArg(property).second;
329
10.0k
  return (this->*(property_info.handle_string))(value, arg);
330
10.0k
}
331
332
bool InternalStats::GetIntProperty(const DBPropertyInfo& property_info,
333
915
                                   uint64_t* value, DBImpl* db) {
334
915
  assert(value != nullptr);
335
0
  assert(property_info.handle_int != nullptr &&
336
915
         !property_info.need_out_of_mutex);
337
0
  db->mutex_.AssertHeld();
338
915
  return (this->*(property_info.handle_int))(value, db, nullptr /* version */);
339
915
}
340
341
bool InternalStats::GetIntPropertyOutOfMutex(
342
153
    const DBPropertyInfo& property_info, Version* version, uint64_t* value) {
343
153
  assert(value != nullptr);
344
0
  assert(property_info.handle_int != nullptr &&
345
153
         property_info.need_out_of_mutex);
346
0
  return (this->*(property_info.handle_int))(value, nullptr /* db */, version);
347
153
}
348
349
9.22k
bool InternalStats::HandleNumFilesAtLevel(std::string* value, Slice suffix) {
350
9.22k
  uint64_t level;
351
9.22k
  const auto* vstorage = cfd_->current()->storage_info();
352
9.22k
  bool ok = ConsumeDecimalNumber(&suffix, &level) && suffix.empty();
353
9.22k
  if (!ok || static_cast<int>(level) >= number_levels_) {
354
0
    return false;
355
9.22k
  } else {
356
9.22k
    char buf[100];
357
9.22k
    snprintf(buf, sizeof(buf), "%d",
358
9.22k
             vstorage->NumLevelFiles(static_cast<int>(level)));
359
9.22k
    *value = buf;
360
9.22k
    return true;
361
9.22k
  }
362
9.22k
}
363
364
0
bool InternalStats::HandleLevelStats(std::string* value, Slice suffix) {
365
0
  char buf[1000];
366
0
  const auto* vstorage = cfd_->current()->storage_info();
367
0
  snprintf(buf, sizeof(buf),
368
0
           "Level Files Size(MB)\n"
369
0
           "--------------------\n");
370
0
  value->append(buf);
371
372
0
  for (int level = 0; level < number_levels_; level++) {
373
0
    snprintf(buf, sizeof(buf), "%3d %8d %8.0f\n", level,
374
0
             vstorage->NumLevelFiles(level),
375
0
             vstorage->NumLevelBytes(level) / kMB);
376
0
    value->append(buf);
377
0
  }
378
0
  return true;
379
0
}
380
381
0
bool InternalStats::HandleStats(std::string* value, Slice suffix) {
382
0
  if (!HandleCFStats(value, suffix)) {
383
0
    return false;
384
0
  }
385
0
  if (!HandleDBStats(value, suffix)) {
386
0
    return false;
387
0
  }
388
0
  return true;
389
0
}
390
391
0
bool InternalStats::HandleCFStats(std::string* value, Slice suffix) {
392
0
  DumpCFStats(value);
393
0
  return true;
394
0
}
395
396
7
bool InternalStats::HandleDBStats(std::string* value, Slice suffix) {
397
7
  DumpDBStats(value);
398
7
  return true;
399
7
}
400
401
0
bool InternalStats::HandleSsTables(std::string* value, Slice suffix) {
402
0
  auto* current = cfd_->current();
403
0
  *value = current->DebugString();
404
0
  return true;
405
0
}
406
407
bool InternalStats::HandleAggregatedTableProperties(std::string* value,
408
103
                                                    Slice suffix) {
409
103
  std::shared_ptr<const TableProperties> tp;
410
103
  auto s = cfd_->current()->GetAggregatedTableProperties(&tp);
411
103
  if (!s.ok()) {
412
0
    return false;
413
0
  }
414
103
  *value = tp->ToString();
415
103
  return true;
416
103
}
417
418
bool InternalStats::HandleAggregatedTablePropertiesAtLevel(std::string* value,
419
700
                                                           Slice suffix) {
420
700
  uint64_t level;
421
700
  bool ok = ConsumeDecimalNumber(&suffix, &level) && suffix.empty();
422
700
  if (!ok || static_cast<int>(level) >= number_levels_) {
423
0
    return false;
424
0
  }
425
700
  std::shared_ptr<const TableProperties> tp;
426
700
  auto s = cfd_->current()->GetAggregatedTableProperties(
427
700
      &tp, static_cast<int>(level));
428
700
  if (!s.ok()) {
429
0
    return false;
430
0
  }
431
700
  *value = tp->ToString();
432
700
  return true;
433
700
}
434
435
bool InternalStats::HandleNumImmutableMemTable(uint64_t* value, DBImpl* db,
436
88
                                               Version* version) {
437
88
  *value = cfd_->imm()->NumNotFlushed();
438
88
  return true;
439
88
}
440
441
bool InternalStats::HandleNumImmutableMemTableFlushed(uint64_t* value,
442
                                                      DBImpl* db,
443
10
                                                      Version* version) {
444
10
  *value = cfd_->imm()->NumFlushed();
445
10
  return true;
446
10
}
447
448
bool InternalStats::HandleMemTableFlushPending(uint64_t* value, DBImpl* db,
449
4
                                               Version* version) {
450
  // Return number of mem tables that are ready to flush (made immutable)
451
4
  *value = (cfd_->imm()->IsFlushPending() ? 
12
:
02
);
452
4
  return true;
453
4
}
454
455
bool InternalStats::HandleNumRunningFlushes(uint64_t* value, DBImpl* db,
456
0
                                            Version* version) {
457
0
  *value = db->num_running_flushes();
458
0
  return true;
459
0
}
460
461
bool InternalStats::HandleCompactionPending(uint64_t* value, DBImpl* db,
462
4
                                            Version* version) {
463
  // 1 if the system already determines at least one compaction is needed.
464
  // 0 otherwise,
465
4
  const auto* vstorage = cfd_->current()->storage_info();
466
4
  *value = (cfd_->compaction_picker()->NeedsCompaction(vstorage) ? 
11
:
03
);
467
4
  return true;
468
4
}
469
470
bool InternalStats::HandleNumRunningCompactions(uint64_t* value, DBImpl* db,
471
4
                                                Version* version) {
472
4
  *value = db->num_total_running_compactions_;
473
4
  return true;
474
4
}
475
476
bool InternalStats::HandleBackgroundErrors(uint64_t* value, DBImpl* db,
477
19
                                           Version* version) {
478
  // Accumulated number of  errors in background flushes or compactions.
479
19
  *value = GetBackgroundErrorCount();
480
19
  return true;
481
19
}
482
483
bool InternalStats::HandleCurSizeActiveMemTable(uint64_t* value, DBImpl* db,
484
23
                                                Version* version) {
485
  // Current size of the active memtable
486
23
  *value = cfd_->mem()->ApproximateMemoryUsage();
487
23
  return true;
488
23
}
489
490
bool InternalStats::HandleCurSizeAllMemTables(uint64_t* value, DBImpl* db,
491
23
                                              Version* version) {
492
  // Current size of the active memtable + immutable memtables
493
23
  *value = cfd_->mem()->ApproximateMemoryUsage() +
494
23
           cfd_->imm()->ApproximateUnflushedMemTablesMemoryUsage();
495
23
  return true;
496
23
}
497
498
bool InternalStats::HandleSizeAllMemTables(uint64_t* value, DBImpl* db,
499
43
                                           Version* version) {
500
43
  *value = cfd_->mem()->ApproximateMemoryUsage() +
501
43
           cfd_->imm()->ApproximateMemoryUsage();
502
43
  return true;
503
43
}
504
505
bool InternalStats::HandleNumEntriesActiveMemTable(uint64_t* value, DBImpl* db,
506
140
                                                   Version* version) {
507
  // Current number of entires in the active memtable
508
140
  *value = cfd_->mem()->num_entries();
509
140
  return true;
510
140
}
511
512
bool InternalStats::HandleNumEntriesImmMemTables(uint64_t* value, DBImpl* db,
513
15
                                                 Version* version) {
514
  // Current number of entries in the immutable memtables
515
15
  *value = cfd_->imm()->current()->GetTotalNumEntries();
516
15
  return true;
517
15
}
518
519
bool InternalStats::HandleNumDeletesActiveMemTable(uint64_t* value, DBImpl* db,
520
5
                                                   Version* version) {
521
  // Current number of entires in the active memtable
522
5
  *value = cfd_->mem()->num_deletes();
523
5
  return true;
524
5
}
525
526
bool InternalStats::HandleNumDeletesImmMemTables(uint64_t* value, DBImpl* db,
527
5
                                                 Version* version) {
528
  // Current number of entries in the immutable memtables
529
5
  *value = cfd_->imm()->current()->GetTotalNumDeletes();
530
5
  return true;
531
5
}
532
533
bool InternalStats::HandleEstimateNumKeys(uint64_t* value, DBImpl* db,
534
15
                                          Version* version) {
535
  // Estimate number of entries in the column family:
536
  // Use estimated entries in tables + total entries in memtables.
537
15
  const auto* vstorage = cfd_->current()->storage_info();
538
15
  *value = cfd_->mem()->num_entries() +
539
15
           cfd_->imm()->current()->GetTotalNumEntries() -
540
15
           (cfd_->mem()->num_deletes() +
541
15
            cfd_->imm()->current()->GetTotalNumDeletes()) *
542
15
               2 +
543
15
           vstorage->GetEstimatedActiveKeys();
544
15
  return true;
545
15
}
546
547
bool InternalStats::HandleNumSnapshots(uint64_t* value, DBImpl* db,
548
180
                                       Version* version) {
549
180
  *value = db->snapshots().count();
550
180
  return true;
551
180
}
552
553
bool InternalStats::HandleOldestSnapshotTime(uint64_t* value, DBImpl* db,
554
150
                                             Version* version) {
555
150
  *value = static_cast<uint64_t>(db->snapshots().GetOldestSnapshotTime());
556
150
  return true;
557
150
}
558
559
bool InternalStats::HandleNumLiveVersions(uint64_t* value, DBImpl* db,
560
5
                                          Version* version) {
561
5
  *value = cfd_->GetNumLiveVersions();
562
5
  return true;
563
5
}
564
565
bool InternalStats::HandleCurrentSuperVersionNumber(uint64_t* value, DBImpl* db,
566
3
                                                    Version* version) {
567
3
  *value = cfd_->GetSuperVersionNumber();
568
3
  return true;
569
3
}
570
571
bool InternalStats::HandleIsFileDeletionsEnabled(uint64_t* value, DBImpl* db,
572
150
                                                 Version* version) {
573
150
  *value = db->IsFileDeletionsEnabled();
574
150
  return true;
575
150
}
576
577
bool InternalStats::HandleBaseLevel(uint64_t* value, DBImpl* db,
578
7
                                    Version* version) {
579
7
  const auto* vstorage = cfd_->current()->storage_info();
580
7
  *value = vstorage->base_level();
581
7
  return true;
582
7
}
583
584
bool InternalStats::HandleTotalSstFilesSize(uint64_t* value, DBImpl* db,
585
18
                                            Version* version) {
586
18
  *value = cfd_->GetTotalSstFilesSize();
587
18
  return true;
588
18
}
589
590
bool InternalStats::HandleEstimatePendingCompactionBytes(uint64_t* value,
591
                                                         DBImpl* db,
592
4
                                                         Version* version) {
593
4
  const auto* vstorage = cfd_->current()->storage_info();
594
4
  *value = vstorage->estimated_compaction_needed_bytes();
595
4
  return true;
596
4
}
597
598
bool InternalStats::HandleEstimateTableReadersMem(uint64_t* value, DBImpl* db,
599
152
                                                  Version* version) {
600
152
  *value = (version == nullptr) ? 
00
: version->GetMemoryUsageByTableReaders();
601
152
  return true;
602
152
}
603
604
bool InternalStats::HandleEstimateLiveDataSize(uint64_t* value, DBImpl* db,
605
1
                                               Version* version) {
606
1
  const auto* vstorage = cfd_->current()->storage_info();
607
1
  *value = vstorage->EstimateLiveDataSize();
608
1
  return true;
609
1
}
610
611
7
void InternalStats::DumpDBStats(std::string* value) {
612
7
  char buf[1000];
613
  // DB-level stats, only available from default column family
614
7
  double seconds_up = (env_->NowMicros() - started_at_ + 1) / kMicrosInSec;
615
7
  double interval_seconds_up = seconds_up - db_stats_snapshot_.seconds_up;
616
7
  snprintf(buf, sizeof(buf),
617
7
           "\n** DB Stats **\nUptime(secs): %.1f total, %.1f interval\n",
618
7
           seconds_up, interval_seconds_up);
619
7
  value->append(buf);
620
  // Cumulative
621
7
  uint64_t user_bytes_written = GetDBStats(InternalDBStatsType::BYTES_WRITTEN);
622
7
  uint64_t num_keys_written = GetDBStats(InternalDBStatsType::NUMBER_KEYS_WRITTEN);
623
7
  uint64_t write_other = GetDBStats(InternalDBStatsType::WRITE_DONE_BY_OTHER);
624
7
  uint64_t write_self = GetDBStats(InternalDBStatsType::WRITE_DONE_BY_SELF);
625
7
  uint64_t wal_bytes = GetDBStats(InternalDBStatsType::WAL_FILE_BYTES);
626
7
  uint64_t wal_synced = GetDBStats(InternalDBStatsType::WAL_FILE_SYNCED);
627
7
  uint64_t write_with_wal = GetDBStats(InternalDBStatsType::WRITE_WITH_WAL);
628
7
  uint64_t write_stall_micros = 0;
629
7
  uint64_t compact_bytes_read = 0;
630
7
  uint64_t compact_bytes_write = 0;
631
7
  uint64_t compact_micros = 0;
632
633
7
  const int kHumanMicrosLen = 32;
634
7
  char human_micros[kHumanMicrosLen];
635
636
  // Data
637
  // writes: total number of write requests.
638
  // keys: total number of key updates issued by all the write requests
639
  // batches: number of group commits issued to the DB. Each group can contain
640
  //          one or more writes.
641
  // so writes/keys is the average number of put in multi-put or put
642
  // writes/batches is the average group commit size.
643
  //
644
  // The format is the same for interval stats.
645
7
  snprintf(buf, sizeof(buf),
646
7
           "Cumulative writes: %s writes, %s keys, %s batches, "
647
7
           "%.1f writes per batch, ingest: %.2f GB, %.2f MB/s\n",
648
7
           NumberToHumanString(write_other + write_self).c_str(),
649
7
           NumberToHumanString(num_keys_written).c_str(),
650
7
           NumberToHumanString(write_self).c_str(),
651
7
           (write_other + write_self) / static_cast<double>(write_self + 1),
652
7
           user_bytes_written / kGB, user_bytes_written / kMB / seconds_up);
653
7
  value->append(buf);
654
  // WAL
655
7
  snprintf(buf, sizeof(buf),
656
7
           "Cumulative WAL: %s writes, %s syncs, "
657
7
           "%.2f writes per sync, written: %.2f GB, %.2f MB/s\n",
658
7
           NumberToHumanString(write_with_wal).c_str(),
659
7
           NumberToHumanString(wal_synced).c_str(),
660
7
           write_with_wal / static_cast<double>(wal_synced + 1),
661
7
           wal_bytes / kGB, wal_bytes / kMB / seconds_up);
662
7
  value->append(buf);
663
  // Compact
664
35
  for (int level = 0; level < number_levels_; 
level++28
) {
665
28
    compact_bytes_read += comp_stats_[level].bytes_read_output_level +
666
28
                          comp_stats_[level].bytes_read_non_output_levels;
667
28
    compact_bytes_write += comp_stats_[level].bytes_written;
668
28
    compact_micros += comp_stats_[level].micros;
669
28
  }
670
7
  snprintf(buf, sizeof(buf),
671
7
           "Cumulative compaction: %.2f GB write, %.2f MB/s write, "
672
7
           "%.2f GB read, %.2f MB/s read, %.1f seconds\n",
673
7
           compact_bytes_write / kGB, compact_bytes_write / kMB / seconds_up,
674
7
           compact_bytes_read / kGB, compact_bytes_read / kMB / seconds_up,
675
7
           compact_micros / kMicrosInSec);
676
7
  value->append(buf);
677
  // Stall
678
7
  AppendHumanMicros(write_stall_micros, human_micros, kHumanMicrosLen, true);
679
7
  snprintf(buf, sizeof(buf),
680
7
           "Cumulative stall: %s, %.1f percent\n",
681
7
           human_micros,
682
           // 10000 = divide by 1M to get secs, then multiply by 100 for pct
683
7
           write_stall_micros / 10000.0 / std::max(seconds_up, 0.001));
684
7
  value->append(buf);
685
686
  // Interval
687
7
  uint64_t interval_write_other = write_other - db_stats_snapshot_.write_other;
688
7
  uint64_t interval_write_self = write_self - db_stats_snapshot_.write_self;
689
7
  uint64_t interval_num_keys_written =
690
7
      num_keys_written - db_stats_snapshot_.num_keys_written;
691
7
  snprintf(buf, sizeof(buf),
692
7
           "Interval writes: %s writes, %s keys, %s batches, "
693
7
           "%.1f writes per batch, ingest: %.2f MB, %.2f MB/s\n",
694
7
           NumberToHumanString(
695
7
               interval_write_other + interval_write_self).c_str(),
696
7
           NumberToHumanString(interval_num_keys_written).c_str(),
697
7
           NumberToHumanString(interval_write_self).c_str(),
698
7
           static_cast<double>(interval_write_other + interval_write_self) /
699
7
               (interval_write_self + 1),
700
7
           (user_bytes_written - db_stats_snapshot_.ingest_bytes) / kMB,
701
7
           (user_bytes_written - db_stats_snapshot_.ingest_bytes) / kMB /
702
7
               std::max(interval_seconds_up, 0.001)),
703
7
  value->append(buf);
704
705
7
  uint64_t interval_write_with_wal =
706
7
      write_with_wal - db_stats_snapshot_.write_with_wal;
707
7
  uint64_t interval_wal_synced = wal_synced - db_stats_snapshot_.wal_synced;
708
7
  uint64_t interval_wal_bytes = wal_bytes - db_stats_snapshot_.wal_bytes;
709
710
7
  snprintf(buf, sizeof(buf),
711
7
           "Interval WAL: %s writes, %s syncs, "
712
7
           "%.2f writes per sync, written: %.2f MB, %.2f MB/s\n",
713
7
           NumberToHumanString(interval_write_with_wal).c_str(),
714
7
           NumberToHumanString(interval_wal_synced).c_str(),
715
7
           interval_write_with_wal /
716
7
              static_cast<double>(interval_wal_synced + 1),
717
7
           interval_wal_bytes / kGB,
718
7
           interval_wal_bytes / kMB / std::max(interval_seconds_up, 0.001));
719
7
  value->append(buf);
720
721
  // Compaction
722
7
  uint64_t interval_compact_bytes_write =
723
7
      compact_bytes_write - db_stats_snapshot_.compact_bytes_write;
724
7
  uint64_t interval_compact_bytes_read =
725
7
      compact_bytes_read - db_stats_snapshot_.compact_bytes_read;
726
7
  uint64_t interval_compact_micros =
727
7
      compact_micros - db_stats_snapshot_.compact_micros;
728
729
7
  snprintf(
730
7
      buf, sizeof(buf),
731
7
      "Interval compaction: %.2f GB write, %.2f MB/s write, "
732
7
      "%.2f GB read, %.2f MB/s read, %.1f seconds\n",
733
7
      interval_compact_bytes_write / kGB,
734
7
      interval_compact_bytes_write / kMB / std::max(interval_seconds_up, 0.001),
735
7
      interval_compact_bytes_read / kGB,
736
7
      interval_compact_bytes_read / kMB / std::max(interval_seconds_up, 0.001),
737
7
      interval_compact_micros / kMicrosInSec);
738
7
  value->append(buf);
739
740
  // Stall
741
7
  AppendHumanMicros(
742
7
      write_stall_micros - db_stats_snapshot_.write_stall_micros,
743
7
      human_micros, kHumanMicrosLen, true);
744
7
  snprintf(buf, sizeof(buf),
745
7
           "Interval stall: %s, %.1f percent\n",
746
7
           human_micros,
747
           // 10000 = divide by 1M to get secs, then multiply by 100 for pct
748
7
           (write_stall_micros - db_stats_snapshot_.write_stall_micros) /
749
7
               10000.0 / std::max(interval_seconds_up, 0.001));
750
7
  value->append(buf);
751
752
35
  for (int level = 0; level < number_levels_; 
level++28
) {
753
28
    if (!file_read_latency_[level].Empty()) {
754
12
      char buf2[5000];
755
12
      snprintf(buf2, sizeof(buf2),
756
12
               "** Level %d read latency histogram (micros):\n%s\n", level,
757
12
               file_read_latency_[level].ToString().c_str());
758
12
      value->append(buf2);
759
12
    }
760
28
  }
761
762
7
  db_stats_snapshot_.seconds_up = seconds_up;
763
7
  db_stats_snapshot_.ingest_bytes = user_bytes_written;
764
7
  db_stats_snapshot_.write_other = write_other;
765
7
  db_stats_snapshot_.write_self = write_self;
766
7
  db_stats_snapshot_.num_keys_written = num_keys_written;
767
7
  db_stats_snapshot_.wal_bytes = wal_bytes;
768
7
  db_stats_snapshot_.wal_synced = wal_synced;
769
7
  db_stats_snapshot_.write_with_wal = write_with_wal;
770
7
  db_stats_snapshot_.write_stall_micros = write_stall_micros;
771
7
  db_stats_snapshot_.compact_bytes_write = compact_bytes_write;
772
7
  db_stats_snapshot_.compact_bytes_read = compact_bytes_read;
773
7
  db_stats_snapshot_.compact_micros = compact_micros;
774
7
}
775
776
0
void InternalStats::DumpCFStats(std::string* value) {
777
0
  const VersionStorageInfo* vstorage = cfd_->current()->storage_info();
778
779
0
  int num_levels_to_check =
780
0
      (cfd_->ioptions()->compaction_style != kCompactionStyleFIFO)
781
0
          ? vstorage->num_levels() - 1
782
0
          : 1;
783
784
  // Compaction scores are sorted base on its value. Restore them to the
785
  // level order
786
0
  std::vector<double> compaction_score(number_levels_, 0);
787
0
  for (int i = 0; i < num_levels_to_check; ++i) {
788
0
    compaction_score[vstorage->CompactionScoreLevel(i)] =
789
0
        vstorage->CompactionScore(i);
790
0
  }
791
  // Count # of files being compacted for each level
792
0
  std::vector<int> files_being_compacted(number_levels_, 0);
793
0
  for (int level = 0; level < number_levels_; ++level) {
794
0
    for (auto* f : vstorage->LevelFiles(level)) {
795
0
      if (f->being_compacted) {
796
0
        ++files_being_compacted[level];
797
0
      }
798
0
    }
799
0
  }
800
801
0
  char buf[1000];
802
  // Per-ColumnFamily stats
803
0
  PrintLevelStatsHeader(buf, sizeof(buf), cfd_->GetName());
804
0
  value->append(buf);
805
806
0
  CompactionStats stats_sum(0);
807
0
  int total_files = 0;
808
0
  int total_files_being_compacted = 0;
809
0
  double total_file_size = 0;
810
0
  for (int level = 0; level < number_levels_; level++) {
811
0
    int files = vstorage->NumLevelFiles(level);
812
0
    total_files += files;
813
0
    total_files_being_compacted += files_being_compacted[level];
814
0
    if (comp_stats_[level].micros > 0 || files > 0) {
815
0
      stats_sum.Add(comp_stats_[level]);
816
0
      total_file_size += vstorage->NumLevelBytes(level);
817
0
      double w_amp =
818
0
          (comp_stats_[level].bytes_read_non_output_levels == 0) ? 0.0
819
0
          : static_cast<double>(comp_stats_[level].bytes_written) /
820
0
            comp_stats_[level].bytes_read_non_output_levels;
821
0
      PrintLevelStats(buf, sizeof(buf), "L" + ToString(level), files,
822
0
                      files_being_compacted[level],
823
0
                      static_cast<double>(vstorage->NumLevelBytes(level)),
824
0
                      compaction_score[level],
825
0
                      w_amp, comp_stats_[level]);
826
0
      value->append(buf);
827
0
    }
828
0
  }
829
0
  uint64_t curr_ingest = cf_stats_value_[BYTES_FLUSHED];
830
  // Cumulative summary
831
0
  double w_amp = stats_sum.bytes_written / static_cast<double>(curr_ingest + 1);
832
0
  uint64_t total_stall_count =
833
0
      cf_stats_count_[LEVEL0_SLOWDOWN_TOTAL] +
834
0
      cf_stats_count_[LEVEL0_NUM_FILES_TOTAL] +
835
0
      cf_stats_count_[SOFT_PENDING_COMPACTION_BYTES_LIMIT] +
836
0
      cf_stats_count_[HARD_PENDING_COMPACTION_BYTES_LIMIT] +
837
0
      cf_stats_count_[MEMTABLE_COMPACTION] + cf_stats_count_[MEMTABLE_SLOWDOWN];
838
  // Stats summary across levels
839
0
  PrintLevelStats(buf, sizeof(buf), "Sum", total_files,
840
0
                  total_files_being_compacted, total_file_size, 0, w_amp,
841
0
                  stats_sum);
842
0
  value->append(buf);
843
  // Interval summary
844
0
  uint64_t interval_ingest =
845
0
      curr_ingest - cf_stats_snapshot_.ingest_bytes + 1;
846
0
  CompactionStats interval_stats(stats_sum);
847
0
  interval_stats.Subtract(cf_stats_snapshot_.comp_stats);
848
0
  w_amp = interval_stats.bytes_written / static_cast<double>(interval_ingest);
849
0
  PrintLevelStats(buf, sizeof(buf), "Int", 0, 0, 0, 0, w_amp, interval_stats);
850
0
  value->append(buf);
851
852
0
  snprintf(buf, sizeof(buf),
853
0
           "Flush(GB): cumulative %.3f, interval %.3f\n",
854
0
           curr_ingest / kGB, interval_ingest / kGB);
855
0
  value->append(buf);
856
857
0
  snprintf(buf, sizeof(buf), "Stalls(count): %" PRIu64
858
0
                             " level0_slowdown, "
859
0
                             "%" PRIu64
860
0
                             " level0_slowdown_with_compaction, "
861
0
                             "%" PRIu64
862
0
                             " level0_numfiles, "
863
0
                             "%" PRIu64
864
0
                             " level0_numfiles_with_compaction, "
865
0
                             "%" PRIu64
866
0
                             " stop for pending_compaction_bytes, "
867
0
                             "%" PRIu64
868
0
                             " slowdown for pending_compaction_bytes, "
869
0
                             "%" PRIu64
870
0
                             " memtable_compaction, "
871
0
                             "%" PRIu64
872
0
                             " memtable_slowdown, "
873
0
                             "interval %" PRIu64 " total count\n",
874
0
           cf_stats_count_[LEVEL0_SLOWDOWN_TOTAL],
875
0
           cf_stats_count_[LEVEL0_SLOWDOWN_WITH_COMPACTION],
876
0
           cf_stats_count_[LEVEL0_NUM_FILES_TOTAL],
877
0
           cf_stats_count_[LEVEL0_NUM_FILES_WITH_COMPACTION],
878
0
           cf_stats_count_[HARD_PENDING_COMPACTION_BYTES_LIMIT],
879
0
           cf_stats_count_[SOFT_PENDING_COMPACTION_BYTES_LIMIT],
880
0
           cf_stats_count_[MEMTABLE_COMPACTION],
881
0
           cf_stats_count_[MEMTABLE_SLOWDOWN],
882
0
           total_stall_count - cf_stats_snapshot_.stall_count);
883
0
  value->append(buf);
884
885
0
  cf_stats_snapshot_.ingest_bytes = curr_ingest;
886
0
  cf_stats_snapshot_.comp_stats = stats_sum;
887
0
  cf_stats_snapshot_.stall_count = total_stall_count;
888
0
}
889
890
891
#else
892
893
const DBPropertyInfo* GetPropertyInfo(const Slice& property) { return nullptr; }
894
895
#endif  // !ROCKSDB_LITE
896
897
}  // namespace rocksdb