# Postfix Berkeley DB Howto

## Introduction

Postfix uses databases of various kinds to store and look up information. Postfix databases are specified as "type:name". Berkeley DB implements the Postfix database type "hash" and "btree". The name of a Postfix Berkeley DB database is the name of the database file without the ".db" suffix. Berkeley DB databases are maintained with the postmap(1) command.

Note: Berkeley DB version 4 is not supported by Postfix versions before 2.0.

This document describes:

1. How to build Postfix on systems without Berkeley DB library.

2. How to build Postfix on BSD or Linux systems with multiple Berkeley DB versions.

3. How to tweak performance.

4. Missing pthread library trouble.

## Building Postfix on systems without Berkeley DB

Some UNIXes ship without Berkeley DB support; for historical reasons these use DBM files instead. A problem with DBM files is that they can store only limited amounts of data. To build Postfix with Berkeley DB support you need to download and install the source code from http://www.oracle.com/database/berkeley-db/.

Warning: some Linux system libraries use Berkeley DB, as do some third-party libraries such as SASL. If you compile Postfix with a different Berkeley DB implementation, then every Postfix program will dump core because either the system library, the SASL library, or Postfix itself ends up using the wrong version.

The more recent Berkeley DB versions have a compile-time switch, "--with-uniquename", which renames the symbols so that multiple versions of Berkeley DB can co-exist in the same application. Although wasteful, this may be the only way to keep things from falling apart.

To build Postfix after you installed the Berkeley DB from source code, use something like:

>     % make tidy
>     % make makefiles CCARGS="-DHAS_DB -I/usr/local/BerkeleyDB/include" \
>         AUXLIBS="-L/usr/local/BerkeleyDB/lib -ldb"
>     % make

Solaris needs this:

>     % make tidy
>     % make makefiles CCARGS="-DHAS_DB -I/usr/local/BerkeleyDB/include" \
>         AUXLIBS="-R/usr/local/BerkeleyDB/lib -L/usr/local/BerkeleyDB/lib -ldb"
>     % make

The exact pathnames depend on the Berkeley DB version, and on how it was installed.

Warning: the file format produced by Berkeley DB version 1 is not compatible with that of versions 2 and 3 (versions 2 and 3 have the same format). If you switch between DB versions, then you may have to rebuild all your Postfix DB files.

Warning: if you use Berkeley DB version 2 or later, do not enable DB 1.85 compatibility mode. Doing so would break fcntl file locking.

Warning: if you use Perl to manipulate Postfix's Berkeley DB files, then you need to use the same Berkeley DB version in Perl as in Postfix.

## Building Postfix on BSD systems with multiple Berkeley DB versions

Some BSD systems ship with multiple Berkeley DB implementations. Normally, Postfix builds with the default DB version that ships with the system.

To build Postfix on BSD systems with a non-default DB version, use a variant of the following commands:

>     % make tidy
>     % make makefiles CCARGS=-I/usr/include/db3 AUXLIBS=-ldb3
>     % make

Warning: the file format produced by Berkeley DB version 1 is not compatible with that of versions 2 and 3 (versions 2 and 3 have the same format). If you switch between DB versions, then you may have to rebuild all your Postfix DB files.

Warning: if you use Berkeley DB version 2 or later, do not enable DB 1.85 compatibility mode. Doing so would break fcntl file locking.

Warning: if you use Perl to manipulate Postfix's Berkeley DB files, then you need to use the same Berkeley DB version in Perl as in Postfix.

## Building Postfix on Linux systems with multiple Berkeley DB versions

Some Linux systems ship with multiple Berkeley DB implementations. Normally, Postfix builds with the default DB version that ships with the system.

Warning: some Linux system libraries use Berkeley DB. If you compile Postfix with a non-default Berkeley DB implementation, then every Postfix program will dump core because either the system library or Postfix itself ends up using the wrong version.

On Linux, you need to edit the makedefs script in order to specify a non-default DB library. The reason is that the location of the default db.h include file changes randomly between vendors and between versions, so that Postfix has to choose the file for you.

Warning: the file format produced by Berkeley DB version 1 is not compatible with that of versions 2 and 3 (versions 2 and 3 have the same format). If you switch between DB versions, then you may have to rebuild all your Postfix DB files.

Warning: if you use Berkeley DB version 2 or later, do not enable DB 1.85 compatibility mode. Doing so would break fcntl file locking.

Warning: if you use Perl to manipulate Postfix's Berkeley DB files, then you need to use the same Berkeley DB version in Perl as in Postfix.

## Tweaking performance

Postfix provides two configuration parameters that control how much buffering memory Berkeley DB will use.

- berkeley_db_create_buffer_size (default: 16 MBytes per table). This setting is used by the commands that maintain Berkeley DB files: postalias(1) and postmap(1). For "hash" files, create performance degrades rapidly unless the memory pool is O(file size). For "btree" files, create performance is good with sorted input even for small memory pools, but with random input degrades rapidly unless the memory pool is O(file size).

- berkeley_db_read_buffer_size (default: 128 kBytes per table). This setting is used by all other Postfix programs. The buffer size is adequate for reading. If the cache is smaller than the table, random read performance is hardly cache size dependent, except with btree tables, where the cache size must be large enough to contain the entire path from the root node. Empirical evidence shows that 64 kBytes may be sufficient. We double the size to play safe, and to anticipate changes in implementation and bloat.

## Missing pthread library trouble

When building Postfix fails with:

>     undefined reference to `pthread_condattr_setpshared'
>     undefined reference to `pthread_mutexattr_destroy'
>     undefined reference to `pthread_mutexattr_init'
>     undefined reference to `pthread_mutex_trylock'

Add the "-lpthread" library to the "make makefiles" command.

>     % make makefiles .... AUXLIBS="... -lpthread"

More information is available at http://www.oracle.com/database/berkeley-db/.