Beschleunigung der Konvertierung von MyISAM nach InnoDB


15

Ich habe einen MySQL 5.1-Server mit einer Datenbank von ca. 450 Tabellen und 4 GB Speicherplatz. Die überwiegende Mehrheit dieser Tabellen (alle bis auf 2) sind MyIsam. Dies war größtenteils in Ordnung (Transaktionen sind nicht erforderlich), aber die Anwendung verzeichnete einen Anstieg des Datenverkehrs und bestimmte Tabellen waren aufgrund der Tabellensperrung bei Aktualisierungen betroffen. Das ist der Grund, warum 2 der Tabellen jetzt InnoDB sind.

Die Konvertierung für die kleineren Tabellen (100.000 Zeilen) dauert nicht lange und führt zu minimalen Ausfallzeiten. Einige meiner Tracking-Tabellen nähern sich jedoch 50 Millionen Zeilen. Gibt es eine Möglichkeit, ALTER TABLE...ENGINE InnoDBgroße Tische zu beschleunigen ? Und wenn nicht, gibt es andere Methoden zur Konvertierung, um Ausfallzeiten für diese schreiblastigen Tabellen zu minimieren?


1
Beachten Sie Folgendes: Mehrere Fragen in einem Post halten Personen davon ab, eine der Fragen zu beantworten, wenn sie eine Antwort veröffentlichen.
BenV

Ich VtC als das ist ziemlich kompliziert zu beantworten. Sie sollten möglichst mehrere Fragen einzeln öffnen.
Jcolebrand

Ich nehme den Rat gerne an, um daraus eine einzelne Frage zu machen, aber wird empfohlen, diese Frage zu löschen und einfach eine neue zu öffnen? Das Umschreiben würde meistens darin bestehen, die zweiten zwei Kugeln zu entfernen und die erste zu ändern (ich habe den Titel ebenfalls aktualisiert, um zu reflektieren, welche Speicher-Engines)
Derek Downey

Beides wäre in Ordnung. Normalerweise ist es einfacher , zwei weitere Fragen zu schreiben und die eine zu löschen. Sie können diese jedoch genauso einfach als "Referenz" belassen und die anderen beiden darauf verweisen lassen, da dies die Frage "Dies ist mein Gesamtziel" ist.
Jcolebrand

Bearbeite diese in einen Punkt und poste dann die folgenden Fragen.
Brian Ballsun-Stanton

Antworten:


10

Lassen Sie mich mit den Worten beginnen: Ich hasse ALTER. Es ist böse, IMHO.

Angenommen, dies ist Ihr aktuelles Tabellenschema.

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;

Hier ist der Pfad, den ich empfehle -

Erstellen Sie ein neues Tabellenobjekt, das das alte ersetzt:

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

Fügen Sie alle Zeilen der alten Tabelle nach Namen in die neue Tabelle ein:

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

Rauch teste deine Migration:

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;

Tauschen Sie die Tabellennamen aus, damit Sie für den Fall, dass ein Rollback erforderlich ist, ein Backup erstellen können.

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

Fahren Sie mit den Regressionstests fort.

Dieser Ansatz wird bei Tabellen mit mehreren Indizes und Millionen von Zeilen immer bevorzugter.

Gedanken?


1
Einverstanden ... obwohl, wenn es stark transaktionell ist, Sie möglicherweise die Datenbank herunterfahren müssen, während Sie dies tun. (Aber ein Alter Table wird Ihnen höchstwahrscheinlich längere Ausfallzeiten bescheren.)
Joe

Ja, ich dachte, es würde Ausfallzeiten für die aktiveren Tabellen erfordern. Ich werde einige Tests durchführen müssen, aber warum würde ALTER TABLEes länger dauern als INSERT INTO...SELECTbei 50 Millionen Zeilen?
Derek Downey

Das wird es nicht. Grundsätzlich macht MySQL intern genau das, was dieses Poster vorgeschlagen hat. Es erstellt eine Kopie der Definition und überträgt Ladevorgänge in die Kopie.
Morgan Tocker

Ich mag diese Methode, weil sie den Teil "Kopieren nach tmp" überspringt, was bei großen Tabellen einige Zeit in Anspruch nehmen kann.
Haluk

Lassen Sie mich jetzt hinzufügen, dass ALTERs in MySQL 5.7 viel schneller und einfacher zu handhaben sind.
Randomx

7

1) Verlustschutz ist eine Funktion der Paranoia. Machen Sie immer ein Backup. Wenn Sie wirklich paranoid sind, erstellen Sie eine Sicherungskopie und stellen Sie sie von der Sicherungskopie wieder her.

2) Diese Seite des MySQL-Handbuchs enthält Anweisungen zum Konvertieren von Tabellentypen.

Die schnellste Möglichkeit, eine Tabelle in InnoDB zu ändern, besteht darin, die Einfügungen direkt in eine InnoDB-Tabelle vorzunehmen. Verwenden Sie also ALTER TABLE ... ENGINE = INNODB, oder erstellen Sie eine leere InnoDB-Tabelle mit identischen Definitionen, und fügen Sie die Zeilen mit INSERT INTO ... SELECT * FROM ... ein.

3) PostgreSQL führt eine Volltextsuche durch , die Sphinx- Engine scheint dies für MySQL zu tun


Ich werde mich auf jeden Fall mit Sphinx beschäftigen, da ich erst kürzlich davon gehört habe.
Derek Downey

3

Es ist X-mal einfacher, den gesamten Server (Speicherkonfiguration, Caches, Indizes) zu optimieren, wenn nur eine Engine verwendet wird. Das Mischen von myisam mit innodb in großen Datenbanken wird immer irgendwann hängen bleiben, wenn Kompromisse eingegangen sind, damit beide Engines funktionieren (aber nicht exzellent :)

Ich empfehle Ihnen, sich für einige spezielle Volltextsuchmaschinen wie Sphinx , Lucene ( Solr ) zu interessieren und diese aus der Datenbankebene zu entfernen .

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.