summaryrefslogtreecommitdiff
path: root/src/third_party/wiredtiger/src/lsm/lsm_cursor.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/third_party/wiredtiger/src/lsm/lsm_cursor.c')
-rw-r--r--src/third_party/wiredtiger/src/lsm/lsm_cursor.c54
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);
}