fix db_test error with scribe logger turned on

Summary: as subject

Test Plan: db_test

Reviewers: dhruba

Reviewed By: dhruba

Differential Revision: https://reviews.facebook.net/D4929
This commit is contained in:
heyongqiang 2012-08-27 00:50:26 -07:00
parent fc20273e73
commit d3759ca121
6 changed files with 57 additions and 38 deletions

View File

@ -134,6 +134,7 @@ DBImpl::DBImpl(const Options& options, const std::string& dbname)
log_(NULL), log_(NULL),
tmp_batch_(new WriteBatch), tmp_batch_(new WriteBatch),
bg_compaction_scheduled_(false), bg_compaction_scheduled_(false),
bg_logstats_scheduled_(false),
manual_compaction_(NULL), manual_compaction_(NULL),
logger_(NULL) { logger_(NULL) {
mem_->Ref(); mem_->Ref();
@ -168,7 +169,7 @@ DBImpl::~DBImpl() {
// Wait for background work to finish // Wait for background work to finish
mutex_.Lock(); mutex_.Lock();
shutting_down_.Release_Store(this); // Any non-NULL value is ok shutting_down_.Release_Store(this); // Any non-NULL value is ok
while (bg_compaction_scheduled_) { while (bg_compaction_scheduled_ || bg_logstats_scheduled_) {
bg_cv_.Wait(); bg_cv_.Wait();
} }
mutex_.Unlock(); mutex_.Unlock();
@ -192,6 +193,8 @@ DBImpl::~DBImpl() {
if (owns_cache_) { if (owns_cache_) {
delete options_.block_cache; delete options_.block_cache;
} }
delete logger_;
} }
Status DBImpl::NewDB() { Status DBImpl::NewDB() {

View File

@ -115,7 +115,8 @@ class DBImpl : public DB {
Status WaitForCompactMemTable(); Status WaitForCompactMemTable();
void MaybeScheduleLogDBDeployStats(); void MaybeScheduleLogDBDeployStats();
static void LogDBDeployStats(void* db); static void BGLogDBDeployStats(void* db);
void LogDBDeployStats();
void MaybeScheduleCompaction(); void MaybeScheduleCompaction();
static void BGWork(void* db); static void BGWork(void* db);
@ -169,6 +170,9 @@ class DBImpl : public DB {
// Has a background compaction been scheduled or is running? // Has a background compaction been scheduled or is running?
bool bg_compaction_scheduled_; bool bg_compaction_scheduled_;
// Has a background stats log thread scheduled?
bool bg_logstats_scheduled_;
// Information for a manual compaction // Information for a manual compaction
struct ManualCompaction { struct ManualCompaction {
int level; int level;

View File

@ -8,6 +8,8 @@
#include "db/version_set.h" #include "db/version_set.h"
#include "leveldb/db.h" #include "leveldb/db.h"
#include "leveldb/env.h" #include "leveldb/env.h"
#include "port/port.h"
#include "util/mutexlock.h"
namespace leveldb { namespace leveldb {
@ -18,7 +20,8 @@ void DBImpl::MaybeScheduleLogDBDeployStats() {
|| host_name_.empty()) { || host_name_.empty()) {
return; return;
} }
if (shutting_down_.Acquire_Load()) {
if(bg_logstats_scheduled_ || shutting_down_.Acquire_Load()) {
// Already scheduled // Already scheduled
} else { } else {
int64_t current_ts = 0; int64_t current_ts = 0;
@ -30,43 +33,59 @@ void DBImpl::MaybeScheduleLogDBDeployStats() {
return; return;
} }
last_log_ts = current_ts; last_log_ts = current_ts;
env_->Schedule(&DBImpl::LogDBDeployStats, this); bg_logstats_scheduled_ = true;
env_->Schedule(&DBImpl::BGLogDBDeployStats, this);
} }
} }
void DBImpl::LogDBDeployStats(void* db) { void DBImpl::BGLogDBDeployStats(void* db) {
DBImpl* db_inst = reinterpret_cast<DBImpl*>(db); DBImpl* db_inst = reinterpret_cast<DBImpl*>(db);
db_inst->LogDBDeployStats();
}
if (db_inst->shutting_down_.Acquire_Load()) { void DBImpl::LogDBDeployStats() {
mutex_.Lock();
if (shutting_down_.Acquire_Load()) {
bg_logstats_scheduled_ = false;
bg_cv_.SignalAll();
mutex_.Unlock();
return; return;
} }
mutex_.Unlock();
std::string version_info; std::string version_info;
version_info += boost::lexical_cast<std::string>(kMajorVersion); version_info += boost::lexical_cast<std::string>(kMajorVersion);
version_info += "."; version_info += ".";
version_info += boost::lexical_cast<std::string>(kMinorVersion); version_info += boost::lexical_cast<std::string>(kMinorVersion);
std::string data_dir; std::string data_dir;
db_inst->env_->GetAbsolutePath(db_inst->dbname_, &data_dir); env_->GetAbsolutePath(dbname_, &data_dir);
uint64_t file_total_size = 0; uint64_t file_total_size = 0;
uint32_t file_total_num = 0; uint32_t file_total_num = 0;
for (int i = 0; i < db_inst->versions_->NumberLevels(); i++) { for (int i = 0; i < versions_->NumberLevels(); i++) {
file_total_num += db_inst->versions_->NumLevelFiles(i); file_total_num += versions_->NumLevelFiles(i);
file_total_size += db_inst->versions_->NumLevelBytes(i); file_total_size += versions_->NumLevelBytes(i);
} }
VersionSet::LevelSummaryStorage scratch; VersionSet::LevelSummaryStorage scratch;
const char* file_num_summary = db_inst->versions_->LevelSummary(&scratch); const char* file_num_summary = versions_->LevelSummary(&scratch);
std::string file_num_per_level(file_num_summary); std::string file_num_per_level(file_num_summary);
const char* file_size_summary = db_inst->versions_->LevelDataSizeSummary( const char* file_size_summary = versions_->LevelDataSizeSummary(
&scratch); &scratch);
std::string data_size_per_level(file_num_summary); std::string data_size_per_level(file_num_summary);
int64_t unix_ts; int64_t unix_ts;
db_inst->env_->GetCurrentTime(&unix_ts); env_->GetCurrentTime(&unix_ts);
db_inst->logger_->Log_Deploy_Stats(version_info, db_inst->host_name_, logger_->Log_Deploy_Stats(version_info, host_name_,
data_dir, file_total_size, file_total_num, file_num_per_level, data_dir, file_total_size, file_total_num, file_num_per_level,
data_size_per_level, unix_ts); data_size_per_level, unix_ts);
mutex_.Lock();
bg_logstats_scheduled_ = false;
bg_cv_.SignalAll();
mutex_.Unlock();
} }
} }

View File

@ -22,7 +22,7 @@ namespace leveldb {
static int64_t TotalFileSize(const std::vector<FileMetaData*>& files) { static int64_t TotalFileSize(const std::vector<FileMetaData*>& files) {
int64_t sum = 0; int64_t sum = 0;
for (size_t i = 0; i < files.size(); i++) { for (size_t i = 0; i < files.size() && files[i]; i++) {
sum += files[i]->file_size; sum += files[i]->file_size;
} }
return sum; return sum;
@ -1223,7 +1223,10 @@ void VersionSet::AddLiveFiles(std::set<uint64_t>* live) {
int64_t VersionSet::NumLevelBytes(int level) const { int64_t VersionSet::NumLevelBytes(int level) const {
assert(level >= 0); assert(level >= 0);
assert(level < NumberLevels()); assert(level < NumberLevels());
return TotalFileSize(current_->files_[level]); if(current_ && level < current_->files_->size())
return TotalFileSize(current_->files_[level]);
else
return 0;
} }
int64_t VersionSet::MaxNextLevelOverlappingBytes() { int64_t VersionSet::MaxNextLevelOverlappingBytes() {

View File

@ -6,12 +6,11 @@ const std::string ScribeLogger::COL_SEPERATOR = "\x1";
const std::string ScribeLogger::DEPLOY_STATS_CATEGORY = "leveldb_deploy_stats"; const std::string ScribeLogger::DEPLOY_STATS_CATEGORY = "leveldb_deploy_stats";
ScribeLogger::ScribeLogger(const std::string& host, int port, ScribeLogger::ScribeLogger(const std::string& host, int port,
int retry_times, uint32_t retry_intervals, int batch_size) int retry_times, uint32_t retry_intervals)
: host_(host), : host_(host),
port_(port), port_(port),
retry_times_(retry_times), retry_times_(retry_times),
retry_intervals_ (retry_intervals), retry_intervals_ (retry_intervals) {
batch_size_ (batch_size) {
shared_ptr<TSocket> socket(new TSocket(host_, port_)); shared_ptr<TSocket> socket(new TSocket(host_, port_));
shared_ptr<TFramedTransport> framedTransport(new TFramedTransport(socket)); shared_ptr<TFramedTransport> framedTransport(new TFramedTransport(socket));
framedTransport->open(); framedTransport->open();
@ -25,23 +24,16 @@ void ScribeLogger::Log(const std::string& category,
entry.category = category; entry.category = category;
entry.message = message; entry.message = message;
std::vector<LogEntry> logs;
logs.push_back(entry);
logger_mutex_.Lock(); logger_mutex_.Lock();
logs_.push_back(entry); ResultCode ret = scribe_client_->Log(logs);
int retries_left = retry_times_;
if (logs_.size() >= batch_size_) { while (ret == TRY_LATER && retries_left > 0) {
ResultCode ret = scribe_client_->Log(logs_); Env::Default()->SleepForMicroseconds(retry_intervals_);
int retries_left = retry_times_; ret = scribe_client_->Log(logs);
while (ret == TRY_LATER && retries_left > 0) { retries_left--;
Env::Default()->SleepForMicroseconds(retry_intervals_);
ret = scribe_client_->Log(logs_);
retries_left--;
}
// Clear the local messages if either successfully write out
// or has failed in the last 10 calls.
if (ret == OK || logs_.size() > batch_size_ * 5) {
logs_.clear();
}
} }
logger_mutex_.Unlock(); logger_mutex_.Unlock();

View File

@ -34,7 +34,6 @@ private:
int batch_size_; int batch_size_;
scribeClient* scribe_client_; scribeClient* scribe_client_;
std::vector<LogEntry> logs_;
port::Mutex logger_mutex_; port::Mutex logger_mutex_;
int retry_times_; int retry_times_;
@ -48,8 +47,7 @@ public:
static const std::string DEPLOY_STATS_CATEGORY; static const std::string DEPLOY_STATS_CATEGORY;
ScribeLogger(const std::string& host, int port, ScribeLogger(const std::string& host, int port,
int retry_times=3, uint32_t retry_intervals=1000000, int retry_times=3, uint32_t retry_intervals=1000000);
int batch_size=1);
virtual ~ScribeLogger(); virtual ~ScribeLogger();
virtual void Log(const std::string& category, const std::string& message); virtual void Log(const std::string& category, const std::string& message);