ExportXMLWordPrintableJSON

    • Storage Engines - Transactions
    • 614.587
    • SE Transactions - 2026-11-06
    • 1

      eviction=(cache_tolerance_for_app_eviction=N) is documented as a tolerance on eviction_dirty_trigger and eviction_updates_trigger (dist/api_data.py:833-840). Between the trigger and trigger × (1 + N/100), application threads assist in eviction step by step (__evict_is_session_cache_trigger_tolerant, src/evict/evict_inline.h:768-851). The tolerance does not cover eviction_trigger. With the default incremental_app_eviction=false, the tolerance is never applied. Line numbers reference develop at 50c032ba6.

      Location of the check in __wt_evict_app_assist_worker_check (src/evict/evict_inline.h:871-1001):

      • :952-954 calls __wt_evict_needed(session, busy, readonly, true, &pct_full) and returns if it returns false.
      • :972-979 overwrites pct_full with the cache fill percentage from __wt_evict_clean_needed only when incremental_app_eviction=true and the eviction trigger is not exceeded.
      • :985-991 calls __evict_is_session_cache_trigger_tolerant only if pct_full <= evict->eviction_trigger. This is the only call to this function.

      Why the condition at :985 is false without incremental_app_eviction: _wt_evict_needed (:587-675) sets pct_full via _wti_evict_threshold_pct (:558-566, called at :662-665):

      pct_full = MAX(0, 100 - MIN(eviction_trigger - pct_clean,
                                  dirty_trigger - pct_dirty,
                                  updates_trigger - pct_updates))
      

      __wt_evict_needed returns clean_needed || updates_needed || (!busy && dirty_needed) (:674). When it returns true, at least one usage exceeds its trigger, so the minimum is negative and pct_full > 100. Because eviction_trigger cannot exceed 100 (src/evict/evict_conn.c:28-41, :76-79), pct_full <= eviction_trigger is always false. The disaggregated storage branch for followers and role changes (:635-654) sets pct_full = 100 - (eviction_trigger - pct_clean) and returns clean_needed, producing the same result. The test added by WT-18211 (test/catch2/misc_tests/test_evict_needed_pct_full.cpp) verifies this property of pct_full.

      History:
      WT-15563 (6db8dcb35, PR #12442) added the condition in its current form, with the same pct_full formula and the preceding incremental branch. WT-15690, WT-16612, and WT-18211 did not modify it. The same condition exists in mongodb-8.2 (src/evict/evict_inline.h:834) and mongodb-8.0 (src/include/cache_inline.h:683 at cd0025dd3). Because mongodb-8.0 lacks the incremental_app_eviction branch entirely, the tolerance has no effect there in any configuration.

      Affected users:
      Deployments configuring cache_tolerance_for_app_eviction to a non-zero value without incremental_app_eviction=true (for example through wiredTigerEngineRuntimeConfig or storage.wiredTiger.engineConfig.configString). The tolerance does nothing there, while the cache: cache tolerance configured statistic (WT-16453) reports it as set. WT-16453 notes Atlas clusters running with a non-zero tolerance. mongod does not set either option by default.

      Proposed fix

      Check the eviction trigger directly, and only when the tolerance is non-zero:

      uint8_t cache_tolerance = __wt_atomic_load_uint8_relaxed(
        &conn->cache->cache_eviction_controls.cache_tolerance_for_app_eviction);
      if (cache_tolerance != 0 && !__wt_evict_clean_needed(session, NULL) &&
        __evict_is_session_cache_trigger_tolerant(session, cache_tolerance))
          return (0);
      

      With incremental_app_eviction=true, this matches current behavior (cache fill percentage within the eviction trigger). When N=0, it avoids calling __wt_evict_clean_needed. Comparing pct_full with 100 + N instead would mix units (percent of cache versus percent of a trigger) and would allow the tolerance to apply above eviction_trigger.

      Test

      test/suite/test_cache_tolerance01.py: an uncommitted transaction holds about 22% of a 200MB cache dirty with eviction_dirty_trigger=20. A read-committed reader with cache_max_wait_ms=500 searches another file, and application_cache_ops shows whether it was pulled into eviction. Scenarios:

      • N=0: reader assists.
      • N=100: reader does not assist (fails on develop, passes with the fix).
      • N=100 with eviction_trigger=20: reader assists (fails if the eviction trigger check is omitted from the fix).

      Separate observations, not part of this ticket:

      • busy && pct_full < 100.0 at src/evict/evict_inline.h:960 is unreachable for the same reason.
      • WT_CONNECTION::reconfigure does not clear incremental_app_eviction, prefer_scrub_eviction, and skip_update_obsolete_check once set (src/evict/evict_conn.c:286-292, :306-308).
      • search and search_near in autocommit with cache_max_wait_ms retry WT_ROLLBACK in API_RETRYABLE without waiting (src/cursor/cur_file.c:314).

      Pull request: https://github.com/wiredtiger/wiredtiger/pull/14942

        1. WT-18905-tests.zip
          19 kB
        2. WT-18905-tests-and-measurements.zip
          19 kB

            Assignee:
            Vamsi Boyapati
            Reporter:
            Mikhail Sotnikov (EXT)
            Votes:
            0 Vote for this issue
            Watchers:
            1 Start watching this issue

              Created:
              Updated:
              Resolved: