summaryrefslogtreecommitdiff
path: root/src/third_party/wiredtiger/src/evict/evict_lru.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/third_party/wiredtiger/src/evict/evict_lru.c')
-rw-r--r--src/third_party/wiredtiger/src/evict/evict_lru.c28
1 files changed, 24 insertions, 4 deletions
diff --git a/src/third_party/wiredtiger/src/evict/evict_lru.c b/src/third_party/wiredtiger/src/evict/evict_lru.c
index d134d7e504f..455e8c15bef 100644
--- a/src/third_party/wiredtiger/src/evict/evict_lru.c
+++ b/src/third_party/wiredtiger/src/evict/evict_lru.c
@@ -272,11 +272,24 @@ __wt_evict_thread_run(WT_SESSION_IMPL *session, WT_THREAD *thread)
WT_CACHE *cache;
WT_CONNECTION_IMPL *conn;
WT_DECL_RET;
+ uint32_t session_flags;
bool did_work, was_intr;
+ bool is_owner;
conn = S2C(session);
cache = conn->cache;
+ /*
+ * Cache a history store cursor to avoid deadlock: if an eviction thread thread marks a file
+ * busy and then opens a different file (in this case, the HS file), it can deadlock with a
+ * thread waiting for the first file to drain from the eviction queue. See WT-5946 for details.
+ */
+ if (!F_ISSET(conn, WT_CONN_IN_MEMORY)) {
+ session_flags = 0; /* [-Werror=maybe-uninitialized] */
+ WT_RET(__wt_hs_cursor(session, &session_flags, &is_owner));
+ WT_RET(__wt_hs_cursor_close(session, session_flags, is_owner));
+ }
+
if (conn->evict_server_running && __wt_spin_trylock(session, &cache->evict_pass_lock) == 0) {
/*
* Cannot use WT_WITH_PASS_LOCK because this is a try lock. Fix when that is supported. We
@@ -466,6 +479,13 @@ __wt_evict_create(WT_SESSION_IMPL *session)
conn = S2C(session);
+ /*
+ * In case recovery has allocated some transaction IDs, bump to the current state. This will
+ * prevent eviction threads from pinning anything as they start up and read metadata in order to
+ * open cursors.
+ */
+ WT_RET(__wt_txn_update_oldest(session, WT_TXN_OLDEST_STRICT | WT_TXN_OLDEST_WAIT));
+
WT_ASSERT(session, conn->evict_threads_min > 0);
/* Set first, the thread might run before we finish up. */
F_SET(conn, WT_CONN_EVICTION_RUN);
@@ -2265,7 +2285,7 @@ __wt_cache_eviction_worker(WT_SESSION_IMPL *session, bool busy, bool readonly, d
WT_DECL_RET;
WT_TRACK_OP_DECL;
WT_TXN_GLOBAL *txn_global;
- WT_TXN_STATE *txn_state;
+ WT_TXN_SHARED *txn_shared;
uint64_t elapsed, time_start, time_stop;
uint64_t initial_progress, max_progress;
bool app_thread;
@@ -2276,7 +2296,7 @@ __wt_cache_eviction_worker(WT_SESSION_IMPL *session, bool busy, bool readonly, d
cache = conn->cache;
time_start = time_stop = 0;
txn_global = &conn->txn_global;
- txn_state = WT_SESSION_TXN_STATE(session);
+ txn_shared = WT_SESSION_TXN_SHARED(session);
/*
* It is not safe to proceed if the eviction server threads aren't setup yet.
@@ -2303,7 +2323,7 @@ __wt_cache_eviction_worker(WT_SESSION_IMPL *session, bool busy, bool readonly, d
--cache->evict_aggressive_score;
WT_STAT_CONN_INCR(session, txn_fail_cache);
if (app_thread)
- WT_TRET(__wt_msg(session, "%s", session->txn.rollback_reason));
+ WT_TRET(__wt_msg(session, "%s", session->txn->rollback_reason));
}
WT_ERR(ret);
}
@@ -2316,7 +2336,7 @@ __wt_cache_eviction_worker(WT_SESSION_IMPL *session, bool busy, bool readonly, d
* below 100%, limit the work to 5 evictions and return. If that's not the case, we can do
* more.
*/
- if (!busy && txn_state->pinned_id != WT_TXN_NONE &&
+ if (!busy && txn_shared->pinned_id != WT_TXN_NONE &&
txn_global->current != txn_global->oldest_id)
busy = true;
max_progress = busy ? 5 : 20;