summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKeith Bostic <keith.bostic@mongodb.com>2016-07-06 00:17:50 -0400
committerMichael Cahill <michael.cahill@mongodb.com>2016-07-29 16:13:37 +1000
commit859c8eda1e33b8056332f9bc31fae1ff09e4d9ed (patch)
treeef6b49c4175c0ee41bfbe4372cc0074d92532fd9
parent24cd107c1d7a7402fc8397e4416323651279eaeb (diff)
downloadmongo-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.c13
-rw-r--r--src/btree/bt_curprev.c5
-rw-r--r--src/include/cursor.i2
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);
}