diff options
Diffstat (limited to 'src/third_party/wiredtiger/src/lsm/lsm_cursor.c')
-rw-r--r-- | src/third_party/wiredtiger/src/lsm/lsm_cursor.c | 54 |
1 files changed, 39 insertions, 15 deletions
diff --git a/src/third_party/wiredtiger/src/lsm/lsm_cursor.c b/src/third_party/wiredtiger/src/lsm/lsm_cursor.c index a18269baa28..7c9ac35d489 100644 --- a/src/third_party/wiredtiger/src/lsm/lsm_cursor.c +++ b/src/third_party/wiredtiger/src/lsm/lsm_cursor.c @@ -97,10 +97,11 @@ __clsm_enter_update(WT_CURSOR_LSM *clsm) hard_limit = F_ISSET(lsm_tree, WT_LSM_TREE_NEED_SWITCH) ? 1 : 0; if (have_primary) { + WT_ENTER_PAGE_INDEX(session); WT_WITH_BTREE(session, ((WT_CURSOR_BTREE *)primary)->btree, - ovfl = __wt_btree_size_overflow( - session, hard_limit ? + ovfl = __wt_btree_lsm_size(session, hard_limit ? 2 * lsm_tree->chunk_size : lsm_tree->chunk_size)); + WT_LEAVE_PAGE_INDEX(session); /* If there was no overflow, we're done. */ if (!ovfl) @@ -391,26 +392,37 @@ __clsm_open_cursors( c = &clsm->iface; session = (WT_SESSION_IMPL *)c->session; txn = &session->txn; - lsm_tree = clsm->lsm_tree; chunk = NULL; + locked = 0; + lsm_tree = clsm->lsm_tree; - if (update) { - if (txn->isolation == TXN_ISO_SNAPSHOT) - F_SET(clsm, WT_CLSM_OPEN_SNAPSHOT); - } else + /* + * Ensure that any snapshot update has cursors on the right set of + * chunks to guarantee visibility is correct. + */ + if (update && txn->isolation == TXN_ISO_SNAPSHOT) + F_SET(clsm, WT_CLSM_OPEN_SNAPSHOT); + + /* + * Query operations need a full set of cursors. Overwrite cursors + * do queries in service of updates. + */ + if (!update || !F_ISSET(c, WT_CURSTD_OVERWRITE)) F_SET(clsm, WT_CLSM_OPEN_READ); if (lsm_tree->nchunks == 0) return (0); - ckpt_cfg[0] = WT_CONFIG_BASE(session, session_open_cursor); + ckpt_cfg[0] = WT_CONFIG_BASE(session, WT_SESSION_open_cursor); ckpt_cfg[1] = "checkpoint=" WT_CHECKPOINT ",raw"; ckpt_cfg[2] = NULL; - /* Copy the key, so we don't lose the cursor position. */ - if (F_ISSET(c, WT_CURSTD_KEY_INT) && !WT_DATA_IN_ITEM(&c->key)) - WT_RET(__wt_buf_set( - session, &c->key, c->key.data, c->key.size)); + /* + * If the key is pointing to memory that is pinned by a chunk + * cursor, take a copy before closing cursors. + */ + if (F_ISSET(c, WT_CURSTD_KEY_INT)) + WT_CURSOR_NEEDKEY(c); F_CLR(clsm, WT_CLSM_ITERATE_NEXT | WT_CLSM_ITERATE_PREV); @@ -1201,9 +1213,21 @@ __clsm_search_near(WT_CURSOR *cursor, int *exactp) deleted = __clsm_deleted(clsm, &cursor->value); if (!deleted) __clsm_deleted_decode(clsm, &cursor->value); - else if ((ret = cursor->next(cursor)) == 0) { - cmp = 1; - deleted = 0; + else { + /* + * We have a key pointing at memory that is + * pinned by the current chunk cursor. In the + * unlikely event that we have to reopen cursors + * to move to the next record, make sure the cursor + * flags are set so a copy is made before the current + * chunk cursor releases its position. + */ + F_CLR(cursor, WT_CURSTD_KEY_SET); + F_SET(cursor, WT_CURSTD_KEY_INT); + if ((ret = cursor->next(cursor)) == 0) { + cmp = 1; + deleted = 0; + } } WT_ERR_NOTFOUND_OK(ret); } |