diff --git a/newbrt/brt-internal.h b/newbrt/brt-internal.h index 57777606adeaf7ab3ec48f3bf3611660fee10905..9b052a6a30f5deb02cc3958ce8d423d4e5c40f49 100644 --- a/newbrt/brt-internal.h +++ b/newbrt/brt-internal.h @@ -765,14 +765,19 @@ typedef struct brt_status { u_int64_t updates; u_int64_t updates_broadcast; u_int64_t descriptor_set; - u_int64_t partial_fetch_hit; // node partition is present - u_int64_t partial_fetch_miss; // node is present but partition is absent - u_int64_t partial_fetch_compressed; // node partition is present but compressed - u_int64_t msn_discards; // how many messages were ignored by leaf because of msn - u_int64_t max_workdone; // max workdone value of any buffer - u_int64_t dsn_gap; // dsn has detected a gap in continuity of root-to-leaf path (internal node was evicted and re-read) - u_int64_t bytes_leaf; // memory used by leaf nodes - u_int64_t bytes_nonleaf; // memory used by nonleaf nodes + u_int64_t partial_fetch_hit; // node partition is present + u_int64_t partial_fetch_miss; // node is present but partition is absent + u_int64_t partial_fetch_compressed; // node partition is present but compressed + u_int64_t msn_discards; // how many messages were ignored by leaf because of msn + u_int64_t max_workdone; // max workdone value of any buffer + u_int64_t dsn_gap; // dsn has detected a gap in continuity of root-to-leaf path (internal node was evicted and re-read) + u_int64_t bytes_leaf; // memory used by leaf nodes + u_int64_t bytes_nonleaf; // memory used by nonleaf nodes + uint64_t max_search_excess_retries; // max number of excess search retries (retries - treeheight) due to TRY_AGAIN + uint64_t max_search_root_tries; // max number of times root node was fetched in a single search + uint64_t search_root_retries; // number of searches that required the root node to be fetched more than once + uint64_t search_tries_gt_height; // number of searches that required more tries than the height of the tree + uint64_t search_tries_gt_heightplus3; // number of searches that required more tries than the height of the tree plus three } BRT_STATUS_S, *BRT_STATUS; void toku_brt_get_status(BRT_STATUS); diff --git a/newbrt/brt.c b/newbrt/brt.c index fa4425e566e50313a9e00b32aa5c83ee1c845cbc..0ccfbb7d0cadec35e84b2df3e4cb60101ed7fc3b 100644 --- a/newbrt/brt.c +++ b/newbrt/brt.c @@ -6260,8 +6260,16 @@ toku_brt_search (BRT brt, brt_search_t *search, BRT_GET_CALLBACK_FUNCTION getf, // All searches are performed through this function. { int r; + uint retrycount = 0; // How many retries did it take to get the result? + uint root_tries = 0; // How many times did we fetch the root node from disk? + uint tree_height; // How high is the tree? This is the height of the root node plus one (leaf is at height 0). + BOOL retry = false; // Have we attempted this search yet? try_again: + + if (retry) // don't count first attempt as a retry + retrycount++; + retry = true; assert(brt->h); @@ -6311,9 +6319,10 @@ toku_brt_search (BRT brt, brt_search_t *search, BRT_GET_CALLBACK_FUNCTION getf, r = toku_pin_brtnode(brt, *rootp, fullhash,(UNLOCKERS)NULL,(ANCESTORS)NULL, &infinite_bounds, &bfe, &node); assert(r==0 || r== TOKUDB_TRY_AGAIN); if (r == TOKUDB_TRY_AGAIN) { + root_tries++; goto try_again; } - + tree_height = node->height + 1; // height of tree (leaf is at height 0) struct unlock_brtnode_extra unlock_extra = {brt,node}; struct unlockers unlockers = {TRUE, unlock_brtnode_fun, (void*)&unlock_extra, (UNLOCKERS)NULL}; @@ -6361,6 +6370,23 @@ toku_brt_search (BRT brt, brt_search_t *search, BRT_GET_CALLBACK_FUNCTION getf, int r2 = getf(0,NULL, 0,NULL, getf_v); if (r2!=0) r = r2; } + + { // accounting (to detect and measure thrashing) + if (root_tries > 1) { // if root was read from disk more than once + brt_status.search_root_retries++; + if (root_tries > brt_status.max_search_root_tries) + brt_status.max_search_root_tries = root_tries; + } + if (retrycount > tree_height) { // if at least one node was read from disk more than once + brt_status.search_tries_gt_height++; + uint excess_tries = retrycount - tree_height; + if (excess_tries > brt_status.max_search_excess_retries) + brt_status.max_search_excess_retries = excess_tries; + if (retrycount > (tree_height+3)) + brt_status.search_tries_gt_heightplus3++; + } + } + return r; }