diff options
author | Alex Gorrod <alexander.gorrod@mongodb.com> | 2017-06-07 07:20:49 +1000 |
---|---|---|
committer | Alex Gorrod <alexander.gorrod@mongodb.com> | 2017-06-07 07:20:49 +1000 |
commit | 60341ff5b540ed35c8378910d92fe6c128f398e6 (patch) | |
tree | 989cb325f5ea6e335fda4852ae6cfca6a13d3b11 /src/third_party/wiredtiger/src/lsm/lsm_cursor.c | |
parent | a85685ce5ed0e07107476e1f4098034452cf7d6a (diff) | |
download | mongo-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.c | 120 |
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; |