diff options
author | Dan Pasette <dan@10gen.com> | 2015-08-10 11:34:16 -0400 |
---|---|---|
committer | Dan Pasette <dan@mongodb.com> | 2015-08-10 11:34:16 -0400 |
commit | b3c07dda3afe9cf30e7fb7942a44e8fa7ac5b0a6 (patch) | |
tree | b944ac0c14ef84a1ca4e83684530c23a410d5bcc | |
parent | e8668374eeefc844167e9c5fa1981ace9c6d2b10 (diff) | |
download | mongo-b3c07dda3afe9cf30e7fb7942a44e8fa7ac5b0a6.tar.gz |
Import wiredtiger-wiredtiger-mongodb-3.0.4-51-g58bc810.tar.gz from wiredtiger branch mongodb-3.0
-rw-r--r-- | src/third_party/wiredtiger/dist/api_data.py | 3 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/config/config_def.c | 2 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/conn/conn_sweep.c | 133 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/include/dhandle.h | 1 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/include/wiredtiger.in | 10 |
5 files changed, 84 insertions, 65 deletions
diff --git a/src/third_party/wiredtiger/dist/api_data.py b/src/third_party/wiredtiger/dist/api_data.py index 5ad422befb4..215e3f81803 100644 --- a/src/third_party/wiredtiger/dist/api_data.py +++ b/src/third_party/wiredtiger/dist/api_data.py @@ -374,7 +374,8 @@ connection_runtime_config = [ type='category', subconfig=[ Config('close_idle_time', '30', r''' amount of time in seconds a file handle needs to be idle - before attempting to close it''', min=1, max=100000), + before attempting to close it. A setting of 0 means that idle + handles are not closed''', min=0, max=100000), Config('close_handle_minimum', '250', r''' number of handles open before the file manager will look for handles to close'''), diff --git a/src/third_party/wiredtiger/src/config/config_def.c b/src/third_party/wiredtiger/src/config/config_def.c index d068c196771..2dfcf862cc8 100644 --- a/src/third_party/wiredtiger/src/config/config_def.c +++ b/src/third_party/wiredtiger/src/config/config_def.c @@ -61,7 +61,7 @@ static const WT_CONFIG_CHECK confchk_eviction_subconfigs[] = { static const WT_CONFIG_CHECK confchk_file_manager_subconfigs[] = { { "close_handle_minimum", "string", NULL, NULL, NULL }, - { "close_idle_time", "int", NULL, "min=1,max=100000", NULL }, + { "close_idle_time", "int", NULL, "min=0,max=100000", NULL }, { "close_scan_interval", "int", NULL, "min=1,max=100000", NULL }, diff --git a/src/third_party/wiredtiger/src/conn/conn_sweep.c b/src/third_party/wiredtiger/src/conn/conn_sweep.c index 7a5bb6ccb0b..d658ed8d3f3 100644 --- a/src/third_party/wiredtiger/src/conn/conn_sweep.c +++ b/src/third_party/wiredtiger/src/conn/conn_sweep.c @@ -14,37 +14,34 @@ * handles. */ static int -__sweep_mark(WT_SESSION_IMPL *session, int *dead_handlesp) +__sweep_mark(WT_SESSION_IMPL *session, time_t now) { WT_CONNECTION_IMPL *conn; WT_DATA_HANDLE *dhandle; - time_t now; conn = S2C(session); - *dead_handlesp = 0; - - /* Don't discard handles that have been open recently. */ - WT_RET(__wt_seconds(session, &now)); WT_STAT_FAST_CONN_INCR(session, dh_conn_sweeps); SLIST_FOREACH(dhandle, &conn->dhlh, l) { if (WT_IS_METADATA(dhandle)) continue; - if (F_ISSET(dhandle, WT_DHANDLE_DEAD)) { - ++*dead_handlesp; - continue; - } - if (dhandle->session_inuse != 0 || - now <= dhandle->timeofdeath + conn->sweep_idle_time) - continue; - if (dhandle->timeofdeath == 0) { - dhandle->timeofdeath = now; - WT_STAT_FAST_CONN_INCR(session, dh_conn_tod); + + /* + * There are some internal increments of the in-use count such + * as eviction. Don't keep handles alive because of those + * cases, but if we see multiple cursors open, clear the time + * of death. + */ + if (dhandle->session_inuse > 1) + dhandle->timeofdeath = 0; + + if (F_ISSET(dhandle, WT_DHANDLE_DEAD) || + dhandle->session_inuse != 0 || + dhandle->timeofdeath != 0) continue; - } - /* We now have a candidate to close. */ - ++*dead_handlesp; + dhandle->timeofdeath = now; + WT_STAT_FAST_CONN_INCR(session, dh_conn_tod); } return (0); @@ -112,33 +109,26 @@ err: WT_TRET(__wt_writeunlock(session, dhandle->rwlock)); * until we have reached the configured minimum number of handles. */ static int -__sweep_expire(WT_SESSION_IMPL *session) +__sweep_expire(WT_SESSION_IMPL *session, time_t now) { WT_CONNECTION_IMPL *conn; WT_DATA_HANDLE *dhandle; WT_DECL_RET; - time_t now; conn = S2C(session); - /* Don't discard handles that have been open recently. */ - WT_RET(__wt_seconds(session, &now)); - WT_STAT_FAST_CONN_INCR(session, dh_conn_sweeps); SLIST_FOREACH(dhandle, &conn->dhlh, l) { /* - * Ignore open files once the open file count reaches the + * Ignore open files once the btree file count is below the * minimum number of handles. */ - if (conn->open_file_count < conn->sweep_handles_min) + if (conn->open_btree_count < conn->sweep_handles_min) break; - if (WT_IS_METADATA(dhandle)) - continue; - if (!F_ISSET(dhandle, WT_DHANDLE_OPEN) || - F_ISSET(dhandle, WT_DHANDLE_DEAD)) - continue; - if (dhandle->session_inuse != 0 || + if (WT_IS_METADATA(dhandle) || + dhandle->session_inuse != 0 || + dhandle->timeofdeath == 0 || now <= dhandle->timeofdeath + conn->sweep_idle_time) continue; @@ -151,11 +141,12 @@ __sweep_expire(WT_SESSION_IMPL *session) } /* - * __sweep_flush -- - * Flush pages from dead trees. + * __sweep_discard_trees -- + * Discard pages from dead trees. */ static int -__sweep_flush(WT_SESSION_IMPL *session) +__sweep_discard_trees( + WT_SESSION_IMPL *session, time_t now, u_int *dead_handlesp) { WT_CONNECTION_IMPL *conn; WT_DATA_HANDLE *dhandle; @@ -163,8 +154,15 @@ __sweep_flush(WT_SESSION_IMPL *session) conn = S2C(session); + *dead_handlesp = 0; + WT_STAT_FAST_CONN_INCR(session, dh_conn_sweeps); SLIST_FOREACH(dhandle, &conn->dhlh, l) { + if (!F_ISSET(dhandle, WT_DHANDLE_OPEN | WT_DHANDLE_EXCLUSIVE) && + (dhandle->timeofdiscard == 0 || + now <= dhandle->timeofdiscard + conn->sweep_idle_time)) + ++*dead_handlesp; + if (!F_ISSET(dhandle, WT_DHANDLE_OPEN) || !F_ISSET(dhandle, WT_DHANDLE_DEAD)) continue; @@ -173,9 +171,11 @@ __sweep_flush(WT_SESSION_IMPL *session) WT_WITH_DHANDLE(session, dhandle, ret = __wt_conn_btree_sync_and_close(session, 0, 0)); - /* We closed the btree handle, bump the statistic. */ - if (ret == 0) + /* We closed the btree handle. */ + if (ret == 0) { WT_STAT_FAST_CONN_INCR(session, dh_conn_handles); + ++*dead_handlesp; + } WT_RET_BUSY_OK(ret); } @@ -188,7 +188,7 @@ __sweep_flush(WT_SESSION_IMPL *session) * Remove closed dhandles from the connection list. */ static int -__sweep_remove_handles(WT_SESSION_IMPL *session) +__sweep_remove_handles(WT_SESSION_IMPL *session, time_t now) { WT_CONNECTION_IMPL *conn; WT_DATA_HANDLE *dhandle, *dhandle_next; @@ -201,22 +201,26 @@ __sweep_remove_handles(WT_SESSION_IMPL *session) dhandle_next = SLIST_NEXT(dhandle, l); if (WT_IS_METADATA(dhandle)) continue; - if (F_ISSET(dhandle, WT_DHANDLE_OPEN) || - dhandle->session_inuse != 0 || - dhandle->session_ref != 0) + if (F_ISSET(dhandle, WT_DHANDLE_EXCLUSIVE | WT_DHANDLE_OPEN) || + dhandle->session_inuse != 0 || dhandle->session_ref != 0) + continue; + if (dhandle->timeofdiscard != 0 && + now <= dhandle->timeofdiscard + conn->sweep_idle_time) continue; /* Make sure we get exclusive access. */ if ((ret = - __wt_try_writelock(session, dhandle->rwlock)) == EBUSY) + __wt_try_writelock(session, dhandle->rwlock)) == EBUSY) { + dhandle->timeofdiscard = now; continue; + } WT_RET(ret); /* * If there are no longer any references to the handle in any * sessions, attempt to discard it. */ - if (F_ISSET(dhandle, WT_DHANDLE_OPEN) || + if (F_ISSET(dhandle, WT_DHANDLE_EXCLUSIVE | WT_DHANDLE_OPEN) || dhandle->session_inuse != 0 || dhandle->session_ref != 0) { WT_RET(__wt_writeunlock(session, dhandle->rwlock)); continue; @@ -225,9 +229,14 @@ __sweep_remove_handles(WT_SESSION_IMPL *session) WT_WITH_DHANDLE(session, dhandle, ret = __wt_conn_dhandle_discard_single(session, 0, 1)); - /* If the handle was not successfully discarded, unlock it. */ - if (ret != 0) + /* + * If the handle was not successfully discarded, unlock it and + * don't retry the discard until it times out again. + */ + if (ret != 0) { + dhandle->timeofdiscard = now; WT_TRET(__wt_writeunlock(session, dhandle->rwlock)); + } WT_RET_BUSY_OK(ret); WT_STAT_FAST_CONN_INCR(session, dh_conn_ref); } @@ -245,7 +254,8 @@ __sweep_server(void *arg) WT_CONNECTION_IMPL *conn; WT_DECL_RET; WT_SESSION_IMPL *session; - int dead_handles; + time_t now; + u_int dead_handles; session = arg; conn = S2C(session); @@ -258,29 +268,34 @@ __sweep_server(void *arg) /* Wait until the next event. */ WT_ERR(__wt_cond_wait(session, conn->sweep_cond, (uint64_t)conn->sweep_interval * WT_MILLION)); + WT_ERR(__wt_seconds(session, &now)); /* * Mark handles with a time of death, and report whether any - * handles are marked dead. + * handles are marked dead. If sweep_idle_time is 0, handles + * never become idle. */ - WT_ERR(__sweep_mark(session, &dead_handles)); - - if (dead_handles == 0 && - conn->open_file_count < conn->sweep_handles_min) - continue; + if (conn->sweep_idle_time != 0) + WT_ERR(__sweep_mark(session, now)); - /* Close handles if we have reached the configured limit */ - if (conn->open_file_count >= conn->sweep_handles_min) { + /* + * Close handles if we have reached the configured limit. + * If sweep_idle_time is 0, handles never become idle. + */ + if (conn->sweep_idle_time != 0 && + conn->open_btree_count >= conn->sweep_handles_min) { WT_WITH_DHANDLE_LOCK(session, - ret = __sweep_expire(session)); + ret = __sweep_expire(session, now)); WT_ERR(ret); } - WT_ERR(__sweep_flush(session)); + WT_ERR(__sweep_discard_trees(session, now, &dead_handles)); - WT_WITH_DHANDLE_LOCK(session, - ret = __sweep_remove_handles(session)); - WT_ERR(ret); + if (dead_handles > 0) { + WT_WITH_DHANDLE_LOCK(session, + ret = __sweep_remove_handles(session, now)); + WT_ERR(ret); + } } if (0) { diff --git a/src/third_party/wiredtiger/src/include/dhandle.h b/src/third_party/wiredtiger/src/include/dhandle.h index 034db30a0a2..b188c19566b 100644 --- a/src/third_party/wiredtiger/src/include/dhandle.h +++ b/src/third_party/wiredtiger/src/include/dhandle.h @@ -45,6 +45,7 @@ struct __wt_data_handle { uint32_t session_ref; /* Sessions referencing this handle */ int32_t session_inuse; /* Sessions using this handle */ time_t timeofdeath; /* Use count went to 0 */ + time_t timeofdiscard; /* Time of last failed discard */ uint64_t name_hash; /* Hash of name */ const char *name; /* Object name as a URI */ diff --git a/src/third_party/wiredtiger/src/include/wiredtiger.in b/src/third_party/wiredtiger/src/include/wiredtiger.in index c28ce83d122..ddb738e8fb8 100644 --- a/src/third_party/wiredtiger/src/include/wiredtiger.in +++ b/src/third_party/wiredtiger/src/include/wiredtiger.in @@ -1619,8 +1619,9 @@ struct __wt_connection { * handles open before the file manager will look for handles to close., * a string; default \c 250.} * @config{ close_idle_time, amount of time in - * seconds a file handle needs to be idle before attempting to close - * it., an integer between 1 and 100000; default \c 30.} + * seconds a file handle needs to be idle before attempting to close it. + * A setting of 0 means that idle handles are not closed., an integer + * between 0 and 100000; default \c 30.} * @config{ close_scan_interval, interval in * seconds at which to check for files that are inactive and close * them., an integer between 1 and 100000; default \c 10.} @@ -1993,8 +1994,9 @@ struct __wt_connection { * before the file manager will look for handles to close., a string; default \c * 250.} * @config{ close_idle_time, amount of time in - * seconds a file handle needs to be idle before attempting to close it., an - * integer between 1 and 100000; default \c 30.} + * seconds a file handle needs to be idle before attempting to close it. A + * setting of 0 means that idle handles are not closed., an integer between 0 + * and 100000; default \c 30.} * @config{ close_scan_interval, interval in seconds at * which to check for files that are inactive and close them., an integer * between 1 and 100000; default \c 10.} |