| Tested on | Rocky Linux 10.2 (Red Quartz) |
|---|---|
| Package | 389-ds-base 3.2.0-8.el10_2 |
| Applies to | RHEL, Rocky Linux, AlmaLinux, Oracle Linux, CentOS Stream, Fedora |
| Privilege | sudo or root |
| Scope | Back up and restore 389 Directory Server, including checksum verification, off-host copies, systemd automation, and isolated restore testing. |
| Related guides | Install 389 Directory Server dsconf commands 389 Directory Server architecture |
Native backup captures every database in a 389 Directory Server instance, including database-native and replication-related material that ordinary LDIF export omits. However, restoring an online backup clears the replication changelog and requires replica reinitialization. Offline-backup recovery depends on backup age, changelog retention, and the replication topology.
This guide walks through native backup and restore on ldap1.example.com (source) and isolated recovery testing on ldap2.example.com (destination). You will choose the right method, create and protect backups, restore databases, recover configuration when required, and prove recovery in a test environment.
Before you start:
- Install 389 Directory Server — source instance
ldap1and isolated restore hostldap2in this lab - dsconf commands — online backup and restore tasks
- dsctl commands — offline
db2bak,bak2db, anddbverify
Step 1 Choose backup and restore method
Step 2 Plan recovery objectives (RPO/RTO)
Step 3 Check the instance before backup
Step 4 Create a backup (online · offline)
Step 5 Inspect, checksum, and copy off-host
Step 6 Restore databases (online · offline)
Step 7 Restore configuration, certificates, and schema
Step 8 Validate, automate, and test recoveryJump links: Step 1 · Step 2 · Step 3 · Step 4 (online · offline) · Step 5 · Step 6 (online · offline) · Step 7 · Step 8
Step 1: Choose backup and restore method
For targeted entry changes without a full LDIF import, you can use the ldapadd command or ldapmodify command.
| Method | Format | Primary purpose |
|---|---|---|
| Native backup | Database-native backup directory | Restore a compatible Directory Server instance |
| LDIF export | Portable text data | Migration, transformation, or selected data transfer |
ldapadd or ldapmodify |
LDIF entries or change records | Add or modify selected data |
| Replication initialization | Replica data transfer | Create or rebuild a replica |
Native backup:
Restores all databases in the instance.
LDIF export:
Can export one backend or selected directory data.
Replication initialization:
Should normally be used to rebuild a replica when another
healthy supplier remains available.Use native backup when you need complete instance database recovery. Use export and import LDIF when you need portable or suffix-specific data movement.
| Workflow | Correct tool |
|---|---|
| Back up all instance databases online | dsconf backup create |
| Back up all instance databases offline | dsctl db2bak |
| Restore all databases online | dsconf backup restore |
| Restore all databases offline | dsctl bak2db |
| Restore one backend or selected entries | LDIF export/import |
| Restore configuration and certificates | Manual recovery from config_files |
| Rebuild a replica | Replication initialization or dedicated replica recovery |
| Check instance configuration | dsctl healthcheck |
| Check backend integrity offline | dsctl dbverify (limited on LMDB) |
Step 2: Plan backup and recovery strategy
Define recovery objectives before choosing tools:
RPO:
How much directory data the organization can afford to lose.
RTO:
How long the directory service can remain unavailable.Recovery-planning worksheet
| Requirement | Your value |
|---|---|
| Backup frequency | |
| Online or offline backup | |
| Retention period | |
| Local backup copies | |
| Off-site copies | |
| Restore-test frequency | |
| Encryption at rest | |
| Recovery owner | |
| Maximum acceptable data loss | |
| Maximum recovery time |
Example tiers:
Daily online backup:
Provides frequent recovery points without planned downtime.
Weekly offline backup:
Provides a stopped-instance backup suitable for important recovery points.
Monthly restore test:
Proves that the backup, configuration, schema, and certificates are usable.Account for write volume, replication topology, changelog retention, configuration and certificate changes, custom-schema changes, backup storage capacity, and time to copy archives off the server—not database size alone.
This lab uses ldap1 on ldap1.example.com as the production source and ldap2 on ldap2.example.com as an isolated restore-test host with the same dc=example,dc=com suffix.
Step 3: Check the instance before backing up
Confirm the instance is running:
dsctl ldap1 statusInstance "ldap1" is runningCheck the installed package version:
rpm -q 389-ds-base389-ds-base-3.2.0-8.el10_2.x86_64List suffixes and backends:
dsconf ldap1 backend suffix listdc=example,dc=com (userroot)Run the instance health check:
dsctl ldap1 healthcheckHealthcheck complete.
No issues found.Check database and backup storage:
du -sh /var/lib/dirsrv/slapd-ldap1/db /var/lib/dirsrv/slapd-ldap1/bak9.0M /var/lib/dirsrv/slapd-ldap1/db
122M /var/lib/dirsrv/slapd-ldap1/bakdf -h /var/lib/dirsrv/slapd-ldap1/db /var/lib/dirsrv/slapd-ldap1/bakFilesystem Size Used Avail Use% Mounted on
/dev/mapper/rlm-root 14G 11G 2.4G 82% /
/dev/mapper/rlm-root 14G 11G 2.4G 82% /Review existing backup directories:
find /var/lib/dirsrv/slapd-ldap1/bak -mindepth 1 -maxdepth 1 -type d -printf '%TY-%Tm-%Td %TH:%TM %p\n' | sortRecord Directory Server version, backend implementation, backup timestamps, entry counts, replication status, certificate expiry dates, and health-check warnings. Avoid writing backups to /tmp, /var/tmp, or /root when the service runs with a private temporary directory.
Step 4: Create a backup
Complete Step 3 before you create a recovery point. Choose one path: online backup when the directory must stay available, or offline backup during a maintenance window.
Online path
Online backup keeps the instance available while a background task writes the archive.
Create a named backup under the instance backup directory:
dsconf ldap1 backup create /var/lib/dirsrv/slapd-ldap1/bak/ldap1-pre-restore-labThe backup create task has finished successfullyBy default, unnamed backups also land under /var/lib/dirsrv/slapd-ldap1/bak/ with a timestamped directory name.
Review the errors log when backup behavior is unexpected:
grep -iE 'backup|error|warning' /var/log/dirsrv/slapd-ldap1/errors | tail -5[18/Jul/2026:22:14:49.615975608 +0530] - INFO - task_backup_thread - Beginning backup of 'ldbm database'
[18/Jul/2026:22:14:49.890590423 +0530] - INFO - task_backup_thread - Backup finished.Use online backup when the directory must remain available, you need frequent recovery points, and you understand replication implications on restored replicas. Do not modify the certificate database while the backup runs.
Offline path
Offline backup reads the database files while the instance is stopped.
Stop the instance cleanly:
dsctl ldap1 stopCreate the backup:
dsctl ldap1 db2bak /var/lib/dirsrv/slapd-ldap1/bak/ldap1-offline-labdb2bak successfulRestart the instance:
dsctl ldap1 startdsctl ldap1 statusInstance "ldap1" is runningUse offline backup when a maintenance window is available, you want a stopped-instance recovery point, or write activity is high and an unchanging snapshot is preferred. Always use dsctl stop; do not terminate ns-slapd with kill.
Step 5: Inspect, checksum, and copy off-host
After Step 4, verify the archive before you rely on it for recovery or copy it to another host.
Inspect and protect the archive
On 389 DS 3.2 with LMDB, a native backup directory in this lab contains:
data.mdb
dse_index.ldif
dse_instance.ldif
INFO.mdb
config_files/List the archive:
backup=/var/lib/dirsrv/slapd-ldap1/bak/ldap1-pre-restore-lab
find "$backup" -maxdepth 2 -printf '%M %u:%g %s %p\n' | sortInspect config_files:
find "$backup/config_files" -maxdepth 2 -type f -printf '%P\n' | sortcert9.db
certmap.conf
dse.ldif
key4.db
pin.txt
pwdfile.txt
schema/99user.ldif
slapd-collations.confCreate a checksum manifest that excludes the manifest file itself:
(
cd "$backup"
find . -type f ! -name SHA256SUMS -print0 |
sort -z |
xargs -0 sha256sum > SHA256SUMS
)Verify it:
(
cd "$backup"
sha256sum -c SHA256SUMS
)./INFO.mdb: OK
...Excerpt: sha256sum -c prints one line per file; only the first line is shown here.
Protect ownership and permissions with chown command:
chown -R dirsrv:dirsrv "$backup"
chmod -R go-rwx "$backup"
restorecon -RFv "$backup"Treat backups as sensitive. They can contain password hashes, private keys, certificate-database passwords, ACIs, replication credentials, and encryption keys. Maintain at least one recent local backup, one copy on separate storage, and one copy outside the failure domain.
Verify cross-host compatibility
Native backup formats are tied to the database implementation. An LMDB backup cannot be restored into an instance configured for Berkeley DB, or vice versa. LDIF export/import does not have that limitation.
Compare Directory Server releases on the source and recovery hosts:
rpm -q 389-ds-base389-ds-base-3.2.0-8.el10_2.x86_64ssh root@ldap2.example.com 'rpm -q 389-ds-base'389-ds-base-3.2.0-8.el10_2.x86_64Check the database implementation on both instances:
dsconf ldap1 backend config get |
grep '^nsslapd-backend-implement:'nsslapd-backend-implement: mdbdsconf ldap2 backend config get |
grep '^nsslapd-backend-implement:'nsslapd-backend-implement: mdbCompare configured backends:
dsconf ldap1 backend suffix listdc=example,dc=com (userroot)dsconf ldap2 backend suffix listdc=example,dc=com (userroot)Restore a native backup only into an instance with the same database implementation and compatible Directory Server software and backend layout. Prefer the same product release for a recovery host. Use LDIF export/import when moving between BDB and LMDB or when the destination database layout intentionally differs.
Copy the backup to an isolated host
Copy the archive to an isolated recovery host. This lab uses ldap2:
rsync -aHAX --numeric-ids "$backup/" \
root@ldap2.example.com:/var/lib/dirsrv/slapd-ldap2/bak/ldap1-pre-restore-lab/Verify the remote copy:
ssh root@ldap2.example.com \
'cd /var/lib/dirsrv/slapd-ldap2/bak/ldap1-pre-restore-lab && sha256sum -c SHA256SUMS'./INFO.mdb: OK
...Step 6: Restore databases
Route application reads and writes away from all suffixes on the target instance before restore. Native restore replaces every database in the instance. It does not merge backup content with the current database, and files under config_files are not applied automatically.
Choose one path: online restore when the instance can stay running, or offline restore when you can stop the instance for a controlled recovery.
Online restore
The server process remains running, but every database in the instance is replaced.
On the isolated restore host, verify checksums:
backup=/var/lib/dirsrv/slapd-ldap2/bak/ldap1-pre-restore-lab
cd "$backup" && sha256sum -c SHA256SUMSRestore every database in the instance:
dsconf ldap2 backup restore /var/lib/dirsrv/slapd-ldap2/bak/ldap1-pre-restore-labThe backup restore task has finished successfullyReview the errors log before declaring success:
grep -iE 'restore|error|warning' /var/log/dirsrv/slapd-ldap2/errors | tail -5[18/Jul/2026:22:15:51.185546185 +0530] - INFO - task_restore_thread - Beginning restore to 'ldbm database'
[18/Jul/2026:22:15:51.361678615 +0530] - INFO - task_restore_thread - Restore finished.In this lab, deleting uid=user498 and running online restore returned the entry:
ldapsearch -LLL -o ldif-wrap=no -Y EXTERNAL -H ldapi://%2Frun%2Fslapd-ldap2.socket -b \
"uid=user498,ou=people,dc=example,dc=com" -s base dndn: uid=user498,ou=people,dc=example,dc=comOffline restore
Offline restore is the preferred high-confidence workflow when you can stop the instance.
Stop Directory Server on the recovery host:
dsctl ldap2 stopRestore the archive:
dsctl ldap2 bak2db /var/lib/dirsrv/slapd-ldap2/bak/ldap1-pre-restore-lab/bak2db successfulStart the instance:
dsctl ldap2 startdsctl ldap2 statusInstance "ldap2" is runningReview the errors log:
grep -iE 'restore|error|warning' /var/log/dirsrv/slapd-ldap2/errors | tail -5[18/Jul/2026:22:15:59.232981501 +0530] - INFO - dbmdb_copyfile - Copying /var/lib/dirsrv/slapd-ldap2/bak/ldap1-pre-restore-lab/data.mdb to /var/lib/dirsrv/slapd-ldap2/db/data.mdb
[18/Jul/2026:22:15:59.248613202 +0530] - INFO - dbmdb_copyfile - Copying /var/lib/dirsrv/slapd-ldap2/bak/ldap1-pre-restore-lab/INFO.mdb to /var/lib/dirsrv/slapd-ldap2/db/INFO.mdbRun the health check:
dsctl ldap2 healthcheckHealthcheck complete.
No issues found.After deleting uid=user500 on ldap2, offline restore in this lab also returned the missing entry and restored the entry count to 770.
Use offline restore when recovering from corruption, performing a controlled rollback, or when the instance should not serve clients during replacement.
Step 7: Restore configuration, certificates, and custom schema
Database restore does not automatically restore dse.ldif, the NSS certificate database, private keys, pin.txt, or custom schema files. Red Hat confirms that these files are included under each backup's config_files directory but are deliberately not restored automatically. They must be selected and restored manually.
The commands below demonstrate same-instance recovery for ldap1. Do not copy ldap1's dse.ldif directly into an instance named ldap2 unless you have reviewed all instance paths, ports, hostnames, backends, and TLS settings.
Preserve current configuration first:
dsctl ldap1 stopcp -a /etc/dirsrv/slapd-ldap1 /etc/dirsrv/slapd-ldap1.before-restoreRestore dse.ldif while preserving metadata:
cp -a /var/lib/dirsrv/slapd-ldap1/bak/ldap1-pre-restore-lab/config_files/dse.ldif /etc/dirsrv/slapd-ldap1/dse.ldifRestore the NSS database as a coherent set. Do not restore only cert9.db or only key4.db. Restore related files from the same backup recovery point:
config_backup="/var/lib/dirsrv/slapd-ldap1/bak/ldap1-pre-restore-lab/config_files"
config_live="/etc/dirsrv/slapd-ldap1"
cp -a \
"$config_backup/cert9.db" \
"$config_backup/key4.db" \
"$config_backup/pin.txt" \
"$config_backup/pwdfile.txt" \
"$config_backup/certmap.conf" \
"$config_backup/slapd-collations.conf" \
"$config_live/"cert9.db, key4.db, and the associated password files belong to one NSS database state. Do not mix files from different backups.
Restore slapd-collations.conf when the instance used customized collation rules or when the file must match the recovered configuration and indexes. Do not blindly copy an older release's file onto a newer installation without comparing it with the destination package version.
Restore custom schema:
cp -a "$config_backup/schema/." "$config_live/schema/"Restore SELinux contexts:
restorecon -RFv "$config_live"Inspect ownership and mode before starting:
stat "$config_live/dse.ldif" "$config_live/cert9.db" "$config_live/key4.db"File: /etc/dirsrv/slapd-ldap1/dse.ldif
Size: 98085 Blocks: 192 IO Block: 4096 regular file
Access: (0640/-rw-r-----) Uid: ( 389/ dirsrv) Gid: ( 389/ dirsrv)
File: /etc/dirsrv/slapd-ldap1/cert9.db
Size: 45056 Blocks: 88 IO Block: 4096 regular file
Access: (0600/-rw-------) Uid: ( 389/ dirsrv) Gid: ( 389/ dirsrv)
File: /etc/dirsrv/slapd-ldap1/key4.db
Size: 102400 Blocks: 208 IO Block: 4096 regular file
Access: (0600/-rw-------) Uid: ( 389/ dirsrv) Gid: ( 389/ dirsrv)Start and verify:
dsctl ldap1 startdsconf ldap1 config getdsctl ldap1 healthcheckHealthcheck complete.
No issues found.After certificate recovery, also test LDAPS and certificate presentation rather than relying only on healthcheck.
Step 8: Validate, automate, and test recovery
Complete database and configuration recovery before you return a host to production. This step covers replication cautions, backup automation, isolated restore testing, and common failure modes.
Handle replicated-server backups
Keep replicated-topology recovery in the dedicated restore replicated server article. Important rules:
- Online backup supports frequent data protection on a single server.
- Restoring an online backup clears the associated changelog and requires replica reinitialization.
- When another healthy supplier has current data, rebuilding from that supplier is usually safer than restoring an old backup.
- Offline backup avoids the automatic changelog cleanup associated with online-backup restore. It does not guarantee that replication can resume: if required changes have expired from the surviving supplier's changelog, the restored replica still needs reinitialization.
- Compare backup age with replication changelog retention.
- Do not reconnect a restored supplier to production until replication state is validated.
For a complete topology failure, restore one authoritative supplier first and initialize remaining replicas from it.
Automate backups and retention
Create a backup script that verifies LMDB archive contents on 389 DS 3.2:
#!/usr/bin/env bash
set -euo pipefail
instance="ldap1"
backup_root="/var/lib/dirsrv/slapd-${instance}/bak"
stamp="$(date +%Y_%m_%d_%H_%M_%S)"
archive="${backup_root}/${instance}-${stamp}"
install -d -o dirsrv -g dirsrv -m 700 "$backup_root"
dsconf "$instance" backup create "$archive"
test -s "${archive}/data.mdb"
test -s "${archive}/dse_index.ldif"
test -s "${archive}/dse_instance.ldif"
test -s "${archive}/INFO.mdb"
test -d "${archive}/config_files"
test -s "${archive}/config_files/dse.ldif"
(
cd "$archive"
find . -type f ! -name SHA256SUMS -print0 |
sort -z |
xargs -0 sha256sum > SHA256SUMS
sha256sum -c SHA256SUMS >/dev/null
)
printf 'Backup completed and verified: %s\n' "$archive"The exact LMDB filenames can remain release-specific because this script targets the tested LMDB 3.2 environment.
Save it as /usr/local/sbin/backup-389ds, then protect it:
chown root:root /usr/local/sbin/backup-389ds
chmod 750 /usr/local/sbin/backup-389dsRun the script once:
/usr/local/sbin/backup-389dsThe backup create task has finished successfully
Backup completed and verified: /var/lib/dirsrv/slapd-ldap1/bak/ldap1-2026_07_18_22_16_19Create /etc/systemd/system/backup-389ds.service:
[Unit]
Description=Back up 389 Directory Server ldap1
After=dirsrv@ldap1.service
[Service]
Type=oneshot
UMask=0077
ExecStartPre=/usr/bin/systemctl is-active --quiet dirsrv@ldap1.service
ExecStart=/usr/local/sbin/backup-389dsThis makes the backup fail visibly when Directory Server is not active instead of starting it unexpectedly.
Create /etc/systemd/system/backup-389ds.timer with a daily schedule:
[Unit]
Description=Daily 389 Directory Server backup
[Timer]
OnCalendar=*-*-* 02:00:00
Persistent=true
RandomizedDelaySec=10m
Unit=backup-389ds.service
[Install]
WantedBy=timers.targetOnCalendar defines the schedule, and Persistent=true causes a missed calendar run to be triggered when the timer becomes active again.
Enable and verify scheduling:
systemctl daemon-reloadsystemctl enable --now backup-389ds.timersystemctl list-timers backup-389ds.timerNEXT LEFT LAST PASSED UNIT ACTIVATES
Sun 2026-07-19 02:03:43 IST 3h 47min Sat 2026-07-18 10:52:19 IST - backup-389ds.timer backup-389ds.service
1 timers listed.
Pass --all to see loaded but inactive timers, too.Test the service:
systemctl start backup-389ds.servicesystemctl status backup-389ds.serviceFinished backup-389ds.service - Back up 389 Directory Server ldap1.Review backup failures in the journal:
journalctl -u backup-389ds.service -n 50 --no-pagerJul 18 22:16:19 ldap1.example.com backup-389ds[...]: Backup completed and verified: /var/lib/dirsrv/slapd-ldap1/bak/ldap1-2026_07_18_22_16_19
Jul 18 22:16:19 ldap1.example.com systemd[1]: Finished backup-389ds.service - Back up 389 Directory Server ldap1.A backup timer without failure review or alerting can fail silently from an operational perspective.
Preview local retention for directories named ldap1-* before deleting anything:
find /var/lib/dirsrv/slapd-ldap1/bak -mindepth 1 -maxdepth 1 -type d -name 'ldap1-*' -mtime +14 -printWhen the preview list is correct, delete expired backups:
find /var/lib/dirsrv/slapd-ldap1/bak -mindepth 1 -maxdepth 1 -type d -name 'ldap1-*' -mtime +14 -exec rm -rf \
-- {} +Do not delete an old backup until the new backup succeeded, expected files exist, checksum verification passed, and any off-site copy completed.
Test restoration and troubleshoot
A backup is not proven until it restores successfully in an isolated environment with no production replication, DNS, or load-balancer registration.
Test workflow used in this lab:
- Copy the backup from
ldap1toldap2. - Verify
SHA256SUMS.
Online restore test:
- Keep
ldap2running. - Restore with
dsconf ldap2 backup restore BACKUP_PATH. - Review the errors log.
Offline restore test:
- Stop
ldap2. - Restore with
dsctl ldap2 bak2db BACKUP_PATH. - Start
ldap2and review the errors log.
For either path:
- Run
dsctl ldap2 healthcheck. - Validate counts, DNs, binds, ACIs, schema, TLS, encrypted attributes, plug-ins, and application searches.
Run the health check:
dsctl ldap2 healthcheckHealthcheck complete.
No issues found.Compare entry counts:
ldapsearch -LLL -o ldif-wrap=no -Y EXTERNAL -H ldapi://%2Frun%2Fslapd-ldap2.socket -b "dc=example,dc=com" \
"(objectClass=*)" dn |
grep -Ec '^dn::? '770On LMDB backends, dbverify reports success without deep validation:
dsctl ldap2 stopdsctl ldap2 dbverify userRootdsctl ldap2 start[18/Jul/2026:22:16:29.296571907 +0530] - INFO - ldbm_instance_config_cachememsize_set - force a minimal value 512000
[18/Jul/2026:22:16:29.315709179 +0530] - WARN - dbmdb_verify - With lmdb, db_verify feature is meaningless and is always successfull.
dbverify successfulFor an LMDB backend, a successful dbverify result is not equivalent to a deep page-by-page validation performed for a BDB backend. Prove backup usability with an isolated restore, LDAP searches, bind tests, entry-count comparisons, and application-level checks.
Test user password bind, group membership, ACIs, custom schema, TLS, encrypted attributes, and application searches after every restore test.
| Symptom | Likely cause | Fix |
|---|---|---|
Backup fails under /tmp or /root |
Path not writable by dirsrv |
Use /var/lib/dirsrv/slapd-INSTANCE/bak/ |
| Backup reports permission denied | Ownership, mode, or SELinux context | chown dirsrv:dirsrv, chmod go-rwx, restorecon |
config_files is missing |
Version, command, or destination path | Check errors log and package behavior on your release |
| Restore cannot find the backup | Wrong path or permissions | Confirm data.mdb, config_files, and dirsrv read access |
| TLS fails after config restore | Missing or mismatched NSS files | Restore cert9.db, key4.db, pin.txt, and contexts together |
| Restored searches are slow | Index or backend problem after restore | Check backend status, indexes, and access-log notes=A / notes=U |
| Production recovery slower than lab | Remote retrieval and replication cutover | Measure retrieve, verify, restore, health check, and client reconnection separately |
What's next
After you complete this guide, continue with:
- Restore a Replicated 389 Directory Server Safely — replica recovery after restore
- Update and Upgrade 389 Directory Server Safely — package updates with verified backups
- Migrate 389 Directory Server from Berkeley DB to LMDB — backend conversion with rollback files
- Migrate 389 Directory Server to a New Server — host replacement planning
- Configure Low Disk Space Protection in 389 Directory Server — disk space for backup retention
Summary
- Choose native backup, LDIF export, or replication initialization for the recovery problem you are solving.
- Define RPO, RTO, retention, and restore-test schedule.
- Record instance health, version, backends, and storage before backup.
- Create an online or offline native backup under
/var/lib/dirsrv/slapd-INSTANCE/bak/. - Inspect the archive, generate checksums, verify cross-host compatibility, and copy off-host.
- Restore databases online with
dsconf backup restoreor offline withdsctl bak2db. - Restore
config_filesmanually when the recovery point requiresdse.ldif, certificates, or custom schema. - Validate replication impact, automate backups, and prove recovery in an isolated test environment.
References
- Red Hat Directory Server 13 — Backing up and restoring Red Hat Directory Server
- Red Hat Directory Server 13 — File locations overview
- 389 Directory Server — Expanded backup design
- Red Hat Directory Server 13 — Configuring and managing replication
- Red Hat Directory Server 13.2 release notes

