From 6760ca87aef6ffdccbbd0505ed80b089bf24758f Mon Sep 17 00:00:00 2001 From: Leo Yuriev Date: Fri, 21 Jul 2017 16:03:43 +0300 Subject: [PATCH 01/26] mdbx: update links to stable/0.0 branch. Change-Id: I1387108236b20b173a703194b006acd60eaae94e --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index f81dfef1..ee625c97 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,9 @@ libmdbx Extended LMDB, aka "Расширенная LMDB". *The Future will Positive. Всё будет хорошо.* -[![Build Status](https://travis-ci.org/ReOpen/libmdbx.svg?branch=master)](https://travis-ci.org/ReOpen/libmdbx) +[![Build Status](https://travis-ci.org/ReOpen/libmdbx.svg?branch=stable%2F0.0)](https://travis-ci.org/ReOpen/libmdbx) -English version by Google [is here](https://translate.googleusercontent.com/translate_c?act=url&ie=UTF8&sl=ru&tl=en&u=https://github.com/ReOpen/libmdbx/tree/master). +English version by Google [is here](https://translate.googleusercontent.com/translate_c?act=url&ie=UTF8&sl=ru&tl=en&u=https://github.com/ReOpen/libmdbx/tree/stable%2F0.0). ## Кратко From 4874852b796c0570376b184e2d689e97e14733b1 Mon Sep 17 00:00:00 2001 From: Leo Yuriev Date: Sun, 23 Jul 2017 14:16:19 +0300 Subject: [PATCH 02/26] mdbx: backport - fix mdbx_set_attr(). Change-Id: I6628a0629a17f99f39098b8ccb76259cd65dd353 --- mdbx.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mdbx.c b/mdbx.c index 009b9d43..60ce25e3 100644 --- a/mdbx.c +++ b/mdbx.c @@ -864,13 +864,14 @@ int mdbx_set_attr(MDB_txn *txn, MDB_dbi dbi, return rc; } + old_attr = 0; rc = mdbx_attr_peek(&old_data, &old_attr); if (unlikely(rc != MDB_SUCCESS)) return rc; if (old_attr == attr && (!data || (data->mv_size == old_data.mv_size - && memcpy(data->mv_data, old_data.mv_data, old_data.mv_size) == 0))) + && memcmp(data->mv_data, old_data.mv_data, old_data.mv_size) == 0))) return MDB_SUCCESS; mc.mc_next = txn->mt_cursors[dbi]; From f55c30f2863b107d1118111eb18e537fb6514a33 Mon Sep 17 00:00:00 2001 From: Leo Yuriev Date: Wed, 26 Jul 2017 13:14:19 +0300 Subject: [PATCH 03/26] mdbx: backport - don't madvise(MADV_REMOVE). Avoid lost changes and corruption in case a collision between mdbx_env_open() in one process and write-txn with next-pgno updates in an another process. Change-Id: I890db9251edbd77ac0ace10bed10a24517d709ec --- mdb.c | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) diff --git a/mdb.c b/mdb.c index 482873a3..6f8d3da2 100644 --- a/mdb.c +++ b/mdb.c @@ -4341,7 +4341,7 @@ mdb_env_create(MDB_env **env) } static int __cold -mdb_env_map(MDB_env *env, void *addr, size_t usedsize) +mdb_env_map(MDB_env *env, void *addr) { unsigned flags = env->me_flags; @@ -4381,12 +4381,6 @@ mdb_env_map(MDB_env *env, void *addr, size_t usedsize) } #endif -#ifdef MADV_REMOVE - if (flags & MDB_WRITEMAP) { - (void) madvise(env->me_map + usedsize, env->me_mapsize - usedsize, MADV_REMOVE); - } -#endif - /* Turn on/off readahead. It's harmful when the DB is larger than RAM. */ if (madvise(env->me_map, env->me_mapsize, (flags & MDB_NORDAHEAD) ? MADV_RANDOM : MADV_WILLNEED)) return errno; @@ -4439,7 +4433,7 @@ mdb_env_set_mapsize(MDB_env *env, size_t size) #endif env->me_mapsize = size; old = (env->me_flags & MDB_FIXEDMAP) ? env->me_map : NULL; - rc = mdb_env_map(env, old, usedsize); + rc = mdb_env_map(env, old); if (rc) return rc; } @@ -4557,8 +4551,7 @@ mdb_env_open2(MDB_env *env, MDB_meta *meta) newenv = 0; } - const size_t usedsize = (meta->mm_last_pg + 1) * env->me_psize; - rc = mdb_env_map(env, (flags & MDB_FIXEDMAP) ? meta->mm_address : NULL, usedsize); + rc = mdb_env_map(env, (flags & MDB_FIXEDMAP) ? meta->mm_address : NULL); if (rc) return rc; From a783325a6d9966fc7ffc476537831510b17d576c Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Wed, 26 Jul 2017 21:37:40 +0100 Subject: [PATCH 04/26] mdbx: backport - ITS#8699 more for cursor_del ITS#8622. Set C_DEL flag on reinit'd subcursor Change-Id: I8ad1c10afd481f61b8e521d02c4d2de3be5089d7 --- mdb.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/mdb.c b/mdb.c index 6f8d3da2..8aea98b8 100644 --- a/mdb.c +++ b/mdb.c @@ -8805,8 +8805,10 @@ mdb_cursor_del0(MDB_cursor *mc) if (m3->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED) { if (!(node->mn_flags & F_SUBDATA)) m3->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(node); - } else + } else { mdb_xcursor_init1(m3, node); + m3->mc_xcursor->mx_cursor.mc_flags |= C_DEL; + } } } } From ecbc0b9c12d018b70d62f736e1bdef5343186722 Mon Sep 17 00:00:00 2001 From: Leo Yuriev Date: Sat, 12 Aug 2017 10:48:50 +0300 Subject: [PATCH 05/26] mdbx: update links after move the repo. Change-Id: Ib9d0bbc02f628ee5df673f419cd6152785e19573 --- Makefile | 2 +- README.md | 6 +++--- lmdb.h | 2 +- mdb.c | 4 ++-- 4 files changed, 7 insertions(+), 7 deletions(-) diff --git a/Makefile b/Makefile index b3039973..e2c9be86 100644 --- a/Makefile +++ b/Makefile @@ -1,5 +1,5 @@ # GNU Makefile for libmdbx (reliable lightning memory-mapped DB library for Linux). -# https://github.com/ReOpen/libmdbx +# https://github.com/leo-yuriev/libmdbx ######################################################################## # Configuration. The compiler options must enable threaded compilation. diff --git a/README.md b/README.md index ee625c97..cedd4a52 100644 --- a/README.md +++ b/README.md @@ -3,9 +3,9 @@ libmdbx Extended LMDB, aka "Расширенная LMDB". *The Future will Positive. Всё будет хорошо.* -[![Build Status](https://travis-ci.org/ReOpen/libmdbx.svg?branch=stable%2F0.0)](https://travis-ci.org/ReOpen/libmdbx) +[![Build Status](https://travis-ci.org/leo-yuriev/libmdbx.svg?branch=stable%2F0.0)](https://travis-ci.org/leo-yuriev/libmdbx) -English version by Google [is here](https://translate.googleusercontent.com/translate_c?act=url&ie=UTF8&sl=ru&tl=en&u=https://github.com/ReOpen/libmdbx/tree/stable%2F0.0). +English version by Google [is here](https://translate.googleusercontent.com/translate_c?act=url&ie=UTF8&sl=ru&tl=en&u=https://github.com/leo-yuriev/libmdbx/tree/stable%2F0.0). ## Кратко @@ -28,7 +28,7 @@ _libmdbx_ является потомком "Lightning Memory-Mapped Database", известной под аббревиатурой [LMDB](https://en.wikipedia.org/wiki/Lightning_Memory-Mapped_Database). Изначально доработка производилась в составе проекта -[ReOpenLDAP](https://github.com/ReOpen/ReOpenLDAP). Примерно за год +[ReOpenLDAP](https://github.com/leo-yuriev/ReOpenLDAP). Примерно за год работы внесенные изменения приобрели самостоятельную ценность. Осенью 2015 доработанный движок был выделен в отдельный проект, который был [представлен на конференции Highload++ diff --git a/lmdb.h b/lmdb.h index a1c086d3..4d7d658e 100644 --- a/lmdb.h +++ b/lmdb.h @@ -212,7 +212,7 @@ typedef int mdb_filehandle_t; #define MDB_VERSION_DATE "2017-02-17" /** A stringifier for the version info */ -#define MDB_VERSTR(a,b,c,d) "MDBX " #a "." #b "." #c ": (" d ", https://github.com/ReOpen/libmdbx)" +#define MDB_VERSTR(a,b,c,d) "MDBX " #a "." #b "." #c ": (" d ", https://github.com/leo-yuriev/libmdbx)" /** A helper for the stringifier macro */ #define MDB_VERFOO(a,b,c,d) MDB_VERSTR(a,b,c,d) diff --git a/mdb.c b/mdb.c index 8aea98b8..394c3010 100644 --- a/mdb.c +++ b/mdb.c @@ -1048,7 +1048,7 @@ typedef struct MDB_pgstate { } MDB_pgstate; /** Context for deferred cleanup of reader's threads. - * to avoid https://github.com/ReOpen/ReOpenLDAP/issues/48 */ + * to avoid https://github.com/leo-yuriev/ReOpenLDAP/issues/48 */ typedef struct MDBX_rthc { struct MDBX_rthc *rc_next; pthread_t rc_thread; @@ -4624,7 +4624,7 @@ void mdbx_rthc_dtor(void) * TSD-деструкторах и поэтому может выгрузить lib.so до того как * отработали все деструкторы. * - Исходное проявление проблемы было зафиксировано - * в https://github.com/ReOpen/ReOpenLDAP/issues/48 + * в https://github.com/leo-yuriev/ReOpenLDAP/issues/48 * * Предыдущее решение посредством выделяемого динамически MDB_rthc * было не удачным, так как порождало либо утечку памяти, From 70042069eb9aef6d4976fd3450540a054d61e5f5 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Fri, 4 May 2018 16:56:57 +0300 Subject: [PATCH 06/26] mdbx: backport - fix FIRST_DUP/LAST_DUP cursor bounds check (ITS#8722). --- mdb.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/mdb.c b/mdb.c index 394c3010..b8317bb8 100644 --- a/mdb.c +++ b/mdb.c @@ -6673,6 +6673,11 @@ fetchm: rc = MDB_INCOMPATIBLE; break; } + if (mc->mc_ki[mc->mc_top] >= NUMKEYS(mc->mc_pg[mc->mc_top])) { + mc->mc_ki[mc->mc_top] = NUMKEYS(mc->mc_pg[mc->mc_top]); + rc = MDB_NOTFOUND; + break; + } { MDB_node *leaf = NODEPTR(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]); if (!F_ISSET(leaf->mn_flags, F_DUPDATA)) { @@ -7365,6 +7370,7 @@ mdb_cursor_del(MDB_cursor *mc, unsigned flags) if (!(m2->mc_flags & C_INITIALIZED)) continue; if (m2->mc_pg[mc->mc_top] == mp) { MDB_node *n2 = leaf; + if (m2->mc_ki[mc->mc_top] >= NUMKEYS(mp)) continue; if (m2->mc_ki[mc->mc_top] != mc->mc_ki[mc->mc_top]) { n2 = NODEPTR(mp, m2->mc_ki[mc->mc_top]); if (n2->mn_flags & F_SUBDATA) continue; From 55893f8c3946743dd3894def0846f3a1815dc322 Mon Sep 17 00:00:00 2001 From: Leo Yuriev Date: Fri, 4 May 2018 16:59:54 +0300 Subject: [PATCH 07/26] mdbx: fix check make target (minor). --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index e2c9be86..4bef98b3 100644 --- a/Makefile +++ b/Makefile @@ -71,7 +71,7 @@ clean: tests: $(TESTS) -check: tests +check: tests mdbx_chk [ -d testdb ] || mkdir testdb && rm -f testdb/* \ && echo "*** LMDB-TEST-0" && ./mtest0 && ./mdbx_chk -v testdb \ && echo "*** LMDB-TEST-1" && ./mtest1 && ./mdbx_chk -v testdb \ From 9baca673ac3d9b191bf58e11c01b9c0508b89fad Mon Sep 17 00:00:00 2001 From: Hallvard Furuseth Date: Fri, 4 May 2018 17:09:30 +0300 Subject: [PATCH 08/26] mdbx: backport - XCURSOR_REFRESH() fixups/cleanup. * Check NUMKEYS(), similar to f34b61f9471d1c03fe0517b9d817c50c920e378a "ITS#8722 fix FIRST_DUP/LAST_DUP cursor bounds check". * Move XCURSOR_INITED() into XCURSOR_REFRESH(). This adds a check in mdb_cursor_put, below /* converted, write the original data first */. * Factor mc_ki[] out to XCURSOR_REFRESH(). * Replace an mc_pg[] with mp which is equal (mdb_cursor_del0). * This checks XCURSOR_INITED() and fixes the mn_flags check. --- mdb.c | 51 ++++++++++++++++++++++----------------------------- 1 file changed, 22 insertions(+), 29 deletions(-) diff --git a/mdb.c b/mdb.c index b8317bb8..6a31b56b 100644 --- a/mdb.c +++ b/mdb.c @@ -1026,17 +1026,19 @@ typedef struct MDB_xcursor { unsigned char mx_dbflag; } MDB_xcursor; - /** Check if there is an inited xcursor, so #XCURSOR_REFRESH() is proper */ + /** Check if there is an inited xcursor */ #define XCURSOR_INITED(mc) \ ((mc)->mc_xcursor && ((mc)->mc_xcursor->mx_cursor.mc_flags & C_INITIALIZED)) - /** Update sub-page pointer, if any, in \b mc->mc_xcursor. Needed + /** Update the xcursor's sub-page pointer, if any, in \b mc. Needed * when the node which contains the sub-page may have moved. Called - * with \b mp = mc->mc_pg[mc->mc_top], \b ki = mc->mc_ki[mc->mc_top]. + * with leaf page \b mp = mc->mc_pg[\b top]. */ -#define XCURSOR_REFRESH(mc, mp, ki) do { \ +#define XCURSOR_REFRESH(mc, top, mp) do { \ MDB_page *xr_pg = (mp); \ - MDB_node *xr_node = NODEPTR(xr_pg, ki); \ + MDB_node *xr_node; \ + if (!XCURSOR_INITED(mc) || (mc)->mc_ki[top] >= NUMKEYS(xr_pg)) break; \ + xr_node = NODEPTR(xr_pg, (mc)->mc_ki[top]); \ if ((xr_node->mn_flags & (F_DUPDATA|F_SUBDATA)) == F_DUPDATA) \ (mc)->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(xr_node); \ } while (0) @@ -2608,8 +2610,8 @@ done: if (m2 == mc) continue; if (m2->mc_pg[mc->mc_top] == mp) { m2->mc_pg[mc->mc_top] = np; - if (XCURSOR_INITED(m2) && IS_LEAF(np)) - XCURSOR_REFRESH(m2, np, m2->mc_ki[mc->mc_top]); + if (IS_LEAF(np)) + XCURSOR_REFRESH(m2, mc->mc_top, np); } } } @@ -7208,8 +7210,7 @@ new_sub: if (m3->mc_ki[i] >= mc->mc_ki[i] && insert_key) { m3->mc_ki[i]++; } - if (XCURSOR_INITED(m3)) - XCURSOR_REFRESH(m3, mp, m3->mc_ki[i]); + XCURSOR_REFRESH(m3, i, mp); } } } @@ -7250,7 +7251,6 @@ put_sub: MDB_xcursor *mx = mc->mc_xcursor; unsigned i = mc->mc_top; MDB_page *mp = mc->mc_pg[i]; - int nkeys = NUMKEYS(mp); for (m2 = mc->mc_txn->mt_cursors[mc->mc_dbi]; m2; m2=m2->mc_next) { if (m2 == mc || m2->mc_snum < mc->mc_snum) continue; @@ -7258,8 +7258,8 @@ put_sub: if (m2->mc_pg[i] == mp) { if (m2->mc_ki[i] == mc->mc_ki[i]) { mdb_xcursor_init2(m2, mx, dupdata_flag); - } else if (!insert_key && m2->mc_ki[i] < nkeys) { - XCURSOR_REFRESH(m2, mp, m2->mc_ki[i]); + } else if (!insert_key) { + XCURSOR_REFRESH(m2, i, mp); } } } @@ -7369,13 +7369,7 @@ mdb_cursor_del(MDB_cursor *mc, unsigned flags) if (m2 == mc || m2->mc_snum < mc->mc_snum) continue; if (!(m2->mc_flags & C_INITIALIZED)) continue; if (m2->mc_pg[mc->mc_top] == mp) { - MDB_node *n2 = leaf; - if (m2->mc_ki[mc->mc_top] >= NUMKEYS(mp)) continue; - if (m2->mc_ki[mc->mc_top] != mc->mc_ki[mc->mc_top]) { - n2 = NODEPTR(mp, m2->mc_ki[mc->mc_top]); - if (n2->mn_flags & F_SUBDATA) continue; - } - m2->mc_xcursor->mx_cursor.mc_pg[0] = NODEDATA(n2); + XCURSOR_REFRESH(m2, mc->mc_top, mp); } } } @@ -8279,8 +8273,8 @@ mdb_node_move(MDB_cursor *csrc, MDB_cursor *cdst, int fromleft) m3->mc_ki[csrc->mc_top] = cdst->mc_ki[cdst->mc_top]; m3->mc_ki[csrc->mc_top-1]++; } - if (XCURSOR_INITED(m3) && IS_LEAF(mps)) - XCURSOR_REFRESH(m3, m3->mc_pg[csrc->mc_top], m3->mc_ki[csrc->mc_top]); + if (IS_LEAF(mps)) + XCURSOR_REFRESH(m3, csrc->mc_top, m3->mc_pg[csrc->mc_top]); } } else /* Adding on the right, bump others down */ @@ -8301,8 +8295,8 @@ mdb_node_move(MDB_cursor *csrc, MDB_cursor *cdst, int fromleft) } else { m3->mc_ki[csrc->mc_top]--; } - if (XCURSOR_INITED(m3) && IS_LEAF(mps)) - XCURSOR_REFRESH(m3, m3->mc_pg[csrc->mc_top], m3->mc_ki[csrc->mc_top]); + if (IS_LEAF(mps)) + XCURSOR_REFRESH(m3, csrc->mc_top, m3->mc_pg[csrc->mc_top]); } } } @@ -8500,8 +8494,8 @@ mdb_page_merge(MDB_cursor *csrc, MDB_cursor *cdst) m3->mc_ki[top-1] > csrc->mc_ki[top-1]) { m3->mc_ki[top-1]--; } - if (XCURSOR_INITED(m3) && IS_LEAF(psrc)) - XCURSOR_REFRESH(m3, m3->mc_pg[top], m3->mc_ki[top]); + if (IS_LEAF(psrc)) + XCURSOR_REFRESH(m3, top, m3->mc_pg[top]); } } { @@ -8763,8 +8757,7 @@ mdb_cursor_del0(MDB_cursor *mc) } else if (m3->mc_ki[mc->mc_top] > ki) { m3->mc_ki[mc->mc_top]--; } - if (XCURSOR_INITED(m3)) - XCURSOR_REFRESH(m3, m3->mc_pg[mc->mc_top], m3->mc_ki[mc->mc_top]); + XCURSOR_REFRESH(m3, mc->mc_top, mp); } } } @@ -9305,8 +9298,8 @@ mdb_page_split(MDB_cursor *mc, MDB_val *newkey, MDB_val *newdata, pgno_t newpgno m3->mc_ki[ptop] >= mc->mc_ki[ptop]) { m3->mc_ki[ptop]++; } - if (XCURSOR_INITED(m3) && IS_LEAF(mp)) - XCURSOR_REFRESH(m3, m3->mc_pg[mc->mc_top], m3->mc_ki[mc->mc_top]); + if (IS_LEAF(mp)) + XCURSOR_REFRESH(m3, mc->mc_top, m3->mc_pg[mc->mc_top]); } } mdb_debug("mp left: %d, rp left: %d", SIZELEFT(mp), SIZELEFT(rp)); From df08b5144c2cc2a75ae17dd2538bd16c506d73b5 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Fri, 4 May 2018 17:14:14 +0300 Subject: [PATCH 09/26] mdbx: backport - fix regression in 0.9.19 (ITS#8760). --- mdb.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/mdb.c b/mdb.c index 6a31b56b..082e823e 100644 --- a/mdb.c +++ b/mdb.c @@ -10204,8 +10204,11 @@ int mdb_dbi_open(MDB_txn *txn, const char *name, unsigned flags, MDB_dbi *dbi) MDB_node *node = NODEPTR(mc.mc_pg[mc.mc_top], mc.mc_ki[mc.mc_top]); if (unlikely((node->mn_flags & (F_DUPDATA|F_SUBDATA)) != F_SUBDATA)) return MDB_INCOMPATIBLE; - } else if (! (rc == MDB_NOTFOUND && (flags & MDB_CREATE))) { - return rc; + } else { + if (rc != MDB_NOTFOUND || !(flags & MDB_CREATE)) + return rc; + if (F_ISSET(txn->mt_flags, MDB_TXN_RDONLY)) + return EACCES; } /* Done here so we cannot fail after creating a new DB */ From 2bccc85ff82fb70fa7df2fdeb7a763c8333ef1f1 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Fri, 4 May 2018 17:15:43 +0300 Subject: [PATCH 10/26] mdbx: backport - can't use fakepage mp_ptrs directly (ITS#8819). --- mdb.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mdb.c b/mdb.c index 082e823e..43f95cb0 100644 --- a/mdb.c +++ b/mdb.c @@ -7081,8 +7081,9 @@ prep_subDB: } else { memcpy((char *)mp + mp->mp_upper + PAGEBASE, (char *)fp + fp->mp_upper + PAGEBASE, olddata.mv_size - fp->mp_upper - PAGEBASE); + memcpy((char *)(&mp->mp_ptrs), (char *)(&fp->mp_ptrs), NUMKEYS(fp) * sizeof(mp->mp_ptrs[0])); for (i=0; imp_ptrs[i] = fp->mp_ptrs[i] + offset; + mp->mp_ptrs[i] += offset; } } From 0c4b39bd119dfe995f7a91195679615db35c7d02 Mon Sep 17 00:00:00 2001 From: Leo Yuriev Date: Fri, 4 May 2018 17:22:59 +0300 Subject: [PATCH 11/26] mdbx: fix wrong freeDB search. Avoid search freeDB while tree is updating. Bug was inherited from LMDB. https://github.com/leo-yuriev/libmdbx/issues/31 --- mdb.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mdb.c b/mdb.c index 43f95cb0..740ad00d 100644 --- a/mdb.c +++ b/mdb.c @@ -2140,6 +2140,10 @@ mdb_page_alloc(MDB_cursor *mc, int num, MDB_page **mp, int flags) /* If mc is updating the freeDB, then the freelist cannot play * catch-up with itself by growing while trying to save it. */ flags &= ~(MDBX_ALLOC_GC | MDBX_ALLOC_KICK | MDBX_COALESCE | MDBX_LIFORECLAIM); + } else if (unlikely(txn->mt_dbs[FREE_DBI].md_entries == 0)) { + /* avoid (recursive) search inside empty tree and while tree is updating, + * https://github.com/leo-yuriev/libmdbx/issues/31 */ + flags &= ~MDBX_ALLOC_GC; } } From 7eb1b363097db64cc881f5dac8572789f820f357 Mon Sep 17 00:00:00 2001 From: Leo Yuriev Date: Fri, 4 May 2018 17:26:04 +0300 Subject: [PATCH 12/26] mdbx: minor fixup comments and warnings. --- mdb.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-) diff --git a/mdb.c b/mdb.c index 740ad00d..669aae0a 100644 --- a/mdb.c +++ b/mdb.c @@ -44,10 +44,8 @@ # define _GNU_SOURCE #endif -/* LY: Please do not ask us for Windows support, just never! - * But you can make a fork for Windows, or become maintainer for FreeBSD... */ #ifndef __gnu_linux__ -# warning "This version of ReOpenMDBX supports only GNU Linux" +# warning "This version of libmdbx supports only GNU Linux" #endif #include @@ -56,21 +54,21 @@ #include "./defs.h" #if !__GNUC_PREREQ(4,2) - /* LY: Actualy ReOpenMDBX was not tested with compilers + /* LY: Actualy libmdbx was not tested with compilers * older than GCC 4.4 (from RHEL6). * But you could remove this #error and try to continue at your own risk. * In such case please don't rise up an issues related ONLY to old compilers. */ -# warning "ReOpenMDBX required at least GCC 4.2 compatible C/C++ compiler." +# warning "libmdbx required at least GCC 4.2 compatible C/C++ compiler." #endif #if !__GLIBC_PREREQ(2,12) - /* LY: Actualy ReOpenMDBX was not tested with something + /* LY: Actualy libmdbx was not tested with something * older than glibc 2.12 (from RHEL6). * But you could remove this #error and try to continue at your own risk. * In such case please don't rise up an issues related ONLY to old systems. */ -# warning "ReOpenMDBX required at least GLIBC 2.12." +# warning "libmdbx required at least GLIBC 2.12." #endif #if MDB_DEBUG From e94d6efec6168c9ee07eaa9476eed6cd36e91789 Mon Sep 17 00:00:00 2001 From: Leo Yuriev Date: Thu, 10 May 2018 14:09:37 +0300 Subject: [PATCH 13/26] mdbx: update Project Status. --- README.md | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index cedd4a52..4a1ea684 100644 --- a/README.md +++ b/README.md @@ -5,8 +5,16 @@ Extended LMDB, aka "Расширенная LMDB". *The Future will Positive. Всё будет хорошо.* [![Build Status](https://travis-ci.org/leo-yuriev/libmdbx.svg?branch=stable%2F0.0)](https://travis-ci.org/leo-yuriev/libmdbx) -English version by Google [is here](https://translate.googleusercontent.com/translate_c?act=url&ie=UTF8&sl=ru&tl=en&u=https://github.com/leo-yuriev/libmdbx/tree/stable%2F0.0). +## Project Status for now + - The stable versions (the _stable/*_ branches) of are frozen, i.e. no new features or API changes, but only bug fixes. + - The next (the _devel_ branch) version **is under active development**, i.e. current API and set of features are extreme volatile. + - The immediate goal of development is formation of the stable API and the stable internal database format, which allows realise all planned features. + - Planned features: Integrity check by Merkle tree, Support for raw block devices, Separate place for large data items, Using "roaring bitmaps" for garbage collector, Non-linear page reclaiming, Asynchronous lazy data flush to disk(s), etc. + +----- + +English version by Google [is here](https://translate.googleusercontent.com/translate_c?act=url&ie=UTF8&sl=ru&tl=en&u=https://github.com/leo-yuriev/libmdbx/tree/stable%2F0.0). ## Кратко From 31873e8e2c3fc180df9087fd7654b346a0be8ece Mon Sep 17 00:00:00 2001 From: Leo Yuriev Date: Thu, 21 Jun 2018 19:51:23 +0300 Subject: [PATCH 14/26] mdbx-ci: migrate to Circle-CI 2.0 Change-Id: If8b77d070277cf88dfe81f5bf33dd33466dca0d9 --- .circleci/config.yml | 9 +++++++++ circle.yml | 14 -------------- 2 files changed, 9 insertions(+), 14 deletions(-) create mode 100644 .circleci/config.yml delete mode 100644 circle.yml diff --git a/.circleci/config.yml b/.circleci/config.yml new file mode 100644 index 00000000..a71e15e9 --- /dev/null +++ b/.circleci/config.yml @@ -0,0 +1,9 @@ +version: 2 +jobs: + build: + docker: + - image: circleci/buildpack-deps:artful + steps: + - checkout + - run: make all lmdb + - run: make check diff --git a/circle.yml b/circle.yml deleted file mode 100644 index 1caf0d92..00000000 --- a/circle.yml +++ /dev/null @@ -1,14 +0,0 @@ -machine: - timezone: - Europe/Moscow - -database: - override: - -compile: - override: - - make all lmdb - -test: - override: - - make check From c381573d1fa8b67514add3c3d86f8c77490737b4 Mon Sep 17 00:00:00 2001 From: Leo Yuriev Date: Thu, 21 Jun 2018 20:05:09 +0300 Subject: [PATCH 15/26] mdbx-tests: include for modern glibc. Change-Id: I9ac297c6c029b2d88faaa84aab5180dc9d6a5d7a --- mtest0.c | 1 + mtest1.c | 1 + mtest2.c | 1 + mtest3.c | 1 + mtest4.c | 1 + mtest5.c | 1 + mtest6.c | 1 + mtest7.c | 1 + mtest8.c | 1 + 9 files changed, 9 insertions(+) diff --git a/mtest0.c b/mtest0.c index c09019f1..aec9ae85 100644 --- a/mtest0.c +++ b/mtest0.c @@ -21,6 +21,7 @@ #include #include #include +#include #include "mdbx.h" #include diff --git a/mtest1.c b/mtest1.c index ffe79123..5ef53310 100644 --- a/mtest1.c +++ b/mtest1.c @@ -20,6 +20,7 @@ #include #include #include +#include #include "mdbx.h" #define E(expr) CHECK((rc = (expr)) == MDB_SUCCESS, #expr) diff --git a/mtest2.c b/mtest2.c index 12b1e126..81f8bf3c 100644 --- a/mtest2.c +++ b/mtest2.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "mdbx.h" #define E(expr) CHECK((rc = (expr)) == MDB_SUCCESS, #expr) diff --git a/mtest3.c b/mtest3.c index a55ec604..ab5c28c1 100644 --- a/mtest3.c +++ b/mtest3.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "mdbx.h" #define E(expr) CHECK((rc = (expr)) == MDB_SUCCESS, #expr) diff --git a/mtest4.c b/mtest4.c index 3d67a0f9..0e7536d6 100644 --- a/mtest4.c +++ b/mtest4.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "mdbx.h" #define E(expr) CHECK((rc = (expr)) == MDB_SUCCESS, #expr) diff --git a/mtest5.c b/mtest5.c index ed19f412..d5e04306 100644 --- a/mtest5.c +++ b/mtest5.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "mdbx.h" #define E(expr) CHECK((rc = (expr)) == MDB_SUCCESS, #expr) diff --git a/mtest6.c b/mtest6.c index d988c93c..7d76daee 100644 --- a/mtest6.c +++ b/mtest6.c @@ -23,6 +23,7 @@ #include #include #include +#include #include "mdbx.h" #define E(expr) CHECK((rc = (expr)) == MDB_SUCCESS, #expr) diff --git a/mtest7.c b/mtest7.c index 0e15bc9e..991418c6 100644 --- a/mtest7.c +++ b/mtest7.c @@ -18,6 +18,7 @@ #include #include #include +#include #include "mdbx.h" #define E(expr) CHECK((rc = (expr)) == MDB_SUCCESS, #expr) diff --git a/mtest8.c b/mtest8.c index f5895628..d4b7bd7b 100644 --- a/mtest8.c +++ b/mtest8.c @@ -18,6 +18,7 @@ #include #include #include +#include #include "mdbx.h" #define E(expr) CHECK((rc = (expr)) == MDB_SUCCESS, #expr) From 5bb92a4277357564a9a5e8d6dd7013be7c412a0a Mon Sep 17 00:00:00 2001 From: Leo Yuriev Date: Thu, 21 Jun 2018 20:09:27 +0300 Subject: [PATCH 16/26] mdbx: add `fallthrough` for modern gcc. Change-Id: I948adc0e534dd9ba42b7d64e8105870cc77f82e6 --- mdb.c | 3 ++- mdb_dump.c | 2 +- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/mdb.c b/mdb.c index 669aae0a..eff5dbe7 100644 --- a/mdb.c +++ b/mdb.c @@ -7032,7 +7032,8 @@ more: offset *= 4; /* space for 4 more */ break; } - /* FALLTHRU: Big enough MDB_DUPFIXED sub-page */ + /* Big enough MDB_DUPFIXED sub-page */ + /* fallthrough */ case MDB_CURRENT | MDB_NODUPDATA: case MDB_CURRENT: fp->mp_flags |= P_DIRTY; diff --git a/mdb_dump.c b/mdb_dump.c index 0b5db58e..485f8f4f 100644 --- a/mdb_dump.c +++ b/mdb_dump.c @@ -186,7 +186,7 @@ int main(int argc, char *argv[]) break; case 'l': list = 1; - /*FALLTHROUGH*/; + /* fallthrough */ case 'a': if (subname) usage(prog); From b1620bbe47ff526754443c027d1dd22f6de656bd Mon Sep 17 00:00:00 2001 From: Leonid Yuriev Date: Fri, 21 Sep 2018 15:15:13 +0300 Subject: [PATCH 17/26] mdbx: backport - prevent DB corruption due rebalance bugs. Won't fix https://github.com/leo-yuriev/libmdbx/issues/38 in the 'stable/0.0' branch, but add checks to prevent DB corruption. --- mdb.c | 19 ++++++++++++++++++- mdbx.c | 2 +- 2 files changed, 19 insertions(+), 2 deletions(-) diff --git a/mdb.c b/mdb.c index eff5dbe7..d4530e62 100644 --- a/mdb.c +++ b/mdb.c @@ -602,6 +602,8 @@ typedef struct MDB_page { indx_t mp_ptrs[1]; /**< dynamic size */ } MDB_page; +#define PAGETYPE(p) ((p)->mp_flags & (P_BRANCH | P_LEAF | P_LEAF2 | P_OVERFLOW)) + /** Size of the page header, excluding dynamic data at the end */ #define PAGEHDRSZ ((unsigned) offsetof(MDB_page, mp_ptrs)) @@ -3364,6 +3366,8 @@ mdb_freelist_save(MDB_txn *txn) const int lifo = (env->me_flags & MDBX_LIFORECLAIM) != 0; mdb_cursor_init(&mc, txn, FREE_DBI, NULL); + mc.mc_next = txn->mt_cursors[FREE_DBI]; + txn->mt_cursors[FREE_DBI] = &mc; /* MDB_RESERVE cancels meminit in ovpage malloc (when no WRITEMAP) */ clean_limit = (env->me_flags & (MDB_NOMEMINIT|MDB_WRITEMAP)) @@ -3645,6 +3649,7 @@ bailout: txn->mt_lifo_reclaimed = NULL; } } + txn->mt_cursors[FREE_DBI] = mc.mc_next; return rc; } @@ -8166,6 +8171,12 @@ mdb_node_move(MDB_cursor *csrc, MDB_cursor *cdst, int fromleft) DKBUF; + mdb_tassert(csrc->mc_txn, PAGETYPE(csrc->mc_pg[csrc->mc_top]) == PAGETYPE(cdst->mc_pg[cdst->mc_top])); + if (unlikely(PAGETYPE(csrc->mc_pg[csrc->mc_top]) != PAGETYPE(cdst->mc_pg[cdst->mc_top]))) { + cdst->mc_txn->mt_flags |= MDB_TXN_ERROR; + return MDB_PROBLEM; + } + /* Mark src and dst as dirty. */ if (unlikely((rc = mdb_page_touch(csrc)) || (rc = mdb_page_touch(cdst)))) @@ -8396,6 +8407,12 @@ mdb_page_merge(MDB_cursor *csrc, MDB_cursor *cdst) mdb_cassert(csrc, csrc->mc_snum > 1); /* can't merge root page */ mdb_cassert(csrc, cdst->mc_snum > 1); + mdb_tassert(csrc->mc_txn, PAGETYPE(psrc) == PAGETYPE(pdst)); + if (unlikely(PAGETYPE(psrc) != PAGETYPE(pdst))) { + cdst->mc_txn->mt_flags |= MDB_TXN_ERROR; + return MDB_PROBLEM; + } + /* Mark dst as dirty. */ if (unlikely(rc = mdb_page_touch(cdst))) return rc; @@ -8599,7 +8616,7 @@ mdb_rebalance(MDB_cursor *mc) m3 = &m2->mc_xcursor->mx_cursor; else m3 = m2; - if (!(m3->mc_flags & C_INITIALIZED) || (m3->mc_snum < mc->mc_snum)) + if (m3 == mc || !(m3->mc_flags & C_INITIALIZED)) continue; if (m3->mc_pg[0] == mp) { m3->mc_snum = 0; diff --git a/mdbx.c b/mdbx.c index 60ce25e3..5b3f605f 100644 --- a/mdbx.c +++ b/mdbx.c @@ -530,7 +530,7 @@ int mdbx_replace(MDB_txn *txn, MDB_dbi dbi, rc = mdbx_cursor_get(&mc, &present_key, &present_data, MDB_SET_KEY); if (unlikely(rc != MDB_SUCCESS)) { old_data->iov_base = NULL; - old_data->iov_len = rc; + old_data->iov_len = 0; if (rc != MDB_NOTFOUND || (flags & MDB_CURRENT)) goto bailout; } else if (flags & MDB_NOOVERWRITE) { From d23a3f3bc41ed240b3d480ba60a4c05c0617513d Mon Sep 17 00:00:00 2001 From: Leonid Yuriev Date: Fri, 21 Sep 2018 15:55:05 +0300 Subject: [PATCH 18/26] mdbx: drop inherited broken audit. Internal self-audit (inherited from LMDB) is invalid and useless for sub-db and dupsort cases. --- mdb.c | 162 ---------------------------------------------------------- 1 file changed, 162 deletions(-) diff --git a/mdb.c b/mdb.c index d4530e62..be98564b 100644 --- a/mdb.c +++ b/mdb.c @@ -1306,9 +1306,6 @@ static void mdb_debug_log(int type, const char *function, int line, const char * # define mdb_assert_enabled() \ unlikely(mdb_runtime_flags & MDBX_DBG_ASSERT) -# define mdb_audit_enabled() \ - unlikely(mdb_runtime_flags & MDBX_DBG_AUDIT) - # define mdb_debug_enabled(type) \ unlikely(mdb_runtime_flags & \ (type & (MDBX_DBG_TRACE | MDBX_DBG_EXTRA))) @@ -1319,7 +1316,6 @@ static void mdb_debug_log(int type, const char *function, int line, const char * # else # define mdb_debug_enabled(type) (0) # endif -# define mdb_audit_enabled() (0) # define mdb_assert_enabled() (0) # define mdb_assert_fail(env, msg, func, line) \ __assert_fail(msg, __FILE__, line, func) @@ -1429,161 +1425,6 @@ mdb_dkey(MDB_val *key, char *buf) return buf; } -#if 0 /* LY: debug stuff */ -static const char * -mdb_leafnode_type(MDB_node *n) -{ - static char *const tp[2][2] = {{"", ": DB"}, {": sub-page", ": sub-DB"}}; - return F_ISSET(n->mn_flags, F_BIGDATA) ? ": overflow page" : - tp[F_ISSET(n->mn_flags, F_DUPDATA)][F_ISSET(n->mn_flags, F_SUBDATA)]; -} - -/** Display all the keys in the page. */ -static void -mdb_page_list(MDB_page *mp) -{ - pgno_t pgno = mdb_dbg_pgno(mp); - const char *type, *state = (mp->mp_flags & P_DIRTY) ? ", dirty" : ""; - MDB_node *node; - unsigned i, nkeys, nsize, total = 0; - MDB_val key; - DKBUF; - - switch (mp->mp_flags & (P_BRANCH|P_LEAF|P_LEAF2|P_META|P_OVERFLOW|P_SUBP)) { - case P_BRANCH: type = "Branch page"; break; - case P_LEAF: type = "Leaf page"; break; - case P_LEAF|P_SUBP: type = "Sub-page"; break; - case P_LEAF|P_LEAF2: type = "LEAF2 page"; break; - case P_LEAF|P_LEAF2|P_SUBP: type = "LEAF2 sub-page"; break; - case P_OVERFLOW: - mdb_print("Overflow page %zu pages %u%s\n", - pgno, mp->mp_pages, state); - return; - case P_META: - mdb_print("Meta-page %zu txnid %zu\n", - pgno, ((MDB_meta *)PAGEDATA(mp))->mm_txnid); - return; - default: - mdb_print("Bad page %zu flags 0x%X\n", pgno, mp->mp_flags); - return; - } - - nkeys = NUMKEYS(mp); - mdb_print("%s %zu numkeys %u%s\n", type, pgno, nkeys, state); - - for (i=0; imp_leaf2_ksize; - key.mv_data = LEAF2KEY(mp, i, nsize); - total += nsize; - mdb_print("key %u: nsize %u, %s\n", i, nsize, DKEY(&key)); - continue; - } - node = NODEPTR(mp, i); - key.mv_size = node->mn_ksize; - key.mv_data = node->mn_data; - nsize = NODESIZE + key.mv_size; - if (IS_BRANCH(mp)) { - mdb_print("key %u: page %zu, %s\n", i, NODEPGNO(node), DKEY(&key)); - total += nsize; - } else { - if (F_ISSET(node->mn_flags, F_BIGDATA)) - nsize += sizeof(pgno_t); - else - nsize += NODEDSZ(node); - total += nsize; - nsize += sizeof(indx_t); - mdb_print("key %u: nsize %u, %s%s\n", - i, nsize, DKEY(&key), mdb_leafnode_type(node)); - } - total = EVEN(total); - } - mdb_print("Total: header %u + contents %u + unused %u\n", - IS_LEAF2(mp) ? PAGEHDRSZ : PAGEBASE + mp->mp_lower, total, SIZELEFT(mp)); -} - -static void -mdb_cursor_chk(MDB_cursor *mc) -{ - unsigned i; - MDB_node *node; - MDB_page *mp; - - if (!mc->mc_snum || !(mc->mc_flags & C_INITIALIZED)) return; - for (i=0; imc_top; i++) { - mp = mc->mc_pg[i]; - node = NODEPTR(mp, mc->mc_ki[i]); - if (unlikely(NODEPGNO(node) != mc->mc_pg[i+1]->mp_pgno)) - mdb_print("oops!\n"); - } - if (unlikely(mc->mc_ki[i] >= NUMKEYS(mc->mc_pg[i]))) - mdb_print("ack!\n"); - if (XCURSOR_INITED(mc)) { - node = NODEPTR(mc->mc_pg[mc->mc_top], mc->mc_ki[mc->mc_top]); - if (((node->mn_flags & (F_DUPDATA|F_SUBDATA)) == F_DUPDATA) && - mc->mc_xcursor->mx_cursor.mc_pg[0] != NODEDATA(node)) { - mdb_print("blah!\n"); - } - } -} -#endif /* 0 */ - -/** Count all the pages in each DB and in the freelist - * and make sure it matches the actual number of pages - * being used. - * All named DBs must be open for a correct count. - */ -static void mdb_audit(MDB_txn *txn) -{ - MDB_cursor mc; - MDB_val key, data; - MDB_ID freecount, count; - MDB_dbi i; - int rc; - - freecount = 0; - mdb_cursor_init(&mc, txn, FREE_DBI, NULL); - while ((rc = mdb_cursor_get(&mc, &key, &data, MDB_NEXT)) == 0) - freecount += *(MDB_ID *)data.mv_data; - mdb_tassert(txn, rc == MDB_NOTFOUND); - - count = 0; - for (i = 0; imt_numdbs; i++) { - MDB_xcursor mx; - if (!(txn->mt_dbflags[i] & DB_VALID)) - continue; - mdb_cursor_init(&mc, txn, i, &mx); - if (txn->mt_dbs[i].md_root == P_INVALID) - continue; - count += txn->mt_dbs[i].md_branch_pages + - txn->mt_dbs[i].md_leaf_pages + - txn->mt_dbs[i].md_overflow_pages; - if (txn->mt_dbs[i].md_flags & MDB_DUPSORT) { - rc = mdb_page_search(&mc, NULL, MDB_PS_FIRST); - for (; rc == MDB_SUCCESS; rc = mdb_cursor_sibling(&mc, 1)) { - unsigned j; - MDB_page *mp; - mp = mc.mc_pg[mc.mc_top]; - for (j=0; jmn_flags & F_SUBDATA) { - MDB_db db; - memcpy(&db, NODEDATA(leaf), sizeof(db)); - count += db.md_branch_pages + db.md_leaf_pages + - db.md_overflow_pages; - } - } - } - mdb_tassert(txn, rc == MDB_NOTFOUND); - } - } - if (freecount + count + NUM_METAS != txn->mt_next_pgno) { - mdb_print("audit: %lu freecount: %lu count: %lu total: %lu next_pgno: %lu\n", - txn->mt_txnid, freecount, count+NUM_METAS, - freecount+count+NUM_METAS, txn->mt_next_pgno); - } -} - int mdb_cmp(MDB_txn *txn, MDB_dbi dbi, const MDB_val *a, const MDB_val *b) { @@ -3995,9 +3836,6 @@ mdb_txn_commit(MDB_txn *txn) env->me_pghead = NULL; mdb_midl_shrink(&txn->mt_free_pgs); - if (mdb_audit_enabled()) - mdb_audit(txn); - rc = mdb_page_flush(txn, 0); if (likely(rc == MDB_SUCCESS)) { MDB_meta meta; From e1ce55d0e6928f0bcf095c078daab8c7152613d0 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Wed, 29 Aug 2018 01:25:01 +0100 Subject: [PATCH 19/26] mdbx-doc: import - GET_MULTIPLE etc don't return the key (ITS#8908). Unnecessary since these are DUPs, the key will always be the same --- lmdb.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lmdb.h b/lmdb.h index 4d7d658e..d20b21ec 100644 --- a/lmdb.h +++ b/lmdb.h @@ -390,7 +390,7 @@ typedef enum MDB_cursor_op { MDB_GET_BOTH, /**< Position at key/data pair. Only for #MDB_DUPSORT */ MDB_GET_BOTH_RANGE, /**< position at key, nearest data. Only for #MDB_DUPSORT */ MDB_GET_CURRENT, /**< Return key/data at current cursor position */ - MDB_GET_MULTIPLE, /**< Return key and up to a page of duplicate data items + MDB_GET_MULTIPLE, /**< Return up to a page of duplicate data items from current cursor position. Move cursor to prepare for #MDB_NEXT_MULTIPLE. Only for #MDB_DUPFIXED */ MDB_LAST, /**< Position at last key/data item */ @@ -399,7 +399,7 @@ typedef enum MDB_cursor_op { MDB_NEXT, /**< Position at next data item */ MDB_NEXT_DUP, /**< Position at next data item of current key. Only for #MDB_DUPSORT */ - MDB_NEXT_MULTIPLE, /**< Return key and up to a page of duplicate data items + MDB_NEXT_MULTIPLE, /**< Return up to a page of duplicate data items from next cursor position. Move cursor to prepare for #MDB_NEXT_MULTIPLE. Only for #MDB_DUPFIXED */ MDB_NEXT_NODUP, /**< Position at first data item of next key */ @@ -410,7 +410,7 @@ typedef enum MDB_cursor_op { MDB_SET, /**< Position at specified key */ MDB_SET_KEY, /**< Position at specified key, return key + data */ MDB_SET_RANGE, /**< Position at first key greater than or equal to specified key. */ - MDB_PREV_MULTIPLE /**< Position at previous page and return key and up to + MDB_PREV_MULTIPLE /**< Position at previous page and return up to a page of duplicate data items. Only for #MDB_DUPFIXED */ } MDB_cursor_op; From c5e72817cac7de09dc4e351c0cced960197aa637 Mon Sep 17 00:00:00 2001 From: moneromooo-monero Date: Tue, 15 May 2018 10:53:13 +0100 Subject: [PATCH 20/26] mdbx-doc: import - mdb_cursor_del does not invalidate the cursor (ITS#8857). --- lmdb.h | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lmdb.h b/lmdb.h index d20b21ec..f1b08f57 100644 --- a/lmdb.h +++ b/lmdb.h @@ -1589,6 +1589,10 @@ int mdb_cursor_put(MDB_cursor *cursor, MDB_val *key, MDB_val *data, /** @brief Delete current key/data pair * * This function deletes the key/data pair to which the cursor refers. + * This does not invalidate the cursor, so operations such as MDB_NEXT + * can still be used on it. + * Both MDB_NEXT and MDB_GET_CURRENT will return the same record after + * this operation. * @param[in] cursor A cursor handle returned by #mdb_cursor_open() * @param[in] flags Options for this operation. This parameter * must be set to 0 or one of the values described here. From 629e58788261d2d069ea62be0e9a1d666eab6b32 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Wed, 30 Jan 2019 23:43:34 +0000 Subject: [PATCH 21/26] mdbx: import - tweak mdb_page_split (ITS#8969). Bump up number of keys for which we use fine-grained splitpoint search Change-Id: I9830e143f5f5aaa4c2170a304ebc89cf67b7f3bc --- mdb.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mdb.c b/mdb.c index be98564b..8c6cbd18 100644 --- a/mdb.c +++ b/mdb.c @@ -8921,7 +8921,7 @@ mdb_page_split(MDB_cursor *mc, MDB_val *newkey, MDB_val *newdata, pgno_t newpgno * the split so the new page is emptier than the old page. * This yields better packing during sequential inserts. */ - if (nkeys < 20 || nsize > pmax/16 || newindx >= nkeys) { + if (nkeys < 32 || nsize > pmax/16 || newindx >= nkeys) { /* Find split point */ psize = 0; if (newindx <= split_indx || newindx >= nkeys) { From 6a0fb17132b9d83820569ec1c0f322137c4d0ae3 Mon Sep 17 00:00:00 2001 From: Leo Yuriev Date: Sun, 3 Feb 2019 13:00:51 +0300 Subject: [PATCH 22/26] mdbx: sync/update CHANGES. Change-Id: I0ad0fd44a1cc7cedd87a96c366ce476b14a2e8d0 --- CHANGES | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/CHANGES b/CHANGES index 93486855..ec85e239 100644 --- a/CHANGES +++ b/CHANGES @@ -3,7 +3,28 @@ MDBX Add error MDB_PROBLEM, replace some MDB_CORRUPTED Workarounds for glibc bugs: #21031 and 21032. -LMDB 0.9.20 Release Engineering +LMDB 0.9.24 Engineering + ITS#8969 Tweak mdb_page_split + +LMDB 0.9.23 Release (2018/12/19) + ITS#8756 Fix loose pages in dirty list + ITS#8831 Fix mdb_load flag init + ITS#8844 Fix mdb_env_close in forked process + Documentation + ITS#8857 mdb_cursor_del doesn't invalidate cursor + ITS#8908 GET_MULTIPLE etc don't change passed in key + +LMDB 0.9.22 Release (2018/03/22) + Fix MDB_DUPSORT alignment bug (ITS#8819) + Fix regression with new db from 0.9.19 (ITS#8760) + Fix liblmdb to build on Solaris (ITS#8612) + Fix delete behavior with DUPSORT DB (ITS#8622) + Fix mdb_cursor_get/mdb_cursor_del behavior (ITS#8722) + +LMDB 0.9.21 Release (2017/06/01) + Fix xcursor after cursor_del (ITS#8622) + +LMDB 0.9.20 (Withdrawn) Fix mdb_load with escaped plaintext (ITS#8558) Fix mdb_cursor_last / mdb_put interaction (ITS#8557) From 83193f4a65837e34f32cacec60ff57ad2ce775a9 Mon Sep 17 00:00:00 2001 From: Leo Yuriev Date: Sat, 9 Feb 2019 10:42:39 +0300 Subject: [PATCH 23/26] mdbx: fix typos (minor). --- Doxyfile | 10 +++++----- lmdb.h | 2 +- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Doxyfile b/Doxyfile index 5ca2cfe8..e51fe756 100644 --- a/Doxyfile +++ b/Doxyfile @@ -57,7 +57,7 @@ CREATE_SUBDIRS = NO # Croatian, Czech, Danish, Dutch, Esperanto, Farsi, Finnish, French, German, # Greek, Hungarian, Italian, Japanese, Japanese-en (Japanese with English # messages), Korean, Korean-en, Lithuanian, Norwegian, Macedonian, Persian, -# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrilic, Slovak, +# Polish, Portuguese, Romanian, Russian, Serbian, Serbian-Cyrillic, Slovak, # Slovene, Spanish, Swedish, Ukrainian, and Vietnamese. OUTPUT_LANGUAGE = English @@ -211,7 +211,7 @@ OPTIMIZE_OUTPUT_VHDL = NO # parses. With this tag you can assign which parser to use for a given extension. # Doxygen has a built-in mapping, but you can override or extend it using this # tag. The format is ext=language, where ext is a file extension, and language -# is one of the parsers supported by doxygen: IDL, Java, Javascript, CSharp, C, +# is one of the parsers supported by doxygen: IDL, Java, JavaScript, CSharp, C, # C++, D, PHP, Objective-C, Python, Fortran, VHDL, C, C++. For instance to make # doxygen treat .inc files as Fortran files (default is PHP), and .f files as C # (default is Fortran), use: inc=Fortran f=C. Note that for custom extensions @@ -550,7 +550,7 @@ WARN_IF_UNDOCUMENTED = YES WARN_IF_DOC_ERROR = YES -# This WARN_NO_PARAMDOC option can be abled to get warnings for +# This WARN_NO_PARAMDOC option can be enabled to get warnings for # functions that are documented, but have no documentation for their parameters # or return value. If set to NO (the default) doxygen will only warn about # wrong or incomplete parameter documentation, but not about the absence of @@ -1051,7 +1051,7 @@ EXT_LINKS_IN_WINDOW = NO FORMULA_FONTSIZE = 10 -# Use the FORMULA_TRANPARENT tag to determine whether or not the images +# Use the FORMULA_TRANSPARENT tag to determine whether or not the images # generated for formulas are transparent PNGs. Transparent PNGs are # not supported properly for IE 6.0, but are supported on all modern browsers. # Note that when changing this option you need to delete any form_*.png files @@ -1071,7 +1071,7 @@ SEARCHENGINE = YES # When the SERVER_BASED_SEARCH tag is enabled the search engine will be # implemented using a PHP enabled web server instead of at the web client -# using Javascript. Doxygen will generate the search PHP script and index +# using JavaScript. Doxygen will generate the search PHP script and index # file to put on the web server. The advantage of the server # based approach is that it scales better to large projects and allows # full text search. The disadvances is that it is more difficult to setup diff --git a/lmdb.h b/lmdb.h index f1b08f57..6cb7e6bf 100644 --- a/lmdb.h +++ b/lmdb.h @@ -612,7 +612,7 @@ int mdb_env_create(MDB_env **env); *
  • #MDB_NOTLS * Don't use Thread-Local Storage. Tie reader locktable slots to * #MDB_txn objects instead of to threads. I.e. #mdb_txn_reset() keeps - * the slot reseved for the #MDB_txn object. A thread may use parallel + * the slot reserved for the #MDB_txn object. A thread may use parallel * read-only transactions. A read-only transaction may span threads if * the user synchronizes its use. Applications that multiplex many * user threads over individual OS threads need this option. Such an From b5479260ea362f5f555b965ed9455e7ad4181611 Mon Sep 17 00:00:00 2001 From: Leonid Yuriev Date: Sat, 22 Jun 2019 17:23:25 +0300 Subject: [PATCH 24/26] mdbx: backport - avoid FreeDB corruption due deep recursive rebalance from freelist_save(). Change-Id: I65b0b62c3e787802c0150c74826f181a8f6d7902 --- mdb.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/mdb.c b/mdb.c index 8c6cbd18..149c2882 100644 --- a/mdb.c +++ b/mdb.c @@ -3171,6 +3171,7 @@ mdb_prep_backlog(MDB_txn *txn, MDB_cursor *mc) const int extra = (txn->mt_env->me_flags & MDBX_LIFORECLAIM) ? 2 : 1; if (mdb_backlog_size(txn) < mc->mc_db->md_depth + extra) { + mc->mc_flags &= ~C_RECLAIMING; int rc = mdb_cursor_touch(mc); if (unlikely(rc)) return rc; @@ -3183,6 +3184,7 @@ mdb_prep_backlog(MDB_txn *txn, MDB_cursor *mc) break; } } + mc-> mc_flags |= C_RECLAIMING; } return MDB_SUCCESS; @@ -3207,6 +3209,7 @@ mdb_freelist_save(MDB_txn *txn) const int lifo = (env->me_flags & MDBX_LIFORECLAIM) != 0; mdb_cursor_init(&mc, txn, FREE_DBI, NULL); + mc.mc_flags |= C_RECLAIMING; mc.mc_next = txn->mt_cursors[FREE_DBI]; txn->mt_cursors[FREE_DBI] = &mc; @@ -3235,9 +3238,7 @@ again: total_room = head_room = 0; more = 1; mdb_tassert(txn, pglast <= env->me_pglast); - mc.mc_flags |= C_RECLAIMING; rc = mdb_cursor_del(&mc, 0); - mc.mc_flags &= ~C_RECLAIMING; if (unlikely(rc)) goto bailout; } @@ -3254,9 +3255,7 @@ again: rc = mdb_prep_backlog(txn, &mc); if (unlikely(rc)) goto bailout; - mc.mc_flags |= C_RECLAIMING; rc = mdb_cursor_del(&mc, 0); - mc.mc_flags &= ~C_RECLAIMING; if (unlikely(rc)) goto bailout; } @@ -3279,7 +3278,9 @@ again: if (freecnt < txn->mt_free_pgs[0]) { if (unlikely(!freecnt)) { /* Make sure last page of freeDB is touched and on freelist */ + mc.mc_flags &= ~C_RECLAIMING; rc = mdb_page_search(&mc, NULL, MDB_PS_LAST|MDB_PS_MODIFY); + mc.mc_flags |= C_RECLAIMING; if (unlikely(rc && rc != MDB_NOTFOUND)) goto bailout; } @@ -3333,7 +3334,9 @@ again: if (lifo) { if (refill_idx > (txn->mt_lifo_reclaimed ? txn->mt_lifo_reclaimed[0] : 0)) { /* LY: need just a txn-id for save page list. */ + mc.mc_flags &= ~C_RECLAIMING; rc = mdb_page_alloc(&mc, 0, NULL, MDBX_ALLOC_GC | MDBX_ALLOC_KICK); + mc.mc_flags |= C_RECLAIMING; if (likely(rc == 0)) /* LY: ok, reclaimed from freedb. */ continue; From 4bfb3ec23877b93d274ae1c52c2c0796df1604a3 Mon Sep 17 00:00:00 2001 From: Leonid Yuriev Date: Sat, 27 Jul 2019 22:13:28 +0300 Subject: [PATCH 25/26] Note about moving from Github. The [repository was moved](https://abf.io/erthink/libmdbx) due to illegal discriminatory blocking of access from the territory of the Russian Crimea and for sovereign crimeans. Crimea is Russia. Change-Id: I5a4eb6b50be2e88f4dc6658d00331954e373603a --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 4a1ea684..b9ad9d86 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,7 @@ +## The [repository was moved](https://abf.io/erthink/libmdbx) due to illegal discriminatory blocking of access from the territory of the Russian Crimea and for sovereign crimeans. + +--- + libmdbx ====================================== Extended LMDB, aka "Расширенная LMDB". From 49b83e5adf05369e437e34785f9c8d7cdced37a9 Mon Sep 17 00:00:00 2001 From: Howard Chu Date: Mon, 26 Aug 2019 17:51:53 +0100 Subject: [PATCH 26/26] mdbx: import - ITS#9068 fix backslash escaping. mdb_load wasn't properly inserting escaped backslashes into the data. mdb_dump wasn't escaping backslashes when generating printable output. Change-Id: I94796846f77f0af1f50214dde0c701566cc5e9ff --- mdb_dump.c | 2 ++ mdb_load.c | 4 ++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/mdb_dump.c b/mdb_dump.c index 485f8f4f..27ae8b34 100644 --- a/mdb_dump.c +++ b/mdb_dump.c @@ -67,6 +67,8 @@ static void text(MDB_val *v) end = c + v->mv_size; while (c < end) { if (isprint(*c)) { + if (*c == '\\') + putchar('\\'); putchar(*c); } else { putchar('\\'); diff --git a/mdb_load.c b/mdb_load.c index e2cddd53..73a3c19c 100644 --- a/mdb_load.c +++ b/mdb_load.c @@ -241,7 +241,7 @@ badend: while (c2 < end) { if (*c2 == '\\') { if (c2[1] == '\\') { - c1++; c2 += 2; + *c1++ = *c2; } else { if (c2+3 > end || !isxdigit(c2[1]) || !isxdigit(c2[2])) { Eof = 1; @@ -249,8 +249,8 @@ badend: return EOF; } *c1++ = unhex(++c2); - c2 += 2; } + c2 += 2; } else { /* copies are redundant when no escapes were used */ *c1++ = *c2++;