This is a multi-part message in MIME format.
--------------090509040809000501070508
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
malyn@strangeGizmo.com wrote:
Full_Name: Michael Alyn Miller
Version: Git head
OS: Windows 8.1 x64, NixOS 14.12 x64
URL: ftp://ftp.openldap.org/incoming/michaelalynmiller-151104.c
Submission from: (NULL) (96.251.78.237)
Another issue similar to ITS#8264 and ITS#8299, but this time using
mdb_cursor_del inside of the cursor causes corruption. mdb_del causes
corruption as well, but this is the first time that I have seen mdb_cursor_del
do the wrong thing.
In this case, mdb_cursor_del incorrectly removes one extra key (a key
prefixed with 0c000000000000003a...) in addition to correctly removing all of
the keys that begin with 0d000000000000003a.
mdb_del does not remove that extra key, but instead fails to remove two
0d000000000000003a keys that should have been removed.
I am not sure if these are two different bugs or if they are caused by the same
underlying issue.
Similar reason, two different mistakes. Fixed now in git.
mdb_cursor_del performs correctly on subsequent runs if you do *not* remove the
database between tests, whereas mdb_del continues to fail, but stabilizes on a
different set of results after the first run.
For future reference, here's a patch to your test program that also checks for
cursors pointed adjacent to the item being deleted. The previous fix was
missing a step, fixed now. Note you must build LMDB with -DMDB_DEBUG for the
mdb_cursor_chk() function to be defined.
--
-- Howard Chu
CTO, Symas Corp.
http://www.symas.com
Director, Highland Sun
http://highlandsun.com/hyc/
Chief Architect, OpenLDAP
http://www.openldap.org/project/
--------------090509040809000501070508
Content-Type: text/plain; charset=UTF-8;
name="dif.txt"
Content-Transfer-Encoding: 7bit
Content-Disposition: attachment;
filename="dif.txt"
--- /tmp/michaelalynmiller-151104.c 2015-11-06 10:38:44.772490173 +0000
+++ michaelalynmiller-151104.c 2015-11-06 10:18:13.000000000 +0000
@@ -3696,10 +3696,10 @@
void remove_collection12(MDB_env *env, MDB_dbi dbi, int delete_with_cursor)
{
- int rc;
+ int i, rc;
MDB_txn *txn;
MDB_val key, data;
- MDB_cursor *cursor;
+ MDB_cursor *cursor, *cup, *cdn;
E(mdb_txn_begin(env, NULL, 0, &txn));
@@ -3710,6 +3710,8 @@
E(mdb_del(txn, dbi, &key, &data));
E(mdb_cursor_open(txn, dbi, &cursor));
+ E(mdb_cursor_open(txn, dbi, &cup));
+ E(mdb_cursor_open(txn, dbi, &cdn));
key.mv_size = 8+1;
key.mv_data = "\x0D\x00\x00\x00\x00\x00\x00\x00:";
@@ -3717,13 +3719,19 @@
data.mv_data = NULL;
E(mdb_cursor_get(cursor, &key, &data, MDB_SET_RANGE));
- for (;;) {
+ for (i=0;;i++) {
data.mv_size = 8+1;
data.mv_data = "\x0D\x00\x00\x00\x00\x00\x00\x00;";
if (mdb_cmp(txn, dbi, &data, &key) < 0) {
break;
}
+ E(mdb_cursor_get(cup, &key, &data, MDB_SET));
+ E(mdb_cursor_get(cdn, &key, &data, MDB_SET));
+ mdb_cursor_get(cup, NULL, NULL, MDB_NEXT);
+ mdb_cursor_get(cdn, NULL, NULL, MDB_PREV);
+
+ printf("Deleting %d\n", i);
if (delete_with_cursor) {
E(mdb_cursor_del(cursor, 0));
} else {
@@ -3731,6 +3739,9 @@
data.mv_data = NULL;
E(mdb_del(txn, dbi, &key, &data));
}
+ mdb_cursor_chk(cursor);
+ mdb_cursor_chk(cup);
+ mdb_cursor_chk(cdn);
rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT);
if (rc == MDB_NOTFOUND) {
--------------090509040809000501070508--