Как получить правильный дамп с использованием mysqldump и одной транзакции, когда DDL используется одновременно? - PullRequest
6 голосов
/ 16 января 2009

Я новичок в MySQL и выясняю лучший способ выполнить оперативное горячее логическое резервное копирование, используя mysqldump. Эта страница предлагает следующую командную строку:

mysqldump --single-transaction --flush-logs --master-data=2
          --all-databases > backup_sunday_1_PM.sql

но ... если вы внимательно прочитаете документацию , вы обнаружите, что :

Пока дамп --single-transaction находится в процессе, для обеспечения правильного файла дампа (правильное содержимое таблицы и позиция двоичного журнала), никакое другое соединение не должно использовать следующие утверждения: ALTER TABLE, DROP TABLE, RENAME TABLE, TRUNCATE TABLE. непротиворечивое чтение не изолировано от этих утверждений, поэтому их использование в таблице выгрузка может привести к SELECT, выполненному mysqldump для извлечения содержимого таблицы получить неверное содержимое или не получиться.

Итак, есть ли способ предотвратить этот возможный сценарий повреждения дампа? То есть команды, которые могут временно блокировать эти операторы.

PS: ошибка в MySQL на эту тему http://bugs.mysql.com/bug.php?id=27850

Ответы [ 3 ]

8 голосов
/ 24 января 2009

Откройте командное окно mysql и введите команду:

mysql> FLUSH TABLES WITH READ LOCK;

Это будет блокировать все таблицы в всех базах данных в этом экземпляре MySQL до тех пор, пока вы не введете UNLOCK TABLES (или не завершите соединение клиента, которое удерживает эти блокировки чтения).

Чтобы подтвердить это, вы можете открыть другое командное окно и попробовать сделать ALTER, DROP, RENAME или TRUNCATE. Эти команды зависают, ожидая снятия блокировки чтения. Нажмите Ctrl-C, чтобы прекратить ожидание.

Но хотя таблицы имеют блокировку чтения, вы все равно можете выполнить резервное копирование mysqldump.

Команда FLUSH TABLES WITH READ LOCK может быть такой же, как при использовании опции --lock-all-tables mysqldump. Это не совсем понятно, но этот документ , кажется, поддерживает его:

Другое использование для РАЗБЛОКИРОВКИ СТОЛОВ освободить полученную глобальную блокировку чтения со столами для промывки с замком для чтения.

И FLUSH TABLES WITH READ LOCK, и --lock-all-tables используют фразу "глобальная блокировка чтения", поэтому я думаю, что они делают одно и то же. Следовательно, вы должны иметь возможность использовать эту опцию для mysqldump и защитить от одновременных ALTER, DROP, RENAME и TRUNCATE.


Re. Ваш комментарий: Следующее от Гильема Бихота в журнале ошибок MySQL, с которым вы связались:

Привет. --lock-all-table вызывает FLUSH СТОЛЫ С ЧИТАЮЩИМ ЗАМКОМ. Таким образом, это ожидается блокировка ALTER, DROP, RENAME, или TRUNCATE (если нет ошибки или Я не прав). Тем не менее, --lock-all-tables --single -action не может работать (mysqldump выдает сообщение об ошибке): потому что блокировка всех таблиц блокирует все таблицы сервера против записей на время резервного копирования, тогда как одиночная транзакция предназначена чтобы записи происходили во время резервного копирования (с помощью последовательного чтения SELECT в сделка), они несовместимы в природе.

Из этого следует, что вы не можете получить одновременный доступ во время резервного копирования и одновременно блокировать ALTER, DROP, RENAME и TRUNCATE.

2 голосов
/ 19 февраля 2014

Я думал, что читая эту часть документации, я нашел больше информации:

4.5.4. mysqldump - программа резервного копирования базы данных http://dev.mysql.com/doc/en/mysqldump.html

Для таблиц InnoDB mysqldump предоставляет способ сделать онлайн резервное копирование:

shell> mysqldump --all-databases --single-transaction > all_databases.sql

Эта резервная копия получает глобальную блокировку чтения для всех таблиц (используя FLUSH TABLES WITH READ LOCK) в начале дампа. Как только это блокировка получена, считываются двоичные лог-координаты и Блокировка снята. Если длинные операторы обновления выполняются, когда Выдается инструкция FLUSH, сервер MySQL может зависнуть до эти заявления заканчиваются. После этого дамп освобождается от блокировки и не мешает чтению и записи на столах. Если обновление утверждения, которые получает сервер MySQL, короткие (с точки зрения время выполнения), начальный период блокировки не должен быть заметным, даже со многими обновлениями.

Конфликт с параметрами --opt и --single-transaction:

- опция

Эта опция является сокращенной. Это то же самое, что указать --add-drop-table --add-locks --create-options --disable-keys - расширенная вставка - блокировка таблиц --quick --set-charset. Это должно дать вам быструю операцию дампа и создать файл дампа, который можно перезагрузить на сервер MySQL быстро.

Опция --opt включена по умолчанию. Используйте --skip-opt, чтобы отключить его.

Если я правильно понимаю ваш вопрос, вы хотите, чтобы фактические данные и DDL (язык определения данных) вместе, потому что, если вы хотите только DDL, вы бы использовали --no-data. Более подробную информацию об этом можно найти по адресу:

http://dev.mysql.com/doc/workbench/en/wb-reverse-engineer-create-script.html

Используйте параметр --databases с mysqldump, если вы хотите создать база данных, а также все ее объекты. Если нет CREATE DATABASE Инструкция db_name в вашем файле скрипта, вы должны импортировать базу данных объекты в существующую схему или, если нет схемы, новый безымянная схема создана.

Как предложено Подробное руководство по MySQL 5 Майкл Кофлер Я бы предложил следующие варианты:

--skip-opt
--single-transaction
--add-drop-table
--create-options
--quick
--extended-insert
--set-charset
--disable-keys

Кроме того, не упоминается --order-by-primary Также, если вы используете опцию --databases, вам также следует использовать --add-drop-database, особенно в сочетании с этим ответом Если вы выполняете резервное копирование баз данных, которые Для подключения к различным сетям вам может понадобиться опция --compress.

Таким образом, команда mysqldump (без использования параметров --compress, --databases или --add-drop-database) будет выглядеть так:

mysqldump --skip-opt --order-by-primary --single-transaction --add-drop-table --create-options --quick --extended-insert --set-charset -h db_host -u username --password="myPassword" db_name | mysql --host=other_host db_name

Я удалил ссылку на --disable-keys, которая была дана в книге, так как она неэффективна с InnoDB, насколько я понимаю. Руководство MySql гласит:

Для каждой таблицы окружите операторы INSERT символом / *! 40000 ALTER TABLE tbl_name ОТКЛЮЧИТЬ КЛЮЧИ /; и / ! 40000 ALTER TABLE tbl_name ENABLE KEYS * /; заявления. Это делает загрузку файла дампа быстрее потому что индексы создаются после того, как все строки вставлены. это опция действует только для неуникальных индексов таблиц MyISAM.

Я также нашел этот отчет об ошибке http://bugs.mysql.com/bug.php?id=64309, в котором внизу есть комментарии от Пола Дюбуа, который также написал несколько книг , на которые у меня нет никаких ссылок по этому конкретному вопросу, кроме этих комментариев найдено в отчете об ошибке.

Теперь, чтобы создать « Ultimate Backup », я бы посоветовал рассмотреть что-то вроде этого сценария оболочки

  1. https://github.com/red-ant/mysql-svn-backup/blob/master/mysql-svn.sh
1 голос
/ 12 мая 2013

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

Одним из решений является репликация, а затем резервное копирование ведомого устройства вместо главного. Если ведомое устройство пропускает записи во время резервного копирования, оно просто позже догонит. Это также оставит вас с живым резервным сервером на случай отказа мастера. Что приятно.

...