logoalt Hacker News

Lightning Memory-Mapped Database Manager (LMDB) 1.0

66 pointsby radiatoryesterday at 8:01 PM38 commentsview on HN

Comments

hmryyesterday at 8:54 PM

Do people have good experiences with LMDB, in terms of reliability? I've never used it in production, but I've read through the code and design documents for a database implementation class.

I remember some strange code (such as pushing return values 4k above the stack, with a comment like "this works as long as the caller doesn't use more than 4k of stack space before accessing the return value"), and the author also shared some unconventional opinions about undefined behavior (like "Compilers are deterministic, if I know what platform I'm compiling to then no behavior is undefined. And if compiler authors disagree, they are morons.")

But presumably it's thoroughly tested, so those aren't problems in practice? Would be really interested to hear from people who've actually used it. I've mainly stuck to SQLite instead.

show 10 replies
hilariouslyyesterday at 9:05 PM

Maybe rephrase this part - "It is read-only by default as this provides total immunity to corruption. Using read-write mode offers much higher write performance, but adds the possibility for stray application writes thru pointers to silently corrupt the database."

I generally do think read-write mode would offer higher write performance than read only as well :)

show 1 reply
radiatoryesterday at 8:13 PM

New features in LMDB 1.0 include:

- support for incremental backup

- support for page-level checksums and encryption

- support for DB on raw block devices

- support for 2-phase commit

- support for page sizes up to 64KB

plus other minor additions to the API.

jnwatsontoday at 12:02 AM

Bummer. I'm the maintainer of the Python bindings.

I have to figure out how to support both versions now...

paveworldyesterday at 8:30 PM

HTTP ?? Com’on man

show 1 reply
quotemstryesterday at 10:13 PM

I've never understood the fascination some people have with mmap. Memory-mapped file IO is just a RAM cache combined with a hidden system call (a page fault) to fill the cache. You can do the same thing yourself by using O_DIRECT to fill regular anonymous memory. If you're feeling social, you can fill a mapped and shared memfd.

You can seal memfds too, which means that the "read-only" mode is easy to implement: just map your memfd for write, apply F_SEAL_FUTURE_WRITE, and share the memfd to anyone you want to have read-only access.

By doing your own O_DIRECT IO instead of relying on the kernel's defaults, you get a lot more control. You choose how much readahead to do; you choose your read-cluster size. You choose your cache eviction strategy. You choose when to write back.

BTW: O_DIRECT can also be done asynchronously using aio or io_uring. There's no such thing as an asynchronous page fault. And IO errors? Would you rather deal with EIO or SIGBUS?

Why would you want the kernel to do these things for you? It'll do a worse job: it has less information than you do and has to use blunt heuristics that work sort-of-good-enough for the whole world, not just your program.

And it's not any faster either. O_DIRECT is DMA. A page cache fill is also DMA. It's the same operation, spelled differently.

show 4 replies
heliskyr2today at 3:06 AM

[flagged]