Skip to content

Commit c05a069

Browse files
committed
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.
1 parent 1817230 commit c05a069

File tree

4 files changed

+51
-0
lines changed

4 files changed

+51
-0
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ PHP NEWS
1313
- Date:
1414
. Fixed bug #79015 (undefined-behavior in php_date.c). (cmb)
1515

16+
- DBA:
17+
. Fixed bug #78808 ([LMDB] MDB_MAP_FULL: Environment mapsize limit reached).
18+
(cmb)
19+
1620
- Fileinfo:
1721
. Fixed bug #74170 (locale information change after mime_content_type).
1822
(Sergei Turchanov)

UPGRADING

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -490,6 +490,12 @@ JSON:
490490
Curl:
491491
. libcurl >= 7.15.5 is now required.
492492

493+
DBA:
494+
. As of PHP 7.3.14, dba_open() accepts a fifth optional parameter for lmdb
495+
databases which allows to specify the mapsize. The parameter defaults to
496+
zero, in which case the compiled in default mapsize (usually 1048576) will
497+
be used. The mapsize should be a multiple of the page size of the OS.
498+
493499
Filter:
494500
. FILTER_VALIDATE_FLOAT now also supports a `thousand` option, which
495501
defines the set of allowed thousand separator chars. The default (`"',."`)

ext/dba/dba_lmdb.c

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,18 @@ DBA_OPEN_FUNC(lmdb)
4343
MDB_env *env;
4444
MDB_txn *txn;
4545
int rc, mode = 0644, flags = MDB_NOSUBDIR;
46+
zend_long mapsize = 0;
4647

4748
if(info->argc > 0) {
4849
mode = zval_get_long(&info->argv[0]);
4950

51+
if (info->argc > 1) {
52+
mapsize = zval_get_long(&info->argv[1]);
53+
if (mapsize < 0) {
54+
*error = "mapsize must be greater than or equal to zero";
55+
return FAILURE;
56+
}
57+
}
5058
/* TODO implement handling of the additional flags. */
5159
}
5260

@@ -56,6 +64,14 @@ DBA_OPEN_FUNC(lmdb)
5664
return FAILURE;
5765
}
5866

67+
if (mapsize > 0) {
68+
rc = mdb_env_set_mapsize(env, (size_t) mapsize);
69+
if (rc) {
70+
*error = mdb_strerror(rc);
71+
return FAILURE;
72+
}
73+
}
74+
5975
rc = mdb_env_open(env, info->path, flags, mode);
6076
if (rc) {
6177
*error = mdb_strerror(rc);

ext/dba/tests/bug78808.phpt

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
--TEST--
2+
Bug #78808 ([LMDB] MDB_MAP_FULL: Environment mapsize limit reached)
3+
--SKIPIF--
4+
<?php
5+
if (getenv("SKIP_SLOW_TESTS")) die("skip slow test");
6+
$handler = 'lmdb';
7+
require_once __DIR__ .'/skipif.inc';
8+
?>
9+
--FILE--
10+
<?php
11+
$handler = 'lmdb';
12+
require_once __DIR__ .'/test.inc';
13+
$lmdb_h = dba_open($db_filename, 'c', 'lmdb', 0644, 5*1048576);
14+
for ($i = 0; $i < 50000; $i++) {
15+
dba_insert('key' . $i, 'value '. $i, $lmdb_h);
16+
}
17+
dba_close($lmdb_h);
18+
echo "done\n";
19+
?>
20+
--EXPECT--
21+
done
22+
--CLEAN--
23+
<?php
24+
require_once dirname(__FILE__) .'/clean.inc';
25+
?>

0 commit comments

Comments
 (0)