]> granicus.if.org Git - php/commitdiff
Fix #78808: [LMDB] MDB_MAP_FULL: Environment mapsize limit reached
authorChristoph M. Becker <cmbecker69@gmx.de>
Thu, 14 Nov 2019 10:21:41 +0000 (11:21 +0100)
committerChristoph M. Becker <cmbecker69@gmx.de>
Fri, 3 Jan 2020 17:49:12 +0000 (18:49 +0100)
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
UPGRADING
ext/dba/dba_lmdb.c
ext/dba/tests/bug78808.phpt [new file with mode: 0644]

diff --git a/NEWS b/NEWS
index 2e7761a5eafc6e75dc8dfa9834bdc8d816a63275..b71fad0f8f577b8e9adfc7d12abc36972fcb1e50 100644 (file)
--- 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)
index 09288192405fc395b3589a25411eebef9d2f60d9..f2dd1060d91a87903b9430aee9fc2558793a7d59 100644 (file)
--- 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 (`"',."`)
index 506ae00827863717bb0c5c38a71a1f57c0f8e571..b3f6442e0ccd09f0e7d1e3f1bb5a9d7d2da9b1f9 100644 (file)
@@ -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 (file)
index 0000000..9aa4e22
--- /dev/null
@@ -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';
+?>