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:
parent
1790359df8
commit
96d00d92d7
2
src/third_party/wiredtiger/import.data
vendored
2
src/third_party/wiredtiger/import.data
vendored
@ -2,5 +2,5 @@
|
||||
"vendor": "wiredtiger",
|
||||
"github": "wiredtiger/wiredtiger.git",
|
||||
"branch": "mongodb-5.0",
|
||||
"commit": "28841ae4b05d7140d62e92505f9547c7128b93e8"
|
||||
"commit": "54f80e05d9ebdeb54b36443878a65ac00e6738f9"
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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.
|
||||
|
75
src/third_party/wiredtiger/src/btree/bt_cursor.c
vendored
75
src/third_party/wiredtiger/src/btree/bt_cursor.c
vendored
@ -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));
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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));
|
||||
|
@ -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.
|
||||
|
@ -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,
|
||||
|
Loading…
Reference in New Issue
Block a user