From 97c7b6151ec750524c79db5d08a08ba142b22d37 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Wed, 15 Apr 2015 23:20:55 +0100 Subject: [PATCH 1/3] ITS#8062 fix rebalance (Probably fixes the ITS, definitely fixes a bug) when collapsing the root page, fixups of other cursors was incomplete. --- libraries/liblmdb/mdb.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/libraries/liblmdb/mdb.c b/libraries/liblmdb/mdb.c index c788b85347..4bb7fee47c 100644 --- a/libraries/liblmdb/mdb.c +++ b/libraries/liblmdb/mdb.c @@ -7717,12 +7717,12 @@ mdb_rebalance(MDB_cursor *mc) m3 = m2; if (m3 == mc || m3->mc_snum < mc->mc_snum) continue; if (m3->mc_pg[0] == mp) { - m3->mc_snum--; - m3->mc_top--; for (i=0; imc_snum; i++) { m3->mc_pg[i] = m3->mc_pg[i+1]; m3->mc_ki[i] = m3->mc_ki[i+1]; } + m3->mc_snum--; + m3->mc_top--; } } } @@ -7792,7 +7792,11 @@ mdb_rebalance(MDB_cursor *mc) } else { oldki += NUMKEYS(mn.mc_pg[mn.mc_top]); mn.mc_ki[mn.mc_top] += mc->mc_ki[mn.mc_top] + 1; + /* We want mdb_rebalance to find mn when doing fixups */ + mn.mc_next = mc->mc_txn->mt_cursors[mc->mc_dbi]; + mc->mc_txn->mt_cursors[mc->mc_dbi] = &mn; rc = mdb_page_merge(mc, &mn); + mc->mc_txn->mt_cursors[mc->mc_dbi] = mn.mc_next; mdb_cursor_copy(&mn, mc); } mc->mc_flags &= ~C_EOF; From ddc4aa1aa301ff2c359ccdacde15fedc5c068e9f Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Wed, 15 Apr 2015 23:48:09 +0100 Subject: [PATCH 2/3] ITS#8062 --- libraries/liblmdb/CHANGES | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/liblmdb/CHANGES b/libraries/liblmdb/CHANGES index cf12f2eebd..1d60d7f511 100644 --- a/libraries/liblmdb/CHANGES +++ b/libraries/liblmdb/CHANGES @@ -4,6 +4,7 @@ LMDB 0.9.15 Release Engineering Fix txn init (ITS#7961,#7987) Fix MDB_PREV_DUP (ITS#7955,#7671) Fix compact of empty env (ITS#7956) + Fix mdb_rebalance collapsing root (ITS#8062) Fix mdb_load with large values (ITS#8066) Added workaround for fdatasync bug in ext3fs Build From b0032feb85352d794f4fb318e63195589bdaafc7 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Thu, 16 Apr 2015 00:19:40 +0100 Subject: [PATCH 3/3] ITS#8062 also handle subcursors --- libraries/liblmdb/mdb.c | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/libraries/liblmdb/mdb.c b/libraries/liblmdb/mdb.c index 4bb7fee47c..c2ce4c4c6e 100644 --- a/libraries/liblmdb/mdb.c +++ b/libraries/liblmdb/mdb.c @@ -7790,13 +7790,23 @@ mdb_rebalance(MDB_cursor *mc) if (mc->mc_ki[ptop] == 0) { rc = mdb_page_merge(&mn, mc); } else { + MDB_cursor dummy; oldki += NUMKEYS(mn.mc_pg[mn.mc_top]); mn.mc_ki[mn.mc_top] += mc->mc_ki[mn.mc_top] + 1; /* We want mdb_rebalance to find mn when doing fixups */ - mn.mc_next = mc->mc_txn->mt_cursors[mc->mc_dbi]; - mc->mc_txn->mt_cursors[mc->mc_dbi] = &mn; + if (mc->mc_flags & C_SUB) { + dummy.mc_next = mc->mc_txn->mt_cursors[mc->mc_dbi]; + mc->mc_txn->mt_cursors[mc->mc_dbi] = &dummy; + dummy.mc_xcursor = (MDB_xcursor *)&mn; + } else { + mn.mc_next = mc->mc_txn->mt_cursors[mc->mc_dbi]; + mc->mc_txn->mt_cursors[mc->mc_dbi] = &mn; + } rc = mdb_page_merge(mc, &mn); - mc->mc_txn->mt_cursors[mc->mc_dbi] = mn.mc_next; + if (mc->mc_flags & C_SUB) + mc->mc_txn->mt_cursors[mc->mc_dbi] = dummy.mc_next; + else + mc->mc_txn->mt_cursors[mc->mc_dbi] = mn.mc_next; mdb_cursor_copy(&mn, mc); } mc->mc_flags &= ~C_EOF;