Fix table-cache size bug, gather table-cache statistics and prevent readahead done by fs. Summary:

Summary:
The db_bench test was not using the specified value for the max-file-open. Fixed.

The fs readhead is switched off.

Gather statistics about the table cache and print it out at the end of the tets run.

Test Plan: Revert Plan:

Reviewers: adsharma, sc

Reviewed By: adsharma

Differential Revision: https://reviews.facebook.net/D3441
This commit is contained in:
Dhruba Borthakur 2012-05-29 23:18:16 -07:00
parent 8f293b68a9
commit f50ece60c7
5 changed files with 105 additions and 0 deletions

View File

@ -7,10 +7,12 @@
#include <stdlib.h>
#include "db/db_impl.h"
#include "db/version_set.h"
#include "db/db_statistics.h"
#include "leveldb/cache.h"
#include "leveldb/db.h"
#include "leveldb/env.h"
#include "leveldb/write_batch.h"
#include "leveldb/statistics.h"
#include "port/port.h"
#include "util/crc32c.h"
#include "util/histogram.h"
@ -110,6 +112,10 @@ static int FLAGS_cache_numshardbits = -1;
// Verify checksum for every block read from storage
static bool FLAGS_verify_checksum = false;
// Database statistics
static bool FLAGS_statistics = false;
static class leveldb::DBStatistics* dbstats = NULL;
extern bool useOsBuffer;
namespace leveldb {
@ -398,6 +404,15 @@ class Benchmark {
#endif
}
void PrintStatistics() {
if (FLAGS_statistics) {
fprintf(stdout, "File opened:%ld closed:%ld errors:%ld\n",
dbstats->getNumFileOpens(),
dbstats->getNumFileCloses(),
dbstats->getNumFileErrors());
}
}
public:
Benchmark()
: cache_(FLAGS_cache_size >= 0 ?
@ -542,6 +557,7 @@ class Benchmark {
RunBenchmark(num_threads, name, method);
}
}
PrintStatistics();
}
private:
@ -710,6 +726,8 @@ class Benchmark {
options.block_cache = cache_;
options.write_buffer_size = FLAGS_write_buffer_size;
options.filter_policy = filter_policy_;
options.max_open_files = FLAGS_open_files;
options.statistics = dbstats;
Status s = DB::Open(options, FLAGS_db, &db_);
if (!s.ok()) {
fprintf(stderr, "open error: %s\n", s.ToString().c_str());
@ -983,6 +1001,12 @@ int main(int argc, char** argv) {
} else if (sscanf(argv[i], "--bufferedio=%d%c", &n, &junk) == 1 &&
(n == 0 || n == 1)) {
useOsBuffer = n;
} else if (sscanf(argv[i], "--statistics=%d%c", &n, &junk) == 1 &&
(n == 0 || n == 1)) {
if (n == 1) {
dbstats = new leveldb::DBStatistics();
FLAGS_statistics = true;
}
} else {
fprintf(stderr, "Invalid flag '%s'\n", argv[i]);
exit(1);

36
db/db_statistics.h Normal file
View File

@ -0,0 +1,36 @@
// 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.
#include <stdlib.h>
#include "leveldb/statistics.h"
#include "port/port.h"
#include "util/mutexlock.h"
namespace leveldb {
class DBStatistics: public Statistics {
public:
DBStatistics() { }
void incNumFileOpens() {
MutexLock l(&mu_);
numFileOpens_++;
}
void incNumFileCloses() {
MutexLock l(&mu_);
numFileCloses_++;
}
void incNumFileErrors() {
MutexLock l(&mu_);
numFileErrors_++;
}
private:
port::Mutex mu_;
};
}

View File

@ -5,6 +5,7 @@
#include "db/table_cache.h"
#include "db/filename.h"
#include "db/db_statistics.h"
#include "leveldb/env.h"
#include "leveldb/table.h"
#include "util/coding.h"
@ -16,10 +17,13 @@ struct TableAndFile {
Table* table;
};
static class DBStatistics* dbstatistics;
static void DeleteEntry(const Slice& key, void* value) {
TableAndFile* tf = reinterpret_cast<TableAndFile*>(value);
delete tf->table;
delete tf->file;
dbstatistics ? dbstatistics->incNumFileCloses() : (void)0;
delete tf;
}
@ -36,6 +40,7 @@ TableCache::TableCache(const std::string& dbname,
dbname_(dbname),
options_(options),
cache_(NewLRUCache(entries)) {
dbstatistics = (DBStatistics*)options->statistics;
}
TableCache::~TableCache() {
@ -48,12 +53,14 @@ Status TableCache::FindTable(uint64_t file_number, uint64_t file_size,
char buf[sizeof(file_number)];
EncodeFixed64(buf, file_number);
Slice key(buf, sizeof(buf));
DBStatistics* stats = (DBStatistics*) options_->statistics;
*handle = cache_->Lookup(key);
if (*handle == NULL) {
std::string fname = TableFileName(dbname_, file_number);
RandomAccessFile* file = NULL;
Table* table = NULL;
s = env_->NewRandomAccessFile(fname, &file);
stats ? stats->incNumFileOpens() : (void)0;
if (s.ok()) {
s = Table::Open(*options_, file, file_size, &table);
}
@ -61,6 +68,7 @@ Status TableCache::FindTable(uint64_t file_number, uint64_t file_size,
if (!s.ok()) {
assert(table == NULL);
delete file;
stats ? stats->incNumFileErrors() : (void)0;
// We do not cache error results so that if the error is transient,
// or somebody repairs the file, we recover automatically.
} else {

View File

@ -15,6 +15,7 @@ class Env;
class FilterPolicy;
class Logger;
class Snapshot;
class Statistics;
// DB contents are stored in a set of blocks, each of which holds a
// sequence of key,value pairs. Each block may be compressed before
@ -135,6 +136,9 @@ struct Options {
// Default: NULL
const FilterPolicy* filter_policy;
// If non-null, then we should collect metrics about database operations
Statistics* statistics;
// Create an Options object with default values for all fields.
Options();
};

View File

@ -0,0 +1,33 @@
// 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.
#ifndef STORAGE_LEVELDB_INCLUDE_STATISTICS_H_
#define STORAGE_LEVELDB_INCLUDE_STATISTICS_H_
namespace leveldb {
// Analyze the performance of a db
class Statistics {
public:
// Create an Statistics object with default values for all fields.
Statistics() : numFileOpens_(0), numFileCloses_(0),
numFileErrors_(0) {}
virtual void incNumFileOpens() = 0;
virtual void incNumFileCloses() = 0;
virtual void incNumFileErrors() = 0;
virtual long getNumFileOpens() { return numFileOpens_;}
virtual long getNumFileCloses() { return numFileCloses_;}
virtual long getNumFileErrors() { return numFileErrors_;}
protected:
long numFileOpens_;
long numFileCloses_;
long numFileErrors_;
};
} // namespace leveldb
#endif // STORAGE_LEVELDB_INCLUDE_STATISTICS_H_