Mysql
 sql >> Database >  >> RDS >> Mysql

In MySQL, perché è sicuro disattivare innodb_support_xa per gli aggiornamenti a thread singolo?

Tanto per cominciare...

http://yoshinorimatsunobu.blogspot.com/2009 /08/effetto-ottimo-di-riparazione.html

Prima di InnoDB Plugin 1.0.4, era come:

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

Su e dopo InnoDB Plugin 1.0.4 (e MySQL 5.5), ora è:

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

Come puoi vedere, nella nuova versione, nulla (tranne nel caso sync_binlog> 0) è sincronizzato nella sezione critica. In questo modo, il commit di gruppo ora funziona e garantisce un throughput simultaneo molto migliore.

Ad esempio, con la precedente versione "non funzionante", se avevi 100 thread di commit simultanei, tutti i fsync venivano serializzati e avresti 100 fsync per la preparazione e altri 100 fsync per il commit. Pertanto il commit del gruppo è stato completamente interrotto.

Ora con l'implementazione più recente, fsyncs sono raggruppati in base alla concorrenza delle transazioni, garantendo al contempo l'ordine delle operazioni tra innodb log e binlog. Significa anche che se c'è un solo thread, non c'è miglioramento delle prestazioni.

Per quanto riguarda la tua domanda che, quando si verifica un arresto anomalo dopo che una transazione è stata scritta nel binlog, ma prima che sia scritta nel registro delle transazioni, sono sulla tua stessa pagina.

Se il server si è arrestato in modo anomalo prima del passaggio finale, c'è una leggera possibilità che tu abbia una discrepanza tra innodb log e binlog (uno potrebbe essere davanti all'altro), ma è garantito che hai tutte le informazioni su cosa esaminare nel log di innodb, come viene registrato nella fase di preparazione.

Tuttavia, cosa fare con il non impegnato è ancora non deterministico. Ad esempio, a meno che sync_binlog = 1 c'è la possibilità che uno slave abbia ricevuto i dati ma non abbia ancora sincronizzato completamente il binlog sul master. Non puoi semplicemente ripetere la transazione non riuscita perché potrebbe essere già stata eseguita su uno degli slave.

Il che significa anche che il binlog potrebbe essere più breve del registro innodb, restituendo "Il registro binario [nome_file] è più corto della dimensione prevista". come descritto nel documento ufficiale, e devi ricostruire lo schiavo da zero. Non molto umano.

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

Poiché la coerenza in termini di ordinamento delle operazioni è garantita indipendentemente da innodb_support_xa impostazione (che contraddice quanto detto nel documento ufficiale su innodb_support_xa , forse perché è stato scritto sullo stock innodb 5.0.3 molto prima della correzione della concorrenza), e la coerenza tra il log innodb sul master e il log relay sullo slave non è rigorosamente garantita anche con innodb_support_xa , non vedo alcun senso nell'usare innodb_support_xa . È spaventoso non seguire la raccomandazione ufficiale, tuttavia, in molti punti sembra stantia e sbagliata.

Mi chiedo se c'è qualche correlazione tra il innodb_flush_log_at_trx_commit impostazione e innodb_support_xa comportamento quando il primo è impostato su 2 o 0.

Un modo pratico di pensare è che il failover sullo slave è sicuro - dopo tutto, la transazione non riuscita era qualcosa che si desiderava completare - ma non eseguire mai il failback sul master, poiché potrebbero esserci delle discrepanze nei dati. È necessario copiare completamente i dati dallo slave, prima di trasformare il master in un nuovo slave. In altre parole, quando il master si è arrestato in modo anomalo, fidati dello slave da quel momento in poi:in questo modo, non è necessario pasticciare con il registro di innodb per il ripristino del crash.

Nota inoltre che MySQL 5.5 supporta la replica semi-sincrona, sulla stessa linea di "fidati allo slave" - ​​ho pensato che potresti essere interessato.

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