Om te beginnen...
http://yoshinorimatsunobu.blogspot.com/2009 /08/great-performance-effect-of-fixing.html
Vóór InnoDB Plugin 1.0.4 was het als volgt:
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
Op en na InnoDB Plugin 1.0.4 (en MySQL 5.5), is het 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
Zoals je kunt zien, is er in de nieuwe versie niets (behalve in het geval sync_binlog
> 0) is gefsynchroniseerd in de kritieke sectie. Op die manier werkt groepstoezegging nu en zorgt voor een veel betere gelijktijdige doorvoer.
Bijvoorbeeld, met de vorige "gebroken" versie, als je 100 threads gelijktijdige commits had, waren alle fsyncs geserialiseerd en zou je 100 fsyncs krijgen voor voorbereiding en nog eens 100 fsyncs voor commit. Daarom was de groepstoezegging volledig verbroken.
Met de nieuwere implementatie worden fsyncs nu gegroepeerd op basis van de gelijktijdigheid van transacties, terwijl de volgorde van bewerkingen tussen innodb log en binlog wordt gegarandeerd. Het betekent ook dat als er maar één thread is, er geen prestatiewinst is.
Wat betreft uw vraag dat, wanneer een crash optreedt nadat een transactie naar de binlog is geschreven, maar voordat deze naar de transactielog is geschreven, ik op dezelfde pagina zit als u.
Als de server crashte voor de laatste stap, is er een kleine kans dat je een discrepantie hebt tussen innodb log en binlog (de een kan voorlopen op de ander), maar het is gegarandeerd dat je alle informatie hebt over wat je moet doen. onderzoeken in het innodb-logboek, zoals het is vastgelegd in de voorbereidingsfase.
Wat te doen met de niet-gecommitteerde is echter nog steeds niet deterministisch. Bijvoorbeeld, tenzij sync_binlog = 1
er is een kans dat een slave de gegevens heeft ontvangen maar de binlog nog niet volledig op de master heeft gesynchroniseerd. U kunt de mislukte transactie niet zomaar opnieuw doen, omdat deze mogelijk al op een van de slaven is uitgevoerd.
Wat ook betekent dat de binlog korter kan zijn dan de innodb-log, met als resultaat "De binaire log [bestandsnaam] is korter dan de verwachte grootte." zoals beschreven in het officiële document, en je moet de slaaf helemaal opnieuw opbouwen. Niet erg mensvriendelijk.
http://dev.mysql.com/doc/refman /5.1/nl/binary-log.html
Omdat consistentie in de volgorde van bewerkingen wordt gegarandeerd, onafhankelijk van de innodb_support_xa
instelling (die in tegenspraak is met wat wordt gezegd in het officiële document op innodb_support_xa
, misschien omdat het is geschreven over de standaard innodb 5.0.3 ver voor de concurrency fix), en consistentie tussen innodb log op de master en relais log op de slave is niet strikt gegarandeerd, zelfs niet met innodb_support_xa
, ik zie geen enkel punt in het gebruik van innodb_support_xa
. Het is echter eng om de officiële aanbeveling niet op te volgen, maar het lijkt op veel punten muf en verkeerd.
Ik vraag me af of er een verband is tussen de innodb_flush_log_at_trx_commit
instelling en de innodb_support_xa
gedrag wanneer de eerste is ingesteld op 2 of 0.
Een praktische manier van denken is dat failover naar de slave veilig is - de mislukte transactie was immers iets dat je gedaan wilde hebben - maar faal nooit terug naar de master, aangezien er enige discrepantie in de gegevens kan zijn. U moet de gegevens van de slave volledig kopiëren voordat u van de master een nieuwe slave maakt. Met andere woorden, wanneer de master crashte, vertrouw dan vanaf dat moment op de slave - op die manier hoef je niet te rommelen met innodb log voor crashherstel.
Merk ook op dat MySQL 5.5 semi-synchrone replicatie ondersteunt, in dezelfde lijn als "vertrouw de slaaf" - dacht dat je misschien geïnteresseerd zou zijn.
http://dev.mysql.com/doc/refman /5.5/nl/replicatie-semisync.html