summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Pasette <dan@10gen.com>2015-08-10 11:34:16 -0400
committerDan Pasette <dan@mongodb.com>2015-08-10 11:34:16 -0400
commitb3c07dda3afe9cf30e7fb7942a44e8fa7ac5b0a6 (patch)
treeb944ac0c14ef84a1ca4e83684530c23a410d5bcc
parente8668374eeefc844167e9c5fa1981ace9c6d2b10 (diff)
downloadmongo-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.py3
-rw-r--r--src/third_party/wiredtiger/src/config/config_def.c2
-rw-r--r--src/third_party/wiredtiger/src/conn/conn_sweep.c133
-rw-r--r--src/third_party/wiredtiger/src/include/dhandle.h1
-rw-r--r--src/third_party/wiredtiger/src/include/wiredtiger.in10
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{&nbsp;&nbsp;&nbsp;&nbsp;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{&nbsp;&nbsp;&nbsp;&nbsp;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{&nbsp;&nbsp;&nbsp;&nbsp;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{&nbsp;&nbsp;&nbsp;&nbsp;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.}