Резервні копії баз даних
Як налаштувати дампи MySQL і PostgreSQL за розкладом, винести їх за межі машини та перевірити, що копія справді відновлюється.
Оновлено 23 серпня 2026 р.
VPS не має автоматичних резервних копій машини чи знімків стану: усе, що ви не скопіювали самостійно, існує в єдиному екземплярі. Дамп бази даних — це перше, що варто налаштувати, бо відновлювати дані нізвідки, тоді як сайт можна розгорнути заново.
Ручний дамп
PostgreSQL:
pg_dump -Fc -U shop -h 127.0.0.1 shop > /srv/backups/shop-$(date +%F).dump
pg_dumpall -U postgres --roles-only > /srv/backups/roles.sql
MySQL і MariaDB:
mysqldump --single-transaction --quick --routines --events \
-u root shop | gzip > /srv/backups/shop-$(date +%F).sql.gz
--single-transaction робить узгоджений дамп InnoDB без блокування таблиць — без нього сайт зависне під час експорту. Формат -Fc у PostgreSQL стиснений і дає змогу відновлювати окремі таблиці.
Не вказуйте паролі в командному рядку: створіть ~/.pgpass або ~/.my.cnf з правами 600.
За розкладом
mkdir -p /srv/backups && chmod 700 /srv/backups
crontab -e
20 3 * * * /usr/local/bin/db-backup.sh >> /var/log/db-backup.log 2>&1
Скрипт /usr/local/bin/db-backup.sh:
#!/bin/bash
set -euo pipefail
DEST=/srv/backups
STAMP=$(date +%F-%H%M)
pg_dump -Fc -U shop -h 127.0.0.1 shop > "$DEST/shop-$STAMP.dump.tmp"
mv "$DEST/shop-$STAMP.dump.tmp" "$DEST/shop-$STAMP.dump"
find "$DEST" -name '*.dump' -mtime +14 -delete
Запис у тимчасовий файл із подальшим перейменуванням має значення: якщо дамп перерветься, ви не сплутаєте обрізаний файл із повною резервною копією. set -euo pipefail зупиняє скрипт на першій помилці, а не продовжує мовчки.
Виносьте резервні копії за межі машини
Копія на тому самому диску не врятує від помилки під час міграції, шифрувальника чи перевстановлення ОС на вкладці «Доступ». Надсилайте дампи за межі сервера:
rsync -az --delete /srv/backups/ backup@other-host:/store/vds/
Або в будь-яке S3-сумісне сховище через rclone. Зважайте на пропускну здатність до 500 Мбіт/с і ліміт запису на диск залежно від тарифу: 60 МБ/с на ядро.
Перевірка відновлення
Резервна копія, яку ви жодного разу не відновлювали, — не резервна копія.
createdb -U postgres shop_check
pg_restore -U postgres -d shop_check /srv/backups/shop-2026-08-23.dump
psql -U postgres -d shop_check -c "SELECT count(*) FROM users;"
dropdb -U postgres shop_check
Для MySQL: gunzip -c dump.sql.gz | mysql -u root shop_check.
Робіть це раз на місяць і фіксуйте дату перевірки.
Типові помилки
| Симптом | Причина |
|---|---|
| Дамп важить лише кілька кілобайт | Скрипт не пройшов автентифікацію, а помилка пішла в /dev/null |
| Забракло місця на диску | Немає видалення старих копій за mtime |
| Відновлення падає на правах | Ролі не були вивантажені — потрібен --roles-only |
| Cron мовчить, копій немає | У Cron немає вашого PATH — використовуйте абсолютні шляхи |
| Уночі сайт гальмує | Дамп конкурує за диск — зсуньте час, додайте --quick |
Тримайте щонайменше дві копії в різних місцях і стежте за розміром дампу: різке падіння розміру означає, що вивантажилася не вся база даних.