From c05a069adfcca56763d5db06afce8801382477a5 Mon Sep 17 00:00:00 2001 From: "Christoph M. Becker" Date: Thu, 14 Nov 2019 11:21:41 +0100 Subject: [PATCH] Fix #78808: [LMDB] MDB_MAP_FULL: Environment mapsize limit reached We implement support for a fifth parameter, which allows to specify the mapsize. The parameter defaults to zero, in which case the compiled in default mapsize (usually 1048576) will be used. The mapsize should be a multiple of the page size of the OS. --- NEWS | 4 ++++ UPGRADING | 6 ++++++ ext/dba/dba_lmdb.c | 16 ++++++++++++++++ ext/dba/tests/bug78808.phpt | 25 +++++++++++++++++++++++++ 4 files changed, 51 insertions(+) create mode 100644 ext/dba/tests/bug78808.phpt diff --git a/NEWS b/NEWS index 2e7761a5ea..b71fad0f8f 100644 --- a/NEWS +++ b/NEWS @@ -13,6 +13,10 @@ PHP NEWS - Date: . Fixed bug #79015 (undefined-behavior in php_date.c). (cmb) +- DBA: + . Fixed bug #78808 ([LMDB] MDB_MAP_FULL: Environment mapsize limit reached). + (cmb) + - Fileinfo: . Fixed bug #74170 (locale information change after mime_content_type). (Sergei Turchanov) diff --git a/UPGRADING b/UPGRADING index 0928819240..f2dd1060d9 100644 --- a/UPGRADING +++ b/UPGRADING @@ -490,6 +490,12 @@ JSON: Curl: . libcurl >= 7.15.5 is now required. + DBA: + . As of PHP 7.3.14, dba_open() accepts a fifth optional parameter for lmdb + databases which allows to specify the mapsize. The parameter defaults to + zero, in which case the compiled in default mapsize (usually 1048576) will + be used. The mapsize should be a multiple of the page size of the OS. + Filter: . FILTER_VALIDATE_FLOAT now also supports a `thousand` option, which defines the set of allowed thousand separator chars. The default (`"',."`) diff --git a/ext/dba/dba_lmdb.c b/ext/dba/dba_lmdb.c index 506ae00827..b3f6442e0c 100644 --- a/ext/dba/dba_lmdb.c +++ b/ext/dba/dba_lmdb.c @@ -43,10 +43,18 @@ DBA_OPEN_FUNC(lmdb) MDB_env *env; MDB_txn *txn; int rc, mode = 0644, flags = MDB_NOSUBDIR; + zend_long mapsize = 0; if(info->argc > 0) { mode = zval_get_long(&info->argv[0]); + if (info->argc > 1) { + mapsize = zval_get_long(&info->argv[1]); + if (mapsize < 0) { + *error = "mapsize must be greater than or equal to zero"; + return FAILURE; + } + } /* TODO implement handling of the additional flags. */ } @@ -56,6 +64,14 @@ DBA_OPEN_FUNC(lmdb) return FAILURE; } + if (mapsize > 0) { + rc = mdb_env_set_mapsize(env, (size_t) mapsize); + if (rc) { + *error = mdb_strerror(rc); + return FAILURE; + } + } + rc = mdb_env_open(env, info->path, flags, mode); if (rc) { *error = mdb_strerror(rc); diff --git a/ext/dba/tests/bug78808.phpt b/ext/dba/tests/bug78808.phpt new file mode 100644 index 0000000000..9aa4e22a32 --- /dev/null +++ b/ext/dba/tests/bug78808.phpt @@ -0,0 +1,25 @@ +--TEST-- +Bug #78808 ([LMDB] MDB_MAP_FULL: Environment mapsize limit reached) +--SKIPIF-- + +--FILE-- + +--EXPECT-- +done +--CLEAN-- + -- 2.40.0