Як конвертувати базу даних з MyISAM в InnoDB?


9

Я збираюся конвертувати всі таблиці бази даних 500 Мб з MyISAM в InnoDB, щоб побачити, чи поліпшить це загальну продуктивність зайнятого сайту Drupal 6. Мені цікаво, який найкращий (тобто найбезпечніший / найпростіший / найшвидший) спосіб зробити перетворення.


Здається, це питання, пов'язане з Друпалом, чи не так?
тостінні

2
Не безпосередньо, але це те, що адміністратори Drupal повинні робити при нагоді.
mpdonadio

Я оновив свою відповідь, щоб використовувати нову команду SQL для фільтрації таблиць MyISAM, які мають індекси FULLTEXT. Будь ласка, повторіть усі кроки з нуля, використовуючи мою оновлену відповідь.
RolandoMySQLDBA

Якщо ваш Drupal-сайт не налаштований на пошук за допомогою індексів FULLTEXT, можливо, вам захочеться перейти до всіх таблиць з індексами FULLTEXT і видалити ці індекси з цих таблиць. Щоб знайти всі таблиці, що мають індекси FULLTEXT, запустіть SELECT table_schema, таблицю FROM information_schema.statistics WHERE index_type = 'FULLTEXT';
RolandoMySQLDBA

Відповіді:


7

Як MySQL DBA, я довіряю MySQL зробити перетворення, змусивши MySQL написати сценарій для мене.

Формуйте команду Linux для запуску цього запиту

mysql -h... -u... -p... -A --skip-column-names -e"SELECT CONCAT('ALTER TABLE ',db,'.',tb,' ENGINE=InnoDB;') FROM (SELECT A.db,A.tb,A.tbsize FROM (SELECT table_schema db,table_name tb,(data_length+index_length) tbsize FROM information_schema.tables WHERE engine='MyISAM' AND table_schema NOT IN ('information_schema','mysql')) A LEFT JOIN (SELECT table_schema db,table_name tb FROM information_schema.statistics WHERE index_type='FULLTEXT') B USING (db,tb) WHERE B.db IS NULL) AA ORDER BY tbsize" > /root/ConvertMyISAM2InnoDB.sql

Сценарій спочатку перетворить найменші таблиці. Цей скрипт також був обхід будь-яких таблиць MyISAM, які мають індекси FULLTEXT.

Переглядаючи сценарій, ви можете просто запустити його в MySQL наступним чином:

mysql -h... -u... -p... -A < /root/ConvertMyISAM2InnoDB.sql

або якщо ви хочете побачити терміни кожної конверсії, увійдіть в mysql і запустіть це:

mysql> source /root/ConvertMyISAM2InnoDB.sql

Це не повинно псуватися, оскільки повне блокування таблиці відбувається під час виконання перетворення.

Після перетворення всіх таблиць вам потрібно налаштувати параметри MySQL для використання InnoDB і зменшити масштаб вниз на key_buffer.

Прочитайте це, щоб встановити пул буфера InnoDB: /dba/1/what-are-the-main-differences-between-innodb-and-myisam/2194#2194

Прочитайте також це: /drupal/1715/what-would-the-optimal-mysql-configuration-for-a-drupal-7-site-be/2367#2367

Спробувати !!!


Роланд, я спробував ваше рішення, але після імпорту ConvertMyISAM2InnoDB.sql до бази даних я отримую цю помилку: "ПОМИЛКА 1214 (HY000) у рядку 585: Тип використовуваної таблиці не підтримує індекси FULLTEXT". Тож чи повинен я знати, чи відбулася конверсія в деяких таблицях, і як мені вирішити цю помилку? Спасибі
alfish

Я боявся, що це станеться. Це просто означає, що одна таблиця MyISAM мала індекс FULLTEXT. Увійдіть в mysql і запустіть, ніби ви хочете побачити час. Іншими словами, запустіть source /root/ConvertMyISAM2InnoDB.sql
RolandoMySQLDBA

Я спробую оновити сценарій покоління SQL, щоб пропустити таблиці, які мають індекси FULLTEXT.
RolandoMySQLDBA

Тим часом повторіть усі ці кроки з нуля. Перший рядок регенерованого файлу містить файл MyISAM з індексом FULLTEXT. Просто видаліть цей перший рядок і повторно запустіть сценарій.
RolandoMySQLDBA

Ну, запустивши цей прохолодний перетворення Баш скрипт ( yoodey.com / ... ), я зрозумів, що , мабуть, тільки таблиця на моїй базі даних , яка використовує повний текст «search_index». Це призводить до припинення перетворення, але після скасування перетворення на ньому решта продовжувалася плавно. Запустивши джерело ConvertMyISAM2InnoDB.sql, я не зміг точно визначити винуватця. У будь-якому разі я ціную вашу допомогу.
alfish

4

Я написав для цього команду ударного часу.

<?php
/**
 * Implements hook_drush_command().
 */
function convert_drush_command() {
  $items = array();

  // the key in the $items array is the name of the command.
  $items['convert-engine'] = array(
    // a short description of your command
    'description' => "Convert MYSQL Table Type",
  );
  return $items;
}

function drush_convert_engine() {
  $args = func_get_args();
  $engine = $args[0];

  $result = db_query("SHOW TABLES");
  while ($row = db_fetch_array($result)) {
    $table = array_shift($row);
    drush_log(dt('Converting @table to @engine', array('@table' => $table, '@engine' => $engine)), 'success');
    db_query("ALTER TABLE $table ENGINE = $engine");
  }
}

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

Ви можете розмістити це у conver.drush.inc, наприклад у папці .drush, або виконати його якось на своєму веб-сайті, наприклад, із блоком php devel Execute. Як сценарій "барабан", ви можете назвати його так:

drush convert-engine InnoDB

Попередження : Якщо хтось щось робить із базою даних під час виконання цих команд, ваша база даних буде повністю зіпсована. Незбережно. Отже, переведіть свій сайт у режим обслуговування та зробіть резервну копію, перш ніж спробувати це! І звичайно, спробуйте спочатку на сайті розробки / тестування :)


5
Погодьтеся з Berdir, створити резервну копію свого сайту. Поки ця операція триває, ваша база даних буде ЗАКЛЮЧЕНА. Якщо ви хочете, щоб модуль міг це зробити, дайте кадр DB Tuner .
mikeytown2

@ mikeytown2: Це досить класний модуль :)
Бердір

1
Хороший сценарій, але здається, що це занадто непомітно, порівняно з цим безпосередньо під клієнтом MySQL.
тостінні

2
Сценарій - це рівно 5 рядків коду. Решта - інтегрувати його з барабаном. Існує спосіб зробити це в одній команді sql в MySQL. Так чи інакше, ви повинні написати сценарій.
Бердір
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.