From 2f0bdbb0b59e3db8ce844032a85df05d09e64cd3 Mon Sep 17 00:00:00 2001 From: Уласов Алексей Date: Thu, 14 Aug 2025 18:55:46 +0300 Subject: [PATCH] Add script and readme files. --- README.md | 23 +++++++++++++++++++++++ backup_mysql.sh | 185 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 208 insertions(+), 0 deletions(-) create mode 100644 README.md create mode 100644 backup_mysql.sh diff --git a/README.md b/README.md new file mode 100644 index 0000000..2fac33d --- /dev/null +++ b/README.md @@ -0,0 +1,23 @@ +# Скрипт для резервного копирования БД MySQL + +## Для работы скрипта необходимо указать данные для подключения к CУБД + +```bash +# Расположение лог-файла результата работы скрипта +SCRIPT_LOG=/var/log/backups_mysql.log +# Имя пользователя для подключения к СУБД +DB_USER="" +# Пароль пользователя для подключения к СУБД +DB_PASSWORD="" +# Имя хоста для подключения к СУБД +DB_HOST="" +# Опции с которыми будут делаться дамбы БД +DUMP_OPTIONS="--single-transaction --quick --no-autocommit --force --add-drop-table --skip-add-locks" +# Расположение временного каталога для дампов +DUMP_FOLDER=/backups/tmp +# Имя временного архивного файла с дампами БД +ARCHIVE_NAME=archive.tar.gz +# Каталог где будут храниться архивы с дампами БД +DESTINATION_FOLDER=/backups +``` + diff --git a/backup_mysql.sh b/backup_mysql.sh new file mode 100644 index 0000000..45e7992 --- /dev/null +++ b/backup_mysql.sh @@ -0,0 +1,185 @@ +#!/usr/bin/env bash + +set -o pipefail + +PATH="$PATH:/usr/local/bin:/usr/local/sbin" + +SCRIPT_LOG=/var/log/backups_mysql.log + +DB_USER="" + +DB_PASSWORD="" + +DB_HOST="" + +DB_LIST=() + +DUMP_OPTIONS="--single-transaction --quick --no-autocommit --force --add-drop-table --skip-add-locks" + +DUMP_FOLDER=/backups/tmp + +ARCHIVE_NAME=archive.tar.gz + +DESTINATION_FOLDER=/backups + + +function LOG() +{ + local msg="$1" + date=$(date '+%Y-%m-%d %H:%M:%S') + echo "[$date] $msg" >> $SCRIPT_LOG +} + +function DELETE_TMP_FOLDER() +{ + if [ -d "${DUMP_FOLDER}" ]; then + rm -rf "${DUMP_FOLDER}" &> /dev/null + if [ $? -ne 0 ]; then + LOG "ERROR: Can not delete ${DUMP_FOLDER}" + exit 2 + else + LOG "SUCCESS: Delete ${DUMP_FOLDER}" + fi + fi +} + +function CREATE_TMP_FOLDER() +{ + if [ -d "${DUMP_FOLDER}" ]; then + LOG "ERROR: Dump folder ${DUMP_FOLDER} exists." + exit 2 + else + mkdir -p "${DUMP_FOLDER}" &> /dev/null + if [ $? -ne 0 ]; then + LOG "ERROR: Create dump folder ${DUMP_FOLDER} failed." + DELETE_TMP_FOLDER + exit 2 + else + LOG "SUCCESS: ${DUMP_FOLDER} is created." + fi + fi +} + +function READ_DBS() +{ + + sql="SHOW DATABASES WHERE \`Database\` NOT IN('information_schema', 'performance_schema', 'mysql')" + + DB_LIST=$(mysql -N --host=${DB_HOST} --user=${DB_USER} --password=${DB_PASSWORD} -e "$sql") &> /dev/null + if [ $? -ne 0 ]; then + LOG "ERROR: Getting list of databases failed." + exit 2 + else + if [[ -n $DB_LIST ]]; then + LOG "SUCCESS: Getting list of databases success." + else + LOG "ERROR: List of databases is empty." + exit 2 + fi + fi +} + + +function CHECK_DISK_USAGE() +{ + sql="SELECT table_schema , ROUND(SUM(data_length + index_length) / 1024 / 1024, 0) FROM information_schema.TABLES;" + + DBS_SIZE=$(mysql -N --host=${DB_HOST} --user=${DB_USER} --password=${DB_PASSWORD} -e "$sql"| awk '{print $2}') &> /dev/null + if [ $? -eq 0 ] ; then + LOG "SUCCESS: Determining the size of MySQL databases." + else + LOG "ERROR: Determining the size of MySQL databases failed." + exit 2 + fi + + DST_AVAIL_SIZE=$(df -m ${DESTINATION_FOLDER} | awk 'NR==2{print $4}') &> /dev/null + if [ $? -eq 0 ] ; then + LOG "SUCCESS: Determining the amount of available disk space on ${DESTINATION_FOLDER} partition." + else + LOG "ERROR: Determining the amount of available disk space on ${DESTINATION_FOLDER} partition failed." + exit 2 + fi + + + if [ $DST_AVAIL_SIZE -lt $DBS_SIZE ] ; then + LOG "ERROR: There is not ${DESTINATION_FOLDER} enough available disk space." + exit 2 + else + LOG "SUCCESS: There is ${DESTINATION_FOLDER} enough available disk space." + fi +} + +function DUMP_DBS() +{ + for DB_NAME in $DB_LIST + do + LOG "Dumping ${DB_NAME}..." + mysqldump --host=${DB_HOST} --user=${DB_USER} --password=${DB_PASSWORD} ${DUMP_OPTIONS} ${DB_NAME} > ${DUMP_FOLDER}/${DB_NAME}.sql + + if [ $? -eq 0 ] ; then + LOG "SUCCESS: Dump ${DB_NAME} is created." + else + LOG "ERROR: Dump ${DB_NAME} is failed." + DELETE_TMP_FOLDER + exit 2 + fi + done +} + +function COMPRESS_DUMPS() +{ + (cd ${DUMP_FOLDER} && tar cf - *.sql) | gzip -9 > ${DUMP_FOLDER}/${ARCHIVE_NAME} + + if [ $? -eq 0 ] ; then + LOG "SUCCESS: Archive has been created." + else + LOG "ERROR: Archive creation failed." + DELETE_TMP_FOLDER + exit 2 + fi +} + +function CHECK_ARCHIVE() +{ + tar -tf ${DUMP_FOLDER}/${ARCHIVE_NAME} &> /dev/null; + if [ $? -eq 0 ] ; then + LOG "SUCCESS: Archive verification completed." + else + LOG "ERROR: Archive verification failed" + DELETE_TMP_FOLDER + exit 2 + fi +} + +function MOVE_ARCHIVE() +{ + date=$(date '+%Y-%m-%d_%H-%M') + mv ${DUMP_FOLDER}/${ARCHIVE_NAME} ${DESTINATION_FOLDER}/${DB_HOST}_${date}.tar.gz &> /dev/null + if [ $? -eq 0 ] ; then + LOG "SUCCESS: Archive has been moved." + else + LOG "ERROR: Archive moving failed" + DELETE_TMP_FOLDER + exit 2 + fi + +} + + +LOG "### Backup mysql started ###" +LOG "Checking the amount of available disk space on ${DESTINATION_FOLDER} partition." +CHECK_DISK_USAGE +LOG "Creatting temporary folder:" +CREATE_TMP_FOLDER +LOG "Getting list of databases:" +READ_DBS +LOG "Dump databases:" +DUMP_DBS +LOG "Compressing dumps:" +COMPRESS_DUMPS +LOG "Checking archive:" +CHECK_ARCHIVE +LOG "Moving archive:" +MOVE_ARCHIVE +DELETE_TMP_FOLDER +LOG "### Backup mysql ended ###" \ No newline at end of file -- libgit2 0.22.2