Translate

суботу, 14 грудня 2013 р.

Використання Innobackupex (Xtrabuckup) для бекапу MySQL

Mysqldump буде влаштовувати вас лише до того моменту, доки він зможе знімати дамп на протязі прийнятного часу. База збільшується і це саме час задуматись про альтернативи. І такою альтернативою може бути Xtrabackup.

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 використовуватиме стандартні шляхи до my.cnf та інсталяції MySQL. Якщо для root установлено пароль, то звісно необхідно додати їх до команди
Дещо "розумніший" варіант створення бекапу:

# 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

2 коментарі:

  1. Класна стаття, дякую. Особисто я зараз роблю бекапи за допомогою LMV - знімаю снапшот директорії з БД - там також є свої мінуси, але все ж спосіб набагато швидший, ніж mysqldump.

    ВідповістиВидалити
    Відповіді
    1. Так, mysqldump - дуже повільний варіант.

      Недолік снапшоту LVM-у в низькій швидкості (в ~5-7 разів повільніше) роботи дискової підсистеми у випадку, коли LVM-розділ має снапшот.

      Для снапшотів можна спробувати ZFS http://ipeacocks.blogspot.ie/2013/10/zfs-filesystem-on-linux-configuration.html А ще краще його спробувати під Солярісом.

      Innobackupex може бути чудовим і дешевим варіантом організації бекапів а з xbstream, їх можна прямо відсилати на бекап-сервер.

      Видалити