Как мне преобразовать базу данных из MyISAM в InnoDB?


9

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


Это не похоже на вопрос, связанный с Drupal, не так ли?
Тостинни

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, я доверяю 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

Что ж, запустив этот крутой скрипт bash для конвертации ( yoodey.com/… ), я понял, что, по-видимому, единственной таблицей в моей базе данных, которая использует полный текст, является 'search_index'. Это приводит к остановке преобразования, но после отмены преобразования на нем все прошло гладко. Запустив источник ConvertMyISAM2InnoDB.sql, я не смог точно определить виновника. В любом случае, я ценю вашу помощь.
морская рыба

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 Drush с тех пор.

Вы можете поместить его в файл convert.drush.inc, например, в папку .drush, или выполнить его каким-либо образом на своем сайте, например, с помощью блока php devel execute. В качестве скриптового сценария вы можете назвать его так:

drush convert-engine InnoDB

Предупреждение : если кто-то что-то делает с базой данных во время выполнения этих команд, ваша база данных будет полностью испорчена. Неустранимый. Итак, переведите ваш сайт в режим обслуживания и сделайте резервную копию, прежде чем пытаться это сделать! И, конечно же, сначала попробуйте на сайте разработки / тестирования :)


5
Согласитесь с Бердиром, сделайте резервную копию своего сайта. Пока эта операция продолжается, ваша база данных будет заблокирована. Если вам нужен модуль, который может это сделать, попробуйте DB Tuner .
mikeytown2

@ mikeytown2: Это очень крутой модуль :)
Бердир,

1
Хороший сценарий, но он кажется слишком излишним по сравнению с тем, чтобы делать это напрямую с клиентом MySQL.
Тостинни

2
В скрипте ровно 5 строк кода. Остальное - интегрировать его с drush. Есть способ сделать это с помощью одной команды sql в MySQL. Так или иначе, вы должны написать сценарий.
Бердир
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.