E / A-Wartezeit, die so viel Verlangsamung verursacht (EXT4 JDB2 bei 99% E / A) Während des Mysql-Commits

14

Ich schreibe einen Indexer mit Python, der Dokumente indiziert und in die Datenbank einfügt. Bevor es ein einzelner Prozess war, habe ich es jetzt mit 4 parallelen Prozessen geschafft, mehrere Prozesse zu verarbeiten. Nach jeder Textextraktion wird der Index in die Datenbank eingefügt und ein Commit ausgeführt.

Jetzt trifft es auf das IO-Problem, das Haupt-IO-Problem ist nicht mein Prozess, sondern das jdb2-Journalsystem von EXT4. Es liegt bei 99,99% und die CPU wartet bei jedem MySQL-Commit auf E / A.

Ich habe viele gesehen, die dieses Problem im Internet hatten und deren Lösung darin besteht, mit barrier = 0 zu mounten. Würde das Journaling komplett deaktivieren? Meine Server haben UPS und sind in Versuchung, dies zu tun, oder?

Phyo Arkar Lwin
quelle
Sind alle Ihre Daten InnoDB ???
RolandoMySQLDBA

Antworten:

4

Stellen Sie die Datenbank in ein Nicht-Journal-Dateisystem. Zumindest größere Server (Oracle, SQL Server) haben eine eigene Journalfunktion (Transaktionslog) und optimieren ihre IO entsprechend. Sie haben Protokoll und Datenbank auf getrennten Dateisystemen und Datenträgern und verlassen sich auf datenbankinterne Funktionen zur Behandlung fehlerhafter E / A. Normalerweise gibt es keine (größeren Setup-) Dateisystemänderungen außer dem Schreibdatum, da die Dateien nicht erweitert werden - sie würden mit ihrer "endgültigen" Größe generiert (ok, Administratoren können das ändern), und die Änderungen werden wie gesagt von der Datenbank verfolgt Ebene Transaktionsprotokoll.

Möglicherweise möchten Sie uns auch mitteilen, wie Ihre Hardwareschicht lautet. Die meisten Leute unterschätzen, dass IOPS der einschränkende Faktor für eine Datenbank ist, und denken, ein kleiner CD-Satz sei eine geeignete Umgebung für eine große Datenbank. Während einige von uns an Datenbanken arbeiten, die eine größere Anzahl von Datenträgern verwenden, unterstützt dies möglicherweise eine höhere Anzahl von IOPS.

TomTom
quelle
Ich würde dies ändern, um ein Dateisystem zu verwenden, das nicht das Journal für Daten, sondern nur Metadaten verwendet. Ext4 kann auch so konfiguriert werden.
the-wabbit
Ja. Am Ende verdoppelt das Journal die E / A - und das Datenbankprotokoll macht dasselbe noch einmal, sodass Sie mit viel mehr E / A auskommen, als Sie müssen. Und Redundanz, die grundsätzlich nicht benötigt wird. Das System sollte NICE sein, um die Datei zu schützen ... aber nutzlos, wenn die Anwendung dies bereits tut, welche Datenbanken dies tun.
TomTom
Welches bietet die beste Leistung bei Nicht-Journaling? Vielen Dank!
Phyo Arkar Lwin
4

Es wird immer einen Kompromiss zwischen Ausfallsicherheit und Leistung geben.

Mit MySQL auf ext4 bewirkt der Standardwert barriers = 1 zwar eine Verlangsamung, die erste Aktion sollte jedoch nicht darin bestehen, das Journal zu deaktivieren oder data = writeback einzuschalten.

Erstens, wenn Ausfallsicherheit von großer Bedeutung ist, lohnt sich ein batteriegepuffertes RAID auf jeden Fall.

Die von mir ausgewählten Einhängeoptionen, insbesondere für nicht batteriegepuffertes RAID, sind:

/dev/mapper/vg-mysql--data  /var/lib/mysql/data ext4  defaults,noatime,nodiratime,barrier=1,data=ordered  0 0

Dabei wird absichtlich nicht data = writeback verwendet, da ich keine Beschädigung des Dateisystems riskieren möchte, die dazu führt, dass "alte Daten nach einem Absturz und einer Journalwiederherstellung in Dateien angezeigt werden" (Zitat von man mount).

Die ideale Konfiguration in my.cnf für die vollständige Ausfallsicherheit bei E / A-bezogenen Einstellungen ist:

[mysqld]
sync_binlog = 1
innodb_flush_log_at_trx_commit = 1

Ich habe mich für die folgende Abfolge von Kompromissen entschieden, um die Leistung zu steigern:

  1. sync_binlog = 0: Dies ist die erste MySQL-Konfiguration, die ich aus der vollen Ausfallsicherheit heraus ändere. Der Grund dafür ist, dass es eine signifikante Leistungsverbesserung gibt, insbesondere dort, wo binlog_format=row(leider für Jira erforderlich). Ich verwende genügend MySQL-Replikate im Cluster, sodass ich eine Binärkopie von einem anderen Replikat erstellen würde, wenn das Binärprotokoll durch ein Stromausfallszenario beschädigt würde.
  2. innodb_flush_log_at_trx_commit = 2: Während ein Wert von 1 für die vollständige ACID - Konformität erforderlich ist, wird bei jedem Commit der Protokollpuffer in die Datei geschrieben, der Vorgang zum Löschen auf die Festplatte wird jedoch nicht ausgeführt Die Protokolldatei wird auch dann einmal pro Sekunde erstellt, wenn der Wert 2 ist. Beachten Sie, dass aufgrund von Prozessplanungsproblemen nicht 100% ig jede Sekunde gespült wird. " (Zitat aus MySQL-Dokumenten)
  3. Aktualisieren Sie die zu verwendenden Mount-Optionen data=writeback. Beachten Sie, dass Sie, wenn dies Ihr Root-Dateisystem ist, auch eine Kernel-Befehlszeilenoption übergeben müssen. Darauf habe ich bei coderwall ein paar Schritte gemacht .
  4. Testen Sie verschiedene Werte von innodb_flush_method. Es wird gezeigt, dass O_DIRECT die Leistung in einigen Workloads verbessert, aber es ist nicht selbstverständlich, dass dies in Ihrer Umgebung funktioniert.
  5. Upgrade auf SSDs, wobei in diesem Fall werden Sie auch erhöhen wollen innodb_io_capacity, und tune Einstellungen wie innodb_adaptive_flushing, innodb_read_io_threads, innodb_write_io_threads, innodb_purge_threads, und andere mögliche Einstellungen.
JinnKo
quelle
3

Es ist sehr wahrscheinlich, dass Ihr I / O-Backend mit der Last nicht so gut zurechtkommt. Sie sollten sicherstellen, dass Ihr Dateisystem keine Daten aufzeichnet. Ich würde vorschlagen, die data=writeback,relatime,nobarrierParameter zum Mounten für die Datenpartition Ihrer Datenbank als erste schnelle und fehlerhafte Optimierung zu verwenden.

Abgesehen von Ihren Symptomen verwenden Sie anscheinend auch kein Schreib-Caching für Ihren Controller. Stellen Sie sicher, dass Sie einen batteriegepufferten oder flashgepufferten Schreibcache auf Ihrem Controller verwenden, und aktivieren Sie ihn. Dadurch können Sie die Leistung erheblich steigern, ohne das Risiko eines Datenverlusts oder einer Beschädigung erheblich zu erhöhen. Beachten Sie, dass die Verwendung des Schreibcaches ohne Batterie oder Flash-Backup das Risiko von Datenverlust oder -beschädigung erheblich erhöht. Tun Sie dies also nur zu Testzwecken und / oder wenn Sie den Verlust in Kauf nehmen können.

das-wabbit
quelle
also wie wäre es mit: data = writeback, relatime, nobarrier und dann mysql logging komplett deaktivieren? Ich denke, das würde die Dinge viel beschleunigen?
Phyo Arkar Lwin
hdpram -i zeigt, dass ich Schreibcache verwende. also hmm?
Phyo Arkar Lwin
@ V3ss0n Sie können die Protokollierung für eine Transaktions-Engine nicht deaktivieren - sie ist das Herzstück davon. Sie können das Transaktionsprotokoll auf einen anderen Festplattensatz verschieben , da es ein völlig anderes Zugriffsmuster (meist lineare Schreibvorgänge) aufweist als Ihre Hauptdatenbankdaten (zufällige Lese- / Schreibvorgänge). Dies ist eine häufig empfohlene Konfiguration. Was Ihre Speicherkonfiguration betrifft: Sie verwenden keinen RAID-Controller, sondern nur einzelne Festplatten mit eingeschaltetem Schreibcache? Dies würde keinem Ihrer synchronen Schreibvorgänge helfen, da sie explizite Cache-Flush-Anforderungen enthalten.
the-wabbit
Ist nobarrierdas selbe wie barrier=0?
Nic Cottrell
@ NicCottrell ja, sie sind die gleichen.
Kouton
3

Dies ist eine alte Frage, aber wir hatten in der vergangenen Woche die gleichen Probleme (hohe E / A-Wartezeiten und schreckliche Einfüge- / Aktualisierungsgeschwindigkeiten) auf einem neuen dedizierten Server. Diese Lösung behebt dieses Problem direkt.

Das Deaktivieren tune2fs -O "^has_journal" /dev/<drive>der Journalerstellung mit war die schnellste Lösung, da die E / A-Wartezeit aufgrund des JDB2-Prozesses entfällt. Dies wird jedoch nur empfohlen, wenn Sie über ein batteriegepuffertes Laufwerk verfügen, da bei einem Absturz Daten verloren gehen. InnoDB-Tabellen sind sicher, wenn Sie sie doublewritein MySQL aktiviert haben . Dateien wie .frm, Protokolle usw. sind jedoch nicht sicher. Wir haben versucht, diese Dateien auf ein anderes Laufwerk zu verschieben (insbesondere die Bin-Protokolle), aber das Warten auf jdb2 IO blieb bestehen. Es hat uns also nicht sehr wohl gefühlt.

data=writeback,relatime,nobarrierEs hat nicht dazu beigetragen, das Schreiben / Lesen zu beschleunigen, sondern das Journaling auf der gesamten Partition zu deaktivieren. Weitere Optionen für ext4 finden Sie in der EXT4-Dokumentation .

Der wahre Schuldige in unserem Fall war sync_binlog. Wir hatten eingestellt ist wie 1in /etc/mysql/my.cnfund es war tödlich Leistung.

Percona bestätigt dies hier . Wir haben es auf den Standardwert von eingestellt 0und die Leistung um über 500% gesteigert.

Kouton
quelle
0

In welches Datenbankmodul fügen Sie diese Daten ein?

Wenn es sich um MyISAM handelt: Dies muss die gesamte Tabelle während eines Schreibvorgangs sperren, sodass das Ausführen von Threads für gleichzeitige Einfügungen JEDES System tötet, egal wie leistungsfähig es ist.

Stellen Sie sicher, dass Sie InnoDB für diese Tabellen verwenden.

adaptr
quelle
Da er Transaktionen festlegt, ist die Engine nicht MyISAM, da MyISAM keine Transaktionen unterstützt.
the-wabbit
Arr, Brainfart.
24.
Ich benutze innodb, mysql5.5 ist standardmäßig innodb.
Phyo Arkar Lwin
0

Auch nicht direkt mit MySQL verwandt, aber einige HD haben Probleme mit ext4 aufgrund von aggressivem Power-Management ... in diesem Fall steigt die Maschinenlast ohne erkennbare Aktivität.

Versuchen Sie es zu deaktivieren. Überprüfen Sie zunächst, welchen Wert Sie haben (wenn Sie ihn ohne Neustart zurücksetzen müssen), und deaktivieren Sie ihn dann.

Überprüfen Sie den aktuellen Wert:

    hdparm -B /dev/sda

Deaktiviere es

   hdparm -B 255 /dev/sda

(oder was auch immer deine HD ist) und teste. Wahrscheinlich wird es bei den meisten Problemen nicht helfen, aber es könnte einigen Benutzern da draußen helfen. Durch einen Neustart wird der Wert zurückgesetzt oder der Wert 255 wird manuell durch den vorherigen Wert ersetzt.

Wenn es hilft, überprüfen Sie die /etc/default/hdparmoder /etc/hdparm.conffür eine dauerhaftere Konfiguration, indem Sie es beim Booten einstellen.

Higuita
quelle