Ускорение конвертации MyISAM в InnoDB

15

У меня есть сервер MySQL 5.1 с базой данных приблизительно 450 таблиц, занимающий 4 ГБ. Подавляющее большинство этих таблиц (все, кроме 2) являются MyIsam. По большей части это нормально (транзакции не нужны), но приложение набирает трафик, и на некоторые таблицы влияют блокировки таблиц при обновлении. Вот почему 2 таблицы сейчас являются InnoDB.

Преобразование в таблицы меньшего размера (100 тыс. Строк) совсем не занимает много времени, вызывая минимальное время простоя. Однако некоторые из моих таблиц отслеживания приближаются к 50 миллионам строк. Есть ли способ ускорить ALTER TABLE...ENGINE InnoDBна больших столах? А если нет, то есть ли другие способы преобразования, минимизирующие время простоя в этих таблицах с интенсивной записью?

Дерек Дауни
источник
1
Что нужно иметь в виду: несколько вопросов в одном посте, как правило, отговаривают людей, которые могут ответить на один из вопросов, опубликовать ответ.
BenV
Я VtC, так как это довольно сложно ответить. Вам следует открыть несколько вопросов по отдельности.
Jcolebrand
Я с удовольствием приму совет, чтобы превратить его в один вопрос, но рекомендуется ли удалять этот вопрос и просто открывать новый? при переписывании в основном удаляются вторые 2 маркера и меняются первые (я также обновил заголовок, чтобы отразить, какие механизмы хранения данных)
Дерек Дауни,
Либо было бы хорошо. Обычно проще написать два других вопроса и удалить один. Тем не менее, вы могли бы так же легко оставить этот вопрос «для справки» и попросить двух других вернуться к нему, как к вопросу «это моя общая цель».
Jcolebrand
отредактируйте это в одну пулю, затем опубликуйте последующие вопросы.
Брайан Баллсун-Стэнтон

Ответы:

10

Позвольте мне начать с того, что я ненавижу ALTER. Это зло, ИМХО.

Скажем, это ваша текущая схема таблицы -

CREATE TABLE my_table_of_love (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
my_value VARCHAR(40),
date_created DATE,
PRIMARY KEY(id)
) ENGINE=MyISAM CHARSET=utf8;

Вот путь, который я рекомендую -

Создайте новый объект таблицы, который заменит старый:

CREATE TABLE my_table_of_love_NEW (
id INT UNSIGNED NOT NULL AUTO_INCREMENT,
my_value VARCHAR(40),
date_created DATE,
PRIMARY KEY(id)
) ENGINE=InnoDB CHARSET=utf8

Вставьте все строки из старой таблицы по имени в новую таблицу:

INSERT INTO my_table_of_love_NEW (id,my_value,date_created)
SELECT id,my_value,date_created FROM my_table_of_love;

Дым проверяет вашу миграцию:

SELECT COUNT(*) FROM my_table_of_love_NEW;
SELECT COUNT(*) FROM my_table_of_love;
SELECT a.id,a.my_value,a.date_created FROM my_table_of_love_NEW a
LEFT JOIN my_table_of_love b ON (b.id = a.id)
WHERE a.my_value != b.my_value;

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

RENAME TABLE my_table_of_love TO my_table_of_love_OLD;
RENAME TABLE my_table_of_love_NEW TO my_table_of_love;

Перейдите к регрессионному тестированию.

Такой подход становится все более предпочтительным с таблицами с несколькими индексами и миллионами строк.

Мысли?

randomx
источник
1
Согласен ... хотя, если это сильно транзакционно, вам может понадобиться отключить базу данных при этом. (но, скорее всего, изменение таблицы приведет к более длительному времени простоя)
Джо
Да, я подумал, что для более активных таблиц потребуется простои. Мне нужно будет выполнить несколько тестов, но почему это ALTER TABLEзаймет больше времени, чем INSERT INTO...SELECTна 50 миллионов строк?
Дерек Дауни
Не будет По сути, MySQL внутренне работает именно так, как предложил этот постер. Это создает копию определения и ручеек загружается в копию.
Морган Токер
Мне нравится этот метод, потому что он пропускает часть «copy to tmp», которая может занять некоторое время для больших таблиц.
Haluk
Позвольте мне теперь добавить, что в MySQL 5.7 ALTER намного быстрее и легче справляются.
randomx
7

1) Защита от потери является функцией паранойи. Всегда делайте резервную копию. Если вы действительно параноик, сделайте резервную копию, а затем восстановите ее.

2) На этой странице руководства MySQL есть инструкции по преобразованию типов таблиц.

Самый быстрый способ изменить таблицу на InnoDB - сделать вставки непосредственно в таблицу InnoDB. То есть используйте ALTER TABLE ... ENGINE = INNODB или создайте пустую таблицу InnoDB с идентичными определениями и вставьте строки с помощью INSERT INTO ... SELECT * FROM ....

3) PostgreSQL выполняет полнотекстовый поиск , движок Sphinx, кажется, делает это для MySQL

Брайан Баллсун-Стэнтон
источник
я определенно посмотрю на сфинкса, поскольку я только недавно услышал об этом.
Дерек Дауни
3

Оптимизировать весь сервер (конфигурация памяти, кэши, индексы) в X раз проще, когда используется только один движок. Смешивание myisam с innodb в больших базах данных всегда застревает в какой-то момент, когда компромисс заставляет оба двигателя работать хорошо (но не отлично) :)

Я рекомендую Вам заинтересоваться некоторыми специализированными полнотекстовыми поисковыми системами, такими как sphinx , lucene ( solr ) и избавиться от них на уровне базы данных.

sbczk
источник