LINUX.ORG.RU
решено ФорумAdmin

Помогите с backup-скриптом баз MySQL

 ,


1

1

Сейчас имею такой черновой вариант скрипта:

#!/bin/bash
#Settings
BACKUP_PATH="/home/alex/backups/db/"
MYSQL_USER="root"
MYSQL_PASS="password"
#DB_NAME="jiradb slave_db"

## MySQL backup and copy to another server 
mysqldump -u $MYSQL_USER -p$MYSQL_PASS jiradb | gzip > $BACKUP_PATH-`date +%d.%m.%y.%H:%M:%S.sql_dump.gz`
mysqldump -u $MYSQL_USER -p$MYSQL_PASS slave_db | gzip > $BACKUP_PATH-`date +%d.%m.%y.%H:%M:%S.sql_dump.gz`
rsync -avz /home/alex/backups/ alex@192.168.0.102:/home/alex/backups/
Он конечно работает, но не так как хотелось бы. Т.е. бекапит все в один дамп-файл (архив). Хочу сделать чтобы каждая база бекапилась в отдельные дамп-архивы. Как организовать? В идеале хотелось бы, чтобы указав в скрипте: название БД, пароль и каталог для бекапа каждая база бекапилась в свой каталог - /home/alex/backups/db/<имя_каталога_базы>/<date_and_time.sql_dump.gz>

Перемещено beastie из general


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

beastie ★★★★★ ()

Т.е. бекапит все в один дамп-файл (архив).

Кстати у тебя второй файл не создаётся что ли? Значит jiradb очень маленькая и бэкапится меньше секунды, а второй строкой затирается.

ziemin ★★ ()

осиль массивы или хеши в bash. Потом задаешь массив или хеш (элементы - БД\логин\пароль\папка) - и процессишь его. Кстати, запускать mysqldump -pxxx не секурно (могут подсмотреть пароль в списке процессов), так что сохраняй пароль в переменной MYSQL_PWD перед вызовом mysqldump.

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

Не выйдет. А если баз будет несколько одновременно? И все же как бекапить базы отдельно друг от друга? Оно бекапит все в один архив.

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

также можешь набыдлокодить bash функцию, которая принимает 4 аргумента, БД\логин\пароль\папка, и вызывать ее столько раз, сколько БД надо бакапить.

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

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

каждый админ должен написать свой бакап скрипт и биллинг!

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

В шею таких одминов! ☺ Админ — существо ленивое и ценящее своё время. Каждая лишняя минута в бюро украдена у шашлыков! ☺ Но с другой стороны это не избавляет от требования знать, как оно работает. Удачная комбинация этих двух пунктов и есть хороший админ.

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

Оно бекапит все в один архив.

Всё? Файл же перезаписывается! Распакуй и посмотри, что внутри. И вообще у тебя почти всё готово. Осталось:

#!/bin/bash
#Settings
BACKUP_PATH="/home/alex/backups/db/"
MYSQL_USER="root"
MYSQL_PASS="password"
DB_NAME="jiradb slave_db"

## MySQL backup and copy to another server
 
for db in $DB_NAME
do
  mysqldump -u $MYSQL_USER -p$MYSQL_PASS $db | gzip > $BACKUP_PATH/$db-`date +%d.%m.%y.%H:%M:%S.sql_dump.gz`
done
rsync -avz /home/alex/backups/ alex@192.168.0.102:/home/alex/backups/

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

Да, работает. Спасибо. Теперь бы еще сделать, чтобы базы раскидались в отдельные каталоги в ../db. Потому как хочу сделать ротацию.

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

Отлично, оказывается все просто.

Теперь прикрутить ротацию файлов и будет ok. Так понимаю, нужно тоже делать в цикле - поиск с помощью find в ../db? В каждом каталоге будет сохранено максимум 20 бекап-дампов (в архивах), остальные удаляются.

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

Я делал так (правда паковал работающие образы vbox):

if [ "`ls -t "$backupdir" | wc -l`" -gt 7 ]
then
  rmfile="$backupdir/`ls -t "$backupdir" | tail -n 1`"
  rm "$rmfile" && log Старый архив удален: $rmfile || log Не удалось удалить старый архив: $rmfile
else
  log Удаление старых архивов не требуется
fi

Щас посмотрел - стоило сортировать по времени, пожалуй. Так должно работать, если вручную ничего в каталоге не менять.

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

backupdir естественно нужно заменить на твою переменную, добавить /$db и засунуть в цикл. Хранятся последние семь файлов.

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

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

rm `ls -t | awk 'NR>20'`
Единственная проблема - у меня не получается сформировать правильно цикл поиска. Для проверки делаю простой цикл:
#!/bin/bash
for Dir in $(find /home/alex/backups/db/jiradb/* -maxdepth 0 -type d);
do 
        rm `ls -t | awk 'NR>20'`;
done
но не работает. Хотя если выполнять команду вручную в /jiradb, то все работает. С циклами в bash никак не выходит дружить пока.

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

в /jiradb

А из какого каталога ты скрипт выполняешь? ls-то из текущего выполняется.

И зачем ты идёшь по всем файлам-бэкапам? Вот же:

for db in $DB_NAME
do
  [ -d $BACKUP_PATH/$db ] || mkdir $BACKUP_PATH/$db
  mysqldump -u $MYSQL_USER -p$MYSQL_PASS $db | gzip > $BACKUP_PATH/$db/$db-`date +%d.%m.%y.%H:%M:%S.sql_dump.gz`
  rm `ls -t $BACKUP_PATH/$db | awk 'NR>20'`
done

Есть ещё опция bash -x. Показывает все выполняемые команды скрипта. Это для отладки.

$ bash -x script.sh

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

ls-то из текущего выполняется

Да, я об этом не подумал.

И зачем ты идёшь по всем файлам-бэкапам? Вот же:

rm: невозможно удалить «jiradb-17.05.13.21:53:59.sql_dump.gz»: Нет такого файла или каталога                                                                            
rm: невозможно удалить «jiradb-17.05.13.21:48:01.sql_dump.gz»: Нет такого файла или каталога                                                                            
rm: невозможно удалить «jiradb-17.05.13.21:39:23.sql_dump.gz»: Нет такого файла или каталога                                                                            
rm: невозможно удалить «jiradb-17.05.13.21:19:52.sql_dump.gz»: Нет такого файла или каталога                                                                            
rm: невозможно удалить «jiradb-17.05.13.21:10:10.sql_dump.gz»: Нет такого файла или каталога                                                                            
rm: невозможно удалить «jiradb-17.05.13.21:09:08.sql_dump.gz»: Нет такого файла или каталога                                                                            
rm: невозможно удалить «jiradb-17.05.13.21:08:57.sql_dump.gz»: Нет такого файла или каталога                                                                            
rm: невозможно удалить «jiradb-17.05.13.21:08:41.sql_dump.gz»: Нет такого файла или каталога                                                                            
rm: невозможно удалить «jiradb-17.05.13.20:57:41.sql_dump.gz»: Нет такого файла или каталога                                                                            
rm: невозможно удалить «jiradb-17.05.13.20:42:16.sql_dump.gz»: Нет такого файла или каталога                                                                            
rm: невозможно удалить «jiradb-17.05.13.20:28:28.sql_dump.gz»: Нет такого файла или каталога
rm: невозможно удалить «slave_db-17.05.13.21:53:59.sql_dump.gz»: Нет такого файла или каталога                                                                          
rm: невозможно удалить «slave_db-17.05.13.21:39:23.sql_dump.gz»: Нет такого файла или каталога                                                                          
rm: невозможно удалить «slave_db-17.05.13.20:42:16.sql_dump.gz»: Нет такого файла или каталога
ls -la jiradb/ slave_db/
jiradb/:
итого 72
drwxrwxr-x 2 alex alex 4096 Май 18 00:42 .
drwxrwxr-x 4 alex alex 4096 Май 17 23:56 ..
-rw-rw-r-- 1 alex alex   20 Май 17 20:28 jiradb-17.05.13.20:28:28.sql_dump.gz
-rw-rw-r-- 1 alex alex   20 Май 17 20:42 jiradb-17.05.13.20:42:16.sql_dump.gz
-rw-rw-r-- 1 alex alex   20 Май 17 20:57 jiradb-17.05.13.20:57:41.sql_dump.gz
-rw-rw-r-- 1 alex alex   20 Май 17 21:08 jiradb-17.05.13.21:08:41.sql_dump.gz
-rw-rw-r-- 1 alex alex   20 Май 17 21:08 jiradb-17.05.13.21:08:57.sql_dump.gz
-rw-rw-r-- 1 alex alex   20 Май 17 21:09 jiradb-17.05.13.21:09:08.sql_dump.gz
-rw-rw-r-- 1 alex alex   20 Май 17 21:10 jiradb-17.05.13.21:10:10.sql_dump.gz
-rw-rw-r-- 1 alex alex   20 Май 17 21:19 jiradb-17.05.13.21:19:52.sql_dump.gz
-rw-rw-r-- 1 alex alex   20 Май 17 21:39 jiradb-17.05.13.21:39:23.sql_dump.gz
-rw-rw-r-- 1 alex alex   20 Май 17 21:48 jiradb-17.05.13.21:48:01.sql_dump.gz
-rw-rw-r-- 1 alex alex   20 Май 17 21:53 jiradb-17.05.13.21:53:59.sql_dump.gz
-rw-rw-r-- 1 alex alex   20 Май 17 23:39 jiradb-17.05.13.23:39:04.sql_dump.gz
-rw-rw-r-- 1 alex alex   20 Май 17 23:39 jiradb-17.05.13.23:39:47.sql_dump.gz
-rw-rw-r-- 1 alex alex   20 Май 18 00:38 jiradb-18.05.13.00:38:06.sql_dump.gz
-rw-rw-r-- 1 alex alex   20 Май 18 00:39 jiradb-18.05.13.00:39:37.sql_dump.gz
-rw-rw-r-- 1 alex alex   20 Май 18 00:42 jiradb-18.05.13.00:42:47.sql_dump.gz

slave_db/:
итого 40
drwxrwxr-x 2 alex alex 4096 Май 18 00:42 .
drwxrwxr-x 4 alex alex 4096 Май 17 23:56 ..
-rw-rw-r-- 1 alex alex   20 Май 17 20:42 slave_db-17.05.13.20:42:16.sql_dump.gz
-rw-rw-r-- 1 alex alex   20 Май 17 21:39 slave_db-17.05.13.21:39:23.sql_dump.gz
-rw-rw-r-- 1 alex alex   20 Май 17 21:53 slave_db-17.05.13.21:53:59.sql_dump.gz
-rw-rw-r-- 1 alex alex   20 Май 17 23:39 slave_db-17.05.13.23:39:04.sql_dump.gz
-rw-rw-r-- 1 alex alex   20 Май 17 23:39 slave_db-17.05.13.23:39:47.sql_dump.gz
-rw-rw-r-- 1 alex alex   20 Май 18 00:38 slave_db-18.05.13.00:38:06.sql_dump.gz
-rw-rw-r-- 1 alex alex   20 Май 18 00:39 slave_db-18.05.13.00:39:37.sql_dump.gz
-rw-rw-r-- 1 alex alex   20 Май 18 00:42 slave_db-18.05.13.00:42:47.sql_dump.gz
Nokman ()
Ответ на: комментарий от ziemin

Не работает ни предыдущая, ни эта команда. В этой еще и где-то лишние слеши получаются:

rm: невозможно удалить «/home/alex/backups/db//slave_db1111»: Нет такого файла или каталога

Nokman ()

Это плохой бекап скрипт, в нём нет обработки ошибок. Всё может кончиться тем что в $BACKUP_PATH будет несколько месяцев пустых gzip файлов.

Одни из причин, например, некорректная для mysqldump опция в [client] без loose префикса.

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

Вот так работает нормально и все удаляет:

find $BACKUP_PATH/$db | head -n -5|xargs rm -f
но теперь заметил, что базы не бекапятся в одно и тоже время и это плохо. Например, сделаю запуск скрипта по крону, а в нормальном бекапе окажется всего одна из баз. Не пойму в чем дело. После каждого запуска вижу только новые дамп-архивы либо для базы slave_db либо для jiradb. Очень странно.

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

Это плохой бекап скрипт

Как улучшить?

Одни из причин, например, некорректная для mysqldump опция в [client] без loose префикса.

С этого места поподробней, если можна. Эту опцию ведь можно поправить?

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

Посмотри локальную почту root'а. Обычно туда выхлоп скрипта отправляется. Ну или того пользователя от чьего имени cron выполняет задание.

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

Я думаю понял в чем дело. Команда удаления все же работает не совсем корректно. Если каталоги баз пустые, то все работает отлично пока не наберется 5 дамп-архивов (в команде удаления указано - head -n -5), а после этого скорей всего дамп баз выполняется, но команда сразу же удаляет его из каталогов, оставляя ровно 5 архивов. Нужно как-то придумать, чтобы удаляло именно дамп-архивы старее по времени..

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

Да, работает. Так и оставлю пока и буду тестировать. Спасибо за помощь :)

Nokman ()

Окончательный вариант скрипта

#!/bin/bash
# Base settings
BACKUP_PATH="/home/alex/backups/"
MYSQL_USER="root"
MYSQL_PASS="pass"
DB_NAME="DB1 DB2 DB3"
REMOTE_USER="alex"
REMOTE_HOST="192.168.0.102"
REMOTE_PATH="/home/alex/backups/"
# Dumping and archiving MySQL databases
for db in $DB_NAME
do
  [ -d $BACKUP_PATH/$db ] || mkdir $BACKUP_PATH/$db
  mysqldump -u $MYSQL_USER -p$MYSQL_PASS $db | gzip > $BACKUP_PATH/$db/$db-`date +%d.%m.%y.%H:%M:%S.sql_dump.gz`
  cd $BACKUP_PATH/$db
  rm `ls -t | awk 'NR>20'`
  cd -
done
# Backups synchronization 
rsync -avz $BACKUP_PATH $REMOTE_USER@$REMOTE_HOST:$REMOTE_PATH
# Email notification
sendemail -f mail@domen.com -t mail2@domen.com -u Databases Backup -m MySQL databases backup created successfully! -s domen.com:587 -o tls=yes -xu mail@domen.com -xp PASSWORD
Nokman ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.