Commit e8af332d authored by Bradley C. Kuszmaul's avatar Bradley C. Kuszmaul Committed by Yoni Fogel

Merge r18357 to put the logger statistics. Refs #2385. [t:2385].

{{{
svn merge -c18357 https://svn.tokutek.com/tokudb/mysql.branches/3.1.0/tokudb/
}}}
.


git-svn-id: file:///svn/toku/tokudb@18640 c7de825b-a66e-492c-adef-691d508d4ae1
parent 9bac0b07
...@@ -104,6 +104,9 @@ typedef struct __toku_engine_status { ...@@ -104,6 +104,9 @@ typedef struct __toku_engine_status {
u_int64_t sequential_queries; /* ydb sequential queries */ u_int64_t sequential_queries; /* ydb sequential queries */
u_int64_t fsync_count; /* number of times fsync performed */ u_int64_t fsync_count; /* number of times fsync performed */
u_int64_t fsync_time; /* total time required to fsync */ u_int64_t fsync_time; /* total time required to fsync */
u_int64_t logger_ilock_ctr; /* how many times has logger input lock been taken or released */
u_int64_t logger_olock_ctr; /* how many times has logger output condition lock been taken or released */
u_int64_t logger_swap_ctr; /* how many times have logger buffers been swapped */
} ENGINE_STATUS; } ENGINE_STATUS;
typedef enum { typedef enum {
DB_BTREE=1, DB_BTREE=1,
......
...@@ -96,6 +96,9 @@ struct tokulogger { ...@@ -96,6 +96,9 @@ struct tokulogger {
u_int32_t write_block_size; // How big should the blocks be written to various logs? u_int32_t write_block_size; // How big should the blocks be written to various logs?
TXNID oldest_living_xid; TXNID oldest_living_xid;
u_int64_t input_lock_ctr; // how many times has input_lock been taken and released
u_int64_t output_condition_lock_ctr; // how many times has output_condition_lock been taken and released
u_int64_t swap_ctr; // how many times have input/output log buffers been swapped
void (*remove_finalize_callback) (DICTIONARY_ID, void*); // ydb-level callback to be called when a transaction that ... void (*remove_finalize_callback) (DICTIONARY_ID, void*); // ydb-level callback to be called when a transaction that ...
void * remove_finalize_callback_extra; // ... deletes a file is committed or when one that creates a file is aborted. void * remove_finalize_callback_extra; // ... deletes a file is committed or when one that creates a file is aborted.
}; };
......
...@@ -65,7 +65,10 @@ int toku_logger_create (TOKULOGGER *resultp) { ...@@ -65,7 +65,10 @@ int toku_logger_create (TOKULOGGER *resultp) {
r = ml_init(&result->input_lock); if (r!=0) goto panic; r = ml_init(&result->input_lock); if (r!=0) goto panic;
r = toku_pthread_mutex_init(&result->output_condition_lock, NULL); if (r!=0) goto panic; r = toku_pthread_mutex_init(&result->output_condition_lock, NULL); if (r!=0) goto panic;
r = toku_pthread_cond_init(&result->output_condition, NULL); if (r!=0) goto panic; r = toku_pthread_cond_init(&result->output_condition, NULL); if (r!=0) goto panic;
result->input_lock_ctr = 0;
result->output_condition_lock_ctr = 0;
result->output_is_available = TRUE; result->output_is_available = TRUE;
result->swap_ctr = 0;
return 0; return 0;
panic: panic:
...@@ -142,6 +145,7 @@ int toku_logger_close(TOKULOGGER *loggerp) { ...@@ -142,6 +145,7 @@ int toku_logger_close(TOKULOGGER *loggerp) {
int r = 0; int r = 0;
if (!logger->is_open) goto is_closed; if (!logger->is_open) goto is_closed;
ml_lock(&logger->input_lock); ml_lock(&logger->input_lock);
logger->input_lock_ctr++;
LSN fsynced_lsn; LSN fsynced_lsn;
grab_output(logger, &fsynced_lsn); grab_output(logger, &fsynced_lsn);
r = toku_logger_write_buffer(logger, &fsynced_lsn); if (r!=0) goto panic; //Releases the input lock r = toku_logger_write_buffer(logger, &fsynced_lsn); if (r!=0) goto panic; //Releases the input lock
...@@ -233,11 +237,13 @@ grab_output(TOKULOGGER logger, LSN *fsynced_lsn) ...@@ -233,11 +237,13 @@ grab_output(TOKULOGGER logger, LSN *fsynced_lsn)
{ {
int r; int r;
r = toku_pthread_mutex_lock(&logger->output_condition_lock); assert(r==0); r = toku_pthread_mutex_lock(&logger->output_condition_lock); assert(r==0);
logger->output_condition_lock_ctr++;
wait_till_output_available(logger); wait_till_output_available(logger);
logger->output_is_available = FALSE; logger->output_is_available = FALSE;
if (fsynced_lsn) { if (fsynced_lsn) {
*fsynced_lsn = logger->fsynced_lsn; *fsynced_lsn = logger->fsynced_lsn;
} }
logger->output_condition_lock_ctr++;
r = toku_pthread_mutex_unlock(&logger->output_condition_lock); assert(r==0); r = toku_pthread_mutex_unlock(&logger->output_condition_lock); assert(r==0);
} }
...@@ -251,7 +257,7 @@ wait_till_output_already_written_or_output_buffer_available (TOKULOGGER logger, ...@@ -251,7 +257,7 @@ wait_till_output_already_written_or_output_buffer_available (TOKULOGGER logger,
// Exit: Hold the output permission if returns false. // Exit: Hold the output permission if returns false.
{ {
BOOL result; BOOL result;
{ int r = toku_pthread_mutex_lock(&logger->output_condition_lock); assert(r==0); } { int r = toku_pthread_mutex_lock(&logger->output_condition_lock); logger->output_condition_lock_ctr++; assert(r==0); }
while (1) { while (1) {
if (logger->fsynced_lsn.lsn >= lsn.lsn) { // we can look at the fsynced lsn since we have the lock. if (logger->fsynced_lsn.lsn >= lsn.lsn) { // we can look at the fsynced lsn since we have the lock.
result = TRUE; result = TRUE;
...@@ -267,7 +273,7 @@ wait_till_output_already_written_or_output_buffer_available (TOKULOGGER logger, ...@@ -267,7 +273,7 @@ wait_till_output_already_written_or_output_buffer_available (TOKULOGGER logger,
assert(r==0); assert(r==0);
} }
*fsynced_lsn = logger->fsynced_lsn; *fsynced_lsn = logger->fsynced_lsn;
{ int r = toku_pthread_mutex_unlock(&logger->output_condition_lock); assert(r==0); } { int r = toku_pthread_mutex_unlock(&logger->output_condition_lock); logger->output_condition_lock_ctr++; assert(r==0); }
return result; return result;
} }
...@@ -279,11 +285,13 @@ release_output (TOKULOGGER logger, LSN fsynced_lsn) ...@@ -279,11 +285,13 @@ release_output (TOKULOGGER logger, LSN fsynced_lsn)
{ {
int r; int r;
r = toku_pthread_mutex_lock(&logger->output_condition_lock); assert(r==0); r = toku_pthread_mutex_lock(&logger->output_condition_lock); assert(r==0);
logger->output_condition_lock_ctr++;
logger->output_is_available = TRUE; logger->output_is_available = TRUE;
if (logger->fsynced_lsn.lsn < fsynced_lsn.lsn) { if (logger->fsynced_lsn.lsn < fsynced_lsn.lsn) {
logger->fsynced_lsn = fsynced_lsn; logger->fsynced_lsn = fsynced_lsn;
} }
r = toku_pthread_cond_broadcast(&logger->output_condition); assert(r==0); r = toku_pthread_cond_broadcast(&logger->output_condition); assert(r==0);
logger->output_condition_lock_ctr++;
r = toku_pthread_mutex_unlock(&logger->output_condition_lock); assert(r==0); r = toku_pthread_mutex_unlock(&logger->output_condition_lock); assert(r==0);
} }
...@@ -296,6 +304,7 @@ swap_inbuf_outbuf (TOKULOGGER logger) ...@@ -296,6 +304,7 @@ swap_inbuf_outbuf (TOKULOGGER logger)
logger->inbuf = logger->outbuf; logger->inbuf = logger->outbuf;
logger->outbuf = tmp; logger->outbuf = tmp;
assert(logger->inbuf.n_in_buf == 0); assert(logger->inbuf.n_in_buf == 0);
logger->swap_ctr++;
} }
static void static void
...@@ -333,11 +342,13 @@ toku_logger_make_space_in_inbuf (TOKULOGGER logger, int n_bytes_needed) ...@@ -333,11 +342,13 @@ toku_logger_make_space_in_inbuf (TOKULOGGER logger, int n_bytes_needed)
{ {
int r; int r;
if (logger->inbuf.n_in_buf + n_bytes_needed <= LOGGER_MIN_BUF_SIZE) return 0; if (logger->inbuf.n_in_buf + n_bytes_needed <= LOGGER_MIN_BUF_SIZE) return 0;
logger->input_lock_ctr++;
r = ml_unlock(&logger->input_lock); if (r!=0) goto panic; r = ml_unlock(&logger->input_lock); if (r!=0) goto panic;
LSN fsynced_lsn; LSN fsynced_lsn;
grab_output(logger, &fsynced_lsn); grab_output(logger, &fsynced_lsn);
r = ml_lock(&logger->input_lock); if (r!=0) goto panic; r = ml_lock(&logger->input_lock); if (r!=0) goto panic;
logger->input_lock_ctr++;
// Some other thread may have written the log out while we didn't have the lock. If we have space now, then be happy. // Some other thread may have written the log out while we didn't have the lock. If we have space now, then be happy.
if (logger->inbuf.n_in_buf + n_bytes_needed <= LOGGER_MIN_BUF_SIZE) { if (logger->inbuf.n_in_buf + n_bytes_needed <= LOGGER_MIN_BUF_SIZE) {
release_output(logger, fsynced_lsn); release_output(logger, fsynced_lsn);
...@@ -376,6 +387,7 @@ int toku_logger_fsync (TOKULOGGER logger) ...@@ -376,6 +387,7 @@ int toku_logger_fsync (TOKULOGGER logger)
int r; int r;
if (logger->is_panicked) return EINVAL; if (logger->is_panicked) return EINVAL;
r = ml_lock(&logger->input_lock); assert(r==0); r = ml_lock(&logger->input_lock); assert(r==0);
logger->input_lock_ctr++;
r = toku_logger_maybe_fsync(logger, logger->inbuf.max_lsn_in_buf, TRUE); r = toku_logger_maybe_fsync(logger, logger->inbuf.max_lsn_in_buf, TRUE);
if (r!=0) { if (r!=0) {
toku_logger_panic(logger, r); toku_logger_panic(logger, r);
...@@ -591,6 +603,7 @@ int toku_logger_maybe_fsync (TOKULOGGER logger, LSN lsn, int do_fsync) ...@@ -591,6 +603,7 @@ int toku_logger_maybe_fsync (TOKULOGGER logger, LSN lsn, int do_fsync)
int r; int r;
if (do_fsync) { if (do_fsync) {
// reacquire the locks (acquire output permission first) // reacquire the locks (acquire output permission first)
logger->input_lock_ctr++;
r = ml_unlock(&logger->input_lock); assert(r==0); r = ml_unlock(&logger->input_lock); assert(r==0);
LSN fsynced_lsn; LSN fsynced_lsn;
BOOL already_done = wait_till_output_already_written_or_output_buffer_available(logger, lsn, &fsynced_lsn); BOOL already_done = wait_till_output_already_written_or_output_buffer_available(logger, lsn, &fsynced_lsn);
...@@ -599,9 +612,11 @@ int toku_logger_maybe_fsync (TOKULOGGER logger, LSN lsn, int do_fsync) ...@@ -599,9 +612,11 @@ int toku_logger_maybe_fsync (TOKULOGGER logger, LSN lsn, int do_fsync)
// otherwise we now own the output permission, and our lsn isn't outputed. // otherwise we now own the output permission, and our lsn isn't outputed.
r = ml_lock(&logger->input_lock); assert(r==0); r = ml_lock(&logger->input_lock); assert(r==0);
logger->input_lock_ctr++;
swap_inbuf_outbuf(logger); swap_inbuf_outbuf(logger);
logger->input_lock_ctr++;
r = ml_unlock(&logger->input_lock); // release the input lock now, so other threads can fill the inbuf. (Thus enabling group commit.) r = ml_unlock(&logger->input_lock); // release the input lock now, so other threads can fill the inbuf. (Thus enabling group commit.)
assert(r==0); assert(r==0);
...@@ -621,6 +636,7 @@ int toku_logger_maybe_fsync (TOKULOGGER logger, LSN lsn, int do_fsync) ...@@ -621,6 +636,7 @@ int toku_logger_maybe_fsync (TOKULOGGER logger, LSN lsn, int do_fsync)
toku_logfilemgr_update_last_lsn(logger->logfilemgr, logger->written_lsn); toku_logfilemgr_update_last_lsn(logger->logfilemgr, logger->written_lsn);
release_output(logger, fsynced_lsn); release_output(logger, fsynced_lsn);
} else { } else {
logger->input_lock_ctr++;
r = ml_unlock(&logger->input_lock); r = ml_unlock(&logger->input_lock);
assert(r==0); assert(r==0);
} }
...@@ -635,7 +651,7 @@ toku_logger_write_buffer (TOKULOGGER logger, LSN *fsynced_lsn) ...@@ -635,7 +651,7 @@ toku_logger_write_buffer (TOKULOGGER logger, LSN *fsynced_lsn)
// Note: Only called during single-threaded activity from toku_logger_restart, so locks aren't really needed. // Note: Only called during single-threaded activity from toku_logger_restart, so locks aren't really needed.
{ {
swap_inbuf_outbuf(logger); swap_inbuf_outbuf(logger);
{ int r = ml_unlock(&logger->input_lock); assert(r==0); } { logger->input_lock_ctr++; int r = ml_unlock(&logger->input_lock); assert(r==0); }
write_outbuf_to_logfile(logger, fsynced_lsn); write_outbuf_to_logfile(logger, fsynced_lsn);
if (logger->write_log_files) { if (logger->write_log_files) {
int r = toku_file_fsync_without_accounting(logger->fd); int r = toku_file_fsync_without_accounting(logger->fd);
...@@ -657,6 +673,7 @@ int toku_logger_restart(TOKULOGGER logger, LSN lastlsn) ...@@ -657,6 +673,7 @@ int toku_logger_restart(TOKULOGGER logger, LSN lastlsn)
LSN fsynced_lsn; LSN fsynced_lsn;
grab_output(logger, &fsynced_lsn); grab_output(logger, &fsynced_lsn);
r = ml_lock(&logger->input_lock); assert(r == 0); r = ml_lock(&logger->input_lock); assert(r == 0);
logger->input_lock_ctr++;
r = toku_logger_write_buffer(logger, &fsynced_lsn); assert(r == 0); r = toku_logger_write_buffer(logger, &fsynced_lsn); assert(r == 0);
// close the log file // close the log file
...@@ -1172,3 +1189,12 @@ toku_logger_call_remove_finalize_callback(TOKULOGGER logger, DICTIONARY_ID dict_ ...@@ -1172,3 +1189,12 @@ toku_logger_call_remove_finalize_callback(TOKULOGGER logger, DICTIONARY_ID dict_
if (logger->remove_finalize_callback) if (logger->remove_finalize_callback)
logger->remove_finalize_callback(dict_id, logger->remove_finalize_callback_extra); logger->remove_finalize_callback(dict_id, logger->remove_finalize_callback_extra);
} }
void
toku_logger_get_status(TOKULOGGER logger, LOGGER_STATUS s) {
s->ilock_ctr = logger->input_lock_ctr;
s->olock_ctr = logger->output_condition_lock_ctr;
s->swap_ctr = logger->swap_ctr;
}
...@@ -143,5 +143,15 @@ toku_logger_maybe_fsync (TOKULOGGER logger, LSN lsn, int do_fsync); ...@@ -143,5 +143,15 @@ toku_logger_maybe_fsync (TOKULOGGER logger, LSN lsn, int do_fsync);
// fsync // fsync
// release the outlock // release the outlock
typedef struct logger_status {
u_int64_t ilock_ctr;
u_int64_t olock_ctr;
u_int64_t swap_ctr;
} LOGGER_STATUS_S, *LOGGER_STATUS;
void toku_logger_get_status(TOKULOGGER logger, LOGGER_STATUS s);
#endif #endif
...@@ -1388,6 +1388,15 @@ env_get_engine_status(DB_ENV * env, ENGINE_STATUS * engstat) { ...@@ -1388,6 +1388,15 @@ env_get_engine_status(DB_ENV * env, ENGINE_STATUS * engstat) {
engstat->fsync_count = fsync_count; engstat->fsync_count = fsync_count;
engstat->fsync_time = fsync_time; engstat->fsync_time = fsync_time;
} }
{
LOGGER_STATUS_S log_stat;
TOKULOGGER logger = env->i->logger;
toku_logger_get_status(logger, &log_stat);
engstat->logger_ilock_ctr = log_stat.ilock_ctr;
engstat->logger_olock_ctr = log_stat.olock_ctr;
engstat->logger_swap_ctr = log_stat.swap_ctr;
}
} }
return r; return r;
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment