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.
This commit is contained in:
Christoph M. Becker 2019-11-14 11:21:41 +01:00
parent 18172303f4
commit c05a069adf
4 changed files with 51 additions and 0 deletions

4
NEWS
View file

@ -13,6 +13,10 @@ PHP NEWS
- Date: - Date:
. Fixed bug #79015 (undefined-behavior in php_date.c). (cmb) . Fixed bug #79015 (undefined-behavior in php_date.c). (cmb)
- DBA:
. Fixed bug #78808 ([LMDB] MDB_MAP_FULL: Environment mapsize limit reached).
(cmb)
- Fileinfo: - Fileinfo:
. Fixed bug #74170 (locale information change after mime_content_type). . Fixed bug #74170 (locale information change after mime_content_type).
(Sergei Turchanov) (Sergei Turchanov)

View file

@ -490,6 +490,12 @@ JSON:
Curl: Curl:
. libcurl >= 7.15.5 is now required. . 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:
. FILTER_VALIDATE_FLOAT now also supports a `thousand` option, which . FILTER_VALIDATE_FLOAT now also supports a `thousand` option, which
defines the set of allowed thousand separator chars. The default (`"',."`) defines the set of allowed thousand separator chars. The default (`"',."`)

View file

@ -43,10 +43,18 @@ DBA_OPEN_FUNC(lmdb)
MDB_env *env; MDB_env *env;
MDB_txn *txn; MDB_txn *txn;
int rc, mode = 0644, flags = MDB_NOSUBDIR; int rc, mode = 0644, flags = MDB_NOSUBDIR;
zend_long mapsize = 0;
if(info->argc > 0) { if(info->argc > 0) {
mode = zval_get_long(&info->argv[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. */ /* TODO implement handling of the additional flags. */
} }
@ -56,6 +64,14 @@ DBA_OPEN_FUNC(lmdb)
return FAILURE; 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); rc = mdb_env_open(env, info->path, flags, mode);
if (rc) { if (rc) {
*error = mdb_strerror(rc); *error = mdb_strerror(rc);

View file

@ -0,0 +1,25 @@
--TEST--
Bug #78808 ([LMDB] MDB_MAP_FULL: Environment mapsize limit reached)
--SKIPIF--
<?php
if (getenv("SKIP_SLOW_TESTS")) die("skip slow test");
$handler = 'lmdb';
require_once __DIR__ .'/skipif.inc';
?>
--FILE--
<?php
$handler = 'lmdb';
require_once __DIR__ .'/test.inc';
$lmdb_h = dba_open($db_filename, 'c', 'lmdb', 0644, 5*1048576);
for ($i = 0; $i < 50000; $i++) {
dba_insert('key' . $i, 'value '. $i, $lmdb_h);
}
dba_close($lmdb_h);
echo "done\n";
?>
--EXPECT--
done
--CLEAN--
<?php
require_once dirname(__FILE__) .'/clean.inc';
?>