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

Warum ist es in MySQL sicher, innodb_support_xa für Einzelthread-Updates zu deaktivieren?

Zu Beginn...

http://yoshinorimatsunobu.blogspot.com/2009 /08/great-performance-effect-of-fixing.html

Vor InnoDB Plugin 1.0.4 war es so:

obtain mutex
  write innodb log and fsync, for prepare-phase (skip if innodb_support_xa=0)
  write binlog (fsync as appropriate if sync_binlog > 0)
  write innodb log and fsync, for commit-phase
release mutex

Auf und nach InnoDB Plugin 1.0.4 (und MySQL 5.5) ist es jetzt:

write innodb log and fsync, for prepare-phase (skip if innodb_support_xa=0)
obtain mutex
  write binlog (fsync as appropriate if sync_binlog > 0)
  write innodb log, for commit-phase
release mutex
fsync innodb log, for commit-phase

Wie Sie sehen können, ist in der neuen Version nichts (außer falls sync_binlog> 0) wird im kritischen Abschnitt fsync gemacht. Auf diese Weise funktioniert Group Commit jetzt und gewährleistet einen weitaus besseren gleichzeitigen Durchsatz.

Wenn Sie beispielsweise mit der vorherigen "kaputten" Version 100 Threads gleichzeitig übergeben hatten, wurden alle fsyncs serialisiert und Sie würden 100 fsyncs für die Vorbereitung und weitere 100 fsyncs für die Übergabe erhalten. Daher war der Gruppen-Commit komplett kaputt.

Mit der neueren Implementierung werden fsyncs jetzt in Abhängigkeit von der Gleichzeitigkeit von Transaktionen gruppiert, während die Betriebsreihenfolge zwischen innodb-Protokoll und binlog sichergestellt wird. Es bedeutet auch, dass es keinen Leistungsgewinn gibt, wenn es nur einen Thread gibt.

Was Ihre Frage betrifft, wenn ein Absturz auftritt, nachdem eine Transaktion in das Binlog geschrieben wurde, aber bevor sie in das Transaktionsprotokoll geschrieben wurde - ich bin auf derselben Seite wie Sie.

Wenn der Server vor dem letzten Schritt abgestürzt ist, besteht eine geringe Wahrscheinlichkeit, dass Sie eine Diskrepanz zwischen dem innodb-Protokoll und dem binlog haben (jedes könnte dem anderen voraus sein), aber es ist garantiert, dass Sie alle Informationen darüber haben, was zu tun ist untersuchen im Innodb-Log, wie es in der Vorbereitungsphase aufgezeichnet wird.

Was mit den nicht festgeschriebenen Daten zu tun ist, ist jedoch immer noch nicht deterministisch. Zum Beispiel, es sei denn sync_binlog = 1 Es besteht die Möglichkeit, dass ein Slave die Daten erhalten hat, aber das Binlog auf dem Master noch nicht vollständig fsynct hat. Sie können die fehlgeschlagene Transaktion nicht einfach wiederholen, da sie möglicherweise bereits auf einem der Slaves ausgeführt wurde.

Das bedeutet auch, dass das Binlog-Protokoll kürzer als das Innodb-Protokoll sein könnte und „Das Binärprotokoll [Dateiname] ist kürzer als seine erwartete Größe“ zurückgibt. wie im offiziellen Dokument beschrieben, und Sie müssen den Slave von Grund auf neu erstellen. Nicht sehr menschenfreundlich.

http://dev.mysql.com/doc/refman /5.1/en/binary-log.html

Da die Konsistenz in Bezug auf die Operationsreihenfolge unabhängig von innodb_support_xa gewährleistet ist Einstellung (was dem widerspricht, was in der offiziellen Dokumentation zu innodb_support_xa gesagt wird , vielleicht, weil es weit vor dem Concurrency-Fix ​​über den Bestand von innodb 5.0.3 geschrieben wurde), und die Konsistenz zwischen dem innodb-Protokoll auf dem Master und dem Relay-Protokoll auf dem Slave ist nicht unbedingt garantiert, selbst mit innodb_support_xa , sehe ich keinen Sinn darin, innodb_support_xa zu verwenden . Es ist zwar beängstigend, der offiziellen Empfehlung nicht zu folgen, jedoch wirkt sie in vielen Punkten altbacken und falsch.

Ich frage mich, ob es eine Korrelation zwischen innodb_flush_log_at_trx_commit gibt Einstellung und innodb_support_xa Verhalten, wenn Ersteres auf 2 oder 0 gesetzt ist.

Eine praktische Denkweise ist, dass ein Failover zum Slave sicher ist – schließlich war die fehlgeschlagene Transaktion etwas, das Sie erledigen wollten – aber niemals ein Failback zum Master, da es zu Diskrepanzen in den Daten kommen kann. Sie müssen die Daten vollständig vom Slave kopieren, bevor Sie den Master zu einem neuen Slave machen. Mit anderen Worten, wenn der Master abgestürzt ist, vertrauen Sie von da an dem Slave - auf diese Weise müssen Sie nicht mit dem innodb-Protokoll für die Wiederherstellung nach einem Absturz herumspielen.

Beachten Sie auch, dass MySQL 5.5 halbsynchrone Replikation unterstützt, ähnlich wie "Trust the Slave" - ​​dachte, Sie könnten daran interessiert sein.

http://dev.mysql.com/doc/refman /5.5/en/replication-semisync.html