Read Berkeley DB 5.3 Logs with db5.3_printlog

Something wrote to a Berkeley DB environment at 3am and db5.3_printlog can show you exactly what, provided you resist the urge to kill it mid-read. You will dump a transaction log in readable form, narrow the dump to a range of log sequence numbers, and keep the environment safe while you dig. The examples use db5.3_printlog from Ubuntu's db5.3-util package, version 5.3.28+dfsg2-7, against Berkeley DB library version 5.3.28.

1. Confirm the installed utility

Check which executable will actually run, and record its library version:

$ command -v db5.3_printlog
/usr/bin/db5.3_printlog
$ db5.3_printlog -V
Berkeley DB 5.3.28: (September  9, 2013)

The db_printlog name is also supplied by the db-util package on this machine; the local manpages describe both as the same Berkeley DB 5.3 tool. Use the versioned name in scripts if you want the dependency to be obvious to whoever reads them next.

Checkpoint: if command -v finds nothing, stop and install or enable the package through your normal process. Do not copy a utility across from a different Berkeley DB release into the environment directory.

2. Identify the correct environment home

Pass the Berkeley DB environment directory with -h. Leave it out and the utility falls back to DB_HOME if that variable is set, otherwise the current working directory, which is a classic source of confusing empty output or an outright error. Make the path explicit instead:

$ export DB_HOME=/srv/example-bdb
$ db5.3_printlog -h "$DB_HOME" > /tmp/example-bdb.log.txt

That redirection creates a text report and leaves the Berkeley DB log files themselves untouched. Before running it, look at the directory without changing anything:

$ ls -la /srv/example-bdb
$ find /srv/example-bdb -maxdepth 1 -type f -name 'log.*' -printf '%f\n' | sort

Do not assume a file named log.* is the only input that matters. If the application set a separate log directory with Berkeley DB's set_lg_dir option, the environment needs a DB_CONFIG file recording that path, or the utility cannot reliably find the logs at all. The official Berkeley DB documentation calls this out specifically.

3. Dump the logs in normal order

Run the utility against the environment and capture standard output:

$ db5.3_printlog -h /srv/example-bdb > /tmp/example-bdb.log.txt
$ printf 'exit status: %s\n' "$?"
exit status: 0
$ sed -n '1,12p' /tmp/example-bdb.log.txt

Zero is the successful exit status. The report holds records with LSNs like [22][28]: the first number identifies the log file, the second its byte offset. Exact record names and fields depend on the Berkeley DB operations that produced this environment, and the output is meant for a person or a follow-on script, not as a backup format.

An empty report from a successful command usually means you picked the wrong environment, or its logs are missing. If the command fails outright, save the error text and status before trying another path, and do not create or delete files in the environment just to coax output out of it.

4. Narrow the report with LSN boundaries

Use -b for the first LSN and -e for the stopping one. Each value is a log file number, a slash, and an offset, with no spaces anywhere in it:

$ db5.3_printlog -h /srv/example-bdb -b 22/28 -e 22/4096 \
    > /tmp/example-bdb-range.txt
$ test -s /tmp/example-bdb-range.txt && echo 'report is non-empty'

Take these boundary values from LSNs printed in an earlier report, or from the incident record itself. They are not timestamps, record numbers, or byte ranges you can guess from the size of the directory. Keep the slash exactly as shown. A range that errors out or returns nothing useful means rerun the full dump and check the available LSNs, rather than widening a production investigation blindly.

Use -r to read the log files in reverse order:

$ db5.3_printlog -r -h /srv/example-bdb \
    > /tmp/example-bdb-reverse.txt

That only changes reading order. It is not an undo operation and it does not rewrite the logs.

5. Stop cleanly, skip the unsafe shortcut

The utility attaches itself to the Berkeley DB environment while it runs. If a report is taking too long, stop it with an interrupt such as Ctrl-C, which sends SIGINT and gives the program a chance to detach and release its environment resources properly:

$ db5.3_printlog -h /srv/example-bdb > /tmp/example-bdb.log.txt
^C

Warning: do not kill it with an uncatchable signal as a routine shortcut while it is attached to a live environment. The manpage specifically warns that the utility needs to detach gracefully or it risks environment corruption. If another process is actively updating the database, coordinate the diagnostic with whoever owns it, and expect the report to reflect a moving target.

The -N option skips shared-region mutexes and ignores other problems, including potentially fatal Berkeley DB errors. It exists for debugging a failure that blocks normal access, not for routine contention: make a safe copy or use the application's documented maintenance procedure first.

6. Treat passwords and privileges carefully

If the environment is password-protected, -P accepts it directly:

$ db5.3_printlog -h /srv/example-bdb -P 'REPLACE_WITH_ENVIRONMENT_PASSWORD' \
    > /tmp/example-bdb.log.txt

Warning: never paste a real password into shell history, a ticket or a shared transcript. Berkeley DB tries to overwrite the command-line string in memory, but the local manpage still warns that another account might observe the arguments before that happens. Use a safer credential mechanism if your deployment offers one, remove the placeholder before you actually run the command, and treat the resulting report as potentially sensitive, since log records can contain application data and identifiers.

If access is denied, check ownership and mode before reaching for more privilege:

$ namei -l /srv/example-bdb
$ ls -ld /srv/example-bdb
$ ls -l /srv/example-bdb/log.*

Only then consider running it elevated:

$ sudo db5.3_printlog -h /srv/example-bdb > /tmp/example-bdb.log.txt

sudo changes who can read the environment. It does not repair a missing log directory, and it will not make an invalid LSN valid. Keep the output file's permissions restricted if the log turns out to hold sensitive records.

Done means