Bash-скрипт резервного копирования MySQL с отправкой файла в Telegram
Содержание гайда
Оставлять дамп базы данных на том же самом сервере, где крутится продакшн, бессмысленно — при аварии накопителя погибнет и база, и ее локальная копия.
Ниже представлен полнофункциональный, готовый к продакшну Bash-скрипт. Он умеет:
- Создавать целостный дамп MySQL/MariaDB через
mysqldumpс флагом--single-transaction(без блокировки таблиц на чтение/запись). - Мгновенно сжимать дамп максимальным алгоритмом сжатия
gzip -9. - Автоматически проверять размер архива: если он до 50 МБ — скрипт физически отправляет сам файл бэкапа в ваш Telegram-чат через метод
sendDocument. Если файл тяжелее 50 МБ — отправляется форматированное HTML-сообщение с размером и сервером. - Автоматически удалять локальные архивы старше 14 дней.
- Логировать ошибки и присылать тревогу в Telegram в случае аварии.
1. Регистрация бота Telegram
- Откройте Telegram и напишите боту
@BotFather. - Отправьте
/newbot, укажите имя и юзернейм (например,myserver_backup_bot). - Скопируйте токен вида:
7891234567:AAHkL...(TELEGRAM_BOT_TOKEN). - Нажмите
Startв чате со своим ботом. - Узнайте свой
chat_id: напишите боту@userinfobot— он пришлет ваш цифровой ID (TELEGRAM_CHAT_ID).
2. Исходный код скрипта db_backup.sh
Создайте рабочий файл:
sudo mkdir -p /opt/scripts /var/backups/mysql
sudo nano /opt/scripts/db_backup.sh
Вставьте следующий код:
#!/usr/bin/env bash
# ==============================================================================
# Скрипт автоматического бэкапа MySQL с отправкой в Telegram
# ==============================================================================
set -e
# --- КОНФИГУРАЦИЯ БАЗЫ ДАННЫХ ---
DB_USER="root"
DB_PASS="ВашСложныйПарольОтБазы"
DB_NAME="production_db" # Либо укажите --all-databases для всех баз
DB_HOST="127.0.0.1"
DB_PORT="3306"
# --- КОНФИГУРАЦИЯ ХРАНИЛИЩА ---
BACKUP_DIR="/var/backups/mysql"
DAYS_TO_KEEP=14
TIMESTAMP=$(date +"%Y-%m-%d_%H-%M-%S")
BACKUP_FILENAME="${DB_NAME}_${TIMESTAMP}.sql.gz"
BACKUP_PATH="${BACKUP_DIR}/${BACKUP_FILENAME}"
# --- КОНФИГУРАЦИЯ TELEGRAM ---
TG_BOT_TOKEN="7891234567:AAHkLYourActualBotTokenHere"
TG_CHAT_ID="123456789"
SERVER_NAME=$(hostname)
# Функция отправки сообщения в Telegram
send_telegram_msg() {
local message="$1"
curl -s -X POST "https://api.telegram.org/bot${TG_BOT_TOKEN}/sendMessage" \
-d "chat_id=${TG_CHAT_ID}" \
-d "parse_mode=HTML" \
-d "text=${message}" > /dev/null 2>&1
}
# Функция отправки файла в Telegram
send_telegram_doc() {
local file_path="$1"
local caption="$2"
curl -s -X POST "https://api.telegram.org/bot${TG_BOT_TOKEN}/sendDocument" \
-F "chat_id=${TG_CHAT_ID}" \
-F "document=@${file_path}" \
-F "caption=${caption}" \
-F "parse_mode=HTML" > /dev/null 2>&1
}
mkdir -p "${BACKUP_DIR}"
echo "[*] Старт резервного копирования базы ${DB_NAME} на сервере ${SERVER_NAME}..."
# Создание дампа с компрессией на лету
if mysqldump --host="${DB_HOST}" \
--port="${DB_PORT}" \
--user="${DB_USER}" \
--password="${DB_PASS}" \
--single-transaction \
--quick \
--routines \
--triggers \
"${DB_NAME}" | gzip -9 > "${BACKUP_PATH}"; then
FILE_SIZE_BYTES=$(stat -c%s "${BACKUP_PATH}")
FILE_SIZE_HUMAN=$(du -h "${BACKUP_PATH}" | cut -f1)
echo "[+] Дамп успешно создан: ${BACKUP_PATH} (${FILE_SIZE_HUMAN})"
# Проверка лимита Telegram Bot API (50 МБ = 50000000 байт)
if [ "${FILE_SIZE_BYTES}" -le 50000000 ]; then
CAPTION="✅ <b>Бэкап БД создан успешно</b>%0A🖥 <b>Сервер:</b> ${SERVER_NAME}%0A📦 <b>База:</b> ${DB_NAME}%0A📊 <b>Размер:</b> ${FILE_SIZE_HUMAN}"
send_telegram_doc "${BACKUP_PATH}" "${CAPTION}"
else
MSG="✅ <b>Бэкап создан (Архив > 50 МБ)</b>%0A🖥 <b>Сервер:</b> ${SERVER_NAME}%0A📦 <b>База:</b> ${DB_NAME}%0A📊 <b>Размер:</b> ${FILE_SIZE_HUMAN}%0A⚠️ <i>Файл сохранен локально в ${BACKUP_DIR}.</i>"
send_telegram_msg "${MSG}"
fi
else
ERROR_MSG="❌ <b>ОШИБКА БЭКАПА!</b>%0A🖥 <b>Сервер:</b> ${SERVER_NAME}%0A📦 <b>База:</b> ${DB_NAME}%0A🚨 Команда mysqldump завершилась сбоем!"
send_telegram_msg "${ERROR_MSG}"
exit 1
fi
# Удаление старых бэкапов
echo "[*] Очистка архивов старше ${DAYS_TO_KEEP} дней..."
find "${BACKUP_DIR}" -type f -name "*.sql.gz" -mtime +${DAYS_TO_KEEP} -delete
echo "[+] Операция завершена успешно."
3. Выдача прав и проверка работы
Защитите файл паролей от чтения посторонними:
sudo chmod 700 /opt/scripts/db_backup.sh
sudo chown root:root /opt/scripts/db_backup.sh
Выполните проверочный запуск:
sudo /opt/scripts/db_backup.sh
В течение нескольких секунд в ваш Telegram придет файл с дампом базы данных.
4. Настройка ночного расписания в Cron
Откройте системный планировщик задач:
sudo crontab -e
Вставьте строку для ежедневного запуска в 03:30 ночи:
30 3 * * * /bin/bash /opt/scripts/db_backup.sh > /dev/null 2>&1
Частые вопросы
❓ Какой максимальный размер файла можно отправить в Telegram?
Официальный Bot API принимает файлы до 50 МБ через прямой curl-запрос. Если база больше, скрипт отправит отчет со ссылкой и статусом.
❓ Как защитить пароль БД внутри скрипта?
Скрипт использует файл параметров ~/.my.cnf или строгие права доступа chmod 700, запрещающие чтение другим пользователям.
❓ Работает ли скрипт с Docker-контейнерами баз данных?
Да, достаточно заменить команду mysqldump на docker exec -i container_name mysqldump.