NewHalo Edge 3 is here: HTTP/3 everywhere and 42 edge locations.Learn more
Docs / Backups and monitoring

Test your backups by restoring them

Backups and monitoring7 min readUbuntu 24.04 LTS

A backup you have never restored is only a hope. Corrupt archives, missing tables and forgotten folders show up at the worst possible moment unless you find them first. This guide shows how to check your backups, restore them into a safe test location, verify the results, and clean up.

Before you begin

  • Backups made with the earlier guides: a MariaDB dump, a PostgreSQL custom-format dump, and an rsync copy of site files.
  • SSH access as a sudo user, such as alex, on the machine that holds the backups.
  • A test database name that does not already exist. This guide uses appdb_test.
  • A calendar reminder. Monthly restore tests are a good habit.

Step 1: Confirm the backups exist and look sensible

Start by listing the backup folders with sizes and dates. Look for recent files, and for sizes that are not suspiciously small or zero.

ls -lh ~/backups/mariadb ~/backups/postgresql
du -sh ~/backups/example.com
/home/alex/backups/mariadb:
-rw-r--r-- 1 alex alex 2.1M Oct 31 09:14 appdb-2026-10-31.sql.gz

/home/alex/backups/postgresql:
-rw-rw-r-- 1 alex alex  48K Oct 31 09:30 appdb-2026-10-31.dump

41M     /home/alex/backups/example.com

Step 2: Check the archives are not damaged

gzip -t tests a compressed file without extracting it. It prints nothing when the file is intact, so the && echo part prints a confirmation. pg_restore --list reads the table of contents of a PostgreSQL dump, which catches many corrupt files.

gzip -t ~/backups/mariadb/appdb-2026-10-31.sql.gz && echo "MariaDB archive OK"
pg_restore --list ~/backups/postgresql/appdb-2026-10-31.dump > /dev/null && echo "PostgreSQL archive OK"
MariaDB archive OK
PostgreSQL archive OK

Step 3: Restore the MariaDB dump into a test database

The MariaDB dump from the backup guide includes CREATE DATABASE appdb and USE appdb statements. Restoring it on the live server would overwrite the real database. For a safe test, make a separate dump without --databases, which contains only the tables, and load it into appdb_test:

sudo mysqldump --single-transaction --routines --events appdb | gzip > ~/backups/mariadb/appdb-test-dump.sql.gz
sudo mariadb -e "CREATE DATABASE appdb_test;"
gunzip -c ~/backups/mariadb/appdb-test-dump.sql.gz | sudo mariadb appdb_test

The restore prints nothing when it succeeds. Errors appear on screen, so watch for them.

Careful: Test restores on a separate server whenever possible. If you must test on the live server, double-check every database name first.

Step 4: Restore the PostgreSQL dump into a test database

PostgreSQL is safer by design: pg_restore writes into whichever database you name, so you can restore into appdb_test without touching appdb.

sudo -u postgres createdb --owner=alex appdb_test
pg_restore -h localhost -U alex -d appdb_test --no-owner ~/backups/postgresql/appdb-2026-10-31.dump

Step 5: Compare the data

A restore that runs without errors is not yet proof. Compare table counts in the test copy with the live database. Replace customers with a table you know well.

sudo mariadb -e "SELECT COUNT(*) FROM appdb_test.customers;"
sudo mariadb -e "SELECT COUNT(*) FROM appdb.customers;"
psql -h localhost -U alex -d appdb_test -c "SELECT COUNT(*) FROM customers;"
+----------+
| COUNT(*) |
+----------+
|      412 |
+----------+

The two counts should match, or differ only by rows added since the backup was taken.

Step 6: Test a file restore

Restore the site copy into a scratch folder, then compare checksums of a few files against the originals. A checksum is a fingerprint; identical files produce identical fingerprints.

mkdir -p ~/restore-test
rsync -a ~/backups/example.com/ ~/restore-test/
sha256sum ~/backups/example.com/index.html ~/restore-test/index.html
9f2c4e...a71b  /home/alex/backups/example.com/index.html
9f2c4e...a71b  /home/alex/restore-test/index.html

When the two hashes match, the file survived the trip. Repeat for a file that matters, such as a configuration or media file.

Step 7: Clean up the test data

Remove the test databases and the scratch folder once the checks pass. Double-check the names before deleting anything.

sudo -u postgres dropdb appdb_test
sudo mariadb -e "DROP DATABASE appdb_test;"
rm -rf ~/restore-test

Step 8: Record the result

Write a one-line log entry so you can prove later that testing happened. Appending with >> keeps earlier entries.

echo "2026-10-31 restore test OK: mariadb, postgresql, files" >> ~/backups/restore-log.txt

Troubleshooting

  • Restored database is empty: the dump may have been made from the wrong database, or the restore hit an error. Re-run the restore and read the messages.
  • ERROR 1007: database exists: drop the old test database first, then restore again.
  • gzip reports "unexpected end of file": the copy is incomplete. Make a new backup and check the disk for free space with df -h.
  • Permission denied during pg_restore: run as the role that owns the target database, and keep --no-owner.

Next steps

Put the restore test on your monthly calendar, and copy the backups to a second machine using the rsync guide. Schedule the dumps themselves with the cron guide.

Something not working? Chat or email our support team and we will help you get unstuck.

Contact support