[2017] Update: MySQL 5.6 unterstützt Online-Index-Updates
https://dev.mysql.com/doc/refman/8.0/en/innodb-online-ddl-operations.html#online-ddl-index-syntax-notes
In MySQL 5.6 und höher bleibt die Tabelle für Lese- und Schreibvorgänge verfügbar, während der Index erstellt oder gelöscht wird. Die Anweisung CREATE INDEX oder DROP INDEX wird erst beendet, nachdem alle Transaktionen, die auf die Tabelle zugreifen, abgeschlossen sind, sodass der Anfangszustand des Index den neuesten Inhalt der Tabelle widerspiegelt. Zuvor führte das Ändern der Tabelle während der Erstellung oder Löschung eines Index in der Regel zu einem Deadlock, durch den die Anweisung INSERT, UPDATE oder DELETE für die Tabelle abgebrochen wurde.
[2015] Das Aktualisieren der Tabelle zeigt Blockschreibvorgänge in MySQL 5.5 an
Aus der obigen Antwort:
"Wenn Sie eine Version verwenden, die größer als 5.1 ist, werden Indizes erstellt, während die Datenbank online ist. Machen Sie sich also keine Sorgen, dass Sie die Verwendung des Produktionssystems nicht unterbrechen."
Dies ist **** FALSE **** (zumindest für MyISAM / InnoDB-Tabellen, was 99,999% der Leute da draußen verwenden. Clustered Edition ist anders.)
Wenn Sie UPDATE-Operationen für eine Tabelle ausführen, wird BLOCKIERT, während der Index erstellt wird. MySQL ist wirklich sehr, sehr dumm (und ein paar andere Dinge).
Testskript:
(
for n in {1..50}; do
#(time mysql -uroot -e 'select * from website_development.users where id = 41225\G'>/dev/null) 2>&1 | grep real;
(time mysql -uroot -e 'update website_development.users set bio="" where id = 41225\G'>/dev/null) 2>&1 | grep real;
done
) | cat -n &
PID=$!
sleep 0.05
echo "Index Update - START"
mysql -uroot website_development -e 'alter table users add index ddopsonfu (last_name, email, first_name, confirmation_token, current_sign_in_ip);'
echo "Index Update - FINISH"
sleep 0.05
kill $PID
time mysql -uroot website_development -e 'drop index ddopsonfu on users;'
Mein Server (InnoDB):
Server version: 5.5.25a Source distribution
Ausgabe (beachten Sie, wie die 6. Operation für die ~ 400 ms blockiert, die zum Abschluss der Indexaktualisierung erforderlich sind):
1 real 0m0.009s
2 real 0m0.009s
3 real 0m0.009s
4 real 0m0.012s
5 real 0m0.009s
Index Update - START
Index Update - FINISH
6 real 0m0.388s
7 real 0m0.009s
8 real 0m0.009s
9 real 0m0.009s
10 real 0m0.009s
11 real 0m0.009s
Vs Leseoperationen, die nicht blockieren (tauschen Sie den Zeilenkommentar im Skript aus):
1 real 0m0.010s
2 real 0m0.009s
3 real 0m0.009s
4 real 0m0.010s
5 real 0m0.009s
Index Update - START
6 real 0m0.010s
7 real 0m0.010s
8 real 0m0.011s
9 real 0m0.010s
...
41 real 0m0.009s
42 real 0m0.010s
43 real 0m0.009s
Index Update - FINISH
44 real 0m0.012s
45 real 0m0.009s
46 real 0m0.009s
47 real 0m0.010s
48 real 0m0.009s
Aktualisieren des MySQL-Schemas ohne Ausfallzeiten
Bisher gibt es nur eine mir bekannte Methode, um ein MySQL-Schema zu aktualisieren und keinen Verfügbarkeitsausfall zu erleiden. Rundschreiben Meister:
- Auf Master A läuft Ihre MySQL-Datenbank
- Bringen Sie Master B in Betrieb und lassen Sie die Schreibvorgänge von Master A replizieren (B ist ein Slave von A).
- Führen Sie das Schema-Update auf Master B durch. Es wird während des Upgrades ins Hintertreffen geraten
- Lassen Sie Meister B aufholen. Invariant: Ihre Schemaänderung MUSS in der Lage sein, Befehle zu verarbeiten, die aus einem Downversion-Schema repliziert wurden. Änderungen an der Indizierung sind zulässig. Einfache Spaltenzusätze qualifizieren sich normalerweise. Spalte entfernen? wahrscheinlich nicht.
- Tauschen Sie alle Clients ATOMISCH von Master A nach Master B. Wenn Sie sicher sein möchten (vertrauen Sie mir, das tun Sie), sollten Sie sicherstellen, dass der letzte Schreibvorgang in A VOR B nach B repliziert wirdB nimmt seinen ersten Schreibvorgang. Wenn Sie gleichzeitiges Schreiben an 2+ Master zulassen, ... verstehen Sie die MySQL-Replikation auf DEEP-Ebene besser oder Sie sind auf dem Weg in eine Welt voller Schmerzen. Extreme Schmerzen. Haben Sie eine Spalte, die AUTOINCREMENT ist? Sie sind geschraubt (es sei denn, Sie verwenden gerade Zahlen auf einem Master und Quoten auf dem anderen). Vertrauen Sie NICHT darauf, dass die MySQL-Replikation "das Richtige tut". Es ist NICHT klug und wird dich nicht retten. Es ist nur etwas weniger sicher, als binäre Transaktionsprotokolle von der Befehlszeile zu kopieren und von Hand wiederzugeben. Das Trennen aller Clients vom alten Master und das Umschalten auf den neuen Master kann jedoch in Sekundenschnelle erfolgen. Dies ist erheblich schneller als das Warten auf ein mehrstündiges Schema-Upgrade.
- Jetzt ist Meister B dein neuer Meister. Sie haben das neue Schema. Das leben ist gut. Trink ein Bier; das Schlimmste ist vorbei.
- Wiederholen Sie den Vorgang mit Master A und aktualisieren Sie sein Schema so, dass er Ihr neuer sekundärer Master wird, der für den Fall bereit ist, dass Ihr primärer Master (jetzt Master B) die Macht verliert oder einfach aufsteht und an Ihnen stirbt.
Eine einfache Möglichkeit, das Schema zu aktualisieren, ist dies nicht. In einer seriösen Produktionsumgebung funktionsfähig; Ja, so ist es. Bitte, bitte, bitte, wenn es eine einfachere Möglichkeit gibt, einer MySQL-Tabelle einen Index hinzuzufügen, ohne Schreibvorgänge zu blockieren, lassen Sie es mich wissen.
Googeln führte mich zu diesem Artikel, der eine ähnliche Technik beschreibt. Noch besser ist, dass sie empfehlen, an derselben Stelle im Verfahren zu trinken (Beachten Sie, dass ich meine Antwort geschrieben habe, bevor ich den Artikel gelesen habe)!
Perconas pt-online-Schema-Änderung
Der Artikel, den ich oben verlinkt habe, handelt von einem Tool, pt-online-schema-change , das wie folgt funktioniert:
- Erstellen Sie eine neue Tabelle mit derselben Struktur wie das Original.
- Aktualisieren Sie das Schema für eine neue Tabelle.
- Fügen Sie der Originaltabelle einen Trigger hinzu, damit die Änderungen mit der Kopie synchron bleiben
- Kopieren Sie Zeilen in Stapeln aus der Originaltabelle.
- Schieben Sie den Originaltisch aus dem Weg und ersetzen Sie ihn durch einen neuen Tisch.
- Lass den alten Tisch fallen.
Ich habe das Tool noch nie selbst ausprobiert. YMMV
RDS
Ich verwende derzeit MySQL über Amazon RDS . Es ist ein wirklich raffinierter Dienst, der MySQL einschließt und verwaltet, sodass Sie mit einer einzigen Schaltfläche neue Lesereplikate hinzufügen und die Datenbank über Hardware-SKUs hinweg transparent aktualisieren können. Es ist wirklich praktisch. Sie erhalten keinen SUPER-Zugriff auf die Datenbank, sodass Sie nicht direkt mit der Replikation schrauben können (ist dies ein Segen oder ein Fluch?). Sie können jedoch die Read Replica Promotion verwenden , um Ihre Schemaänderungen an einem schreibgeschützten Slave vorzunehmen, und diesen Slave dann zu Ihrem neuen Master heraufstufen. Genau der gleiche Trick wie oben beschrieben, nur viel einfacher auszuführen. Sie tun immer noch nicht viel, um Ihnen bei der Umstellung zu helfen. Sie müssen Ihre App neu konfigurieren und neu starten.