Прискорення конверсії MyISAM в InnoDB


15

У мене є сервер mysql 5.1 з базою даних приблизно 450 таблиць, що займає 4 Гб. Переважна більшість цих таблиць (усі, крім 2) є MyIsam. Здебільшого це добре (не потрібні транзакції), але додаток набирає трафік, і певні таблиці зазнали впливу через блокування таблиць на оновленнях. Ось чому 2 таблиці зараз є InnoDB.

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


1
Що слід пам’ятати: кілька запитань в одному дописі, як правило, відштовхують людей, які можуть відповісти на одне з питань, від розміщення відповіді.
BenV

Я VtC, оскільки відповісти на це досить складно. Вам слід відкрити як кілька запитань окремо.
jcolebrand

Я з радістю прийму поради, щоб перетворити їх на одне запитання, але чи рекомендується це питання видалити та просто відкрити нове? переписання здебільшого видалило б дві кулі та змінило першу (я оновив заголовок, а також відобразив, які саме двигуни зберігання)
Дерек Дауні

Або було б добре. Зазвичай простіше написати два інші питання та видалити одне. Однак ви можете так само легко залишити цю для «довідки», а інші два посилаються на неї, як на питання «це моя загальна мета».
jcolebrand

відредагуйте цю в одну кулю, а потім опублікуйте подальші запитання.
Брайан Балсун-Стентон

Відповіді:


10

Почніть з того, що я ненавиджу АЛЬТЕР. Це зло, ІМХО.

Скажіть, це ваша поточна схема таблиці -

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 робить всередині саме так, як запропонував цей плакат. Він створює копію визначення і пропускає завантаження в копію.
Морган Токер

Мені подобається цей метод, оскільки він пропускає частину «копіювати в tmp», що може зайняти деякий час для великих таблиць.
Галюк

Дозвольте мені зараз додати, що в MySQL 5.7 ALTERs набагато швидше і простіше впоратися.
випадковий

7

1) Захист від втрат - функція параної. Завжди робіть резервну копію. Якщо ви справді параноїк, зробіть резервну копію, а потім відновіть її.

2) На цій сторінці посібника з MySQL є вказівки щодо перетворення типів таблиць.

Найшвидший спосіб змінити таблицю на InnoDB - це зробити вставки безпосередньо до таблиці InnoDB. Тобто використовуйте ALTER TABLE ... ENGINE = INNODB, або створіть порожню таблицю InnoDB з однаковими визначеннями та вставте рядки з INSERT INTO ... SELECT * OF OF ....

3) PostgreSQL здійснює повнотекстовий пошук , Sphinx Engine, здається, робить це для MySQL


я обов'язково загляну в сфінкс, як це я нещодавно чув про це.
Дерек Дауні

3

Оптимізувати весь сервер (конфігурація пам'яті, кеші, індекси) в X рази простіше, коли використовується лише один двигун. Змішування myisam з innodb на великих базах даних завжди буде застрявати в якийсь момент, змушений деяким компромісом, щоб обидва двигуни працювали добре (але не відмінно :)

Я рекомендую зацікавитись деякими спеціалізованими повнотекстовими пошуковими системами, такими як сфінкса , люцена ( solr ) та позбутися від нього з шару бази даних.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.