Перейти к содержимому

Дампы PostgreSQL и MySQL по расписанию

Консистентные дампы pg_dump и mysqldump, сжатие, хранение последних копий, запуск из cron и проверка восстановления.

Уровень
Средний
Время чтения
2 мин чтения
Обновлено
Проверено на
Ubuntu 22.04, Ubuntu 24.04, Debian 12
Содержание
  1. PostgreSQL
  2. MySQL и MariaDB
  3. База в Docker
  4. Скрипт с ротацией
  5. Проверьте восстановление
  6. Частые ошибки

Файлы работающей базы нельзя просто скопировать: в момент копирования они меняются, и копия может оказаться повреждённой. Правильный способ — дамп, согласованный снимок данных, который база делает сама без остановки.

bash
$ mkdir -p /var/backups/db$ chmod 700 /var/backups/db

PostgreSQL

bash
$ sudo -u postgres pg_dump -Fc app > /var/backups/db/app-$(date +%F).dump$ sudo -u postgres pg_dumpall --globals-only > /var/backups/db/globals-$(date +%F).sql

-Fc — сжатый формат, из которого можно восстановить всю базу или отдельные таблицы. Второй файл содержит роли и их права: pg_dump их не сохраняет.

MySQL и MariaDB

bash
$ mysqldump --single-transaction --routines --triggers --events --databases app | gzip > /var/backups/db/app-$(date +%F).sql.gz

--single-transaction делает согласованный дамп таблиц InnoDB без блокировки. На Ubuntu и Debian root подключается к MySQL через сокет без пароля, поэтому команда работает от root как есть.

База в Docker

bash
$ cd /opt/myapp$ docker compose exec -T db pg_dump -U app -Fc app > /var/backups/db/app-$(date +%F).dump

Флаг -T отключает псевдотерминал — без него бинарный дамп будет испорчен.

Скрипт с ротацией

/usr/local/bin/backup-db.sh
$ #!/bin/sh$ set -e$ DIR=/var/backups/db$ STAMP=$(date +%F-%H%M)$ $ sudo -u postgres pg_dump -Fc app > "$DIR/app-$STAMP.dump"$ # mysqldump --single-transaction --routines --triggers --databases app | gzip > "$DIR/app-$STAMP.sql.gz"$ $ # Храним 14 дней$ find "$DIR" -type f -mtime +14 -delete$ echo "$(date -Is) ok"
bash
$ chmod 700 /usr/local/bin/backup-db.sh$ /usr/local/bin/backup-db.sh && ls -lh /var/backups/db
/etc/cron.d/backup-db
0 * * * * root flock -n /run/backup-db.lock /usr/local/bin/backup-db.sh >> /var/log/backup-db.log 2>&1

Дамп раз в час. Дальше отправляйте каталог /var/backups/db за пределы сервера — через restic или rsync.

Проверьте восстановление

Восстанавливайте в отдельную базу, чтобы не задеть рабочую:

PostgreSQL
$ sudo -u postgres createdb app_restore$ sudo -u postgres pg_restore -d app_restore --no-owner /var/backups/db/app-2026-09-25-0300.dump$ sudo -u postgres psql -d app_restore -c "\dt"
MySQL и MariaDB
$ mysql -e "CREATE DATABASE app_restore"$ gunzip -c /var/backups/db/app-2026-09-25-0300.sql.gz | sed "s/\`app\`/\`app_restore\`/g" | mysql$ mysql -e "SHOW TABLES FROM app_restore"

Дамп с --databases содержит команды CREATE DATABASE и USE с именем исходной базы — sed подменяет его, чтобы данные ушли в app_restore. Проверив таблицы и свежие записи, удалите тестовую базу.

Частые ошибки

  • Дампы лежат только на том же сервере — при переустановке или взломе пропадут вместе с базой.
  • Файл дампа нулевого размера — скрипт упал, а cron об этом молчит. Проверяйте лог и размер последнего файла.
  • Дамп MySQL без --single-transaction блокирует таблицы на время выгрузки, и сайт «подвисает».

Дочитайте до конца — статья засчитается в обучении автоматически.

  • pg_dump
  • mysqldump
  • бэкап базы
  • postgresql
  • mysql
  • cron

Статья помогла?