Автоматические бэкапы базы данных: mysqldump/pg_dump и cron
Запустить на сервере одной командой (сначала проверьте содержимое скрипта ниже):
curl -sSL https://cp.lv/scripts/bekapy-bazy-dannyh.sh | sudo bash…или через wget:
wget -qO- https://cp.lv/scripts/bekapy-bazy-dannyh.sh | sudo bashСодержимое скрипта bekapy-bazy-dannyh.sh:
#!/usr/bin/env bash
# Создаёт скрипт бэкапа MySQL, первый дамп и cron-задачу
set -e
SCRIPT=/opt/scripts/mysql-backup.sh
BACKUP_DIR=/var/backups/mysql
# 1. Каталоги для скрипта и дампов
sudo mkdir -p /opt/scripts "$BACKUP_DIR"
# 2. Создать сам скрипт бэкапа ('EOF' — переменные раскроются при запуске)
sudo tee "$SCRIPT" > /dev/null << 'EOF'
#!/bin/bash
set -euo pipefail
DB_NAME="app_db"
DB_USER="backup_user"
BACKUP_DIR="/var/backups/mysql"
KEEP_DAYS=7
DATE=$(date +%F_%H-%M)
mkdir -p "$BACKUP_DIR"
mysqldump --single-transaction --quick --user="$DB_USER" \
"$DB_NAME" | gzip > "$BACKUP_DIR/${DB_NAME}_${DATE}.sql.gz"
find "$BACKUP_DIR" -name "*.sql.gz" -mtime +$KEEP_DAYS -delete
EOF
sudo chmod +x "$SCRIPT"
# 3. Сделать первый бэкап прямо сейчас
sudo "$SCRIPT"
# 4. Cron-задача: ежедневно в 3:30 ночи
echo "30 3 * * * root $SCRIPT >> /var/log/db-backup.log 2>&1" | sudo tee /etc/cron.d/db-backup > /dev/null
echo "Готово: скрипт $SCRIPT создан, первый дамп в $BACKUP_DIR, cron настроен."
Резервная копия базы — это то, что спасает проект при сбое диска, ошибочном DROP TABLE или неудачной миграции. Никакой хостинг не отменяет вашу собственную ответственность за бэкапы: держите копии и проверяйте их восстановление. Ниже — рабочие скрипты для MySQL/MariaDB и PostgreSQL с автозапуском по cron.
Принцип надёжного бэкапа
- Регулярность — по расписанию, без ручного участия.
- Ротация — хранить N последних копий, старые удалять.
- Внешнее хранилище — копировать дампы на другой сервер или в объектное хранилище, а не только на тот же диск.
- Проверка восстановления — периодически разворачивать дамп в тестовую базу.
Бэкап MySQL/MariaDB
Утилита mysqldump создаёт логический дамп — SQL-файл со всеми данными. Создайте файл /opt/scripts/mysql-backup.sh в редакторе (nano, vim или mcedit):
sudo mkdir -p /opt/scripts
sudo nano /opt/scripts/mysql-backup.sh
Содержимое скрипта:
#!/bin/bash
set -euo pipefail
DB_NAME="app_db"
DB_USER="backup_user"
BACKUP_DIR="/var/backups/mysql"
KEEP_DAYS=7
DATE=$(date +%F_%H-%M)
mkdir -p "$BACKUP_DIR"
mysqldump --single-transaction --quick --user="$DB_USER" \
"$DB_NAME" | gzip > "$BACKUP_DIR/${DB_NAME}_${DATE}.sql.gz"
# удалить копии старше KEEP_DAYS дней
find "$BACKUP_DIR" -name "*.sql.gz" -mtime +$KEEP_DAYS -delete
Либо создайте скрипт целиком одной командой — скопируйте и вставьте в консоль (кавычки 'EOF' важны: $-переменные должны остаться в скрипте, а не раскрыться сейчас):
sudo tee /opt/scripts/mysql-backup.sh > /dev/null << 'EOF'
#!/bin/bash
set -euo pipefail
DB_NAME="app_db"
DB_USER="backup_user"
BACKUP_DIR="/var/backups/mysql"
KEEP_DAYS=7
DATE=$(date +%F_%H-%M)
mkdir -p "$BACKUP_DIR"
mysqldump --single-transaction --quick --user="$DB_USER" \
"$DB_NAME" | gzip > "$BACKUP_DIR/${DB_NAME}_${DATE}.sql.gz"
find "$BACKUP_DIR" -name "*.sql.gz" -mtime +$KEEP_DAYS -delete
EOF
sudo chmod +x /opt/scripts/mysql-backup.sh
Флаг --single-transaction снимает согласованный снимок без блокировки таблиц (для InnoDB). Чтобы не хранить пароль в скрипте, создайте файл ~/.my.cnf с правами 600. Откройте его в редакторе:
nano ~/.my.cnf
Содержимое файла:
[client]
user=backup_user
password=СложныйПароль123!
Либо создайте файл одной командой — скопируйте и вставьте в консоль:
tee ~/.my.cnf > /dev/null << 'EOF'
[client]
user=backup_user
password=СложныйПароль123!
EOF
chmod 600 ~/.my.cnf
Сделайте скрипт исполняемым:
chmod +x /opt/scripts/mysql-backup.sh
Бэкап PostgreSQL
Аналогичный скрипт на pg_dump (формат custom удобнее для частичного восстановления). Создайте файл /opt/scripts/postgres-backup.sh в редакторе:
sudo nano /opt/scripts/postgres-backup.sh
Содержимое скрипта:
#!/bin/bash
set -euo pipefail
DB_NAME="app_db"
BACKUP_DIR="/var/backups/postgres"
KEEP_DAYS=7
DATE=$(date +%F_%H-%M)
mkdir -p "$BACKUP_DIR"
pg_dump -Fc "$DB_NAME" > "$BACKUP_DIR/${DB_NAME}_${DATE}.dump"
find "$BACKUP_DIR" -name "*.dump" -mtime +$KEEP_DAYS -delete
Либо создайте скрипт целиком одной командой (кавычки 'EOF' сохраняют $-переменные внутри скрипта):
sudo tee /opt/scripts/postgres-backup.sh > /dev/null << 'EOF'
#!/bin/bash
set -euo pipefail
DB_NAME="app_db"
BACKUP_DIR="/var/backups/postgres"
KEEP_DAYS=7
DATE=$(date +%F_%H-%M)
mkdir -p "$BACKUP_DIR"
pg_dump -Fc "$DB_NAME" > "$BACKUP_DIR/${DB_NAME}_${DATE}.dump"
find "$BACKUP_DIR" -name "*.dump" -mtime +$KEEP_DAYS -delete
EOF
sudo chmod +x /opt/scripts/postgres-backup.sh
Пароль для PostgreSQL хранят в файле ~/.pgpass (права 600). Откройте его в редакторе:
nano ~/.pgpass
Содержимое файла (формат host:port:db:user:password):
localhost:5432:app_db:backup_user:СложныйПароль123!
Либо создайте файл одной командой:
tee ~/.pgpass > /dev/null << 'EOF'
localhost:5432:app_db:backup_user:СложныйПароль123!
EOF
chmod 600 ~/.pgpass
Расписание в cron
Откройте crontab пользователя, под которым работают скрипты:
crontab -e
Добавьте задания — ежедневный бэкап в 3:30 ночи:
30 3 * * * /opt/scripts/mysql-backup.sh >> /var/log/db-backup.log 2>&1
30 3 * * * /opt/scripts/postgres-backup.sh >> /var/log/db-backup.log 2>&1
Проверьте, что задание записалось: crontab -l.
Копирование на другой сервер
Добавьте в конец скрипта отправку дампа на удалённый хост по SSH:
rsync -az "$BACKUP_DIR"/ [email protected]:/remote/db-backups/
Восстановление из дампа
MySQL:
gunzip < app_db_2026-04-17_03-30.sql.gz | mysql -u root -p app_db
PostgreSQL (формат custom):
pg_restore -d app_db --clean app_db_2026-04-17_03-30.dump
Частые вопросы
Как часто делать бэкапы? Зависит от того, сколько данных вы готовы потерять. Для активного сайта — ежедневно, для критичных данных — несколько раз в день или через непрерывное архивирование WAL (PostgreSQL).
mysqldump блокирует базу во время работы?
С флагом --single-transaction для таблиц InnoDB блокировки нет — снимается согласованный снимок. Для MyISAM блокировка возможна.
Где хранить дампы? Не только на том же диске. Копируйте на отдельный сервер или в объектное хранилище: сбой диска не должен уносить и базу, и её резервные копии.
Как убедиться, что бэкап рабочий? Периодически восстанавливайте дамп в отдельную тестовую базу и проверяйте данные. Непроверенный бэкап нельзя считать бэкапом.
Бэкапы — ваша зона ответственности, и мы рекомендуем держать их всегда. Разместить базу с автоматическими копиями можно на тарифах аренда VPS или профильном VPS для баз данных.
