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 <stdlib.h>
#include "db/db_impl.h" #include "db/db_impl.h"
#include "db/version_set.h" #include "db/version_set.h"
#include "db/db_statistics.h"
#include "leveldb/cache.h" #include "leveldb/cache.h"
#include "leveldb/db.h" #include "leveldb/db.h"
#include "leveldb/env.h" #include "leveldb/env.h"
#include "leveldb/write_batch.h" #include "leveldb/write_batch.h"
#include "leveldb/statistics.h"
#include "port/port.h" #include "port/port.h"
#include "util/crc32c.h" #include "util/crc32c.h"
#include "util/histogram.h" #include "util/histogram.h"
@ -110,6 +112,10 @@ static int FLAGS_cache_numshardbits = -1;
// Verify checksum for every block read from storage // Verify checksum for every block read from storage
static bool FLAGS_verify_checksum = false; static bool FLAGS_verify_checksum = false;
// Database statistics
static bool FLAGS_statistics = false;
static class leveldb::DBStatistics* dbstats = NULL;
extern bool useOsBuffer; extern bool useOsBuffer;
namespace leveldb { namespace leveldb {
@ -398,6 +404,15 @@ class Benchmark {
#endif #endif
} }
void PrintStatistics() {
if (FLAGS_statistics) {
fprintf(stdout, "File opened:%ld closed:%ld errors:%ld\n",
dbstats->getNumFileOpens(),
dbstats->getNumFileCloses(),
dbstats->getNumFileErrors());
}
}
public: public:
Benchmark() Benchmark()
: cache_(FLAGS_cache_size >= 0 ? : cache_(FLAGS_cache_size >= 0 ?
@ -542,6 +557,7 @@ class Benchmark {
RunBenchmark(num_threads, name, method); RunBenchmark(num_threads, name, method);
} }
} }
PrintStatistics();
} }
private: private:
@ -710,6 +726,8 @@ class Benchmark {
options.block_cache = cache_; options.block_cache = cache_;
options.write_buffer_size = FLAGS_write_buffer_size; options.write_buffer_size = FLAGS_write_buffer_size;
options.filter_policy = filter_policy_; options.filter_policy = filter_policy_;
options.max_open_files = FLAGS_open_files;
options.statistics = dbstats;
Status s = DB::Open(options, FLAGS_db, &db_); Status s = DB::Open(options, FLAGS_db, &db_);
if (!s.ok()) { if (!s.ok()) {
fprintf(stderr, "open error: %s\n", s.ToString().c_str()); 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 && } else if (sscanf(argv[i], "--bufferedio=%d%c", &n, &junk) == 1 &&
(n == 0 || n == 1)) { (n == 0 || n == 1)) {
useOsBuffer = n; 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 { } else {
fprintf(stderr, "Invalid flag '%s'\n", argv[i]); fprintf(stderr, "Invalid flag '%s'\n", argv[i]);
exit(1); 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/table_cache.h"
#include "db/filename.h" #include "db/filename.h"
#include "db/db_statistics.h"
#include "leveldb/env.h" #include "leveldb/env.h"
#include "leveldb/table.h" #include "leveldb/table.h"
#include "util/coding.h" #include "util/coding.h"
@ -16,10 +17,13 @@ struct TableAndFile {
Table* table; Table* table;
}; };
static class DBStatistics* dbstatistics;
static void DeleteEntry(const Slice& key, void* value) { static void DeleteEntry(const Slice& key, void* value) {
TableAndFile* tf = reinterpret_cast<TableAndFile*>(value); TableAndFile* tf = reinterpret_cast<TableAndFile*>(value);
delete tf->table; delete tf->table;
delete tf->file; delete tf->file;
dbstatistics ? dbstatistics->incNumFileCloses() : (void)0;
delete tf; delete tf;
} }
@ -36,6 +40,7 @@ TableCache::TableCache(const std::string& dbname,
dbname_(dbname), dbname_(dbname),
options_(options), options_(options),
cache_(NewLRUCache(entries)) { cache_(NewLRUCache(entries)) {
dbstatistics = (DBStatistics*)options->statistics;
} }
TableCache::~TableCache() { TableCache::~TableCache() {
@ -48,12 +53,14 @@ Status TableCache::FindTable(uint64_t file_number, uint64_t file_size,
char buf[sizeof(file_number)]; char buf[sizeof(file_number)];
EncodeFixed64(buf, file_number); EncodeFixed64(buf, file_number);
Slice key(buf, sizeof(buf)); Slice key(buf, sizeof(buf));
DBStatistics* stats = (DBStatistics*) options_->statistics;
*handle = cache_->Lookup(key); *handle = cache_->Lookup(key);
if (*handle == NULL) { if (*handle == NULL) {
std::string fname = TableFileName(dbname_, file_number); std::string fname = TableFileName(dbname_, file_number);
RandomAccessFile* file = NULL; RandomAccessFile* file = NULL;
Table* table = NULL; Table* table = NULL;
s = env_->NewRandomAccessFile(fname, &file); s = env_->NewRandomAccessFile(fname, &file);
stats ? stats->incNumFileOpens() : (void)0;
if (s.ok()) { if (s.ok()) {
s = Table::Open(*options_, file, file_size, &table); 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()) { if (!s.ok()) {
assert(table == NULL); assert(table == NULL);
delete file; delete file;
stats ? stats->incNumFileErrors() : (void)0;
// We do not cache error results so that if the error is transient, // We do not cache error results so that if the error is transient,
// or somebody repairs the file, we recover automatically. // or somebody repairs the file, we recover automatically.
} else { } else {

View File

@ -15,6 +15,7 @@ class Env;
class FilterPolicy; class FilterPolicy;
class Logger; class Logger;
class Snapshot; class Snapshot;
class Statistics;
// DB contents are stored in a set of blocks, each of which holds a // 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 // sequence of key,value pairs. Each block may be compressed before
@ -135,6 +136,9 @@ struct Options {
// Default: NULL // Default: NULL
const FilterPolicy* filter_policy; 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. // Create an Options object with default values for all fields.
Options(); 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_