diff options
author | Keith Bostic <keith.bostic@mongodb.com> | 2016-07-06 00:17:50 -0400 |
---|---|---|
committer | Michael Cahill <michael.cahill@mongodb.com> | 2016-07-29 16:13:37 +1000 |
commit | 859c8eda1e33b8056332f9bc31fae1ff09e4d9ed (patch) | |
tree | ef6b49c4175c0ee41bfbe4372cc0074d92532fd9 | |
parent | 24cd107c1d7a7402fc8397e4416323651279eaeb (diff) | |
download | mongo-859c8eda1e33b8056332f9bc31fae1ff09e4d9ed.tar.gz |
WT-2730 Btree can incorrectly match key slots on new pages (#2848)
This problem can occur for both row and column store.
The WT_CURSOR_BTREE.rip_saved field potentially has the same problem
as the cip_saved field, initializing it on point-searches is wrong,
it should be initialized as a cursor moves to a new page.
* Clear cip_saved and rip_saved when starting to iterate from a search
position. This wasn't necessary before because we cleared them in
__cursor_pos_clear(), but I removed that code.
In summary, we now clear them in the iteration code, both when starting
an iteration and when switching to a new page. That's correct because
they have nothing to do with searches so the clear doesn't belong in
__cursor_pos_clear(), and we have to do the clear when switching to a
new page regardless, __cursor_pos_clear() isn't called when switching
to a new page.
(cherry picked from commit 1b6a9220c3ce948f902c6bc44660b76982c7e621)
-rw-r--r-- | src/btree/bt_curnext.c | 13 | ||||
-rw-r--r-- | src/btree/bt_curprev.c | 5 | ||||
-rw-r--r-- | src/include/cursor.i | 2 |
3 files changed, 11 insertions, 9 deletions
diff --git a/src/btree/bt_curnext.c b/src/btree/bt_curnext.c index ddf31528ec3..e6f4728a695 100644 --- a/src/btree/bt_curnext.c +++ b/src/btree/bt_curnext.c @@ -179,11 +179,11 @@ __cursor_var_next(WT_CURSOR_BTREE *cbt, bool newpage) /* Initialize for each new page. */ if (newpage) { - cbt->cip_saved = NULL; cbt->last_standard_recno = __col_var_last_recno(cbt->ref); if (cbt->last_standard_recno == 0) return (WT_NOTFOUND); __cursor_set_recno(cbt, cbt->ref->ref_recno); + cbt->cip_saved = NULL; goto new_page; } @@ -302,12 +302,13 @@ __cursor_row_next(WT_CURSOR_BTREE *cbt, bool newpage) * WT_INSERT_HEAD[0], and so on. This means WT_INSERT lists are * odd-numbered slots, and WT_ROW array slots are even-numbered slots. * - * New page configuration. + * Initialize for each new page. */ if (newpage) { cbt->ins_head = WT_ROW_INSERT_SMALLEST(page); cbt->ins = WT_SKIP_FIRST(cbt->ins_head); cbt->row_iteration_slot = 1; + cbt->rip_saved = NULL; goto new_insert; } @@ -518,11 +519,13 @@ __wt_btcur_iterate_setup(WT_CURSOR_BTREE *cbt) */ F_SET(cbt, WT_CBT_ITERATE_NEXT | WT_CBT_ITERATE_PREV); - /* - * Clear the count of deleted items on the page. - */ + /* Clear the count of deleted items on the page. */ cbt->page_deleted_count = 0; + /* Clear saved iteration cursor position information. */ + cbt->cip_saved = NULL; + cbt->rip_saved = NULL; + /* * If we don't have a search page, then we're done, we're starting at * the beginning or end of the tree, not as a result of a search. diff --git a/src/btree/bt_curprev.c b/src/btree/bt_curprev.c index ad847671c12..cba0c053b90 100644 --- a/src/btree/bt_curprev.c +++ b/src/btree/bt_curprev.c @@ -325,11 +325,11 @@ __cursor_var_prev(WT_CURSOR_BTREE *cbt, bool newpage) /* Initialize for each new page. */ if (newpage) { - cbt->cip_saved = NULL; cbt->last_standard_recno = __col_var_last_recno(cbt->ref); if (cbt->last_standard_recno == 0) return (WT_NOTFOUND); __cursor_set_recno(cbt, cbt->last_standard_recno); + cbt->cip_saved = NULL; goto new_page; } @@ -448,7 +448,7 @@ __cursor_row_prev(WT_CURSOR_BTREE *cbt, bool newpage) * WT_INSERT_HEAD[0], and so on. This means WT_INSERT lists are * odd-numbered slots, and WT_ROW array slots are even-numbered slots. * - * New page configuration. + * Initialize for each new page. */ if (newpage) { /* @@ -465,6 +465,7 @@ __cursor_row_prev(WT_CURSOR_BTREE *cbt, bool newpage) WT_ROW_INSERT_SLOT(page, page->pg_row_entries - 1); cbt->ins = WT_SKIP_LAST(cbt->ins_head); cbt->row_iteration_slot = page->pg_row_entries * 2 + 1; + cbt->rip_saved = NULL; goto new_insert; } diff --git a/src/include/cursor.i b/src/include/cursor.i index 339ec2083ac..c1fb7bfcb9f 100644 --- a/src/include/cursor.i +++ b/src/include/cursor.i @@ -38,8 +38,6 @@ __cursor_pos_clear(WT_CURSOR_BTREE *cbt) cbt->ins_head = NULL; cbt->ins_stack[0] = NULL; - cbt->rip_saved = NULL; - F_CLR(cbt, WT_CBT_POSITION_MASK); } |