diff options
Diffstat (limited to 'src/third_party/wiredtiger/src')
-rw-r--r-- | src/third_party/wiredtiger/src/btree/bt_compact.c | 56 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/btree/bt_walk.c | 25 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/conn/conn_api.c | 8 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/evict/evict_lru.c | 148 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/include/btree.i | 2 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/include/cache.h | 4 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/include/cache.i | 94 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/include/thread_group.h | 15 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/support/hazard.c | 5 | ||||
-rw-r--r-- | src/third_party/wiredtiger/src/txn/txn_ckpt.c | 3 |
10 files changed, 224 insertions, 136 deletions
diff --git a/src/third_party/wiredtiger/src/btree/bt_compact.c b/src/third_party/wiredtiger/src/btree/bt_compact.c index 7ba45f29b76..e005674762d 100644 --- a/src/third_party/wiredtiger/src/btree/bt_compact.c +++ b/src/third_party/wiredtiger/src/btree/bt_compact.c @@ -171,30 +171,64 @@ int __wt_compact_page_skip(WT_SESSION_IMPL *session, WT_REF *ref, bool *skipp) { WT_BM *bm; + WT_DECL_RET; size_t addr_size; u_int type; const uint8_t *addr; - *skipp = false; /* Default to reading. */ - type = 0; /* Keep compiler quiet. */ + /* + * Skip deleted pages, rewriting them doesn't seem useful; in a better + * world we'd write the parent to delete the page. + */ + if (ref->state == WT_REF_DELETED) { + *skipp = true; + return (0); + } - bm = S2BT(session)->bm; + *skipp = false; /* Default to reading */ /* - * We aren't holding a hazard pointer, so we can't look at the page - * itself, all we can look at is the WT_REF information. If there's no - * address, the page isn't on disk, but we have to read internal pages - * to walk the tree regardless; throw up our hands and read it. + * If the page is in-memory, we want to look at it (it may have been + * modified and written, and the current location is the interesting + * one in terms of compaction, not the original location). + * + * This test could be combined with the next one, but this is a cheap + * test and the next one is expensive. */ - __wt_ref_info(ref, &addr, &addr_size, &type); - if (addr == NULL) + if (ref->state != WT_REF_DISK) + return (0); + + /* + * There's nothing to prevent the WT_REF state from changing underfoot, + * which can change its address. For example, the WT_REF address might + * reference an on-page cell, and page eviction can free that memory. + * Lock the WT_REF so we can look at its address. + */ + if (!__wt_atomic_casv32(&ref->state, WT_REF_DISK, WT_REF_LOCKED)) return (0); /* + * The page is on disk, so there had better be an address; assert that + * fact, test at run-time to avoid the core dump. + * * Internal pages must be read to walk the tree; ask the block-manager * if it's useful to rewrite leaf pages, don't do the I/O if a rewrite * won't help. */ - return (type == WT_CELL_ADDR_INT ? 0 : - bm->compact_page_skip(bm, session, addr, addr_size, skipp)); + __wt_ref_info(ref, &addr, &addr_size, &type); + WT_ASSERT(session, addr != NULL); + if (addr != NULL && type != WT_CELL_ADDR_INT) { + bm = S2BT(session)->bm; + ret = bm->compact_page_skip( + bm, session, addr, addr_size, skipp); + } + + /* + * Reset the WT_REF state and push the change. The full-barrier isn't + * necessary, but it's better to keep pages in circulation than not. + */ + ref->state = WT_REF_DISK; + WT_FULL_BARRIER(); + + return (ret); } diff --git a/src/third_party/wiredtiger/src/btree/bt_walk.c b/src/third_party/wiredtiger/src/btree/bt_walk.c index dc1cf4e7f98..fb0d2296823 100644 --- a/src/third_party/wiredtiger/src/btree/bt_walk.c +++ b/src/third_party/wiredtiger/src/btree/bt_walk.c @@ -472,27 +472,14 @@ restart: /* empty_internal = false; } else if (LF_ISSET(WT_READ_COMPACT)) { /* - * Skip deleted pages, rewriting them doesn't - * seem useful. + * Compaction has relatively complex tests to + * decide if a page can be skipped, call out + * to a helper function. */ - if (ref->state == WT_REF_DELETED) + WT_ERR(__wt_compact_page_skip( + session, ref, &skip)); + if (skip) break; - - /* - * If the page is in-memory, we want to look at - * it (it may have been modified and written, - * and the current location is the interesting - * one in terms of compaction, not the original - * location). If the page isn't in-memory, test - * if the page will help with compaction, don't - * read it if we don't have to. - */ - if (ref->state == WT_REF_DISK) { - WT_ERR(__wt_compact_page_skip( - session, ref, &skip)); - if (skip) - break; - } } else { /* * Try to skip deleted pages visible to us. diff --git a/src/third_party/wiredtiger/src/conn/conn_api.c b/src/third_party/wiredtiger/src/conn/conn_api.c index faec72a4ac0..0951fd4e58c 100644 --- a/src/third_party/wiredtiger/src/conn/conn_api.c +++ b/src/third_party/wiredtiger/src/conn/conn_api.c @@ -1055,13 +1055,16 @@ __conn_reconfigure(WT_CONNECTION *wt_conn, const char *config) WT_DECL_RET; WT_SESSION_IMPL *session; const char *p; + bool locked; conn = (WT_CONNECTION_IMPL *)wt_conn; + locked = false; CONNECTION_API_CALL(conn, session, reconfigure, config, cfg); /* Serialize reconfiguration. */ __wt_spin_lock(session, &conn->reconfig_lock); + locked = true; /* * The configuration argument has been checked for validity, update the @@ -1096,7 +1099,8 @@ __conn_reconfigure(WT_CONNECTION *wt_conn, const char *config) __wt_free(session, conn->cfg); conn->cfg = p; -err: __wt_spin_unlock(session, &conn->reconfig_lock); +err: if (locked) + __wt_spin_unlock(session, &conn->reconfig_lock); API_END_RET(session, ret); } @@ -1117,11 +1121,11 @@ __conn_open_session(WT_CONNECTION *wt_conn, *wt_sessionp = NULL; conn = (WT_CONNECTION_IMPL *)wt_conn; - session_ret = NULL; CONNECTION_API_CALL(conn, session, open_session, config, cfg); WT_UNUSED(cfg); + session_ret = NULL; WT_ERR(__wt_open_session( conn, event_handler, config, true, &session_ret)); *wt_sessionp = &session_ret->iface; diff --git a/src/third_party/wiredtiger/src/evict/evict_lru.c b/src/third_party/wiredtiger/src/evict/evict_lru.c index 35c057c9767..acc81f566a5 100644 --- a/src/third_party/wiredtiger/src/evict/evict_lru.c +++ b/src/third_party/wiredtiger/src/evict/evict_lru.c @@ -152,12 +152,24 @@ __wt_evict_list_clear_page(WT_SESSION_IMPL *session, WT_REF *ref) /* * __evict_queue_empty -- * Is the queue empty? + * + * Note that the eviction server is pessimistic and treats a half full + * queue as empty. */ static inline bool -__evict_queue_empty(WT_EVICT_QUEUE *queue) +__evict_queue_empty(WT_EVICT_QUEUE *queue, bool server_check) { - return (queue->evict_current == NULL || - queue->evict_candidates == 0); + uint32_t candidates, used; + + if (queue->evict_current == NULL) + return (true); + + /* The eviction server only considers half of the candidates. */ + candidates = queue->evict_candidates; + if (server_check && candidates > 1) + candidates /= 2; + used = (uint32_t)(queue->evict_current - queue->evict_queue); + return (used >= candidates); } /* @@ -431,7 +443,6 @@ __evict_update_work(WT_SESSION_IMPL *session) { WT_CACHE *cache; WT_CONNECTION_IMPL *conn; - double dirty_trigger; uint64_t bytes_inuse, bytes_max, dirty_inuse; conn = S2C(session); @@ -443,7 +454,7 @@ __evict_update_work(WT_SESSION_IMPL *session) if (!F_ISSET(conn, WT_CONN_EVICTION_RUN)) return (false); - if (!__evict_queue_empty(cache->evict_urgent_queue)) + if (!__evict_queue_empty(cache->evict_urgent_queue, false)) F_SET(cache, WT_CACHE_EVICT_URGENT); /* @@ -456,16 +467,14 @@ __evict_update_work(WT_SESSION_IMPL *session) bytes_inuse = __wt_cache_bytes_inuse(cache); if (bytes_inuse > (cache->eviction_target * bytes_max) / 100) F_SET(cache, WT_CACHE_EVICT_CLEAN); - if (bytes_inuse > (cache->eviction_trigger * bytes_max) / 100) - F_SET(cache, WT_CACHE_EVICT_CLEAN_HARD); + if (__wt_eviction_clean_needed(session, NULL)) + F_SET(cache, WT_CACHE_EVICT_CLEAN | WT_CACHE_EVICT_CLEAN_HARD); dirty_inuse = __wt_cache_dirty_leaf_inuse(cache); if (dirty_inuse > (cache->eviction_dirty_target * bytes_max) / 100) F_SET(cache, WT_CACHE_EVICT_DIRTY); - if ((dirty_trigger = cache->eviction_scrub_limit) < 1.0) - dirty_trigger = (double)cache->eviction_dirty_trigger; - if (dirty_inuse > (uint64_t)(dirty_trigger * bytes_max) / 100) - F_SET(cache, WT_CACHE_EVICT_DIRTY_HARD); + if (__wt_eviction_dirty_needed(session, NULL)) + F_SET(cache, WT_CACHE_EVICT_DIRTY | WT_CACHE_EVICT_DIRTY_HARD); /* * If application threads are blocked by the total volume of data in @@ -497,6 +506,12 @@ __evict_update_work(WT_SESSION_IMPL *session) F_CLR(cache, WT_CACHE_EVICT_CLEAN | WT_CACHE_EVICT_CLEAN_HARD); } + /* If threads are blocked by eviction we should be looking for pages. */ + WT_ASSERT(session, !F_ISSET(cache, WT_CACHE_EVICT_CLEAN_HARD) || + F_ISSET(cache, WT_CACHE_EVICT_CLEAN)); + WT_ASSERT(session, !F_ISSET(cache, WT_CACHE_EVICT_DIRTY_HARD) || + F_ISSET(cache, WT_CACHE_EVICT_DIRTY)); + WT_STAT_CONN_SET(session, cache_eviction_state, F_MASK(cache, WT_CACHE_EVICT_MASK)); @@ -585,7 +600,7 @@ __evict_pass(WT_SESSION_IMPL *session) */ if (cache->evict_empty_score < WT_EVICT_SCORE_CUTOFF || (!WT_EVICT_HAS_WORKERS(session) && - !__evict_queue_empty(cache->evict_urgent_queue))) + !__evict_queue_empty(cache->evict_urgent_queue, false))) WT_RET(__evict_lru_pages(session, true)); if (cache->pass_intr != 0) @@ -921,7 +936,7 @@ __evict_lru_walk(WT_SESSION_IMPL *session) * If the queue we are filling is empty, pages are being requested * faster than they are being queued. */ - if (__evict_queue_empty(queue)) { + if (__evict_queue_empty(queue, false)) { if (F_ISSET(cache, WT_CACHE_EVICT_CLEAN_HARD | WT_CACHE_EVICT_DIRTY_HARD)) { cache->evict_empty_score = WT_MIN( @@ -1530,7 +1545,7 @@ __evict_get_ref( WT_CACHE *cache; WT_DECL_RET; WT_EVICT_ENTRY *evict; - WT_EVICT_QUEUE *other_queue, *queue, *urgent_queue; + WT_EVICT_QUEUE *queue, *other_queue, *urgent_queue; uint32_t candidates; bool is_app, urgent_ok; @@ -1546,9 +1561,9 @@ __evict_get_ref( WT_STAT_CONN_INCR(session, cache_eviction_get_ref); /* Avoid the LRU lock if no pages are available. */ - if (__evict_queue_empty(cache->evict_current_queue) && - __evict_queue_empty(cache->evict_other_queue) && - __evict_queue_empty(urgent_queue)) { + if (__evict_queue_empty(cache->evict_current_queue, is_server) && + __evict_queue_empty(cache->evict_other_queue, is_server) && + (!urgent_ok || __evict_queue_empty(urgent_queue, false))) { WT_STAT_CONN_INCR(session, cache_eviction_get_ref_empty); return (WT_NOTFOUND); } @@ -1562,54 +1577,51 @@ __evict_get_ref( * Such cases are extremely rare in real applications. */ if (is_server && - (cache->evict_empty_score > WT_EVICT_SCORE_CUTOFF || - __evict_queue_empty(cache->evict_fill_queue))) { - do { + (cache->evict_empty_score > WT_EVICT_SCORE_CUTOFF || + __evict_queue_empty(cache->evict_fill_queue, false))) { + while ((ret = __wt_spin_trylock( + session, &cache->evict_queue_lock)) == EBUSY) if ((!urgent_ok || - __evict_queue_empty(urgent_queue)) && + __evict_queue_empty(urgent_queue, false)) && !__evict_queue_full(cache->evict_fill_queue)) return (WT_NOTFOUND); - } while ((ret = __wt_spin_trylock( - session, &cache->evict_queue_lock)) == EBUSY); WT_RET(ret); } else __wt_spin_lock(session, &cache->evict_queue_lock); - /* - * Check if the current queue needs to change. - * The current queue could have changed while we waited for the lock. - */ - queue = cache->evict_current_queue; - other_queue = cache->evict_other_queue; - if (__evict_queue_empty(queue) && !__evict_queue_empty(other_queue)) { - cache->evict_current_queue = other_queue; - cache->evict_other_queue = queue; - } - /* Check the urgent queue first. */ - queue = urgent_ok && !__evict_queue_empty(urgent_queue) ? - urgent_queue : cache->evict_current_queue; + if (urgent_ok && !__evict_queue_empty(urgent_queue, false)) + queue = urgent_queue; + else { + /* + * Check if the current queue needs to change. + * The current queue could have changed while we waited for + * the lock. + * + * The server will only evict half of the pages before looking + * for more. The remainder are left to eviction workers (if any + * configured), or application threads if necessary. + */ + queue = cache->evict_current_queue; + other_queue = cache->evict_other_queue; + if (__evict_queue_empty(queue, is_server) && + !__evict_queue_empty(other_queue, is_server)) { + cache->evict_current_queue = other_queue; + cache->evict_other_queue = queue; + } + } __wt_spin_unlock(session, &cache->evict_queue_lock); /* - * Only evict half of the pages before looking for more. The remainder - * are left to eviction workers (if configured), or application threads - * if necessary. - */ - candidates = queue->evict_candidates; - if (is_server && queue != urgent_queue && candidates > 1) - candidates /= 2; - - /* * We got the queue lock, which should be fast, and chose a queue. * Now we want to get the lock on the individual queue. */ for (;;) { /* Verify there are still pages available. */ - if (__evict_queue_empty(queue) || (uint32_t) - (queue->evict_current - queue->evict_queue) >= candidates) { + if (__evict_queue_empty( + queue, is_server && queue != urgent_queue)) { WT_STAT_CONN_INCR( session, cache_eviction_get_ref_empty2); return (WT_NOTFOUND); @@ -1621,6 +1633,15 @@ __evict_get_ref( break; } + /* + * Only evict half of the pages before looking for more. The remainder + * are left to eviction workers (if configured), or application thread + * if necessary. + */ + candidates = queue->evict_candidates; + if (is_server && queue != urgent_queue && candidates > 1) + candidates /= 2; + /* Get the next page queued for eviction. */ for (evict = queue->evict_current; evict >= queue->evict_queue && @@ -1676,8 +1697,8 @@ __evict_get_ref( } /* Move to the next item. */ - if (evict != NULL && evict + 1 < - queue->evict_queue + queue->evict_candidates) + if (evict != NULL && + evict + 1 < queue->evict_queue + queue->evict_candidates) queue->evict_current = evict + 1; else /* Clear the current pointer if there are no more candidates. */ queue->evict_current = NULL; @@ -1771,22 +1792,9 @@ __wt_cache_eviction_worker(WT_SESSION_IMPL *session, bool busy, u_int pct_full) /* Wake the eviction server if we need to do work. */ __wt_evict_server_wake(session); - /* - * If we're busy, either because of the transaction check we just did, - * or because our caller is waiting on a longer-than-usual event (such - * as a page read), limit the work to a single eviction and return. If - * that's not the case, we can do more. - */ init_evict_count = cache->pages_evict; for (;;) { - /* Check if we have become busy. */ - if (!busy && txn_state->snap_min != WT_TXN_NONE && - txn_global->current != txn_global->oldest_id) - busy = true; - - max_pages_evicted = busy ? 5 : 20; - /* * A pathological case: if we're the oldest transaction in the * system and the eviction server is stuck trying to find space, @@ -1799,6 +1807,20 @@ __wt_cache_eviction_worker(WT_SESSION_IMPL *session, bool busy, u_int pct_full) return (WT_ROLLBACK); } + /* + * Check if we have become busy. + * + * If we're busy (because of the transaction check we just did + * or because our caller is waiting on a longer-than-usual event + * such as a page read), and the cache level drops below 100%, + * limit the work to 5 evictions and return. If that's not the + * case, we can do more. + */ + if (!busy && txn_state->snap_min != WT_TXN_NONE && + txn_global->current != txn_global->oldest_id) + busy = true; + max_pages_evicted = busy ? 5 : 20; + /* See if eviction is still needed. */ if (!__wt_eviction_needed(session, busy, &pct_full) || (pct_full < 100 && @@ -1869,7 +1891,7 @@ __wt_page_evict_urgent(WT_SESSION_IMPL *session, WT_REF *ref) goto done; __wt_spin_lock(session, &urgent_queue->evict_lock); - if (__evict_queue_empty(urgent_queue)) { + if (__evict_queue_empty(urgent_queue, false)) { urgent_queue->evict_current = urgent_queue->evict_queue; urgent_queue->evict_candidates = 0; } diff --git a/src/third_party/wiredtiger/src/include/btree.i b/src/third_party/wiredtiger/src/include/btree.i index 6e32c1bc195..a9ce4f754a9 100644 --- a/src/third_party/wiredtiger/src/include/btree.i +++ b/src/third_party/wiredtiger/src/include/btree.i @@ -406,7 +406,7 @@ __wt_cache_page_evict(WT_SESSION_IMPL *session, WT_PAGE *page) /* Update pages and bytes evicted. */ (void)__wt_atomic_add64(&cache->bytes_evict, page->memory_footprint); - (void)__wt_atomic_add64(&cache->pages_evict, 1); + (void)__wt_atomic_addv64(&cache->pages_evict, 1); } /* diff --git a/src/third_party/wiredtiger/src/include/cache.h b/src/third_party/wiredtiger/src/include/cache.h index 515135f26ab..b24b625aec4 100644 --- a/src/third_party/wiredtiger/src/include/cache.h +++ b/src/third_party/wiredtiger/src/include/cache.h @@ -66,7 +66,7 @@ struct __wt_cache { uint64_t bytes_dirty_leaf; uint64_t pages_dirty_leaf; uint64_t bytes_evict; /* Bytes/pages discarded by eviction */ - uint64_t pages_evict; + volatile uint64_t pages_evict; uint64_t pages_evicted; /* Pages evicted during a pass */ uint64_t bytes_image; /* Bytes of disk images */ uint64_t bytes_inmem; /* Bytes/pages in memory */ @@ -175,7 +175,7 @@ struct __wt_cache { #define WT_CACHE_EVICT_CLEAN_HARD 0x002 /* Clean % blocking app threads */ #define WT_CACHE_EVICT_DIRTY 0x004 /* Evict dirty pages */ #define WT_CACHE_EVICT_DIRTY_HARD 0x008 /* Dirty % blocking app threads */ -#define WT_CACHE_EVICT_SCRUB 0x010 /* Scrub dirty pages pages */ +#define WT_CACHE_EVICT_SCRUB 0x010 /* Scrub dirty pages */ #define WT_CACHE_EVICT_URGENT 0x020 /* Pages are in the urgent queue */ #define WT_CACHE_EVICT_ALL (WT_CACHE_EVICT_CLEAN | WT_CACHE_EVICT_DIRTY) #define WT_CACHE_EVICT_MASK 0x0FF diff --git a/src/third_party/wiredtiger/src/include/cache.i b/src/third_party/wiredtiger/src/include/cache.i index b5605769f1a..4255d04ec37 100644 --- a/src/third_party/wiredtiger/src/include/cache.i +++ b/src/third_party/wiredtiger/src/include/cache.i @@ -193,7 +193,7 @@ __wt_cache_bytes_other(WT_CACHE *cache) * __wt_session_can_wait -- * Return if a session available for a potentially slow operation. */ -static inline int +static inline bool __wt_session_can_wait(WT_SESSION_IMPL *session) { /* @@ -202,17 +202,71 @@ __wt_session_can_wait(WT_SESSION_IMPL *session) * the system cache. */ if (!F_ISSET(session, WT_SESSION_CAN_WAIT)) - return (0); + return (false); /* * LSM sets the no-eviction flag when holding the LSM tree lock, in that * case, or when holding the schema lock, we don't want to highjack the * thread for eviction. */ - if (F_ISSET(session, WT_SESSION_NO_EVICTION | WT_SESSION_LOCKED_SCHEMA)) - return (0); + return (!F_ISSET( + session, WT_SESSION_NO_EVICTION | WT_SESSION_LOCKED_SCHEMA)); +} + +/* + * __wt_eviction_clean_needed -- + * Return if an application thread should do eviction due to the total + * volume of dirty data in cache. + */ +static inline bool +__wt_eviction_clean_needed(WT_SESSION_IMPL *session, u_int *pct_fullp) +{ + WT_CACHE *cache; + uint64_t bytes_inuse, bytes_max; + + cache = S2C(session)->cache; + + /* + * Avoid division by zero if the cache size has not yet been set in a + * shared cache. + */ + bytes_max = S2C(session)->cache_size + 1; + bytes_inuse = __wt_cache_bytes_inuse(cache); + + if (pct_fullp != NULL) + *pct_fullp = (u_int)((100 * bytes_inuse) / bytes_max); + + return (bytes_inuse > (cache->eviction_trigger * bytes_max) / 100); +} + +/* + * __wt_eviction_dirty_needed -- + * Return if an application thread should do eviction due to the total + * volume of dirty data in cache. + */ +static inline bool +__wt_eviction_dirty_needed(WT_SESSION_IMPL *session, u_int *pct_fullp) +{ + WT_CACHE *cache; + double dirty_trigger; + uint64_t dirty_inuse, bytes_max; + + cache = S2C(session)->cache; + + /* + * Avoid division by zero if the cache size has not yet been set in a + * shared cache. + */ + bytes_max = S2C(session)->cache_size + 1; + dirty_inuse = __wt_cache_dirty_leaf_inuse(cache); + + if (pct_fullp != NULL) + *pct_fullp = (u_int)((100 * dirty_inuse) / bytes_max); + + if ((dirty_trigger = cache->eviction_scrub_limit) < 1.0) + dirty_trigger = (double)cache->eviction_dirty_trigger; - return (1); + return (dirty_inuse > (uint64_t)(dirty_trigger * bytes_max) / 100); } /* @@ -223,42 +277,30 @@ __wt_session_can_wait(WT_SESSION_IMPL *session) static inline bool __wt_eviction_needed(WT_SESSION_IMPL *session, bool busy, u_int *pct_fullp) { - WT_CONNECTION_IMPL *conn; WT_CACHE *cache; - double dirty_trigger; - uint64_t bytes_inuse, bytes_max, dirty_inuse; u_int pct_dirty, pct_full; + bool clean_needed, dirty_needed; - conn = S2C(session); - cache = conn->cache; + cache = S2C(session)->cache; /* * If the connection is closing we do not need eviction from an * application thread. The eviction subsystem is already closed. */ - if (F_ISSET(conn, WT_CONN_CLOSING)) + if (F_ISSET(S2C(session), WT_CONN_CLOSING)) return (false); - /* - * Avoid division by zero if the cache size has not yet been set in a - * shared cache. - */ - bytes_max = conn->cache_size + 1; - bytes_inuse = __wt_cache_bytes_inuse(cache); - dirty_inuse = __wt_cache_dirty_leaf_inuse(cache); + clean_needed = __wt_eviction_clean_needed(session, &pct_full); + dirty_needed = __wt_eviction_dirty_needed(session, &pct_dirty); /* * Calculate the cache full percentage; anything over the trigger means * we involve the application thread. */ - if (pct_fullp != NULL) { - pct_full = (u_int)((100 * bytes_inuse) / bytes_max); - pct_dirty = (u_int)((100 * dirty_inuse) / bytes_max); - + if (pct_fullp != NULL) *pct_fullp = (u_int)WT_MAX(0, 100 - WT_MIN( (int)cache->eviction_trigger - (int)pct_full, (int)cache->eviction_dirty_trigger - (int)pct_dirty)); - } /* * Only check the dirty trigger when the session is not busy. @@ -268,11 +310,7 @@ __wt_eviction_needed(WT_SESSION_IMPL *session, bool busy, u_int *pct_fullp) * The next transaction in this session will not be able to start until * the cache is under the limit. */ - if ((dirty_trigger = cache->eviction_scrub_limit) < 1.0) - dirty_trigger = (double)cache->eviction_dirty_trigger; - return (bytes_inuse > (cache->eviction_trigger * bytes_max) / 100 || - (!busy && - dirty_inuse > (uint64_t)(dirty_trigger * bytes_max) / 100)); + return (clean_needed || (!busy && dirty_needed)); } /* diff --git a/src/third_party/wiredtiger/src/include/thread_group.h b/src/third_party/wiredtiger/src/include/thread_group.h index f946dcab144..76758a090c4 100644 --- a/src/third_party/wiredtiger/src/include/thread_group.h +++ b/src/third_party/wiredtiger/src/include/thread_group.h @@ -14,7 +14,14 @@ struct __wt_thread { WT_SESSION_IMPL *session; u_int id; wt_thread_t tid; -#define WT_THREAD_RUN 0x01 + + /* + * WT_THREAD and thread-group function flags, merged because + * WT_THREAD_PANIC_FAIL appears in both groups. + */ +#define WT_THREAD_CAN_WAIT 0x01 /* WT_SESSION_CAN_WAIT */ +#define WT_THREAD_PANIC_FAIL 0x02 /* panic if the thread fails */ +#define WT_THREAD_RUN 0x04 /* thread is running */ uint32_t flags; /* The runner function used by all threads. */ @@ -22,12 +29,6 @@ struct __wt_thread { }; /* - * Flags for thread group functions. - */ -#define WT_THREAD_CAN_WAIT 0x01 -#define WT_THREAD_PANIC_FAIL 0x02 - -/* * WT_THREAD_GROUP -- * Encapsulation of a group of utility threads. */ diff --git a/src/third_party/wiredtiger/src/support/hazard.c b/src/third_party/wiredtiger/src/support/hazard.c index 8ac8f5f9f6d..46b63ac6129 100644 --- a/src/third_party/wiredtiger/src/support/hazard.c +++ b/src/third_party/wiredtiger/src/support/hazard.c @@ -166,9 +166,10 @@ __wt_hazard_clear(WT_SESSION_IMPL *session, WT_PAGE *page) /* * If this was the last hazard pointer in the session, - * we may need to update our transactional context. + * reset the size so that checks can skip this session. */ - --session->nhazard; + if (--session->nhazard == 0) + WT_PUBLISH(session->hazard_size, 0); return (0); } diff --git a/src/third_party/wiredtiger/src/txn/txn_ckpt.c b/src/third_party/wiredtiger/src/txn/txn_ckpt.c index 180a06a3aed..3aad95f5a9f 100644 --- a/src/third_party/wiredtiger/src/txn/txn_ckpt.c +++ b/src/third_party/wiredtiger/src/txn/txn_ckpt.c @@ -423,7 +423,8 @@ __checkpoint_reduce_dirty_cache(WT_SESSION_IMPL *session) * level. */ __wt_sleep(0, 10 * stepdown_us); - cache->eviction_scrub_limit = current_dirty - delta; + cache->eviction_scrub_limit = + WT_MAX(cache->eviction_dirty_target, current_dirty - delta); WT_STAT_CONN_SET(session, txn_checkpoint_scrub_target, cache->eviction_scrub_limit); WT_RET(__wt_epoch(session, &last)); |