diff --git a/buildheader/db.h_4_1 b/buildheader/db.h_4_1 index 99f15cd3e24..ee69194d342 100644 --- a/buildheader/db.h_4_1 +++ b/buildheader/db.h_4_1 @@ -94,7 +94,7 @@ typedef struct __toku_engine_status { u_int64_t txn_abort; /* txn abort operations */ u_int64_t txn_close; /* txn completions (should equal commit+abort) */ u_int64_t txn_oldest_live; /* oldest extant txn txnid */ - char txn_oldest_live_begin; /* oldest extant txn start time */ + char txn_oldest_live_starttime[26]; /* oldest extant txn start time */ u_int64_t next_lsn; /* lsn that will be assigned to next log entry */ u_int64_t cachetable_lock_taken; /* how many times has cachetable lock been taken */ u_int64_t cachetable_lock_released;/* how many times has cachetable lock been released */ diff --git a/buildheader/db.h_4_3 b/buildheader/db.h_4_3 index 4f673b31638..68118206c80 100644 --- a/buildheader/db.h_4_3 +++ b/buildheader/db.h_4_3 @@ -94,7 +94,7 @@ typedef struct __toku_engine_status { u_int64_t txn_abort; /* txn abort operations */ u_int64_t txn_close; /* txn completions (should equal commit+abort) */ u_int64_t txn_oldest_live; /* oldest extant txn txnid */ - char txn_oldest_live_begin; /* oldest extant txn start time */ + char txn_oldest_live_starttime[26]; /* oldest extant txn start time */ u_int64_t next_lsn; /* lsn that will be assigned to next log entry */ u_int64_t cachetable_lock_taken; /* how many times has cachetable lock been taken */ u_int64_t cachetable_lock_released;/* how many times has cachetable lock been released */ diff --git a/buildheader/db.h_4_4 b/buildheader/db.h_4_4 index 64277735f78..59c9ccb6743 100644 --- a/buildheader/db.h_4_4 +++ b/buildheader/db.h_4_4 @@ -94,7 +94,7 @@ typedef struct __toku_engine_status { u_int64_t txn_abort; /* txn abort operations */ u_int64_t txn_close; /* txn completions (should equal commit+abort) */ u_int64_t txn_oldest_live; /* oldest extant txn txnid */ - char txn_oldest_live_begin; /* oldest extant txn start time */ + char txn_oldest_live_starttime[26]; /* oldest extant txn start time */ u_int64_t next_lsn; /* lsn that will be assigned to next log entry */ u_int64_t cachetable_lock_taken; /* how many times has cachetable lock been taken */ u_int64_t cachetable_lock_released;/* how many times has cachetable lock been released */ diff --git a/buildheader/db.h_4_5 b/buildheader/db.h_4_5 index 324b950f3f4..6d92061720f 100644 --- a/buildheader/db.h_4_5 +++ b/buildheader/db.h_4_5 @@ -94,7 +94,7 @@ typedef struct __toku_engine_status { u_int64_t txn_abort; /* txn abort operations */ u_int64_t txn_close; /* txn completions (should equal commit+abort) */ u_int64_t txn_oldest_live; /* oldest extant txn txnid */ - char txn_oldest_live_begin; /* oldest extant txn start time */ + char txn_oldest_live_starttime[26]; /* oldest extant txn start time */ u_int64_t next_lsn; /* lsn that will be assigned to next log entry */ u_int64_t cachetable_lock_taken; /* how many times has cachetable lock been taken */ u_int64_t cachetable_lock_released;/* how many times has cachetable lock been released */ diff --git a/buildheader/db.h_4_6 b/buildheader/db.h_4_6 index fee5459ae7b..b31daf3b285 100644 --- a/buildheader/db.h_4_6 +++ b/buildheader/db.h_4_6 @@ -94,7 +94,7 @@ typedef struct __toku_engine_status { u_int64_t txn_abort; /* txn abort operations */ u_int64_t txn_close; /* txn completions (should equal commit+abort) */ u_int64_t txn_oldest_live; /* oldest extant txn txnid */ - char txn_oldest_live_begin; /* oldest extant txn start time */ + char txn_oldest_live_starttime[26]; /* oldest extant txn start time */ u_int64_t next_lsn; /* lsn that will be assigned to next log entry */ u_int64_t cachetable_lock_taken; /* how many times has cachetable lock been taken */ u_int64_t cachetable_lock_released;/* how many times has cachetable lock been released */ diff --git a/buildheader/make_db_h.c b/buildheader/make_db_h.c index 958f68853f7..8e356e6c8bd 100644 --- a/buildheader/make_db_h.c +++ b/buildheader/make_db_h.c @@ -481,7 +481,7 @@ int main (int argc __attribute__((__unused__)), char *const argv[] __attribute__ printf(" u_int64_t txn_abort; /* txn abort operations */ \n"); printf(" u_int64_t txn_close; /* txn completions (should equal commit+abort) */ \n"); printf(" u_int64_t txn_oldest_live; /* oldest extant txn txnid */ \n"); - printf(" char txn_oldest_live_begin; /* oldest extant txn start time */ \n"); + printf(" char txn_oldest_live_starttime[26]; /* oldest extant txn start time */ \n"); printf(" u_int64_t next_lsn; /* lsn that will be assigned to next log entry */ \n"); printf(" u_int64_t cachetable_lock_taken; /* how many times has cachetable lock been taken */ \n"); printf(" u_int64_t cachetable_lock_released;/* how many times has cachetable lock been released */ \n"); diff --git a/buildheader/tdb.h b/buildheader/tdb.h index 91808bbbf0e..cf11a46bcfd 100644 --- a/buildheader/tdb.h +++ b/buildheader/tdb.h @@ -94,7 +94,7 @@ typedef struct __toku_engine_status { u_int64_t txn_abort; /* txn abort operations */ u_int64_t txn_close; /* txn completions (should equal commit+abort) */ u_int64_t txn_oldest_live; /* oldest extant txn txnid */ - char txn_oldest_live_begin; /* oldest extant txn start time */ + char txn_oldest_live_starttime[26]; /* oldest extant txn start time */ u_int64_t next_lsn; /* lsn that will be assigned to next log entry */ u_int64_t cachetable_lock_taken; /* how many times has cachetable lock been taken */ u_int64_t cachetable_lock_released;/* how many times has cachetable lock been released */ diff --git a/include/db.h b/include/db.h index 91808bbbf0e..cf11a46bcfd 100644 --- a/include/db.h +++ b/include/db.h @@ -94,7 +94,7 @@ typedef struct __toku_engine_status { u_int64_t txn_abort; /* txn abort operations */ u_int64_t txn_close; /* txn completions (should equal commit+abort) */ u_int64_t txn_oldest_live; /* oldest extant txn txnid */ - char txn_oldest_live_begin; /* oldest extant txn start time */ + char txn_oldest_live_starttime[26]; /* oldest extant txn start time */ u_int64_t next_lsn; /* lsn that will be assigned to next log entry */ u_int64_t cachetable_lock_taken; /* how many times has cachetable lock been taken */ u_int64_t cachetable_lock_released;/* how many times has cachetable lock been released */ diff --git a/newbrt/brt.c b/newbrt/brt.c index 435d5622fda..914f03fb7cf 100644 --- a/newbrt/brt.c +++ b/newbrt/brt.c @@ -2663,7 +2663,7 @@ brt_optimize (BRT brt, BOOL upgrade) { TXNID oldest = TXNID_NONE_LIVING; if (!upgrade) { TOKULOGGER logger = toku_cachefile_logger(brt->cf); - oldest = toku_logger_get_oldest_living_xid(logger); + oldest = toku_logger_get_oldest_living_xid(logger, NULL); } XIDS root_xids = xids_get_root_xids(); @@ -4274,7 +4274,7 @@ int toku_brt_cursor ( cursor->brt = brt; cursor->current_in_omt = FALSE; cursor->prefetching = FALSE; - cursor->oldest_living_xid = ttxn ? toku_logger_get_oldest_living_xid(ttxn->logger) : TXNID_NONE; + cursor->oldest_living_xid = ttxn ? toku_logger_get_oldest_living_xid(ttxn->logger, NULL) : TXNID_NONE; cursor->is_snapshot_read = is_snapshot_read; cursor->is_leaf_mode = FALSE; cursor->ttxn = ttxn; @@ -5722,7 +5722,7 @@ BOOL toku_brt_is_empty (BRT brt, /*out*/BOOL *try_again) { TOKULOGGER logger = toku_cachefile_logger(brt->cf); - TXNID oldest = toku_logger_get_oldest_living_xid(logger); + TXNID oldest = toku_logger_get_oldest_living_xid(logger, NULL); XIDS root_xids = xids_get_root_xids(); XIDS message_xids; diff --git a/newbrt/log-internal.h b/newbrt/log-internal.h index 5fd9eac7390..b3be8e22d39 100644 --- a/newbrt/log-internal.h +++ b/newbrt/log-internal.h @@ -107,6 +107,7 @@ struct tokulogger { u_int32_t write_block_size; // How big should the blocks be written to various logs? TXNID oldest_living_xid; + time_t oldest_living_starttime; // timestamp in seconds of when txn with oldest_living_xid started 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 @@ -131,6 +132,7 @@ struct tokutxn { TOKULOGGER logger; TOKUTXN parent; DB_TXN* container_db_txn; // reference to DB_TXN that contains this tokutxn + time_t starttime; // timestamp in seconds of transaction start u_int64_t rollentry_raw_count; // the total count of every byte in the transaction and all its children. OMT open_brts; // a collection of the brts that we touched. Indexed by filenum. diff --git a/newbrt/logger.c b/newbrt/logger.c index 8561b25f116..20077b8502c 100644 --- a/newbrt/logger.c +++ b/newbrt/logger.c @@ -79,6 +79,7 @@ int toku_logger_create (TOKULOGGER *resultp) { // n_in_file is uninitialized result->write_block_size = BRT_DEFAULT_NODE_SIZE; // default logging size is the same as the default brt block size result->oldest_living_xid = TXNID_NONE_LIVING; + result->oldest_living_starttime = 0; toku_logfilemgr_create(&result->logfilemgr); *resultp=result; r = ml_init(&result->input_lock); if (r!=0) goto panic; @@ -1314,10 +1315,13 @@ void toku_logger_note_checkpoint(TOKULOGGER logger, LSN lsn) { logger->last_completed_checkpoint_lsn = lsn; } -TXNID toku_logger_get_oldest_living_xid(TOKULOGGER logger) { +TXNID toku_logger_get_oldest_living_xid(TOKULOGGER logger, time_t * oldest_living_starttime) { TXNID rval = 0; - if (logger) + if (logger) { rval = logger->oldest_living_xid; + if (oldest_living_starttime) + *oldest_living_starttime = logger->oldest_living_starttime; + } return rval; } diff --git a/newbrt/logger.h b/newbrt/logger.h index 17439fec16a..5e33bac661c 100644 --- a/newbrt/logger.h +++ b/newbrt/logger.h @@ -100,7 +100,7 @@ int toku_logger_log_archive (TOKULOGGER logger, char ***logs_p, int flags); TOKUTXN toku_logger_txn_parent (TOKUTXN txn); void toku_logger_note_checkpoint(TOKULOGGER logger, LSN lsn); -TXNID toku_logger_get_oldest_living_xid(TOKULOGGER logger); +TXNID toku_logger_get_oldest_living_xid(TOKULOGGER logger, time_t * oldest_living_starttime); LSN toku_logger_get_next_lsn(TOKULOGGER logger); void toku_logger_set_remove_finalize_callback(TOKULOGGER logger, void (*funcp)(DICTIONARY_ID, void *), void * extra); void toku_logger_call_remove_finalize_callback(TOKULOGGER logger, DICTIONARY_ID dict_id); diff --git a/newbrt/rollback.c b/newbrt/rollback.c index 7f9af8c713c..7aebafb137f 100644 --- a/newbrt/rollback.c +++ b/newbrt/rollback.c @@ -286,11 +286,13 @@ void toku_rollback_txn_close (TOKUTXN txn) { assert(oldest_txn != txn); // We just removed it assert(oldest_txn->txnid64 > txn->logger->oldest_living_xid); //Must be newer than the previous oldest txn->logger->oldest_living_xid = oldest_txn->txnid64; + txn->logger->oldest_living_starttime = oldest_txn->starttime; } else { //No living transactions assert(r==EINVAL); txn->logger->oldest_living_xid = TXNID_NONE_LIVING; + txn->logger->oldest_living_starttime = 0; } } diff --git a/newbrt/txn.c b/newbrt/txn.c index 5f355f2e0e2..02eee16fd09 100644 --- a/newbrt/txn.c +++ b/newbrt/txn.c @@ -152,6 +152,7 @@ int toku_txn_begin_with_xid ( return errno; int r; LSN first_lsn; + result->starttime = time(NULL); // getting timestamp in seconds is a cheap call if (xid == 0) { r = toku_log_xbegin(logger, &first_lsn, 0, parent_tokutxn ? parent_tokutxn->txnid64 : 0); if (r!=0) goto died; diff --git a/src/ydb.c b/src/ydb.c index 4c18d1604a5..583e37403be 100644 --- a/src/ydb.c +++ b/src/ydb.c @@ -1793,14 +1793,16 @@ env_get_engine_status(DB_ENV * env, ENGINE_STATUS * engstat, char * env_panic_st engstat->txn_close = txnstat.close; { uint64_t oldest_xid = 0; + time_t oldest_starttime = 0; uint64_t next_lsn = 0; TOKULOGGER logger = env->i->logger; if (logger) { - oldest_xid = toku_logger_get_oldest_living_xid(env->i->logger); + oldest_xid = toku_logger_get_oldest_living_xid(env->i->logger, &oldest_starttime); next_lsn = (toku_logger_get_next_lsn(env->i->logger)).lsn; } engstat->txn_oldest_live = oldest_xid; engstat->next_lsn = next_lsn; + format_time(&oldest_starttime, engstat->txn_oldest_live_starttime); } } {