-
I've seen than lmdb is a memory mapped database. If I get this correctly, it means that the files are mapped to a memory location and you read-write to those mappings, which they end in the files. As far as I understand, if you have a 16GB database, then the memory usage would be also 16GB, but I've seen that the files are not increasing the same way as the database files. Does it have any improvements, like "demapping" and "remapping" different files on-the-fly, to keep the RAM usage low? I'm asking because I may use lmdb-js on a project where RAM could be limited. I mean, can a 16GB database be used within a 512MB device and grow "infinitely"? Thank you. |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 4 replies
-
Yes, it can! In our application/servers we currently have about 150GB of database on a server with 64GB of RAM (and lots of other processes running). More precisely memory mapping is mapping to virtual memory. And on most (64-bit) OSes this has a maximum of 256TB (so not quite infinite, but pretty huge and vastly larger than typical physical RAM amounts). And mapping virtual memory to physical memory is handled by OS, and is an sophisticated dynamic algorithm that balances on-demand loading from disk with read-ahead, caching, paging etc. Essentially memory mapping means that the database is directly accessing the OS file cache memory. And so accessing data in the database is subject to paging. If you access a part of the database that is not in the OS file cache, it will be loaded from disk. And parts of the database that are not accessed for long periods of time are subject to being paged out and removed from the file cache (and would be paged in/read from disk on next access). Of course if your database is larger than your physical memory, and you have pretty random access to data, you will frequently be accessing pages that aren't cached in physical memory, and will require disk I/O to load, which can significantly reduce performance. This is universally true with all databases though, and is one of the basic constraints of database performance. If you are in this situation, and are concerned about slower disk-bound
Actually yes, LMDB does support dynamic remapping of database chunks. You can simply set the |
Beta Was this translation helpful? Give feedback.
-
Another question is, so in your 150GB db you need to set a 150GB I'm asking because for another project I'm comparing LMDB to SDLite3 with memory-mapped files enabled and they have this explanation:
So you always want a map size equal or bigger than the database size. I don't know how LMDB deals with the map size. Is this also true for LMDB or it deals this in another way? How it deals creating a too high map size? Will it create a file with that size or will the file increase over time with usage? |
Beta Was this translation helpful? Give feedback.
-
No, we do not. lmdb-js automatically handles setting and growing the mapSize for you.
If the mapSize is set to 1GB and your database is about to grow beyond 1GB, internally lmdb-js detects this condition and automatically remaps the database to a memory map that is twice as big (so in this case, it would automatically expand the memory map to 2GB). The memory map size is stored in the database itself, and so on restart LMDB uses the latest database's stored map size. By default, lmdb-js actually starts with a memory map size of 128KB, and then just automatically grows the memory map by doubling map as necessary. So by default, LMDB will always have a memory map that is as big or bigger than the database (with no "legacy" read/writes to worry about). I'd recommend leaving the default, there is no reason to set it any higher, since lmdb-js automatically makes it as big as necessary (in our 150GB we never manually set any map sizes). (These changes are also automatically detected and propagated across processes, if you are running multiple processes as well)
Since memory maps are automatically grown in response to the actual database size, the memory maps are pretty efficient in terms of using the virtual memory address space. In most 64-bit OSes the maximum virtual memory space is 256TB (a lot!). But if you really need more than that, LMDB actually does have an option,
On almost all modern OSes, the file size will increase over time based on the number of actual pages that have been written/used in the database. I believe there are some old OS/memory map implementations that allocate the file size based on the memory map size, and I believe MacOS allocates disk space for the full memory map, while it is open. So even in these cases the dynamic memory maps ensure that the map size is never more than the twice the database size to protect against excessive allocation. But in general, your file size should correspond to the actual used database size, less than the full memory map. |
Beta Was this translation helpful? Give feedback.
Yes, it can! In our application/servers we currently have about 150GB of database on a server with 64GB of RAM (and lots of other processes running). More precisely memory mapping is mapping to virtual memory. And on most (64-bit) OSes this has a maximum of 256TB (so not quite infinite, but pretty huge and vastly larger than typical physical RAM amounts). And mapping virtual memory to physical memory is handled by OS, and is an sophisticated dynamic algorithm that balances on-demand loading from disk with read-ahead, caching, paging etc. Essentially memory mapping means that the database is directly accessing the O…