Назад | Перейти на главную страницу

Резервное копирование БД MySQL: без блокировки, восстановление по таблице, MyISAM / InnoDB

Эта проблема

Я хотел бы реализовать стратегию резервного копирования MySQL на выделенном сервере.

Он имеет несколько баз данных, общая сумма составляет около 150 ГБ. Большая часть этого отнесена к одной из баз данных.

База данных представляет собой смешанный движок MyISAM и InnoDB (планы по капитальному ремонту имеют место в долгосрочной перспективе, но в краткосрочной перспективе нет возможности).

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

Ключевые задачи

Идеальная процедура резервного копирования MySQL позволяет достичь следующих целей.

  1. Согласованные резервные копии MySQL.
  2. Резервные копии без блокировки (или близкие к тому, чтобы база данных могла обслуживать запросы).
  3. Восстановление таблицы.

Предложения на данный момент

Я не системный администратор по профессии, поэтому был бы признателен за мудрые советы сообщества. Некоторые предложения, которые у меня были до сих пор ...

mysqllvm Holland Backup

Holland Backup имеет mysqllvm вариант.

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

Достигает целей 1 и 2.

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

mysqldumplvm Holland Backup

Holland Backup имеет mysqldumplvm вариант.

Этим достигаются цели 1 и 2.

Задача 3, не так уж и много ... Она позволяет восстанавливать только базу данных из дампов .sql, что из-за размера базы данных может занять несколько часов в день, чтобы восстановить фиктивную базу данных только для извлечения одной таблицы. Здесь может возникнуть проблема с дисковым пространством.

Есть способ достичь всех трех целей, но я не знаю, есть ли у продукта такой способ, поэтому я бы написал его следующим образом:

  • Используйте моментальный снимок LVM, чтобы получить согласованное состояние вашей базы данных (не забывайте FLUSH TABLE WITH READ LOCK)
  • Установите снимок в определенное место: / opt / mysql для чтения и записи
  • Запустите mysqld в качестве второго экземпляра с помощью --data-dir = / opt / mysql (и такой опции, как --skip-network, чтобы избежать конфликта и разделить файл сокета в другом месте, кроме /var/lib/mysql/mysql.sock) - Помогите : Запуск нескольких экземпляров Mysql на сервере Unix

Затем вы можете использовать любой сценарий, который будет генерировать таблицу дампа для каждой таблицы с гарантией согласованности, подключившись ко второму экземпляру mysql.

В конце концов, если производительность моментального снимка или размер диска являются проблемой, вы можете просто переместить моментальный снимок на второй сервер, а затем выполнить дамп во втором месте.

Вы также можете рассмотреть Percona XtraBackup (http://www.percona.com/software/percona-xtrabackup) хотя AFAIK не совместим с MyISAM

Отредактировано: на самом деле он совместим с MyISAM

Я полагаю, вы знаете, что цель 3 противоречит цели 1.

Очевидным решением было бы реализовать хранение данных в зеркальной файловой системе. Если вы хотите сделать резервную копию, остановите СУБД, очистите буферы записи, сломайте зеркало и перезапустите СУБД, затем смонтируйте зеркальную файловую систему в другом месте и запустите второй экземпляр СУБД, используя копию, и используйте его для резервного копирования.

(хотя вы можете сломать зеркало, не выключая СУБД, вам придется восстанавливать данные, и у вас не будет согласованного снимка).

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

(использование снимков файловой системы может быть другим подходом, но при использовании LVM или BTRFS возникают большие накладные расходы на производительность).

1, 2 и 3 вы можете достичь, используя Xtrabackup и InnoDB. Для MyISAM невозможно получить все три.

mysqldumplvm Holland Backup

Чтобы подробнее узнать, как это работает:

-> Проблемы FLUSH WITH READ LOCK -> Делает моментальный снимок LVM каталога данных MySQL -> На основе этого снимка запускает отдельный экземпляр MySQL -> Выполняет mysqldump для каждой базы данных в database.sql -> Сжимает эти файлы -> Убивает отдельный экземпляр MySQL и удаляет снимок

Я думаю, что шаг mysqldump можно было бы изменить, чтобы вместо этого перебирать каждую таблицу и mysqldump до database / table.sql. Это позволило бы восстановить по таблице.

Используйте функцию репликации MySQL, чтобы создать вторую базу данных-реплику. Затем сделайте резервные копии на реплике. Блокировка / замедление реплики базы данных никак не повлияет на производительность вашей главной базы данных и обеспечит согласованное резервное копирование.

Резервное копирование каждой таблицы отдельно потребует написания сценария оболочки вокруг mysqldump для разделения файлов резервных копий, ИЛИ (даже быстрее, но работает только с таблицами MyISAM) вы можете закрыть базу данных реплик и просто скопировать весь каталог данных. Каждая таблица будет иметь свои собственные файлы данных. Перезагрузите сервер реплик, и он восстановится из двоичных журналов.