Отключаемые ключи MySqlDump не влияют на импорт

10

У меня есть продолжение моего предыдущего вопроса о скорости импорта с помощью Inno-Tables (сюрприз!).

Сценарий
Я пытаюсь импортировать большой * дамп базы данных на мою локальную машину разработчика в разумные сроки. KEYК таблицам прикреплено множество элементов, которые оказались узким местом, но все еще важны для нашей живой системы.

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

Однако я часто нахожу себя редактирующим текущий дамп, чтобы импортировать его локально, и я наткнулся на эти забавные «комментарии» (The disable/enable keys-lines)

--
-- Dumping data for table `monster`
--

LOCK TABLES `monster` WRITE;
/*!40000 ALTER TABLE `monster` DISABLE KEYS */;
INSERT  INSERT  INSERT
/*!40000 ALTER TABLE `monster` ENABLE KEYS */;
UNLOCK TABLES;

Но на самом деле эти «комментарии» являются условными MySql-утверждениями

Это было для меня новостью, но хорошо, учитывая форму вывода, mysql --versionвсе выглядит хорошо для меня: mysql Ver 14.14 Distrib 5.5.38, for debian-linux-gnu (x86_64) using readline 6.3

Что я предполагаю
Таблица заблокирована (хорошо, это только я на машине). Затем ключи, определенные в схеме таблицы, отключаются, данные импортируются, ключи включаются.
Таким образом, во время фазы «вставки данных» не следует тратить время на ключи, а проверять их после вставки всех данных.

Я бы подумал, что это такое же поведение, как если бы я удалял все KEY 'foo' (foo)'строки из дампа, импортировал дамп и ADD KEY 'foo' ...впоследствии запустил скрипт .

Что я наблюдаю
Это гораздо быстрее вручную удалить ключи, импортировать и повторно добавить ключи, чем полагаться на условные DISABLE KEYSоператоры, созданные моимmysqldump

Ручное редактирование дампа + импорт MySQL + добавление ключей = 15 + 8 + 8 ≈ 30 минут
Простой импорт MySQL: отказался (мне платят только за 8 часов в день> :))

Я не могу не думать, что мне здесь не хватает чего-то очень фундаментального (или база данных троллит меня).

Nuala
источник
2
Краткосрочный: используйте mysqldump --innodb-optimize-keysот Percona percona.com/doc/percona-server/5.5/management/… Долгосрочный: прекратите использовать mysqldump и используйте mydumper или xtrabackup.
января

Ответы:

12

Вы не можете полагаться на InnoDB DISABLE KEYS;и ENABLE KEYS;для InnoDB, потому что он не реализован в InnoDB Storage Engine. Работали ALTER TABLE ... DISABLE KEYS;и ALTER TABLE ... ENABLE KEYS;были предназначены для MyISAM. Как сказано в документации MySQL дляALTER TABLE :

Если вы используете ALTER TABLE для таблицы MyISAM, все неуникальные индексы создаются в отдельном пакете (как для REPAIR TABLE). Это должно сделать ALTER TABLE намного быстрее, если у вас много индексов.

Для таблиц MyISAM обновлением ключей можно управлять явно. Используйте ALTER TABLE ... DISABLE KEYS, чтобы указать MySQL прекратить обновление неуникальных индексов. Затем используйте ALTER TABLE ... ENABLE KEYS, чтобы заново создать отсутствующие индексы. MyISAM делает это с помощью специального алгоритма, который намного быстрее, чем вставка ключей один за другим, поэтому отключение ключей перед выполнением операций массовой вставки должно значительно ускорить процесс. Использование ALTER TABLE ... DISABLE KEYS требует привилегии INDEX в дополнение к привилегиям, упомянутым ранее.

Хотя неуникальные индексы отключены, они игнорируются для операторов, таких как SELECT и EXPLAIN, которые в противном случае использовали бы их.

InnoDB никогда не упоминается в контексте ALTER TABLE ... DISABLE/ENABLE KEYS;

Даже если вы работаете ALTER TABLE ... DISABLE KEYS;с таблицей InnoDB, она генерирует предупреждение:

mysql> show create table mytimes\G
*************************** 1. row ***************************
       Table: mytimes
Create Table: CREATE TABLE `mytimes` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `totalTime` int(11) NOT NULL,
  `totalTimeDesc` varchar(128) DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=5 DEFAULT CHARSET=latin1
1 row in set (0.00 sec)

mysql> alter table mytimes disable keys;
Query OK, 0 rows affected, 1 warning (0.01 sec)

mysql> show warnings;
+-------+------+-------------------------------------------------------------+
| Level | Code | Message                                                     |
+-------+------+-------------------------------------------------------------+
| Note  | 1031 | Table storage engine for 'mytimes' doesn't have this option |
+-------+------+-------------------------------------------------------------+
1 row in set (0.00 sec)

mysql>

Вот почему это не влияет. Пожалуйста, помните, что @jynus упомянул то же самое в своем ответе в пуле 7 .

Помните также, что MyISAM хранит данные и индексы в двух отдельных файлах (.MYD для данных, .MYI для индексов), поэтому было бы тривиально отключить и включить индексы. InnoDB хранит ПЕРВИЧНЫЙ КЛЮЧ и данные строк на одних и тех же страницах InnoDB (через Кластерный индекс). Вторичные индексы будут содержать ПЕРВИЧНЫЙ КЛЮЧ как приложение к каждой записи в листе вторичного индекса . Поскольку данные и индексы переплетаются через кластерный индекс, пока никто не пытался реализовать DISABLE KEYSи ENABLE KEYSв InnoDB.

RolandoMySQLDBA
источник
1
«Я сказал вам» :-)
января
@jynus HA HA :-). Вы должны опубликовать свой комментарий mysqldump для InnoDB ( dba.stackexchange.com/questions/76565/… ) в качестве ответа.
RolandoMySQLDBA
@yoshi Я пишу статью на основе вашего исходного вопроса, следите за обновлениями.
января
@yosi Как и было обещано: dbahire.com/…
jynus
@RolandoMySQLDBA, если InnoDB не может включить / отключить ключи, не должно ли это выдать ошибку вместо простого предупреждения?
Pacerier