Mysql
 sql >> Datenbank >  >> RDS >> Mysql

Warum dauert die Ausführung einer Einfügeabfrage gelegentlich so lange?

Ich habe das gleiche Phänomen auf meinen Systemen festgestellt. Abfragen, die normalerweise eine Millisekunde dauern, dauern plötzlich 1-2 Sekunden. Alle meine Fälle sind einfache INSERT/UPDATE/REPLACE-Anweisungen für einzelne Tabellen – nicht für SELECTs. Es ist keine Belastung, Verriegelung oder Gewindeaufbau erkennbar.

Ich hatte vermutet, dass es daran liegt, schmutzige Seiten zu löschen, Änderungen auf die Festplatte zu spülen oder einen versteckten Mutex, aber ich muss es noch eingrenzen.

Auch ausgeschlossen

  • Serverlast – kein Zusammenhang mit hoher Last
  • Engine -- passiert mit InnoDB/MyISAM/Memory
  • MySQL-Abfrage-Cache – geschieht unabhängig davon, ob er ein- oder ausgeschaltet ist
  • Protokollrotationen – keine Korrelation bei Ereignissen

Die einzige andere Beobachtung, die ich zu diesem Zeitpunkt habe, ergibt sich aus der Tatsache, dass ich dieselbe Datenbank auf mehreren Computern verwende. Ich habe eine schwere Leseanwendung, also verwende ich eine Umgebung mit Replikation - die meiste Last liegt auf den Slaves. Mir ist aufgefallen, dass das Phänomen dort häufiger auftritt, obwohl der Master nur minimal belastet wird. Auch wenn ich keine Sperrprobleme sehe, hat vielleicht Innodb/Mysql Probleme mit der (Thread-)Parallelität? Denken Sie daran, dass die Aktualisierungen auf dem Slave Single-Thread sind.

MySQL-Version 5.1.48

Aktualisieren

Ich glaube, ich habe eine Spur für das Problem in meinem Fall. Auf einigen meiner Server ist mir dieses Phänomen mehr aufgefallen als auf den anderen. Als ich sah, was zwischen den verschiedenen Servern anders war, und einige Dinge herumdrehte, wurde ich zu MySQL innodb-Systemvariable innodb_flush_log_at_trx_commit .

Ich fand das Dokument etwas umständlich zu lesen, aber innodb_flush_log_at_trx_commit kann die Werte 1,2,0 annehmen:

  • Für 1 wird der Protokollpuffer bei jedem Commit in die Protokolldatei geleert, und die Protokolldatei wird bei jedem Commit auf die Festplatte geleert.
  • Für 2 wird der Protokollpuffer bei jedem Commit in die Protokolldatei geleert, und die Protokolldatei wird ungefähr alle 1-2 Sekunden auf die Festplatte geleert.
  • Bei 0 wird der Protokollpuffer jede Sekunde in die Protokolldatei und die Protokolldatei jede Sekunde auf die Festplatte geleert.

Effektiv, in der Reihenfolge (1,2,0), wie gemeldet und dokumentiert, soll man mit steigender Performance im Trade ein erhöhtes Risiko bekommen.

Allerdings habe ich festgestellt, dass die Server mit innodb_flush_log_at_trx_commit=0 schnitten schlechter ab (d. h. hatten 10-100 mal mehr "lange Updates") als die Server mit innodb_flush_log_at_trx_commit=2 . Außerdem haben sich die Dinge bei den schlechten Instanzen sofort verbessert, als ich es auf 2 umgestellt habe (beachten Sie, dass Sie es im laufenden Betrieb ändern können).

Nun meine Frage, was ist bei dir eingestellt? Beachten Sie, dass ich diesen Parameter nicht beschuldige, sondern hervorhebe, dass sein Kontext mit diesem Problem zusammenhängt.