Ускорение конвертации 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;

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

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

Мысли?


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 ) и избавиться от них на уровне базы данных.

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.