Xtrabackup - розробка компанії Percona, програма, що дозволяє робити бекап MySQL-серверів і не блокує базу данних на протязі бекапу. Xtrabackup може працювати з InnoDB, XtraDB і MyISAM (проте з певними обмеження на кшталт інкрементальних бакапів) таблицями. Мабуть, головною особливістю Xtrabackup є його висока швидкість роботи, на відміну від Mysqldump-а, що пояснюється тим, що він працює на бінарному рівні (умовно кажучи, копіює бінарні файли /var/lib/mysql, а не генерує запити як mysqldump).
Для початку я б хотів би розповісти логіку роботи програми Xtrabackup (точніше як я її розумію) і почну саме з особливостей роботи InnoDB. Запити, що генерують користувачі, приходять на mysql-server, записуються у лог транзакцій (mysql bin log) а потім виконуються. Результати запитів одразу не пишуться на жорсткий диск і лишаються в кешах.
У випадку падіння демону Mysql (причин насправді може бути купа), то при наступному старті почнеться відновлення останніх операцій із бін-логу і таким чином база лишиться неушкодженою.
Виходячи із вищесказаного, логіка роботи Xtrabuckup така: за допомогою InnoDB-engine відбувається копіювання необхідних файлів із /var/lib/mysql та створення транзакційного логу операцій на час виконання бекапу.
Як буде видно далі, після бекапу необхідно буде застосувати цей транзакційний лог за допомогою опцій --apply-log /path/to/backup/dir.
Надалі я розповім як користуватись wrapper-ом для xrabackup, що зветься Innobackupex.
Із установкою все просто: або установлюємо версію із репозиторіїв Percona чи користуємось стандартними репозиторіями:
# sudo aptitude install percona-xtrabackup
Повний бекап робиться наступним чином:
# innobackupex /root/backup
....
.>> log scanned up to (137222685)
xtrabackup: Transaction log of lsn (137222685) to (137222685) was copied.
131213 12:57:20 innobackupex: All tables unlocked
innobackupex: Backup created in directory '/root/backup/2013-12-13_12-57-10'
131213 12:57:20 innobackupex: Connection to database server closed
131213 12:57:20 innobackupex: completed OK!
Отже, /root/backup/2013-12-13_12-57-10 - адреса повний бекапу.
Дещо "розумніший" варіант створення бекапу:
# innobackupex -uusername -ppassword --stream tar . | gzip - > /root/backup.tgz
Відбудеться бекап в tar-контейнер і архівація за допомогою zip-алгоритму на виході.
Рестор відбувається також не складно, проте попередньо необхідно застосувати xtrabackup_logfile. Xtrabackup_logfile - це транзакційний лог операцій, що був актуальний на час підготовки бекапу. Про нього я згадував вище.
# innobackupex --apply-log /root/backup/2013-12-13_12-57-10
...
131214 2:41:34 InnoDB: Shutdown completed; log sequence number 478699020
131214 02:41:34 innobackupex: completed OK!
Перед роллбеком варто запунити mysql та видалити ввесь вміст директорії /var/lib/mysql. Далі запускаємо:
# innobackupex --copy-back /root/backup/2013-12-13_12-57-10
...
innobackupex: Starting to copy InnoDB log files
innobackupex: in '/root/backup/2013-12-14_02-33-16'
innobackupex: back to original InnoDB log directory '/var/lib/mysql'
innobackupex: Copying '/root/backup/2013-12-14_02-33-16/ib_logfile0' to '/var/lib/mysql/ib_logfile0'
innobackupex: Copying '/root/backup/2013-12-14_02-33-16/ib_logfile1' to '/var/lib/mysql/ib_logfile1'
innobackupex: Finished copying back files.
131214 02:45:46 innobackupex: completed OK!
Змінюємо власника директорії /var/lib/mysql і запускаємо mysql:
# chown -R mysql:mysql /var/lib/mysql
# service mysql start
http://www.percona.com/doc/percona-xtrabackup/2.1/innobackupex/restoring_a_backup_ibk.html
Ось і все. Час рестора обмежується лише часом копіювання бекап-файлів, тобто швидкістю роботи дискової підсистеми, на відміну від знову ж таки mysqldump-а.
Варто також згадати про можливість робити інкременальні бекапи (дельта змін між повним бекапом і бекапом на час виконання наступного) за допомогою innobackupex. Процедура його виконання не значно складніша попередніх. Для початку виконуємо повний бекап:
# innobackupex /root/backup
...
innobackupex: Backup created in directory '/root/backup/2013-12-14_02-58-51'
131214 02:59:07 innobackupex: Connection to database server closed
131214 02:59:07 innobackupex: completed OK!
/root/backup/2013-12-14_02-58-51 - створений новий бекап і в /root/backup/2013-12-14_02-58-51/xtrabackup_checkpoints можна пересвідчитись в цьому:
backup_type = full-backuped
from_lsn = 0
to_lsn = 478699030
last_lsn = 478699030
compact = 0
Для зручності надалі замість /root/backup/2013-12-14_02-58-51 будемо писати BASE-DIR.
Створюємо перший інкрементальний бекап:
# innobackupex --incremental /root/backup --incremental-basedir=BASE-DIR
...
innobackupex: Backup created in directory '/root/backup/2013-12-14_03-04-52'
131214 03:04:56 innobackupex: Connection to database server closed
131214 03:04:56 innobackupex: completed OK!
/root/backup/2013-12-14_03-04-52 - директорія із першим інкрементальним бекапом, надалі будемо її позначати як INCR-DIR-1
У /root/backup/2013-12-14_03-04-52/xtrabackup_checkpoints знову ж таки можна побачити, що цей бекап інкрементальний.
Для прикладу далі створемо ще один інкрементальний бекап, щоб побачити наскільки функціональним є Xtrabuckup:
# innobackupex --incremental /root/backup --incremental-basedir=INCR-DIR-1
...
innobackupex: Backup created in directory '/root/backup/2013-12-14_03-11-25'
131214 03:11:29 innobackupex: Connection to database server closed
131214 03:11:29 innobackupex: completed OK!
Тобто у якості --incremental-basedir обираємо перший інкрементальний бекап.
Отже, /root/backup/2013-12-14_03-11-25 буде INCR-DIR-2
Підготовка рестору і рестор інкрементальних бекапів відбувається наступним чином. Спочатку застосувується xtrabackup_logfile у кожному із етапів:
# innobackupex --apply-log --redo-only BASE-DIR
...
131214 3:15:20 InnoDB: Shutdown completed; log sequence number 478699030
131214 03:15:20 innobackupex: completed OK!
# innobackupex --apply-log --redo-only BASE-DIR --incremental-dir=INC-DIR-1
...
innobackupex: Copying '/root/backup/2013-12-14_03-04-52/redmine/users.frm' to '/root/backup/2013-12-14_02-58-51/redmine/users.frm'
131214 03:17:11 innobackupex: completed OK!
Коли б це був останній інкрементальний бекап - то ключ --redo-only необхідно було б прибрати http://www.percona.com/doc/percona-xtrabackup/2.1/innobackupex/incremental_backups_innobackupex.html#preparing-an-incremental-backup-with-innobackupex
Виконуємо аналогічне із останнім інкрементальним бекапом:
# innobackupex --apply-log BASE-DIR --incremental-dir=INCR-DIR-2
...
innobackupex: Copying '/root/backup/2013-12-14_03-11-25/redmine/users.frm' to '/root/backup/2013-12-14_02-58-51/redmine/users.frm'
131214 03:21:44 innobackupex: completed OK!
Після злиття інкрементальних бекапів необхідно виконати повне застосування xtrabackup_logfile:
# innobackupex --apply-log BASE-DIR
...
131214 3:27:32 InnoDB: Shutdown completed; log sequence number 478699532
131214 03:27:32 innobackupex: completed OK!
Бекап наразі готовий до рестору:
# innobackupex --copy-back BASE-DIR
Звісно варто не забути попередньо видалити всі файли із /var/lib/mysql та не забути змінити власника директорії на mysql.
Xtrabackup вміє також відсилати бекапи на віддалений сервер за допомогою xbstream:
# innobackupex --parallel=8 --compress --compress-threads=4 --stream=xbstream ./ |ssh user@host "xbstream -x -C /data/backup"
--parallel=8 - бекап данних у 8 потоків (актуально для багатопроцесорних систем)
--compress - увімкнути вбудовану компресію QuickLZ
--compress-threads=4 - компресія в 4 потоки.
Компресія чи бекап в декілька потоків актуальний лише при використанні опції innodb_file_per_table
За допомогою innobackupex також можна відресторити окрему таблицю чи базу. І знову mysql має бути запущений із innodb_file_per_table.
А додати сервер реплікацій можна таким чином http://www.percona.com/doc/percona-xtrabackup/2.1/howtos/setting_up_replication.html
Про певний досвід користування Xtrabackup-ом можна почитати на сторінці інженерів компанії Facebook https://www.facebook.com/note.php?note_id=10150098033318920
Посилання:
http://www.percona.com/doc/percona-xtrabackup/2.1/innobackupex/innobackupex_script.html
http://www.slideshare.net/profyclub_ru/percona-xtra-backup
Класна стаття, дякую. Особисто я зараз роблю бекапи за допомогою LMV - знімаю снапшот директорії з БД - там також є свої мінуси, але все ж спосіб набагато швидший, ніж mysqldump.
ВідповістиВидалитиТак, mysqldump - дуже повільний варіант.
ВидалитиНедолік снапшоту LVM-у в низькій швидкості (в ~5-7 разів повільніше) роботи дискової підсистеми у випадку, коли LVM-розділ має снапшот.
Для снапшотів можна спробувати ZFS http://ipeacocks.blogspot.ie/2013/10/zfs-filesystem-on-linux-configuration.html А ще краще його спробувати під Солярісом.
Innobackupex може бути чудовим і дешевим варіантом організації бекапів а з xbstream, їх можна прямо відсилати на бекап-сервер.