diff options
Diffstat (limited to 'src/third_party/wiredtiger/src/evict/evict_lru.c')
-rw-r--r-- | src/third_party/wiredtiger/src/evict/evict_lru.c | 28 |
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; |