0
0
mirror of https://github.com/mongodb/mongo.git synced 2024-12-01 09:32:32 +01:00

Import wiredtiger: 54f80e05d9ebdeb54b36443878a65ac00e6738f9 from branch mongodb-5.0

ref: 28841ae4b0..54f80e05d9
for: 5.1.0

WT-7550       Properly check pinned page and fix not resetting cursor if error
This commit is contained in:
Chenhao Qu 2021-05-19 05:34:44 +00:00 committed by Evergreen Agent
parent 1790359df8
commit 96d00d92d7
8 changed files with 79 additions and 77 deletions

View File

@ -2,5 +2,5 @@
"vendor": "wiredtiger",
"github": "wiredtiger/wiredtiger.git",
"branch": "mongodb-5.0",
"commit": "28841ae4b05d7140d62e92505f9547c7128b93e8"
"commit": "54f80e05d9ebdeb54b36443878a65ac00e6738f9"
}

View File

@ -660,7 +660,7 @@ __wt_btcur_next_prefix(WT_CURSOR_BTREE *cbt, WT_ITEM *prefix, bool truncating)
F_CLR(cursor, WT_CURSTD_KEY_SET | WT_CURSTD_VALUE_SET);
WT_ERR(__cursor_func_init(cbt, false));
WT_ERR(__wt_cursor_func_init(cbt, false));
/*
* If we aren't already iterating in the right direction, there's some setup to do.

View File

@ -607,7 +607,7 @@ __wt_btcur_prev_prefix(WT_CURSOR_BTREE *cbt, WT_ITEM *prefix, bool truncating)
F_CLR(cursor, WT_CURSTD_KEY_SET | WT_CURSTD_VALUE_SET);
WT_ERR(__cursor_func_init(cbt, false));
WT_ERR(__wt_cursor_func_init(cbt, false));
/*
* If we aren't already iterating in the right direction, there's some setup to do.

View File

@ -49,59 +49,6 @@ __cursor_state_restore(WT_CURSOR *cursor, WT_CURFILE_STATE *state)
F_SET(cursor, F_MASK(state, WT_CURSTD_KEY_EXT | WT_CURSTD_VALUE_EXT));
}
/*
* __cursor_page_pinned --
* Return if we have a page pinned.
*/
static inline bool
__cursor_page_pinned(WT_CURSOR_BTREE *cbt, bool search_operation)
{
WT_CURSOR *cursor;
WT_SESSION_IMPL *session;
cursor = &cbt->iface;
session = CUR2S(cbt);
/*
* Check the page active flag, asserting the page reference with any external key.
*/
if (!F_ISSET(cbt, WT_CBT_ACTIVE)) {
WT_ASSERT(session, cbt->ref == NULL && !F_ISSET(cursor, WT_CURSTD_KEY_INT));
return (false);
}
/*
* Check if the key references an item on a page. When returning from search, the page is pinned
* and the key is internal. After the application sets a key, the key becomes external. For the
* search and search-near operations, we assume locality and check any pinned page first on each
* new search operation. For operations other than search and search-near, check if we have an
* internal key. If the page is pinned and we're pointing into the page, we don't need to search
* at all, we can proceed with the operation. However, if the key has been set, that is, it's an
* external key, we're going to have to do a full search.
*/
if (!search_operation && !F_ISSET(cursor, WT_CURSTD_KEY_INT))
return (false);
/*
* XXX No fast-path searches at read-committed isolation. Underlying transactional functions
* called by the fast and slow path search code handle transaction IDs differently, resulting in
* different search results at read-committed isolation. This makes no difference for the update
* functions, but in the case of a search, we will see different results based on the cursor's
* initial location. See WT-5134 for the details.
*/
if (search_operation && session->txn->isolation == WT_ISO_READ_COMMITTED)
return (false);
/*
* Fail if the page is flagged for forced eviction (so we periodically release pages grown too
* large).
*/
if (cbt->ref->page->read_gen == WT_READGEN_OLDEST)
return (false);
return (true);
}
/*
* __cursor_size_chk --
* Return if an inserted item is too large.
@ -541,7 +488,7 @@ __wt_btcur_search(WT_CURSOR_BTREE *cbt)
* pinned page doesn't find an exact match, search from the root.
*/
valid = false;
if (__cursor_page_pinned(cbt, true)) {
if (__wt_cursor_page_pinned(cbt, true)) {
__wt_txn_cursor_op(session);
if (btree->type == BTREE_ROW) {
@ -555,7 +502,7 @@ __wt_btcur_search(WT_CURSOR_BTREE *cbt)
}
}
if (!valid) {
WT_ERR(__cursor_func_init(cbt, true));
WT_ERR(__wt_cursor_func_init(cbt, true));
if (btree->type == BTREE_ROW) {
WT_ERR(__cursor_row_search(cbt, false, NULL, NULL));
@ -640,7 +587,7 @@ __wt_btcur_search_near(WT_CURSOR_BTREE *cbt, int *exactp)
* search.
*/
valid = false;
if (btree->type == BTREE_ROW && __cursor_page_pinned(cbt, true)) {
if (btree->type == BTREE_ROW && __wt_cursor_page_pinned(cbt, true)) {
__wt_txn_cursor_op(session);
/*
@ -661,7 +608,7 @@ __wt_btcur_search_near(WT_CURSOR_BTREE *cbt, int *exactp)
WT_ERR(__wt_cursor_valid(cbt, cbt->tmp, WT_RECNO_OOB, &valid));
}
if (!valid) {
WT_ERR(__cursor_func_init(cbt, true));
WT_ERR(__wt_cursor_func_init(cbt, true));
/*
* Set the "insert" flag for row-store search; we may intend to position the cursor at the
@ -804,7 +751,7 @@ __wt_btcur_insert(WT_CURSOR_BTREE *cbt)
* Fixed-length column store can never use a positioned cursor to update because the cursor may
* not be positioned to the correct record in the case of implicit records in the append list.
*/
if (btree->type != BTREE_COL_FIX && __cursor_page_pinned(cbt, false) &&
if (btree->type != BTREE_COL_FIX && __wt_cursor_page_pinned(cbt, false) &&
F_ISSET(cursor, WT_CURSTD_OVERWRITE) && !append_key) {
WT_ERR(__wt_txn_autocommit_check(session));
/*
@ -838,7 +785,7 @@ __wt_btcur_insert(WT_CURSOR_BTREE *cbt)
__cursor_state_save(cursor, &state);
retry:
WT_ERR(__cursor_func_init(cbt, true));
WT_ERR(__wt_cursor_func_init(cbt, true));
if (btree->type == BTREE_ROW) {
WT_ERR(__cursor_row_search(cbt, true, NULL, NULL));
@ -969,7 +916,7 @@ __wt_btcur_insert_check(WT_CURSOR_BTREE *cbt)
__cursor_novalue(cursor);
retry:
WT_ERR(__cursor_func_init(cbt, true));
WT_ERR(__wt_cursor_func_init(cbt, true));
WT_ERR(__cursor_row_search(cbt, true, NULL, NULL));
/* Just check for conflicts. */
@ -1035,7 +982,7 @@ __wt_btcur_remove(WT_CURSOR_BTREE *cbt, bool positioned)
* Fixed-length column store can never use a positioned cursor to update because the cursor may
* not be positioned to the correct record in the case of implicit records in the append list.
*/
if (btree->type != BTREE_COL_FIX && __cursor_page_pinned(cbt, false)) {
if (btree->type != BTREE_COL_FIX && __wt_cursor_page_pinned(cbt, false)) {
WT_ERR(__wt_txn_autocommit_check(session));
/*
@ -1062,7 +1009,7 @@ retry:
__cursor_state_save(cursor, &state);
searched = true;
WT_ERR(__cursor_func_init(cbt, true));
WT_ERR(__wt_cursor_func_init(cbt, true));
if (btree->type == BTREE_ROW) {
WT_ERR_NOTFOUND_OK(__cursor_row_search(cbt, false, NULL, NULL), true);
@ -1212,7 +1159,7 @@ __btcur_update(WT_CURSOR_BTREE *cbt, WT_ITEM *value, u_int modify_type)
* Fixed-length column store can never use a positioned cursor to update because the cursor may
* not be positioned to the correct record in the case of implicit records in the append list.
*/
if (btree->type != BTREE_COL_FIX && __cursor_page_pinned(cbt, false)) {
if (btree->type != BTREE_COL_FIX && __wt_cursor_page_pinned(cbt, false)) {
WT_ERR(__wt_txn_autocommit_check(session));
/*
@ -1245,7 +1192,7 @@ __btcur_update(WT_CURSOR_BTREE *cbt, WT_ITEM *value, u_int modify_type)
__cursor_state_save(cursor, &state);
retry:
WT_ERR(__cursor_func_init(cbt, true));
WT_ERR(__wt_cursor_func_init(cbt, true));
WT_ERR(btree->type == BTREE_ROW ? __cursor_row_search(cbt, true, NULL, NULL) :
__cursor_col_search(cbt, NULL, NULL));

View File

@ -506,7 +506,7 @@ __wt_btcur_next_random(WT_CURSOR_BTREE *cbt)
* sampling, pick a roughly random leaf page in the tree and return an entry from it.
*/
if (cbt->ref == NULL || cbt->next_random_sample_size == 0) {
WT_ERR(__cursor_func_init(cbt, true));
WT_ERR(__wt_cursor_func_init(cbt, true));
WT_WITH_PAGE_INDEX(session, ret = __wt_random_descent(session, &cbt->ref, read_flags));
if (ret == 0) {
WT_ERR(__random_leaf(cbt));

View File

@ -16,7 +16,6 @@ int
__wt_hs_row_search(WT_CURSOR_BTREE *hs_cbt, WT_ITEM *srch_key, bool insert)
{
WT_BTREE *hs_btree;
WT_CURSOR *hs_cursor;
WT_DECL_RET;
WT_SESSION_IMPL *session;
bool leaf_found;
@ -26,14 +25,13 @@ __wt_hs_row_search(WT_CURSOR_BTREE *hs_cbt, WT_ITEM *srch_key, bool insert)
hs_btree = CUR2BT(hs_cbt);
session = CUR2S(hs_cbt);
hs_cursor = &hs_cbt->iface;
leaf_found = false;
/*
* Check whether the search key can be find in the provided leaf page, if exists. Otherwise
* perform a full search.
*/
if (hs_cbt->ref != NULL) {
if (__wt_cursor_page_pinned(hs_cbt, true)) {
#ifdef HAVE_DIAGNOSTIC
WT_ORDERED_READ(page, hs_cbt->ref->page);
#endif
@ -44,7 +42,7 @@ __wt_hs_row_search(WT_CURSOR_BTREE *hs_cbt, WT_ITEM *srch_key, bool insert)
WT_ASSERT(session, __wt_hazard_check(session, hs_cbt->ref, NULL) != NULL);
WT_WITH_BTREE(session, hs_btree,
ret = __wt_row_search(hs_cbt, srch_key, insert, hs_cbt->ref, false, &leaf_found));
WT_RET(ret);
WT_ERR(ret);
/*
* Only use the pinned page search results if search returns an exact match or a slot other
@ -58,13 +56,13 @@ __wt_hs_row_search(WT_CURSOR_BTREE *hs_cbt, WT_ITEM *srch_key, bool insert)
/* Ensure there is no eviction happened on this page. */
WT_ASSERT(session, page == hs_cbt->ref->page);
if (!leaf_found)
hs_cursor->reset(hs_cursor);
}
if (!leaf_found)
if (!leaf_found) {
WT_ERR(__wt_cursor_func_init(hs_cbt, true));
WT_WITH_BTREE(
session, hs_btree, ret = __wt_row_search(hs_cbt, srch_key, insert, NULL, false, NULL));
}
if (ret == 0 && !insert) {
WT_ERR(__wt_key_return(hs_cbt));

View File

@ -404,11 +404,11 @@ __cursor_kv_return(WT_CURSOR_BTREE *cbt, WT_UPDATE_VALUE *upd_value)
}
/*
* __cursor_func_init --
* __wt_cursor_func_init --
* Cursor call setup.
*/
static inline int
__cursor_func_init(WT_CURSOR_BTREE *cbt, bool reenter)
__wt_cursor_func_init(WT_CURSOR_BTREE *cbt, bool reenter)
{
WT_SESSION_IMPL *session;
@ -441,6 +441,59 @@ __cursor_func_init(WT_CURSOR_BTREE *cbt, bool reenter)
return (0);
}
/*
* __wt_cursor_page_pinned --
* Return if we have a page pinned.
*/
static inline bool
__wt_cursor_page_pinned(WT_CURSOR_BTREE *cbt, bool search_operation)
{
WT_CURSOR *cursor;
WT_SESSION_IMPL *session;
cursor = &cbt->iface;
session = CUR2S(cbt);
/*
* Check the page active flag, asserting the page reference with any external key.
*/
if (!F_ISSET(cbt, WT_CBT_ACTIVE)) {
WT_ASSERT(session, cbt->ref == NULL && !F_ISSET(cursor, WT_CURSTD_KEY_INT));
return (false);
}
/*
* Check if the key references an item on a page. When returning from search, the page is pinned
* and the key is internal. After the application sets a key, the key becomes external. For the
* search and search-near operations, we assume locality and check any pinned page first on each
* new search operation. For operations other than search and search-near, check if we have an
* internal key. If the page is pinned and we're pointing into the page, we don't need to search
* at all, we can proceed with the operation. However, if the key has been set, that is, it's an
* external key, we're going to have to do a full search.
*/
if (!search_operation && !F_ISSET(cursor, WT_CURSTD_KEY_INT))
return (false);
/*
* XXX No fast-path searches at read-committed isolation. Underlying transactional functions
* called by the fast and slow path search code handle transaction IDs differently, resulting in
* different search results at read-committed isolation. This makes no difference for the update
* functions, but in the case of a search, we will see different results based on the cursor's
* initial location. See WT-5134 for the details.
*/
if (search_operation && session->txn->isolation == WT_ISO_READ_COMMITTED)
return (false);
/*
* Fail if the page is flagged for forced eviction (so we periodically release pages grown too
* large).
*/
if (cbt->ref->page->read_gen == WT_READGEN_OLDEST)
return (false);
return (true);
}
/*
* __cursor_row_slot_key_return --
* Return a row-store leaf page slot's key.

View File

@ -1858,6 +1858,8 @@ static inline bool __wt_cache_stuck(WT_SESSION_IMPL *session)
WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
static inline bool __wt_checksum_match(const void *chunk, size_t len, uint32_t v)
WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
static inline bool __wt_cursor_page_pinned(WT_CURSOR_BTREE *cbt, bool search_operation)
WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
static inline bool __wt_eviction_clean_needed(WT_SESSION_IMPL *session, double *pct_fullp)
WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
static inline bool __wt_eviction_dirty_needed(WT_SESSION_IMPL *session, double *pct_fullp)
@ -1963,6 +1965,8 @@ static inline int __wt_compare_skip(WT_SESSION_IMPL *session, WT_COLLATOR *colla
WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
static inline int __wt_curindex_get_valuev(WT_CURSOR *cursor, va_list ap)
WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
static inline int __wt_cursor_func_init(WT_CURSOR_BTREE *cbt, bool reenter)
WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
static inline int __wt_curtable_get_valuev(WT_CURSOR *cursor, va_list ap)
WT_GCC_FUNC_DECL_ATTRIBUTE((warn_unused_result));
static inline int __wt_dsk_cell_data_ref(WT_SESSION_IMPL *session, int page_type, void *unpack_arg,