summaryrefslogtreecommitdiff
path: root/src/third_party/wiredtiger/src/session/session_api.c
diff options
context:
space:
mode:
authorWill Korteland <will.korteland@mongodb.com>2022-12-12 05:33:05 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-12-12 06:01:19 +0000
commitd2e027eca79453824b5f62c9036924a48fd13952 (patch)
treead6b5ef01a258b11201d1294c7a85cf91118f971 /src/third_party/wiredtiger/src/session/session_api.c
parentd5589eb5ff27c5dd735d69b0e2c7c88c903520f4 (diff)
downloadmongo-d2e027eca79453824b5f62c9036924a48fd13952.tar.gz
Import wiredtiger: 8447470b5842a18026fc08dd76625b57063cffa8 from branch mongodb-master
ref: 03eab5f7ff..8447470b58 for: 6.3.0-rc0 WT-10253 Make sure session dhandle sweep and session cursor sweeps keep up
Diffstat (limited to 'src/third_party/wiredtiger/src/session/session_api.c')
-rw-r--r--src/third_party/wiredtiger/src/session/session_api.c58
1 files changed, 44 insertions, 14 deletions
diff --git a/src/third_party/wiredtiger/src/session/session_api.c b/src/third_party/wiredtiger/src/session/session_api.c
index 574101c266f..b498fc5146e 100644
--- a/src/third_party/wiredtiger/src/session/session_api.c
+++ b/src/third_party/wiredtiger/src/session/session_api.c
@@ -52,43 +52,70 @@ __wt_session_reset_cursors(WT_SESSION_IMPL *session, bool free_buffers)
* Sweep the cursor cache.
*/
int
-__wt_session_cursor_cache_sweep(WT_SESSION_IMPL *session)
+__wt_session_cursor_cache_sweep(WT_SESSION_IMPL *session, bool big_sweep)
{
+ WT_CONNECTION_IMPL *conn;
WT_CURSOR *cursor, *cursor_tmp;
WT_CURSOR_LIST *cached_list;
WT_DECL_RET;
#ifdef HAVE_DIAGNOSTIC
WT_DATA_HANDLE *saved_dhandle;
#endif
- uint64_t now;
- uint32_t position;
- int i, t_ret, nbuckets, nexamined, nclosed;
+ uint64_t now, sweep_max, sweep_min;
+ uint32_t i, nbuckets, nclosed, nexamined, position;
+ int t_ret;
bool productive;
if (!F_ISSET(session, WT_SESSION_CACHE_CURSORS))
return (0);
+ conn = S2C(session);
+
/*
* Periodically sweep for dead cursors; if we've swept recently, don't do it again.
+ *
+ * Each call of this sweep function visits all the cursors in some number of buckets used by the
+ * cursor cache. If any of the visited cursors reference dead or dying data handles those
+ * cursors are fully closed and removed from the cache. Removing a cursor from the cursor cache
+ * has the important effect of freeing a reference to the associated data handle. Data handles
+ * can be closed and marked dead, but cannot be freed until all referencing sessions give up
+ * their references. So sweeping the cursor cache (for all sessions!) is a prerequisite for the
+ * connection data handle sweep to find handles that can be freed.
+ *
+ * We determine the number of buckets to visit based on how this function is called. When
+ * big_sweep is true and enough time has passed, walk through at least a quarter of the buckets,
+ * and as long as there is progress finding enough cursors to close, continue on, up to the
+ * entire set of buckets.
+ *
+ * When big_sweep is false, we start with a small set of buckets to look at and quit when we
+ * stop making progress or when we reach the maximum configured. This way, we amortize the work
+ * of the sweep over many calls in a performance path.
*/
__wt_seconds(session, &now);
- if (now - session->last_cursor_sweep < 1)
+ if (big_sweep && now - session->last_cursor_big_sweep >= 30) {
+ session->last_cursor_big_sweep = session->last_cursor_sweep = now;
+ sweep_min = conn->hash_size / 4;
+ sweep_max = conn->hash_size;
+ } else if (now - session->last_cursor_sweep >= 1) {
+ session->last_cursor_sweep = now;
+ sweep_min = WT_SESSION_CURSOR_SWEEP_MIN;
+ sweep_max = WT_SESSION_CURSOR_SWEEP_MAX;
+ } else
return (0);
- session->last_cursor_sweep = now;
position = session->cursor_sweep_position;
productive = true;
- nbuckets = nexamined = nclosed = 0;
+ nbuckets = nclosed = nexamined = 0;
#ifdef HAVE_DIAGNOSTIC
saved_dhandle = session->dhandle;
#endif
/* Turn off caching so that cursor close doesn't try to cache. */
F_CLR(session, WT_SESSION_CACHE_CURSORS);
- for (i = 0; i < WT_SESSION_CURSOR_SWEEP_MAX && productive; i++) {
+ for (i = 0; i < sweep_max && productive; i++) {
++nbuckets;
cached_list = &session->cursor_cache[position];
- position = (position + 1) & (S2C(session)->hash_size - 1);
+ position = (position + 1) & (conn->hash_size - 1);
TAILQ_FOREACH_SAFE(cursor, cached_list, q, cursor_tmp)
{
/*
@@ -108,7 +135,7 @@ __wt_session_cursor_cache_sweep(WT_SESSION_IMPL *session)
* We continue sweeping as long as we have some good average productivity, or we are under
* the minimum.
*/
- productive = (nclosed + WT_SESSION_CURSOR_SWEEP_MIN > i);
+ productive = (nclosed + sweep_min > i);
}
session->cursor_sweep_position = position;
@@ -1128,10 +1155,13 @@ __session_reset(WT_SESSION *wt_session)
WT_TRET(__wt_session_reset_cursors(session, true));
- if (--session->cursor_sweep_countdown == 0) {
- session->cursor_sweep_countdown = WT_SESSION_CURSOR_SWEEP_COUNTDOWN;
- WT_TRET(__wt_session_cursor_cache_sweep(session));
- }
+ /*
+ * Run the session sweeps. Run the cursor cache sweep with "big" option to sweep more, as we're
+ * not in a performance path.
+ */
+ session->cursor_sweep_countdown = WT_SESSION_CURSOR_SWEEP_COUNTDOWN;
+ WT_TRET(__wt_session_cursor_cache_sweep(session, true));
+ __wt_session_dhandle_sweep(session);
/* Release common session resources. */
WT_TRET(__wt_session_release_resources(session));