闪电内存映射数据库管理器 (LMDB) 1.0

Hacker News Top 工具

摘要

LMDB 1.0 是一款高性能、支持事务的键值存储数据库库,具有 ACID 语义、内存映射存储以及完全的线程/进程安全性。新版本包含从 0.9 版本的升级,并继续提供简单、可靠的嵌入式数据库解决方案。

暂无内容
查看原文
查看缓存全文

缓存时间: 2026/07/02 23:09

# 闪电内存映射数据库管理器 (LMDB) 来源: http://www.lmdb.tech/doc/ ## 简介 LMDB 是一个基于 Btree 的数据库管理库,其设计大致模仿了 BerkeleyDB API,但大大简化。整个数据库通过内存映射暴露,所有数据获取都直接从映射内存中返回,因此在数据获取期间不会发生 malloc 或 memcpy。因此,该库极其简单,因为它不需要自己的页面缓存层,并且具有极高的性能和内存效率。它还完全支持事务,具有完整的 ACID 语义,并且当内存映射为只读时,数据库的完整性不会被应用程序代码的野指针写入破坏。 ## 注意: 本文档适用于 LMDB 1.0。LMDB 0.9 的文档已归档于此 (http://www.lmdb.tech/doc/lmdb0.9/)。 **如果您之前使用过 LMDB 0.9,请参阅从 0.9 版本升级 (http://www.lmdb.tech/doc/upgrading.html)。** 该库完全支持线程感知,并支持来自多个进程和线程的并发读/写访问。数据页面使用写时复制策略,因此永远不会覆盖任何活动数据页面,这也提供了对损坏的抵抗力,并消除了系统崩溃后进行任何特殊恢复过程的需要。写入是完全序列化的;一次只能有一个写事务处于活动状态,这保证了写入器永远不会死锁。数据库结构是多版本的,因此读取器无需锁即可运行;写入器不会阻塞读取器,读取器也不会阻塞写入器。 与其他使用预写式事务日志或仅追加数据写入的著名数据库机制不同,LMDB 在运行期间无需维护。预写式日志器和仅追加数据库都需要定期检查点和/或压缩其日志或数据库文件,否则它们会无限制地增长。LMDB 在数据库内部跟踪空闲页面,并将其用于新的写操作,因此在正常使用中,数据库大小不会无限制增长。 内存映射可用作只读或读写映射。默认为只读,因为这提供了对损坏的完全免疫力。使用读写模式可提供更高的写入性能,但增加了通过指针的应用程序写入可能静默损坏数据库的可能性。当然,如果您的应用程序代码已知是无 bug 的(...),那么这不是问题。 如果这是您第一次使用事务性嵌入式键/值存储,您可能会发现入门 (http://www.lmdb.tech/doc/starting.html) 页面很有帮助。 ## 注意事项 锁定文件的故障排除,以及 BSD 系统上的信号量: - 损坏的锁定文件可能导致同步问题。由中止的程序留下的陈旧读取器事务会导致进一步的写入使数据库快速增长,而陈旧的锁定可能会阻塞进一步的操作。修复:定期使用 `mdb_reader_check` (http://www.lmdb.tech/doc/group__internal.html#ga576f9ec8e49724e52b2cd7ce7b832856) 函数或 `mdb_stat` (http://www.lmdb.tech/doc/man1/mdb_stat_1.html) 工具检查陈旧的读取器。在大多数系统上,陈旧的写入器会被自动清除: - Windows - 自动 - BSD、使用 SysV 信号量的系统 - 自动 - Linux、使用具有 Robust 选项的 POSIX 互斥锁的系统 - 自动。否则,只需让所有使用数据库的程序关闭它;每次首次打开环境时,锁定文件都会被重置。 - 在 BSD 系统或其他配置了 MDB_USE_SYSV_SEM 或 MDB_USE_POSIX_SEM 的系统上,由于其他用户 ID 拥有的信号量,启动可能会失败。修复:以信号量所有者(通常是最后一个用户)或 root 身份打开并关闭数据库,同时确保没有其他进程正在使用数据库。 限制/注意事项(除某些函数中列出的之外): - 在 BSD 系统上或当配置了 MDB_USE_POSIX_SEM 时,通常只有数据库所有者才能使用数据库。如上所述,多个用户可能导致后续启动失败。 - 通常没有纯粹的只读模式,因为读取器需要对锁和锁定文件的写访问。例外情况:在只读文件系统上,或使用 `mdb_env_open()` (http://www.lmdb.tech/doc/group__mdb.html#ga32a193c6bf4d7d5c5d579e71f22e9340) 下描述的 `MDB_NOLOCK` (http://www.lmdb.tech/doc/group__mdb__env.html#ga9b0450b1a87cb9f22e033550e49e5037) 标志时。 - LMDB 配置通常会为未来的增长保留相当大的**未使用**内存地址空间和可能的文件大小。这不会使用实际的内存或磁盘空间,但用户可能需要了解差异,以免被吓到。 - 默认情况下,在 0.9.10 之前的版本中,数据文件中未使用的部分可能会收到来自其他代码释放的内存中的垃圾数据。(当使用 `MDB_WRITEMAP` (http://www.lmdb.tech/doc/group__mdb__env.html#ga7b81e9fd5f8fae38786d67e1a8387fa7) 标志时不会发生这种情况。)从 0.9.10 开始,默认行为是在写入数据文件之前初始化此类内存。由于这种初始化可能会带来轻微的性能成本,应用程序可以使用 `MDB_NOMEMINIT` (http://www.lmdb.tech/doc/group__mdb__env.html#gafa035a1f17ebf31376eafb7bd2cdd448) 标志禁用它。处理敏感数据且不应写出这些数据的应用程序不应使用此标志。当使用 `MDB_WRITEMAP` (http://www.lmdb.tech/doc/group__mdb__env.html#ga7b81e9fd5f8fae38786d67e1a8387fa7) 时,此标志无关紧要。 - 一个线程一次只能使用一个事务,加上任何子事务。每个事务属于一个线程。请参见下文。`MDB_NOTLS` (http://www.lmdb.tech/doc/group__mdb__env.html#ga5dca84a576d14b4bfe2deddc2dc622d3) 标志会改变只读事务的这一行为。 - 在打开它的进程中使用 MDB_env*,不要在 fork() 之后使用。 - 不要在同一进程中同时打开同一个 LMDB 数据库两次。即使是通过普通的 open() 调用也不行——close() 它会破坏 fcntl() 建议性锁定。(在 fork() - exec*() 之后重新打开是允许的,因为锁定文件设置了 FD_CLOEXEC。) - 避免长时间存在的事务。读取事务会阻止由较新写事务释放的页面被重用,因此数据库可能会快速增长。写事务会阻止其他写事务,因为写入是串行化的。 - 避免挂起带有活动事务的进程。这些事务将如上所述成为“长时间存在”的。此外,在写入器提交时挂起的读取事务有时可能会看到错误的数据。 ...当多个进程可以同时使用一个数据库时: - 避免中止带有活动事务的进程。该事务会变成如上所述的“长时间存在”,直到执行陈旧读取器检查或重置锁定文件为止,因为该进程可能不会从锁定文件中移除它。如果系统清除陈旧的写入器,这不适用于写事务,请参见上文。 - 如果无论如何都这样做,请定期检查陈旧的读取器。或者偶尔关闭环境,以便可以重置锁定文件。 - 不要在远程文件系统上使用 LMDB 数据库,即使是在同一主机上的进程之间。这会在某些操作系统上破坏 flock(),可能破坏内存映射同步,并且肯定破坏不同主机上程序之间的同步。 - 如果另一个进程恰好同时打开或关闭数据库,则打开数据库可能会失败。 版权 Copyright 2011-2026 Howard Chu, Symas Corp. 保留所有权利。 只有在 OpenLDAP 公共许可证授权下,才允许以源代码和二进制形式重新分发和使用,无论是否修改。 该许可证的副本可在发行版顶层目录下的 LICENSE 文件中获得,或者通过 http://www.openldap.org/license.html 获取。 衍生自:此代码衍生自 Martin Hedenfalk 编写的 btree.c。 Copyright (c) 2009, 2010 Martin Hedenfalk [email protected] (http://www.lmdb.tech/doc/#) 特此授予出于任何目的(无论是否收费)使用、复制、修改和分发本软件的权利,前提是上述版权声明和本许可声明出现在所有副本中。 本软件按“原样”提供,作者否认与本软件有关的所有保证,包括所有对适销性和适用性的默示保证。在任何情况下,作者均不对因使用或执行本软件而产生的任何特殊、直接、间接或后果性损害或任何数据、利润或使用损失承担责任,无论是合同诉讼、疏忽行为还是其他侵权行为。

相似文章

LMCache/LMCache

GitHub Trending (daily)

LMCache 是一个开源的KV缓存管理层,用于LLM推理,通过支持跨推理引擎持久化存储和复用KV缓存,减少首Token延迟并提升吞吐量。

vllm-project/vllm v0.20.1

GitHub Releases Watchlist

vLLM v0.20.1 是一个小版本更新,针对这款流行的开源大语言模型推理和服务库,继续保持其高吞吐量和高效内存管理的核心优势。

DimMem:面向高效长期智能体记忆的维度结构化

arXiv cs.CL

DimMem 提出了一种用于 LLM 智能体的维度记忆框架,将记忆表示为具有显式字段的原子化、类型化单元,在 LoCoMo-10 和 LongMemEval-S 上实现了最先进的准确率,同时将 token 成本降低了 24%。