Jak przekonwertować bazę danych z MyISAM na InnoDB?


9

Zamienię przekonwertować wszystkie tabele bazy danych 500 MB z MyISAM na InnoDB, aby zobaczyć, czy poprawi to ogólną wydajność zajętej witryny Drupal 6. Zastanawiam się, jaki jest najlepszy (tj. Najbezpieczniejszy / najłatwiejszy / najszybszy) sposób wykonania konwersji.


To nie wydaje się być pytanie związane z Drupalem, prawda?
— tostinni

2
Nie bezpośrednio, ale jest to coś, co administratorzy Drupala muszą czasem robić.
— mpdonadio

Zaktualizowałem swoją odpowiedź, aby użyć nowej komendy SQL do odfiltrowania tabel MyISAM, które mają indeksy FULLTEXT. Uruchom ponownie wszystkie kroki od zera, korzystając z mojej zaktualizowanej odpowiedzi.
— RolandoMySQLDBA

Jeśli Twoja witryna Drupal nie jest skonfigurowana do wyszukiwania przy użyciu indeksów FULLTEXT, możesz przejść do wszystkich tabel z indeksami FULLTEXT i usunąć te indeksy z tych tabel. Aby znaleźć wszystkie tabele z indeksami FULLTEXT, uruchom SELECT table_schema, table FROM information_schema.statistics WHERE index_type = 'FULLTEXT';
— RolandoMySQLDBA

Odpowiedzi:


7

Jako MySQL DBA ufam, że MySQL wykona konwersję, ponieważ MySQL napisze dla mnie skrypt.

Z poziomu polecenia Linux uruchom tę kwerendę

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

Skrypt najpierw skonwertuje najmniejsze tabele. Ten skrypt pominął także wszystkie tabele MyISAM, które mają indeksy FULLTEXT.

Po obejrzeniu skryptu możesz po prostu uruchomić go w MySQL w następujący sposób:

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

lub jeśli chcesz zobaczyć czas każdej konwersji, zaloguj się do mysql i uruchom to:

mysql> source /root/ConvertMyISAM2InnoDB.sql

Nie należy tego pomieszać, ponieważ podczas wykonywania konwersji dochodzi do pełnej blokady tabeli.

Po przekonwertowaniu wszystkich tabel musisz dostroić ustawienia MySQL do użycia InnoDB i przeskalować key_buffer.

Przeczytaj to, aby ustawić pulę buforów InnoDB: /dba/1/what-are-the-main-differences-between-innodb-and-myisam/2194#2194

Przeczytaj również: /drupal/1715/what-would-the-optimal-mysql-configuration-for-a-drupal-7-site-be/2367#2367

Spróbuj !!!


Roland, wypróbowałem twoje rozwiązanie, ale po zaimportowaniu ConvertMyISAM2InnoDB.sql do bazy danych pojawia się błąd: „BŁĄD 1214 (HY000) w wierszu 585: Używany typ tabeli nie obsługuje indeksów FULLTEXT”. Czy powinienem wiedzieć, czy konwersja miała miejsce w niektórych tabelach i jak mam rozwiązać ten błąd? Dzięki
— alfish

Bałem się, że to się stanie. Oznacza to po prostu, że jedna tabela MyISAM miała indeks FULLTEXT. Zaloguj się do mysql i uruchom, jeśli chcesz zobaczyć czas. Innymi słowy, uruchom źródło /root/ConvertMyISAM2InnoDB.sql
— RolandoMySQLDBA

Spróbuję zaktualizować skrypt generowania SQL, aby pominąć tabele, które mają indeksy FULLTEXT.
— RolandoMySQLDBA

W międzyczasie powtórz wszystkie te kroki od zera. Pierwszy wiersz zregenerowanego pliku zawiera plik MyISAM z indeksem FULLTEXT. Wystarczy usunąć ten pierwszy wiersz i ponownie uruchomić skrypt.
— RolandoMySQLDBA

Cóż, uruchamiając ten fajny skrypt konwersji bash ( yoodey.com/… ), zorientowałem się, że najwyraźniej jedyną tabelą w mojej bazie danych, która używa pełnego tekstu, jest „search_index”. Powoduje to zatrzymanie konwersji, ale po anulowaniu konwersji na nim reszta przebiegła bezproblemowo. Uruchamiając źródło ConvertMyISAM2InnoDB.sql, nie mogłem wskazać winowajcy. W każdym razie doceniam twoją pomoc.
— Alfish

4

Jakiś czas temu napisałem dla niego drush.

<?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");
  }
}

Pracowałem dla mnie mniej więcej rok temu, nie jestem pewien, czy interfejs API drush zmienił się od tego czasu.

Możesz umieścić to w pliku convert.drush.inc, na przykład w folderze .drush, lub wykonać jakoś na swojej stronie, na przykład za pomocą devel execute block php. Jako skrypt drush, możesz nazwać to tak:

drush convert-engine InnoDB

Ostrzeżenie : jeśli ktoś zrobi coś z bazą danych podczas działania tych poleceń, baza danych zostanie całkowicie pomieszana. Nie do odzyskania. Przed przejściem do tej czynności przejdź do trybu konserwacji i wykonaj kopię zapasową! I oczywiście najpierw wypróbuj stronę deweloperską / testową :)


5
Zgadzam się z Berdir, wykonaj kopię zapasową witryny. Podczas tej operacji baza danych zostanie ZABLOKOWANA. Jeśli chcesz moduł, który może to zrobić, daj DB Tuner szansę.
— mikeytown2

@ mikeytown2: To całkiem fajny moduł :)
— Berdir

1
Fajny skrypt, ale wydaje się dość przesadny w porównaniu do robienia tego bezpośrednio w kliencie MySQL.
— tostinni

2
Skrypt ma dokładnie 5 linii kodu. Resztą jest zintegrowanie go z drush. Można to zrobić za pomocą pojedynczej komendy SQL w MySQL. Tak czy inaczej, to ma napisać scenariusz.
— Berdir
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.