Accélérer la conversion de MyISAM en InnoDB

15

J'ai un serveur mysql 5.1 avec une base de données d'environ 450 tables, occupant 4 Go. La grande majorité de ces tables (toutes sauf 2) sont MyIsam. Cela a été très bien pour la plupart (pas besoin de transactions), mais l'application a gagné du trafic et certaines tables ont été affectées en raison du verrouillage des tables lors des mises à jour. C'est la raison pour laquelle 2 des tableaux sont maintenant InnoDB.

La conversion sur les petites tables (100 000 lignes) ne prend pas beaucoup de temps, ce qui entraîne un temps d'arrêt minimal. Cependant, quelques-unes de mes tables de suivi approchent de 50 millions de lignes. Existe-t-il un moyen d'accélérer un ALTER TABLE...ENGINE InnoDBsur de grandes tables? Et si ce n'est pas le cas, existe-t-il d'autres méthodes pour convertir les temps d'arrêt minimisés sur ces tableaux lourds en écriture?

Derek Downey
la source
1
Quelque chose à garder à l'esprit: plusieurs questions dans un même message ont tendance à décourager les personnes qui peuvent répondre à l'une des questions de poster une réponse.
BenV
Je VtC car c'est assez compliqué de répondre. Vous devez ouvrir plusieurs questions individuellement.
jcolebrand
je prendrai volontiers les conseils pour en faire une seule question, mais est-il recommandé de supprimer cette question et d'en ouvrir une nouvelle? la réécriture consisterait principalement à retirer les 2 secondes balles et à modifier la première (j'ai également mis à jour le titre pour refléter les moteurs de stockage)
Derek Downey
Soit ce serait bien. Il est généralement plus facile d'écrire deux autres questions et de supprimer l'une. Cependant, vous pouvez tout aussi bien laisser celui-ci pour "référence" et demander aux deux autres d'y faire référence, comme une question "c'est mon objectif global".
jcolebrand
éditez celui-ci dans une puce, puis postez les questions de suivi.
Brian Ballsun-Stanton

Réponses:

10

Permettez-moi de commencer par dire que je déteste ALTER. C'est mauvais, à mon humble avis.

Dites, ceci est votre schéma de table actuel -

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;

Voici le chemin que je recommande -

Créez un nouvel objet table qui remplacera l'ancien:

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

Insérez toutes les lignes de l'ancienne table par nom dans la nouvelle table:

INSERT INTO my_table_of_love_NEW (id,my_value,date_created)
SELECT id,my_value,date_created FROM my_table_of_love;

Testez votre migration de fumée:

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;

Échangez les noms de table afin de pouvoir conserver une sauvegarde au cas où vous auriez besoin de restaurer.

RENAME TABLE my_table_of_love TO my_table_of_love_OLD;
RENAME TABLE my_table_of_love_NEW TO my_table_of_love;

Passez aux tests de régression.

Cette approche devient de plus en plus préférable avec des tables avec plusieurs index et des millions de lignes.

Pensées?

randomx
la source
1
D'accord ... bien que si elle est fortement transactionnelle, vous devrez peut-être supprimer la base de données pendant cette opération. (mais une table alterne va vous donner une plus longue période d'indisponibilité, très probablement)
Joe
Oui, je pensais que cela nécessiterait un temps d'arrêt pour les tables les plus actives. Je vais devoir exécuter des tests, mais pourquoi cela ALTER TABLEprendrait plus de temps que INSERT INTO...SELECTsur 50 millions de lignes?
Derek Downey
Ce ne sera pas le cas. Fondamentalement, MySQL fait en interne exactement comme l'a suggéré cette affiche. Il crée une copie de la définition et charge lentement la copie.
Morgan Tocker
J'aime cette méthode car elle ignore la partie "copier vers tmp", ce qui peut prendre un certain temps pour les grandes tables.
Haluk
Permettez-moi d'ajouter maintenant que dans MySQL 5.7, les ALTER sont beaucoup plus rapides et plus faciles à gérer.
randomx
7

1) La protection contre les pertes est fonction de la paranoïa. Faites toujours une sauvegarde. Si vous êtes vraiment paranoïaque, faites une sauvegarde puis restaurez à partir de la sauvegarde.

2) Cette page du manuel MySQL contient des instructions pour convertir les types de table.

Le moyen le plus rapide de modifier une table en InnoDB est de faire les insertions directement dans une table InnoDB. Autrement dit, utilisez ALTER TABLE ... ENGINE = INNODB, ou créez une table InnoDB vide avec des définitions identiques et insérez les lignes avec INSERT INTO ... SELECT * FROM ....

3) PostgreSQL effectue une recherche en texte intégral , le moteur Sphinx semble le faire pour MySQL

Brian Ballsun-Stanton
la source
je vais certainement me pencher sur le sphinx, comme je ne l'ai entendu que récemment.
Derek Downey
3

Il est X fois plus facile d'optimiser l'ensemble du serveur (configuration de la mémoire, caches, index) lorsque vous n'avez qu'un seul moteur utilisé. Mélanger myisam avec innodb sur de grandes bases de données sera toujours bloqué à un moment donné par certains compromis pour que les deux moteurs fonctionnent bien (mais pas excellents :)

Je vous recommande de vous intéresser à certains moteurs de recherche en texte intégral dédiés tels que sphinx , lucene ( solr ) et de vous en débarrasser de la couche de base de données.

sbczk
la source