- Автор темы
- Администратор
- Модер.
- Команда форума
- #1
Готовый Bash-скрипт бэкапа MySQL с датой/временем в имени, удалением старых копий, уведомлением в Telegram, и копированием на удалённый сервер по SSH/SCP (плюс опционально чистит старые на удалённом).
Скрипт mysql_backup.sh
Проверьте вход без пароля:
2) Права и запуск
3) Cron (пример: каждый день в 02:00)
Добавьте:
Скрипт mysql_backup.sh
Bash:
#!/usr/bin/env bash
set -euo pipefail
# ==============================
# CONFIG: MySQL
# ==============================
DB_NAME="назва_бази"
DB_USER="користувач"
# ==============================
# CONFIG: Local backup
# ==============================
BACKUP_DIR="/var/backups/mysql"
RETENTION_DAYS_LOCAL=7
# gzip: 1=включить, 0=выключить
USE_GZIP=1
# ==============================
# CONFIG: Telegram
# ==============================
TG_BOT_TOKEN="123456:ABCDEF_your_bot_token"
TG_CHAT_ID="123456789" # ваш chat_id (или -100... для группы/канала)
# ==============================
# CONFIG: Remote copy (SCP over SSH)
# ==============================
REMOTE_ENABLE=1
REMOTE_USER="backupuser"
REMOTE_HOST="example.com"
REMOTE_PORT=22
REMOTE_DIR="/srv/backups/mysql"
RETENTION_DAYS_REMOTE=14 # 0 = не удалять на удалённом
# ==============================
# Runtime vars
# ==============================
DATE="$(date +"%Y-%m-%d_%H-%M-%S")"
mkdir -p "$BACKUP_DIR"
EXT="sql"
if [[ "$USE_GZIP" -eq 1 ]]; then EXT="sql.gz"; fi
BACKUP_BASENAME="${DB_NAME}_${DATE}.${EXT}"
BACKUP_FILE="${BACKUP_DIR}/${BACKUP_BASENAME}"
LOG_FILE="${BACKUP_DIR}/backup.log"
# ==============================
# Helpers
# ==============================
tg_send() {
local text="$1"
# минимально безопасная отправка текста
curl -sS -X POST "https://api.telegram.org/bot${TG_BOT_TOKEN}/sendMessage" \
-d "chat_id=${TG_CHAT_ID}" \
--data-urlencode "text=${text}" \
-d "disable_web_page_preview=true" >/dev/null || true
}
log() {
echo "[$(date +"%Y-%m-%d %H:%M:%S")] $*" | tee -a "$LOG_FILE"
}
# ==============================
# Start
# ==============================
START_TS="$(date +%s)"
log "=== Backup started: DB=${DB_NAME} ==="
# ==============================
# Dump
# ==============================
if [[ "$USE_GZIP" -eq 1 ]]; then
# важно: pipefail включен, так что ошибка mysqldump не потеряется
mysqldump --single-transaction -u "$DB_USER" "$DB_NAME" | gzip > "$BACKUP_FILE"
else
mysqldump --single-transaction -u "$DB_USER" "$DB_NAME" > "$BACKUP_FILE"
fi
SIZE_HUMAN="$(du -h "$BACKUP_FILE" | awk '{print $1}')"
log "Backup created: $BACKUP_FILE (size: $SIZE_HUMAN)"
# ==============================
# Local retention
# ==============================
find "$BACKUP_DIR" -type f -name "${DB_NAME}_*.sql" -mtime +"$RETENTION_DAYS_LOCAL" -delete || true
find "$BACKUP_DIR" -type f -name "${DB_NAME}_*.sql.gz" -mtime +"$RETENTION_DAYS_LOCAL" -delete || true
log "Local retention applied: >${RETENTION_DAYS_LOCAL} days"
# ==============================
# Remote copy
# ==============================
REMOTE_RESULT="remote disabled"
if [[ "$REMOTE_ENABLE" -eq 1 ]]; then
log "Remote copy: ensuring dir exists on remote..."
ssh -p "$REMOTE_PORT" "${REMOTE_USER}@${REMOTE_HOST}" "mkdir -p '$REMOTE_DIR'"
log "Remote copy: uploading via scp..."
scp -P "$REMOTE_PORT" "$BACKUP_FILE" "${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_DIR}/"
REMOTE_RESULT="uploaded to ${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_DIR}/${BACKUP_BASENAME}"
log "Remote copy OK: $REMOTE_RESULT"
if [[ "$RETENTION_DAYS_REMOTE" -gt 0 ]]; then
log "Remote retention: deleting >${RETENTION_DAYS_REMOTE} days..."
ssh -p "$REMOTE_PORT" "${REMOTE_USER}@${REMOTE_HOST}" \
"find '$REMOTE_DIR' -type f -name '${DB_NAME}_*.sql*' -mtime +${RETENTION_DAYS_REMOTE} -delete"
log "Remote retention applied: >${RETENTION_DAYS_REMOTE} days"
fi
fi
# ==============================
# Finish + Telegram notify
# ==============================
END_TS="$(date +%s)"
DUR="$((END_TS - START_TS))"
MSG="✅ MySQL backup OK
DB: ${DB_NAME}
File: ${BACKUP_BASENAME}
Size: ${SIZE_HUMAN}
Local: ${BACKUP_DIR}
Remote: ${REMOTE_RESULT}
Duration: ${DUR}s
Time: $(date +"%Y-%m-%d %H:%M:%S")"
tg_send "$MSG"
log "Telegram notified"
log "=== Backup finished successfully (duration: ${DUR}s) ==="
1) Что нужно подготовить
A) Telegram
- Создайте бота у @BotFather, получите TG_BOT_TOKEN.
- Узнайте chat_id:
- напишите боту сообщение
- откройте в браузере (или через curl) getUpdates и посмотрите chat.id
(в группах часто -100...)
B) SSH доступ на удалённый сервер
На машине, где выполняется бэкап:
Bash:
ssh-keygen -t ed25519
ssh-copy-id -p 22 [email protected]
Проверьте вход без пароля:
Bash:
ssh -p 22 [email protected] "echo ok"
2) Права и запуск
Bash:
chmod +x /path/to/mysql_backup.sh
/path/to/mysql_backup.sh
3) Cron (пример: каждый день в 02:00)
Bash:
crontab -e
Добавьте:
Bash:
0 2 * * * /path/to/mysql_backup.sh
