Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #!/bin/env bash
- #Коды выхода:
- #0 - OK
- #1 - Ошибка выполнения (pg_dump, удаление бекапа и тд)
- #2 - Ошибка конфигурации (файла конфига нет или нет какого-то параметра)
- #11 - Недостаточно памяти для бекапа
- #12 - Ошибка подключения к серверу PostgreSQL
- #--------------------
- #Дополнительно:
- #строка для для crontab
- #5 1 * * /путь/до/этого/скрипта
- #--------------------
- if [[ -z $1 ]]; then
- echo "Путь к файлу конфигурации не указан"
- exit 2
- fi
- CONFIG_PATH=$1
- echo $CONFIG_PATH
- # Проверяем, существует ли конфиг файл
- if [[ ! -f "$CONFIG_PATH" ]]; then
- echo "[$(date +"%Y.%m.%d_%H:%M:%S")] [ERROR] Файл конфигурации не существует: $CONFIG_PATH"
- exit 2
- fi
- #Альтернативно можно подгрузить конфиг при помощи:
- #source "$CONFIG_PATH"
- DB_HOST=$(awk -F "=" '/DB_HOST/ {print $2}' $CONFIG_PATH)
- DB_USER=$(awk -F "=" '/DB_USER/ {print $2}' $CONFIG_PATH)
- DB_PASS=$(awk -F "=" '/DB_PASS/ {print $2}' $CONFIG_PATH)
- DB_BASE=$(awk -F "=" '/DB_BASE/ {print $2}' $CONFIG_PATH)
- BACKUP_PATH=$(awk -F "=" '/BACKUP_PATH/ {print $2}' $CONFIG_PATH)
- BACKUP_PREFIX=$(awk -F "=" '/BACKUP_PREFIX/ {print $2}' $CONFIG_PATH)
- BACKUP_COUNT=$(awk -F "=" '/BACKUP_COUNT/ {print $2}' $CONFIG_PATH)
- REQUIRED_VARS=(
- DB_HOST
- DB_USER
- DB_PASS
- DB_BASE
- BACKUP_PATH
- BACKUP_PREFIX
- BACKUP_COUNT
- )
- for var in "${REQUIRED_VARS[@]}"; do
- if [[ -z "${!var}" ]]; then
- echo "[$(date +"%Y.%m.%d_%H:%M:%S")] [ERROR] Переменная $var не задана в файле конфигурации"
- exit 2
- fi
- done
- # Проверяем, что директория бекапов существует
- if [[ ! -d "$BACKUP_PATH" ]]; then
- echo "[$(date +"%Y.%m.%d_%H:%M:%S")] [ERROR] Директория для резервных копий $BACKUP_PATH не существует"
- exit 2
- fi
- LOG_TIMESTAMP=$(date +"%Y.%m.%d_%H%M%S")
- LOG_FILE="$BACKUP_PATH/${BACKUP_PREFIX}.${LOG_TIMESTAMP}.log"
- BACKUP_FILE="$BACKUP_PATH/${BACKUP_PREFIX}.${LOG_TIMESTAMP}.tar"
- function log(){
- CURR_TIMESTAMP=$(date +"%Y.%m.%d_%H:%M:%S")
- echo "[$CURR_TIMESTAMP] $1" | tee -a "$LOG_FILE"
- }
- log "[INFO] Начало резервного копирования..."
- log "[INFO] Пробую подключиться к серверу..."
- #тестируем подключение к серверу PostgreSQL
- if ! pg_isready -h $DB_HOST -p 5432 -U $DB_USER; then
- log "[ERROR] Не удалось подключиться к серверу PostgreSQL"
- exit 12
- fi
- log "[INFO] Успешное подключение к серверу PostgreSQL"
- log "[INFO] Проверяю наличие места на диске для бекапа..."
- function convert_to_bytes(){
- local num=$1
- local measure_unit=$2
- case "$measure_unit" in
- B) echo $((num)) ;;
- kB|K) echo $((num*1024)) ;;
- MB|M) echo $((num*1024*1024)) ;;
- GB|G) echo $((num*1024*1024*1024)) ;;
- TB|T) echo $((num*1024*1024*1024*1024)) ;;
- *) echo "0" ;;
- esac
- }
- export PGPASSWORD=$DB_PASS
- #Парсим вывод размера БД и конвертируем в байты
- #Поскольку посчитать потенциальный бекап при помощи pg_dump
- #сложно, я сделал допущение (грубоватое), что размер БД приблизительно равен размеру бекапа
- DB_SIZE_RAW=$(psql -h "$DB_HOST" -p 5432 -U "$DB_USER" -d "postgres" -c "SELECT pg_size_pretty(pg_database_size('$DB_BASE'));")
- DB_SIZE_NUM=$(echo $DB_SIZE_RAW | grep -oE '[0-9]+' | head -1)
- DB_SIZE_MEASURE_UNIT=$(echo $DB_SIZE_RAW | grep -oE '[kmKMGT]?B|[GKTM]')
- DB_SIZE_BYTES=$(convert_to_bytes $DB_SIZE_NUM $DB_SIZE_MEASURE_UNIT)
- #Аналогично делаем с дисковым пространством
- AVAILABLE_DISK_SPACE_RAW=$(df -h --total | awk 'END{print $4}')
- AVAILABLE_DISK_NUM=$(echo $AVAILABLE_DISK_SPACE_RAW | grep -oE '[0-9]+')
- AVAILABLE_DISK_MEASURE_UNIT=$(echo $AVAILABLE_DISK_SPACE_RAW | grep -oE '[kmKMGT]?B|[GKTM]')
- AVAILABLE_DISK_BYTES=$(convert_to_bytes $AVAILABLE_DISK_NUM $AVAILABLE_DISK_MEASURE_UNIT)
- if [[ $DB_SIZE_BYTES -gt $AVAILABLE_DISK_BYTES ]]; then
- log "[ERROR] Недостаточно места на диске"
- exit 11
- fi
- #добавляем +1, так как скрипт запустился и будет потенциальный бекап
- TOTAL_NUM_OF_BACKUPS=$(($(find "$BACKUP_PATH" -type f -name "*tar.gz" | wc -l)+1))
- #Если число бекапов больше заданного, удаляем самый старый бекап
- if [[ $TOTAL_NUM_OF_BACKUPS -gt $BACKUP_COUNT ]]; then
- log "[INFO] Удаляю самую старую резервную копию..."
- OLDEST_BACKUP=$(find "$BACKUP_PATH" -maxdepth 1 -type f -name "*tar.gz" -printf "%T %p\n" | sort -n | head -1 | cut -d' ' -f2-)
- rm "$OLDEST_BACKUP"
- if [[ ! $? -eq 0 ]]; then
- log "[ERROR] Не удалось удалить резервную копию"
- exit 1
- fi
- fi
- log "[INFO] Создаю резервную копию..."
- pg_dump -h "$DB_HOST" -U "$DB_USER" -d "$DB_BASE" -F t -v -f "$BACKUP_FILE" >> "$LOG_FILE" 2>&1
- if [[ $? -ne 0 ]]; then
- log "[ERROR] Возникла ошибка при создании резервной копии"
- exit 1
- fi
- gzip -9 $BACKUP_FILE
- log "[INFO] Резервная копия успешно создана"
- log "[INFO] Завершение резервного копирования..."
Advertisement
Add Comment
Please, Sign In to add comment