闪电内存映射数据库管理器 (LMDB) 1.0
介绍 LMDB 是一个基于 B 树的数据库管理库,松散地基于 BerkeleyDB API,但大大简化。整个数据库以内存映射的方式暴露,所有数据获取直接从映射的内存中返回数据,因此在数据获取过程中不会发生 malloc 或 memcpy。因此,库的设计非常简单,因为它不需要自己的页面缓存层,并且具有极高的性能和内存效率。它还完全支持事务处理,具有完整的 ACID 语义,当内存映射为只读时,数据库完整性不会被应用程序代码中的任意指针写入所损坏。注:这是 LMDB 1.0 的文档。LMDB 0.9 的文档存档在此。如果您之前使用了 LMDB 0.9,请参阅从 0.9 版本升级的说明。该库对线程完全敏感,支持多个进程和线程的并发读写访问。数据页面采用写时复制策略,因此没有活动数据页面会被覆盖,这也增强了抵抗损坏的能力,并消除了系统崩溃后任何特殊恢复程序的需要。写操作完全序列化;同一时间只能有一个写事务处于活动状态,这保证了写入者永远不会死锁。数据库结构是多版本的,因此读者无锁地运行;写入者不能阻塞读取者,读取者也不会阻塞写入者。与其他知名数据库机制不同,后者使用预写日志或仅附加数据写入,LMDB 在运行期间不需要维护。预写日志记录程序和仅附加数据库通常需要定期检查点和/或压缩它们的日志或数据库文件,否则它们会无限增长。LMDB 跟踪数据库中的空闲页面并重新使用它们进行新的写操作,因此在正常使用情况下,数据库大小不会无限增长。内存映射可以作为只读或读写映射使用。默认情况下它是只读的,因为这提供了完全免受损坏的保护。使用读写模式提供了更高的写性能,但也增加了通过指针的任意应用程序写入可能悄悄损坏数据库的可能性。当然,如果您的应用程序代码被认为没有错误(...),那么这就不是问题。如果这是您第一次使用事务嵌入式键值存储,您可能会发现“入门”页面很有帮助。注意事项 在 BSD 系统上处理锁文件和信号量的故障排除:损坏的锁文件可能导致同步问题。被中止程序留存的过时读取事务会导致进一步的写入迅速增长数据库,过时的锁会阻止进一步操作。修复:定期检查过时的读取器,使用 mdb_reader_check 函数或 mdb_stat 工具。过时的写入器将在大多数系统上自动清除:Windows - 自动处理;BSD 系统使用 SysV 信号量 - 自动处理;Linux 系统使用带有鲁棒选项的 POSIX 互斥锁 - 自动处理。否则只需使所有使用数据库的程序关闭它;锁文件在环境的第一次打开时始终重置。在 BSD 系统或其他配置为 MDB_USE_SYSV_SEM 或 MDB_USE_POSIX_SEM 的系统上,启动可能会因被另一个用户 ID 拥有的信号量而失败。修复:作为拥有信号量的用户(可能是最后一个用户)或作为 root 打开并关闭数据库,而没有其他进程使用数据库。限制/注意事项(除了某些函数列出的限制):只有数据库所有者在 BSD 系统上或其他配置为 MDB_USE_POSIX_SEM 时应正常使用数据库。多个用户会导致之后的启动失败,如上所述。通常没有纯粹的只读模式,因为读取者需要对锁和锁文件的写访问。例外:在只读文件系统上或使用 mdb_env_open() 中描述的 MDB_NOLOCK 标志的情况下。LMDB 配置通常会保留相当多的未使用内存地址空间和可能的文件大小,以供未来增长。这并不占用实际的内存或磁盘空间,但用户可能需要理解这一差异,以免被吓到。默认情况下,在 0.9.10 之前的版本中,数据文件未使用部分可能会从其他代码释放的内存中收到垃圾数据。(使用 MDB_WRITEMAP 标志时不会发生这种情况。)自 0.9.10 起,默认行为是在写入数据文件之前初始化此类内存。由于此初始化可能会导致轻微的性能成本,应用程序可以通过使用 MDB_NOMEMINIT 标志禁用它。处理敏感数据且不得写入的应用程序不应使用此标志。使用 MDB_WRITEMAP 时,该标志无关紧要。一个线程一次只能使用一个事务,以及任何子事务。每个事务属于一个线程。见下文。MDB_NOTLS 标志会更改只读事务的此行为。使用打开它的进程中的 MDB_env*,而不是在 fork() 后。如果不应在同一进程中同时打开同一个 LMDB 数据库。即使是通过普通的 open() 调用 - close() 也会破坏 fcntl(
本站免费、广告极少。如果觉得有帮助,可以请我们喝杯咖啡 —— 任何金额都对持续运营有实际帮助。
☕请我喝杯咖啡