sql >> Databasteknik >  >> RDS >> Mysql

Varför är det säkert att stänga av innodb_support_xa i MySQL för entrådade uppdateringar?

Till att börja med...

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

Innan InnoDB Plugin 1.0.4 var det så här:

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

På och efter InnoDB Plugin 1.0.4 (och MySQL 5.5) är det nu:

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

Som du kan se, i den nya versionen, ingenting (förutom i fallet sync_binlog> 0) fsync'd i det kritiska avsnittet. På så sätt fungerar group commit nu och säkerställer mycket bättre samtidig genomströmning.

Till exempel, med den tidigare "trasna" versionen, om du hade 100 trådar samtidiga commits, var alla fsyncs serialiserade och du skulle få 100 fsyncs för preparering och ytterligare 100 fsyncs för commit. Därför bröts gruppens engagemang helt.

Nu med den nyare implementeringen grupperas fsyncs beroende på transaktionernas samtidighet, samtidigt som operationsordning mellan innodb-logg och binlog säkerställs. Det betyder också att om det bara finns en tråd så finns det ingen prestandavinst.

När det gäller din fråga om att när en krasch inträffar efter att en transaktion skrivs till binloggen, men innan den skrivs till transaktionsloggen - är jag på samma sida som du.

Om servern kraschade före det sista steget, finns det en liten chans att du har en diskrepans mellan innodb-logg och binlog (antingen kan vara före den andra), men det är garanterat att du har all information om vad du ska undersöka i innodb-loggen, som den registreras i förberedelsefasen.

Men vad man ska göra med de oengagerade är fortfarande obestämt. Till exempel om inte sync_binlog = 1 det finns en chans att en slav tagit emot data men inte har synkroniserat binloggen på mastern ännu. Du kan inte bara göra om den misslyckade transaktionen eftersom den redan kan ha körts på en av slavarna.

Vilket också betyder att binloggen kan vara kortare än innodb-loggen, vilket returnerar "Den binära loggen [filnamn] är kortare än dess förväntade storlek." som beskrivs i det officiella dokumentet, och du måste bygga om slaven från grunden. Inte särskilt människovänligt.

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

Eftersom konsekvens i termer av operationsordning garanteras oberoende av innodb_support_xa inställning (som motsäger det som sägs i det officiella dokumentet på innodb_support_xa , kanske för att det skrevs om aktien innodb 5.0.3 långt före samtidighetsfixet), och överensstämmelse mellan innodb-logg på mastern och relälogg på slaven är inte strikt garanterad ens med innodb_support_xa , jag ser ingen mening med att använda innodb_support_xa . Det är dock läskigt att inte följa den officiella rekommendationen, men den verkar inaktuell och felaktig på många punkter.

Jag undrar om det finns någon korrelation mellan innodb_flush_log_at_trx_commit inställningen och innodb_support_xa beteende när den förra är inställd på 2 eller 0.

Ett praktiskt sätt att tänka är att failover till slaven är säkert - trots allt var den misslyckade transaktionen något som du ville få gjort - men aldrig fail-back till master, eftersom det kan finnas en viss diskrepans i data. Du måste helt kopiera data från slaven innan du gör mastern till en ny slav. Med andra ord, när mastern kraschade, lita på slaven från och med då - på så sätt behöver du inte bråka med innodb-loggen för att återställa krascharna.

Notera också att MySQL 5.5 stöder semi-synkron replikering, på samma sätt som "lita på slaven" - tänkte att du kunde vara intresserad.

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




  1. MySQL-val verkar väldigt långsamt men kan inte tänka på hur man ska förbättra?

  2. Android sqlite, begränsa antalet rader i databasen

  3. MySQL LOAD_FILE returnerar NULL

  4. Hur väljer man snabbt 3 slumpmässiga poster från en 30k MySQL-tabell med ett where-filter med en enda fråga?