summaryrefslogtreecommitdiff
path: root/src/third_party/wiredtiger/src/lsm/lsm_cursor.c
diff options
context:
space:
mode:
authorAlex Gorrod <alexander.gorrod@mongodb.com>2017-06-07 07:20:49 +1000
committerAlex Gorrod <alexander.gorrod@mongodb.com>2017-06-07 07:20:49 +1000
commit60341ff5b540ed35c8378910d92fe6c128f398e6 (patch)
tree989cb325f5ea6e335fda4852ae6cfca6a13d3b11 /src/third_party/wiredtiger/src/lsm/lsm_cursor.c
parenta85685ce5ed0e07107476e1f4098034452cf7d6a (diff)
downloadmongo-60341ff5b540ed35c8378910d92fe6c128f398e6.tar.gz
Import wiredtiger: 7aaeaaa054d1ac27a95c79984f7ca69ba739caae from branch mongodb-3.6
ref: 78109ca3fe..7aaeaaa054 for: 3.5.9 SERVER-28820 Recovery failed: WT_NOTFOUND: item not found SERVER-28835 Fix a memory leak in WiredTiger on error when creating thread group WT-2972 Add interface allowing partial updates to existing values WT-3041 Failure of test_perf01 on PPC WT-3063 Reserve records for read-modify-write WT-3076 Add a general-purpose epoch manager WT-3123 Thread group holding lock across thread join WT-3142 Add a workload generator application WT-3158 Fix structure layout on Windows. WT-3160 Improve eviction of internal pages from idle trees WT-3197 aarch64 CRC32C support fails to compile on non-linux ARM platforms WT-3219 Make the clang-analyzer job fail when lint is introduced WT-3222 Review and enhance log statistics WT-3245 Avoid hangs on shutdown when a utility thread encounters an error WT-3247 Test should exit instead of abort to avoid a core dump WT-3248 Performance degradation in workload with large overflow items WT-3253 txn07 test problem WT-3258 Improve visibility into thread wait time due to pages exceeding memory_page_max WT-3261 add a checkpoint epoch to avoid draining the eviction queue WT-3262 Schema operations shouldn't wait for cache WT-3263 Allow archive on restart/recovery if clean shutdown WT-3264 Permanent change to disable logging should eventually remove all logs WT-3265 Verify hits assertion in eviction when transiting handle to exclusive mode WT-3266 Thread group deadlock WT-3267 Upgrade copyright notices from 2016 to 2017. WT-3268 Failure to close cursor can get wiredtiger stuck in a cursor-close loop WT-3269 Miscellaneous cleanup changes WT-3271 Eviction tuning stuck in a loop WT-3275 stress test sanitizer failure WT-3278 log the row-store cursor key instead of page key WT-3281 stress test sanitizer failure WT-3282 Stuck in conn cache pool destroy join WT-3284 tree-walk restart bug WT-3287 review WiredTiger internal panic checks WT-3288 fix error codes for event_handler to be consistent in file operations WT-3292 review/cleanup full-barrier calls in WiredTiger WT-3293 Make internal symbols externally visible WT-3296 LAS table fixes/improvements WT-3297 support the gcc/clang -fvisibility=hidden flag WT-3300 Coverity 1374542: Dereference after null check WT-3302 Failure to create cache pool manager thread results in crash when destroying cache pool WT-3303 Deadlock during first access to lookaside table WT-3307 FI testing: segfault in python test test_bug013 when fault introduced reading turtle file WT-3312 encryption btree configuration test WT-3313 Replace calls to the deprecated LZ4_compress function WT-3314 clarify error handling WT-3327 Checkpoints can hang if time runs backward WT-3331 Test format aborted due to time rollback WT-3333 Make it possible to store 0 bytes into a 'u' format via Python WT-3334 static test suite's BaseDataSet class has 'u' value format bugs WT-3339 The CURSOR_UPDATE_API_CALL macro will dump core on a NULL btree handle WT-3342 Create a new WiredTiger 2.9.2 release WT-3343 WiredTiger database close can attempt unlock of a lock that's not held. WT-3345 Improve rwlock scaling WT-3348 Lint, Windows warnings. WT-3351 Recovery assertion failure: old_lognum < lognum WT-3354 Coverity issues 1375904-1375907 WT-3356 rwlock assertion failure on PPC
Diffstat (limited to 'src/third_party/wiredtiger/src/lsm/lsm_cursor.c')
-rw-r--r--src/third_party/wiredtiger/src/lsm/lsm_cursor.c120
1 files changed, 93 insertions, 27 deletions
diff --git a/src/third_party/wiredtiger/src/lsm/lsm_cursor.c b/src/third_party/wiredtiger/src/lsm/lsm_cursor.c
index 52265f02e62..99920367600 100644
--- a/src/third_party/wiredtiger/src/lsm/lsm_cursor.c
+++ b/src/third_party/wiredtiger/src/lsm/lsm_cursor.c
@@ -1,5 +1,5 @@
/*-
- * Copyright (c) 2014-2016 MongoDB, Inc.
+ * Copyright (c) 2014-2017 MongoDB, Inc.
* Copyright (c) 2008-2014 WiredTiger, Inc.
* All rights reserved.
*
@@ -486,7 +486,7 @@ __clsm_open_cursors(
* cursor, take a copy before closing cursors.
*/
if (F_ISSET(c, WT_CURSTD_KEY_INT))
- WT_CURSOR_NEEDKEY(c);
+ WT_ERR(__cursor_needkey(c));
F_CLR(clsm, WT_CLSM_ITERATE_NEXT | WT_CLSM_ITERATE_PREV);
@@ -844,8 +844,8 @@ __clsm_compare(WT_CURSOR *a, WT_CURSOR *b, int *cmpp)
WT_ERR_MSG(session, EINVAL,
"comparison method cursors must reference the same object");
- WT_CURSOR_NEEDKEY(a);
- WT_CURSOR_NEEDKEY(b);
+ WT_ERR(__cursor_needkey(a));
+ WT_ERR(__cursor_needkey(b));
WT_ERR(__wt_compare(
session, alsm->lsm_tree->collator, &a->key, &b->key, cmpp));
@@ -871,7 +871,7 @@ __clsm_next(WT_CURSOR *cursor)
clsm = (WT_CURSOR_LSM *)cursor;
CURSOR_API_CALL(cursor, session, next, NULL);
- WT_CURSOR_NOVALUE(cursor);
+ __cursor_novalue(cursor);
WT_ERR(__clsm_enter(clsm, false, false));
/* If we aren't positioned for a forward scan, get started. */
@@ -997,7 +997,7 @@ __clsm_next_random(WT_CURSOR *cursor)
clsm = (WT_CURSOR_LSM *)cursor;
CURSOR_API_CALL(cursor, session, next, NULL);
- WT_CURSOR_NOVALUE(cursor);
+ __cursor_novalue(cursor);
WT_ERR(__clsm_enter(clsm, false, false));
for (;;) {
@@ -1051,7 +1051,7 @@ __clsm_prev(WT_CURSOR *cursor)
clsm = (WT_CURSOR_LSM *)cursor;
CURSOR_API_CALL(cursor, session, prev, NULL);
- WT_CURSOR_NOVALUE(cursor);
+ __cursor_novalue(cursor);
WT_ERR(__clsm_enter(clsm, false, false));
/* If we aren't positioned for a reverse scan, get started. */
@@ -1268,8 +1268,8 @@ __clsm_search(WT_CURSOR *cursor)
clsm = (WT_CURSOR_LSM *)cursor;
CURSOR_API_CALL(cursor, session, search, NULL);
- WT_CURSOR_NEEDKEY(cursor);
- WT_CURSOR_NOVALUE(cursor);
+ WT_ERR(__cursor_needkey(cursor));
+ __cursor_novalue(cursor);
WT_ERR(__clsm_enter(clsm, true, false));
ret = __clsm_lookup(clsm, &cursor->value);
@@ -1301,8 +1301,8 @@ __clsm_search_near(WT_CURSOR *cursor, int *exactp)
exact = 0;
CURSOR_API_CALL(cursor, session, search_near, NULL);
- WT_CURSOR_NEEDKEY(cursor);
- WT_CURSOR_NOVALUE(cursor);
+ WT_ERR(__cursor_needkey(cursor));
+ __cursor_novalue(cursor);
WT_ERR(__clsm_enter(clsm, true, false));
F_CLR(clsm, WT_CLSM_ITERATE_NEXT | WT_CLSM_ITERATE_PREV);
@@ -1438,11 +1438,12 @@ err: __clsm_leave(clsm);
*/
static inline int
__clsm_put(WT_SESSION_IMPL *session, WT_CURSOR_LSM *clsm,
- const WT_ITEM *key, const WT_ITEM *value, bool position)
+ const WT_ITEM *key, const WT_ITEM *value, bool position, bool reserve)
{
WT_CURSOR *c, *primary;
WT_LSM_TREE *lsm_tree;
u_int i, slot;
+ int (*func)(WT_CURSOR *);
lsm_tree = clsm->lsm_tree;
@@ -1473,8 +1474,12 @@ __clsm_put(WT_SESSION_IMPL *session, WT_CURSOR_LSM *clsm,
c = clsm->chunks[slot]->cursor;
c->set_key(c, key);
- c->set_value(c, value);
- WT_RET((position && i == 0) ? c->update(c) : c->insert(c));
+ func = c->insert;
+ if (i == 0 && position)
+ func = reserve ? c->reserve : c->update;
+ if (func != c->reserve)
+ c->set_value(c, value);
+ WT_RET(func(c));
}
/*
@@ -1520,11 +1525,16 @@ __clsm_insert(WT_CURSOR *cursor)
clsm = (WT_CURSOR_LSM *)cursor;
- CURSOR_UPDATE_API_CALL(cursor, session, insert, NULL);
- WT_CURSOR_NEEDKEY(cursor);
- WT_CURSOR_NEEDVALUE(cursor);
+ CURSOR_UPDATE_API_CALL(cursor, session, insert);
+ WT_ERR(__cursor_needkey(cursor));
+ WT_ERR(__cursor_needvalue(cursor));
WT_ERR(__clsm_enter(clsm, false, true));
+ /*
+ * It isn't necessary to copy the key out after the lookup in this
+ * case because any non-failed lookup results in an error, and a
+ * failed lookup leaves the original key intact.
+ */
if (!F_ISSET(cursor, WT_CURSTD_OVERWRITE) &&
(ret = __clsm_lookup(clsm, &value)) != WT_NOTFOUND) {
if (ret == 0)
@@ -1533,7 +1543,7 @@ __clsm_insert(WT_CURSOR *cursor)
}
WT_ERR(__clsm_deleted_encode(session, &cursor->value, &value, &buf));
- WT_ERR(__clsm_put(session, clsm, &cursor->key, &value, false));
+ WT_ERR(__clsm_put(session, clsm, &cursor->key, &value, false, false));
/*
* WT_CURSOR.insert doesn't leave the cursor positioned, and the
@@ -1564,15 +1574,21 @@ __clsm_update(WT_CURSOR *cursor)
clsm = (WT_CURSOR_LSM *)cursor;
- CURSOR_UPDATE_API_CALL(cursor, session, update, NULL);
- WT_CURSOR_NEEDKEY(cursor);
- WT_CURSOR_NEEDVALUE(cursor);
+ CURSOR_UPDATE_API_CALL(cursor, session, update);
+ WT_ERR(__cursor_needkey(cursor));
+ WT_ERR(__cursor_needvalue(cursor));
WT_ERR(__clsm_enter(clsm, false, true));
- if (!F_ISSET(cursor, WT_CURSTD_OVERWRITE))
+ if (!F_ISSET(cursor, WT_CURSTD_OVERWRITE)) {
WT_ERR(__clsm_lookup(clsm, &value));
+ /*
+ * Copy the key out, since the insert resets non-primary chunk
+ * cursors which our lookup may have landed on.
+ */
+ WT_ERR(__cursor_needkey(cursor));
+ }
WT_ERR(__clsm_deleted_encode(session, &cursor->value, &value, &buf));
- WT_ERR(__clsm_put(session, clsm, &cursor->key, &value, true));
+ WT_ERR(__clsm_put(session, clsm, &cursor->key, &value, true, false));
/*
* Set the cursor to reference the internal key/value of the positioned
@@ -1612,14 +1628,20 @@ __clsm_remove(WT_CURSOR *cursor)
positioned = F_ISSET(cursor, WT_CURSTD_KEY_INT);
CURSOR_REMOVE_API_CALL(cursor, session, NULL);
- WT_CURSOR_NEEDKEY(cursor);
- WT_CURSOR_NOVALUE(cursor);
+ WT_ERR(__cursor_needkey(cursor));
+ __cursor_novalue(cursor);
WT_ERR(__clsm_enter(clsm, false, true));
- if (!F_ISSET(cursor, WT_CURSTD_OVERWRITE))
+ if (!F_ISSET(cursor, WT_CURSTD_OVERWRITE)) {
WT_ERR(__clsm_lookup(clsm, &value));
+ /*
+ * Copy the key out, since the insert resets non-primary chunk
+ * cursors which our lookup may have landed on.
+ */
+ WT_ERR(__cursor_needkey(cursor));
+ }
WT_ERR(__clsm_put(
- session, clsm, &cursor->key, &__tombstone, positioned));
+ session, clsm, &cursor->key, &__tombstone, positioned, false));
/*
* If the cursor was positioned, it stays positioned with a key but no
@@ -1639,6 +1661,48 @@ err: __clsm_leave(clsm);
}
/*
+ * __clsm_reserve --
+ * WT_CURSOR->reserve method for the LSM cursor type.
+ */
+static int
+__clsm_reserve(WT_CURSOR *cursor)
+{
+ WT_CURSOR_LSM *clsm;
+ WT_DECL_RET;
+ WT_ITEM value;
+ WT_SESSION_IMPL *session;
+
+ clsm = (WT_CURSOR_LSM *)cursor;
+
+ CURSOR_UPDATE_API_CALL(cursor, session, reserve);
+ WT_ERR(__cursor_needkey(cursor));
+ __cursor_novalue(cursor);
+ WT_ERR(__wt_txn_context_check(session, true));
+ WT_ERR(__clsm_enter(clsm, false, true));
+
+ WT_ERR(__clsm_lookup(clsm, &value));
+ /*
+ * Copy the key out, since the insert resets non-primary chunk cursors
+ * which our lookup may have landed on.
+ */
+ WT_ERR(__cursor_needkey(cursor));
+ ret = __clsm_put(session, clsm, &cursor->key, NULL, true, true);
+
+err: __clsm_leave(clsm);
+ CURSOR_UPDATE_API_END(session, ret);
+
+ /*
+ * The application might do a WT_CURSOR.get_value call when we return,
+ * so we need a value and the underlying functions didn't set one up.
+ * For various reasons, those functions may not have done a search and
+ * any previous value in the cursor might race with WT_CURSOR.reserve
+ * (and in cases like LSM, the reserve never encountered the original
+ * key). For simplicity, repeat the search here.
+ */
+ return (ret == 0 ? cursor->search(cursor) : ret);
+}
+
+/*
* __wt_clsm_close --
* WT_CURSOR->close method for the LSM cursor type.
*/
@@ -1692,8 +1756,10 @@ __wt_clsm_open(WT_SESSION_IMPL *session,
__clsm_search, /* search */
__clsm_search_near, /* search-near */
__clsm_insert, /* insert */
+ __wt_cursor_modify_notsup, /* modify */
__clsm_update, /* update */
__clsm_remove, /* remove */
+ __clsm_reserve, /* reserve */
__wt_cursor_reconfigure, /* reconfigure */
__wt_clsm_close); /* close */
WT_CURSOR *cursor;