简介
Postfix 使用各种类型的数据库来存储和检索信息。Postfix 数据库以 "类型:名称" 的形式指定。OpenLDAP LMDB(以下简称 "LMDB")实现了 Postfix 数据库类型 "lmdb"。Postfix LMDB 数据库的名称是数据库文件名称去除 ".lmdb" 后缀的部分。
本文档描述:
构建支持 LMDB 的 Postfix
Postfix 默认不启用 LMDB 支持。要构建支持 LMDB 的 Postfix,请使用类似以下命令:
% make makefiles CCARGS="-DHAS_LMDB -I/usr/local/include" \ AUXLIBS_LMDB="-L/usr/local/lib -llmdb" % make
如果 LMDB 共享库位于运行时链接器未知目录中,请在 "-llmdb" 后添加 "-Wl,-R,/path/to/directory" 选项。
Postfix 3.0 之前的版本使用 AUXLIBS 而不是 AUXLIBS_LMDB。在 Postfix 3.0 及更高版本中,旧的 AUXLIBS 变量仍支持构建静态加载的 LMDB 数据库客户端,但仅新的 AUXLIBS_LMDB 变量支持构建动态加载或静态加载的 LMDB 数据库客户端。
如果未使用 AUXLIBS_LMDB 变量,将无法实现动态数据库客户端加载的目的。每个 Postfix 可执行文件都将依赖 LMDB 数据库库。而这正是动态数据库客户端加载旨在避免的情况。
Solaris 可能需要以下设置:
% make makefiles CCARGS="-DHAS_LMDB -I/usr/local/include" \ AUXLIBS_LMDB="-R/usr/local/lib -L/usr/local/lib -llmdb" % make
确切的路径名取决于 LMDB 的安装方式。
当构建 Postfix 时出现以下错误:
未定义的引用到 `pthread_mutexattr_destroy' 未定义的引用到 `pthread_mutexattr_init' 未定义的引用到 `pthread_mutex_lock'
在 "make makefiles" 命令中添加 "-lpthread" 库。
% make makefiles .... AUXLIBS_LMDB="... -lpthread"
配置 LMDB 设置
Postfix 提供一个配置参数用于控制 LMDB 数据库行为。
- lmdb_map_size(默认:16777216)。此设置指定 LMDB 数据库的初始大小限制(以字节为单位)。每次数据库达到"满"状态时,其大小限制将翻倍。最大大小为"long"类型能表示的最大有符号整数值。
在非 Postfix 程序中使用 LMDB 映射
使用 LMDB 内置锁定协议的程序会破坏 Postfix LMDB 数据库或读取垃圾数据。
Postfix 不使用 LMDB 的内置锁定协议,因为这需要可供所有人写入的锁定文件,且违反 Postfix 安全策略。相反,Postfix 使用基于 fcntl(2) 的外部锁定机制,以防止写入者破坏数据库,并防止读取者获取垃圾数据。
请参阅 lmdb_table(5) 以获取有关所有程序在访问 Postfix LMDB 数据库时必须使用的锁定协议的详细描述。
所需的最低 LMDB 补丁级别
目前,Postfix 要求使用 LMDB 0.9.11 或更高版本。所需的最低 LMDB 补丁级别随时间演进,这是基于 Postfix 部署经验的结果:
- LMDB 0.9.11 允许 Postfix 守护进程记录 LMDB 错误消息,而非在没有通知的情况下突然终止。
- LMDB 0.9.10 修复了一个信息泄露问题,此前 LMDB 会将最多 4 KB 的未初始化堆内存块写入数据库。这可能导致不应持久化的信息被保存,或不应共享的信息被共享。
- LMDB 0.9.9 允许 Postfix 使用外部(基于 fcntl())锁,而不是使用可供所有人写入的 LMDB 锁文件,这违反了 Postfix 的安全模型。
- LMDB 0.9.8 允许 Postfix 在不关闭数据库的情况下从"数据库已满"错误中恢复。此版本新增了对动态调整数据库大小限制的支持。这是必要的,因为 Postfix 数据库大小会随邮件服务器负载而变化。
- LMDB 0.9.7 允许 postmap(1) 和 postalias(1) 命令使用大于物理内存的批量模式事务。这是因为 LMDB 支持超过物理内存大小的数据库。
致谢
- Howard Chu 贡献了初始的 Postfix dict_lmdb 驱动程序。
- Wietse Venema 编写了一个抽象层(slmdb),其行为更类似于 Berkeley DB、NDBM 等。该层会在数据库需要调整大小或被其他进程调整大小后,自动重试 LMDB 请求。
- Howard 和 Wietse 在 LMDB 和 Postfix 的多个版本中进行了多次迭代,期间参考了 Viktor Dukhovni 的反馈。