LINUX.ORG.RU
ФорумAdmin

Bash скрипт для бэкапа

 


0

1

Добра всем и счастья!

Задолбался бороться с ISPManager и его системой бэкапа , нужно другое!

Треба:

1.Архив два раза в день!
2.Архивировать папки(каталоги сайтов) раздельно.
3.Архивировать базы данных mysql раздельно.
4.Все это паковать в итоге в один архив 
5.Отсылать курлом на яд
6.Контролировать кол-во копий и удалять старые.

Знаю,губа не дура, но все пункты осилил кроме 2,3,4 , вернее 3 пункт с именами заплелся, 2-й тоже затырки..

Может есть что то готовое в таком стиле у кого?

Если подождёшь, чуть позже скину свой ваиант. Делает всё это, только бекапы на другой сервак по сети.

ps1h ★★★
()

Если я верно понял, то по третьему пункту:

/usr/bin/mysqldump  -u${sql_user} -p${sql_pass} ${database} | /bin/gzip -c9 > ${path_backup}${pref_backup}_backup_MySQL_DB_MYSQL_MASTER_${date_current}.gz
hanharr
()

По поводу архивации каталогов как вариант:

create_dir_dump() {
cd $1
/bin/tar -c -f - ./* | /bin/gzip -c9 > ${path_backup}${pref_backup}_backup_$2_${date_current}.gz
}

create_dir_dump /etc etc
hanharr
()

7. нотификация об успешно созданной копии на почту

Samamy ★★★
()

бери и мой

1. Dump сайтов(каждый сайт в отдельный архив)
2. Dump Mysql
3. Упаковка всех архивов в 1
4. проверка свободного месте (если диск заполнен) удалить самый старый DUMP
5. заливает на удаленный сервер

cd /root/cloud

echo Wait pls!....................................
sleep 3

#DUMP SITES FILES


tar -czvf /root/cloud/site1.com.gz /var/www/site1.com
echo site1 BACKUP COMPLITED!!!
sleep 3


tar -czvf /root/cloud/site2.com.gz /var/www/site2.com
echo site2 BACKUP COMPLITED!!!
sleep 3


#DUMP SQL BASE

mysqldump -uUserBDSite1 -pPassBD site1 > /root/cloud/site1.com.sql
echo DUMP site1.com.sql COMPLITED!!!!
sleep 1

mysqldump -uUserBDSite2 -pPassBD Site1 > /root/cloud/site2.com.sql
echo DUMP site2.com.sql COMPLITED!!!!
sleep 1



echo Wait pls! Compression All Files...
sleep 1

tar -czf BackupALL_myVPS_`date "+%Y-%m-%d"`.tar.gz site1.com.gz site2.com.gz site1.com.sql site2.com.sql

echo COMPRESSION COMPLITED!!!!

sleep 1

echo Wait PLS! CLEAR TEMP FILES!!!!


rm /root/cloud/site1.com.gz.gz
echo Delete File site1.com.gz

rm /root/cloud/site2.com.gz.gz
echo Delete File site2.com.gz


rm /root/cloud/site1.com.sql
echo Delete File site1.com.sql

rm /root/cloud/site2.com.sql
echo Delete File site2.com.sql


sleep 1
echo ALL COMPLITED..........................................


echo Wait pls Copy to Remote Server....

scp -P 22 `ls -t /root/cloud/ | head -1` cloud@ipRemoteServer:/home/cloud/

echo Copy to Remote Server Complited....
sleep 1

echo Check Free Space......

#Если Диск заполнен более чем на 80% тогда удалить самый старый фаил
file=`ls -t /root/cloud/BackupALL_myVPS_????-??-??.tar.gz | tail -n1`
count=`df | grep /dev/vda1 | awk '{print $5}' | sed '{s/.$//;}'`
min=80

if [ $count -ge $min ]
then
echo The disk is full of more than 80%, Delete Old Files....
   rm $file
   echo File $file Delete
fi

echo ALL COMPLITED..........................................

shrmvl
()
Ответ на: комментарий от skynetyar

3.Архивировать базы данных mysql раздельно.


for i in `mysql -u root -e'show databases;' | grep -v information_schema | grep -v mysql | grep -v performance_schema | grep -v Database`; do mysqldump -u root $i > `date +%Y-%m-%d`-$i; gzip `date +%Y-%m-%d`-$i;done

Имхо этот вариант лучше чем у предыдущего оратора, так как после каждого вновь созданного каталога и базы тебе НЕ придётся править свой скрипт с бекапами.

6.Контролировать кол-во копий и удалять старые.

find /opt/backup -type f -mtime +3 -delete

ps1h ★★★
()

4.Все это паковать в итоге в один архив

Делай всё проще... сначала сжимаешь отдельно все базы и нужные папки в отдельные файлики дата_имя.gz, а потом все вместе собираешь

tar -cjf foo.tar /opt/*.gz    

ps1h ★★★
()
Ответ на: комментарий от ps1h

Вот покажу свой,и где заплелся..

#!/bin/bash

#
#Переменные Базы данных
DBHOST="localhost" #Адрес MySQL сервера
DBUSER="ЮЗЕР" #Имя пользователя базы данных
DBPASS="ПАРОЛЬ" #Пароль пользователя базы данных
DBNAME="ТУТ БАЗА" #Имя базы данных
DBARC=$DBNAME.sql.gz #Имя архива базы данных
#
#Переменные WEBDAV
WEBDAVURL="https://webdav.yandex.ru/ПАПКА/" #Адрес Яндекс.Диск. Папка должна существовать!
WEBDAVUSER="ЮЗЕР@yandex.ru" #Имя пользователя от Яндекс.Диска (Яндекс.Почты)
WEBDAVPASS="ПАСС" #Пароль от Яндекс.Диска
#
#Переменные сайта
SCRIPTDIR="/home/backup" #Абсолютный путь откуда запускается скрипт и где храняться архивы
SCRDIR="/var/www/юзер/data/www/сайт" #Абсолютный путь к сайту от корня диска
SCREXCLUDE="" #Что не попадет в архив
SCRARC="имя.tar.gz" #Имя архива файлов сайта
#
#Переменные Резерных копий
ARCNAME="имя"_$(date '+%F-%H-%M')".tar" #Имя архивной копии сайта
ARCMAX="30" #Количество файлов в локальном хранилище


#start backup
echo "[--------------------------------[`date +%F--%H-%M`]--------------------------------]" 
echo "[----------][`date +%F--%H-%M`] Run the backup script..."
#
#Переходим в корневую директорию вебсервера
cd $SCRDIR
echo "[++--------][`date +%F--%H-%M`] Generate a source code project..."
#
#Создаем файловый архив со сжатием, учитываем исключения
tar cfz $SCRIPTDIR$SCRARC --exclude=$SCREXCLUDE *
#
#Возвращаемся в папку со скриптом, где лежат все архивы
cd $SCRIPTDIR
echo "[+++-------][`date +%F--%H-%M`] Generate a database backup..."
#
#Архивируем базу данных со сжатием
#########################mysqldump -h$DBHOST -u$DBUSER -p$DBPASS $DBNAME | gzip > $DBARC
databases=`mysql --user=$DBUSER --password=$DBPASS -e "SHOW DATABASES;" | tr -d "| " | grep -v Database`
 for db in $databases; do
    if [[ "$db" != "information_schema" ]] && [[ "$db" != _* ]] ; then
        echo "Dumping database: $db"
        mysqldump --force --opt --user=$DBUSER --password=$DBPASS --databases $db > `date +%Y%m%d`.$db.sql
        gzip `date +%Y%m%d`.$db.sql
    fi
done
#########################
echo "[++++------][`date +%F--%H-%M`] Generate a database backup + source..."
#
#Объединяем файловый архив и дамп базы данных, теперь уже без сжатия
tar cf $SCRIPTDIR$db $SCRARC $DBARC
echo "[+++++-----][`date +%F--%H-%M`] Go to yandex drive..."
#
#Отправляем результат в Яндекс.Диск
curl --user $WEBDAVUSER:$WEBDAVPASS -T $ARCNAME $WEBDAVURL
echo "[++++++----][`date +%F--%H-%M`] Delete old arch..."
#
#Убираем промежуточные архивы
rm *.gz
#
#Удаляем старые копии сайта, оставляем несколько свежих копий
ls -t *.tar | tail -n+$ARCMAX | xargs rm -f
#
echo "[++++++++--][`date +%F--%H-%M`] Stat datadir space (USED): `du -h $SCRIPTDIR | tail -n1`" 
echo "[+++++++++-][`date +%F--%H-%M`] Free HDD space: `df -h /home|tail -n1|awk '{print $4}'`"
echo "[++++++++++][`date +%F--%H-%M`] All operations completed successfully!"
exit 0

Вот помогите поправить, я было начал но заплелся опять, он базы нормально выбирает и вроде бы нормально их компанует потом ошибка на архивации...

Конечно в идеале хотелось бы так

База.tar+база.tar+база.tar+база.tar=Архив баз
Каталог.tar+каталог.tar+каталог.tar=Каталог.tar
И все это потом в один архив для удобства дата.tar

skynetyar
() автор топика
Ответ на: комментарий от skynetyar

По идее примерно так для баз и по аналогии для остального

#Архивируем базу данных со сжатием
databases=`mysql --user=$DBUSER --password=$DBPASS -e "SHOW DATABASES;" | tr -d "| " | grep -v Database`
 for db in $databases; do
    if [[ "$db" != "information_schema" ]] && [[ "$db" != _* ]] ; then
        echo "Dumping database: $db"
        mysqldump --force --opt --user=$DBUSER --password=$DBPASS --databases $db | /bin/gzip -c9 > /path/to/database_dump/`date +%Y%m%d`.$db.gz
    fi
done

/bin/tar -c -f - /path/to/database_dump/* | /bin/gzip -c9 > /path/to/backup/arch_databases.gz
rm -rf /path/to/database_dump/*
hanharr
()
Ответ на: комментарий от skynetyar

А, такой момент еще. Либо я чего-то не нагуглил, либо для того, чтобы в архиве данные лежали без полных путей надо сначала перейти в место сборки архива cd $path.

hanharr
()
Ответ на: комментарий от hanharr

Заплелся в архивах, по раздельности все работает,сперва надо сжимать в .gz потом надо пережимать в tar затем удалять rm *.gz

skynetyar
() автор топика
Ответ на: комментарий от skynetyar

По сути это и происходит. Для понимания, можно сначала разложить по разным каталогам архивы БД и архивы каталогов. Потом проходишься по такому каталогу, собираешь всё из него в один архив и очищаешь. Полученные архивы складываешь отдельно и с ними делаешь тоже самое собирая один большой архив.

Как получится можно поиграться названиями архивов, чтобы можно было складывать всё в одну промежуточную директорию и потом с помощью find собирать архивы.

hanharr
()
Ответ на: комментарий от hanharr

Это все получилось, теперь последняя задача надо на ЯД курлом отправлять\синхронизировать папку.

Сейчас это так

curl --user $WEBDAVUSER:$WEBDAVPASS -T $ARCNAMEBASE $WEBDAVURL

Но он тут тупо закидывает туда архив и все....а надо контролировать и там количество архивов..

skynetyar
() автор топика
Ответ на: комментарий от skynetyar

Скриптописатели х...вы!!! Не забываем использовать обработку ошибок после важных команд ( [ $? == 0 ] ) а то получите банан на выходе. Где ключи routines и triggers для mysqldump?

anonymous
()
Ответ на: комментарий от hanharr

Вот из хелпа, чот не стетерю как применить..

Для удаления файла необходимо выполнить команду:
curl --user <username>:<password> --request DELETE https://webdav.yandex.ru/filename
skynetyar
() автор топика
Ответ на: комментарий от shrmvl

cd /root/cloud
echo Wait pls!....................................
sleep 3

«Маловато будет» (c) Почему не sleep 33333 ? Юзеру «интереснее» будет.
Или интерактивнее for i in `seq 1 333333` ; do echo -n .$i; sleep 1; done

anc ★★★★★
()
Ответ на: комментарий от anc

Решил я так синхронизировать, потому что curl никак, можно только запуливать...

SCRIPTDIR="/home/backup"
umount /mnt/yandex
mount -t davfs https://webdav.yandex.ru/KATALOG /mnt/yandex
cp -a $SCRIPTDIR* /mnt/yandex
umount /mnt/yandex

В локальной папке /home/backup все нормально ,остается 3 файла потому что я удаляю их

ls -t *.tar | tail -n+3 | xargs rm -f

Но почему то в ЯДе не удаляется так же последний файл?!?! Почему нет полной синхронизации папок между локальной папкой и ЯДОМ ?

skynetyar
() автор топика
Ответ на: комментарий от skynetyar

ls -t *.tar | tail -n+3 | xargs rm -f

Мамаааа роди меня обратно.

Почему нет полной синхронизации папок между локальной папкой и ЯДОМ ?

Бэкап? Полная синхронизация? Дежавю. В другой теме я уже объяснил почему это «плохо».

anc ★★★★★
()
Ответ на: комментарий от anc

Короче плюнул на этот davf и заюзал rclone и все путем!

rclone sync /home/backup/ yandex:backup

skynetyar
() автор топика
Ответ на: комментарий от hanharr

/bin/tar -c -f - /path/to/database_dump/* | /bin/gzip -c9 > /path/to/backup/arch_databases.gz

1) Что вы пытаетесь получить указывая «/bin/» ?

2) Сжимать уже сжатое - только время терять.

3) Правильнее надо в архив дописывать после дампа каждой базы и сразу потом удалять каждый файл, а не создавать архив в конце, так как это не потребует двойного размера места с дампами и готовым архивом, а потребует только место под архив и под сжатый дамп последней базы из списка.

vodz ★★★★★
()
Последнее исправление: vodz (всего исправлений: 1)
Ответ на: комментарий от skynetyar

Фигня в том что основываться на времени создания файла не верно. Хз что могло произойти. Для этого в имена файлов бэкапа и надо добавлять дату-время что бы была возможность легко отсортировать.
Далее. Вы оставляете два последних *.tar. Это будет работать если точно в этой директории один_бэкап-один_архив. Но вот «завтра» вашей «левой пятке» придет в голову помещать три архива в эту директорию, но к этому «завтра» вы забудете про команду rm. Результат - один из архивов будет снесен.
Или еще, «сегодня» мы решили один архив в неделю, а вот «завтра» решили 8 архивов в сутки, говно вопрос, поменяли в кроне расписание, и вроде профит, скрипт уже никто не смотрит. Только вот шансов на обнаружение проблемы в течении 2-х недель гораздо больше чем в течении 6 часов. Это я к тому что ваши бэкапы будут уже с ошибкой.

anc ★★★★★
()
Ответ на: комментарий от anc

Ну.. В данный момент так все устроено..

Папка cache
1.Дамп каталога /www/ с сохранением структуры --> .gz
2.Дамп всех баз с исключениями -->.gz
Папка backup
3.Объединение в локальной директории bacup архива баз и архива www
Папка cache
4.rm *.gz
Папка backup
5.Удаляем старые копии сайта, оставляем несколько свежих копий
6.rclone sync на ЯД в подпапку

Думаю схема самая верная ,главное последовательность не путать

С применением rclone избавился от глюков и чисток кэша и.т.д...

Применил на 4-х серверах VDS все крутится вроде бы пока =)

skynetyar
() автор топика
Ответ на: комментарий от vodz

1) Что вы пытаетесь получить указывая «/bin/» ?

Вот полный путь, это правильно. Не понимаю к чему докопались. Поясните.

anc ★★★★★
()
Ответ на: комментарий от anc

Вот полный путь, это правильно. Не понимаю к чему докопались. Поясните.

Чего правильного в указании полного пути к tar и gzip? С чего они обязаня быть в /bin ? И я не докопался, в отличии от вас, а вежливо спросил, что именно хотел этим автор.

vodz ★★★★★
()
Ответ на: комментарий от vodz

а вежливо спросил, что именно хотел этим автор.

Немного стеба: Для вас это редкость. :)

Серьезно: Я к вам отношусь с уважением.
По теме: Указание полных путей какбэ правильно. Другой вопрос вынести в переменные, что бы при переносе на другую систему не править по всему тексту.
У вас есть какие-то еще возражения?

anc ★★★★★
()
Ответ на: комментарий от skynetyar

все крутится вроде бы пока

Я вам дал описание «граблей». А как поступать дело ваше.
«Админы делятся на три категории:
1. которые не делают бэкап
2. которые уже делают бэкап
3. которые проверяют бэкап»

anc ★★★★★
()
Ответ на: комментарий от anc

У вас есть какие-то еще возражения?

Если ваш системный PATH изменен, значит это так надо было системному администратору. Не надо умничать там где нет никакого основания. А то так можно дойти до того, что скажем в юниксах, которые говно мамонта не будет никакого gzip-а, а у имеющегося компрессора будут другие ключи, и ваши переменные к бинарю тоже пойдут лесом. Хотите проверить доступность утилит, ну — ваше право. Проверили, поплакали, если не нашлось и всё, что-то большее уже выглядит как форменное извращение.

vodz ★★★★★
()
Ответ на: комментарий от vodz

Возражений два.
1. Очень часто возникают темы, когда «юзеры» не прописывая полный путь, жалуются что мол мой скрипт не работает.
2. «Если ваш системный PATH изменен» а вот тут не обязательно, что изменен. Достаточно закинуть «каку» в путь который будет по списку выше. Да это хак. Но все-таки. Не буду описывать зачем мне больше десяти лет назад надо было такое сделать. Ничего плохого я не сделал, только для «себя любимого». Однако осадочек паранойя «от выполненного самим» таки есть. Ведь такое же и для «гадости» можно исполнить.

anc ★★★★★
()
Последнее исправление: anc (всего исправлений: 1)

Я, конечно, осознаю, на каком форуме нахожусь и что сейчас начнется... Но, все-таки, предложу не городить велосипед из костылей, а взять нормальное решение:

https://www.borgbackup.org/

https://torsion.org/borgmatic/

Для дампа базы mysql нужно будет добавить пару строк своего кода.

P.S. Вместо Яндекс диска взять нормальный сервис, или примонтировать этот самый ЯДиск через fuse.

aquadon ★★★★★
()
Последнее исправление: aquadon (всего исправлений: 1)
Ответ на: комментарий от anc

1. Очень часто возникают темы, когда «юзеры» не прописывая полный путь, жалуются что мол мой скрипт не работает.

Скрипт по бэкапу базы — основной системный обеспечивающий скрипт по работоспособности конкретного хоста :) Какие юзеры? Полные пути в скриптах я вижу, но как правило они или для (/usr)/sbin либо к /usr/local/* , первое — не Unix-стандарт, второе единственно верное решение. Поменять PATH, убрав /bin с первой позиции — это надо прям не знаю какое надо СЕРЬЕЗНОЕ обоснование, и если оно в результате у пользователя не работает, то в этом случае у него есть полное право жаловаться, но и получать по полной, если пользователь сам так испоганил PATH.

vodz ★★★★★
()
Последнее исправление: vodz (всего исправлений: 1)
Ответ на: комментарий от vodz

Скрипт по бэкапу базы — основной системный обеспечивающий скрипт по работоспособности конкретного хоста :) Какие юзеры?

Слово «юзеры» я не случайно взял в кавычки. :) Темы вида «вот запускаю руками - работает, прописал в крон - не работает» или «запускаю под рутом - работает, через sudo - не работает» и т.д. и т.п

Поменять PATH, убрав /bin с первой позиции — это надо прям не знаю какое надо СЕРЬЕЗНОЕ обоснование

А вы посмотрите на «свой любимый дистр» из каробки.
Для примера копейкоос

# which cp
alias cp='cp -i'
	/usr/bin/cp

/usr/bin/cp хардлинк /bin/cp т.е. заменив /usr/bin/cp на что-то другое может быть «очень интересно». :)
Хотя описывая тот старый случай было проще, запихнули по пути который был выше :) Что бы было понятно, это был не взлом (от взлома тут не спасет), а только «молчаливая борьба админов», большая контора, смена власти, «новые» думали что они такие «умные» отнять у нас доступ к нужным нам сервисам просто сменив пароль рута :)

Но я в целом писал о том, что не полагаться на PATH как таковой, а писать полные пути - это правильно. Не конкретный случай с /bin и бэкапом, просто общую практику.

anc ★★★★★
()
Ответ на: комментарий от anc

Может так?

#!/bin/bash
PATH=/etc:/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin

whereis bash \ which bash

Универсального решения не существует, у меня и без #!/bin/bash работало...

skynetyar
() автор топика
Последнее исправление: skynetyar (всего исправлений: 1)
Ответ на: комментарий от skynetyar

Не парьтесь. Это обсуждение с vodz, у каждого из нас своя точка зрения. И каждая имеет место быть. В спорах рождается истина.

Свою точку зрения я описал выше, задать переменными, что бы по всему скрипту не писать /bin/tar &etc. Хотя я и сам зачастую таким грешу, более того могу написать например cp, просто по тому что в тот момент был занят и вот так написал. Но фэншуйно имхо переменными. Минус этого «фэншуя» перенос на другую систему где нужные бинарники лежат по другим путям, приходиться править переменные.

which

В самом первом посте даже не стал упоминать о подобной фигне. Хоть и встречал такое в чужих скриптах для задания переменных. Чуш полная, какая нафиг разница если все равно берется из переменной PATH ?

anc ★★★★★
()
Ответ на: комментарий от skynetyar

Универсального решения не существует, у меня и без #!/bin/bash работало...

А это вот отдельная история.
1. Без указания запуститься с дефолтным шелом, а что там sh, dash, zsh, *sh поведение возможно будет разным.
2. Но даже при указании это может быть линк совсем на что-то другое, тот же dash

anc ★★★★★
()
Ответ на: комментарий от anc

А можно мне для саморазвития пояснение по поводу переменных? Что именно туда писать или вы имеете ввиду явно указать в скрипте переменную PATH?

hanharr
()
Ответ на: комментарий от hanharr

В начале скрипта указать переменные и их использовать в скрипте
#!/bin/bash

IT='/usr/sbin/iptables'
IPSET='/usr/sbin/ipset'

$IT -F
$IPSET -X

и т.д

anc ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.