Рано или поздно встаёт вопрос бэкапа базы. Учитывая тенденции, базой в несколько гигабайт сейчас никого не удивишь. Да и процесс бэкапа сейчас уже немного другой, нежели раньше. Просто банально выполнить mysqldump – сейчас мало кто использует, так как есть ряд причин:
– для таблиц MyIsam она полностью блокирует на запись все таблицы на момент бэкапа
– процесс выполняется достаточно долго
– данный процесс может сильно нагружать дисковую систему
Но что же делать?
На помощь приходят файловые системы, которые поддерживают снапшоты. В частности это касается zfs, ufs, xfs. Удачнее всего это реализовано конечно в zfs. На примере её и будем рассматривать наш бэкап.
Почему такой способ удобнее всего? Потому что снапшот делается за очень короткое время и его потом легко переносить на другой сервер.
И так, какова идея: ставим блокировку чтение на все базы, делаем снапшот, разблокируем базы. Следует учесть тот момент, переносить базу нужно вместе с журналами (ib_logfile*), иначе могут быть проблемы.
Ниже приведу скрипт для создания снапшотов:
#!/bin/sh
USER=root
PASS=pass
MYSQL=/usr/bin/mysql
POOL1=database
POOL2=rpool
ZFS1=mysql
ZFS2=log
SNAPSHOT=backup
${MYSQL} -u${USER} -p${PASS} -e 'FLUSH TABLES WITH READ LOCK;'
zfs snapshot ${POOL1}/${ZFS1}@${SNAPSHOT}
zfs snapshot ${POOL2}/${ZFS2}@${SNAPSHOT}
${MYSQL} -u${USER} -p${PASS} -e 'UNLOCK TABLES;'
После того, как созданы снапшоты, будем их копировать на новый сервер такой командой:
#zfs send -v rpool/log@backup | ssh skeletor@XX.XX.XX.XX "sudo /usr/sbin/zfs receive -Fd rpool"
Для вывода процесса копирания используем в связке с pv:
# zfs send pool/opt@snap1 | pv | zfs recv tank/opt 8.58GB 0:02:37 [95.7MB/s]
Эта команда по сути копирует снапшот и тут же разворачивает его на новом сервере.
Очень важно, указать полный путь к zfs во втором пайпе. Есть ещё один важный момент: имена пулов, zfs на старом и новом сервере должны совпадать, иначе будут проблемы. Ещё нужно юзера skeletor добавить в sudo (или pfexec) без пароля, иначе не пройдёт перенос.
Некоторые могут посоветовать при копировании использовать mbuff, который ускоряет процесс переноса, но он так же сильно нагружает диски, поэтому здесь лучше использовать “классику”.
После первого запуска mysql на новом сервере он долго просматривал логи, пересоздал журналы и запустился.
Примечание.
1) По непонятным причинам один и 20-бэкапов залочил полностью базу и в течении продолжительного времени не разлочивал её. Пришлось вручную убить процесс бэкапа и разлочить базу. В итоге я отказался от процесса lock/unlock и просто делаю снапшот наживую.
2) Очень интересная заметка для проверки валидности пересылаемого снапшота http://blog.richardelling.com/2009/10/check-integrity-of-zfs-send-streams.html
Вариант бэкапа-2
Для переноса базы можно использовать и такой вариант: передача не через ssh, а через сокет (созданный с помощью netcat) + в добавок можно лимитировать скорость через flowadm. Какие плюсы данного метода:
– можно контролировать нагрузку на диски путём лимитирования скорости
– достигается высокая скорость передачи данных в заданном лимите (при использовании ssh мы тратим ресурсы на шифрование данных)
И так, на принимающей стороне выполняем команду:
# netcat -4dl 1.1.1.1 6633 | zfs receive -Fd database
На передающей стороне:
# flowadm add-flow -l net0 -a remote_ip=1.1.1.1 -p maxbw=10M db-flow
# zfs send -rvp database/mysql@sr602 | netcat 1.1.1.1 6633
Статистику по передаваемым данным можно смотреть через flowstat. Скорость указывается в мегабитах/с.
Примечание.
параметры ‘-p’ и ‘-r’ означают сохранить параметры zfs при передаче и передать снешпоты рекурсивно соответственно.
3 коментарі “[mysql] Бэкап большой базы”
собственно вот http://www.mydumper.org/
U nas problema s ZFSom….koroche my sdelali zfs send gde to 10 file.. .potom peresozdali pool…kogda zfs receive sdelali..9 file byl uspewno..no odin bolshoi file oshibku dal… vot takoi (cannot receive new filesystem stream invalid backup stream
)… Est’ u vas idea..ranshe stolknilis s takimi oshibkami..?????
Вы делали zfs send в файл, а потом из файла zfs receive?