RDS staat zelfs de hoofdgebruiker de SUPER
. niet toe privilege, en dit is vereist om FLUSH TABLES WITH READ LOCK
uit te voeren . (Dit is een ongelukkige beperking van RDS).
De foutieve instructie wordt gegenereerd door de --master-data
optie, wat natuurlijk nodig is als je de precieze binlog-coördinaten wilt leren waar de back-up begint. FLUSH TABLES WITH READ LOCK
verkrijgt een globale leesvergrendeling op alle tabellen, waardoor mysqldump START TRANSACTION WITH CONSISTENT SNAPSHOT
(zoals het doet met --single-transaction
) en dan SHOW MASTER STATUS
om de binaire log-coördinaten te verkrijgen, waarna het de globale leesvergrendeling vrijgeeft omdat het een transactie heeft die de zichtbare gegevens in een staat houdt die consistent is met die logpositie.
RDS doorbreekt dit mechanisme door de SUPER
. te weigeren privilege en biedt geen duidelijke oplossing.
Er zijn enkele hacky-opties beschikbaar om dit op de juiste manier te omzeilen, maar geen van alle is bijzonder aantrekkelijk:
-
doe de back-up tijdens een periode met weinig verkeer. Als de binlog-coördinaten niet zijn gewijzigd tussen het moment dat u de back-up start en nadat de back-up is begonnen met het schrijven van gegevens naar het uitvoerbestand of de doelserver (ervan uitgaande dat u
--single-transaction
hebt gebruikt ) dan zal dit werken omdat je weet dat de coördinaten niet veranderden terwijl het proces liep. -
observeer de binlog-positie op de master vlak voordat u de back-up start en gebruik deze coördinaten met
CHANGE MASTER TO
. Als hetbinlog_format
. van uw master is ingesteld opROW
dan zou dit moeten werken, hoewel u waarschijnlijk een paar initiële fouten zult moeten overslaan, maar daarna geen fouten meer zou moeten hebben. Dit werkt omdat op rijen gebaseerde replicatie erg deterministisch is en stopt als het iets probeert in te voegen dat er al is of iets probeert te verwijderen dat al weg is. Eenmaal voorbij de fouten, bevindt u zich op de echte binlog-coördinaten waar de consistente momentopname daadwerkelijk begon. -
zoals in het vorige item, maar probeer na het herstellen van de back-up de juiste positie te bepalen met behulp van
mysqlbinlog --base64-output=decode-rows --verbose
om het binlog van de master te lezen op de coördinaten die je hebt verkregen, controleer je nieuwe slave om te zien welke van de gebeurtenissen al moeten zijn uitgevoerd voordat de snapshot daadwerkelijk begon, en gebruik de coördinaten die op deze manier zijn bepaald omCHANGE MASTER TO
. -
gebruik een extern proces om een leesvergrendeling op elke tafel op de server te verkrijgen, waardoor alle schrijfbewerkingen worden gestopt; merk op dat de binlog-positie van
SHOW MASTER STATUS
is gestopt met ophogen, start de back-up en ontgrendel die vergrendelingen.
Als je een van deze benaderingen gebruikt, behalve misschien de laatste, is het vooral van cruciaal belang dat je tabelvergelijkingen maakt om er zeker van te zijn dat je slave identiek is aan de master als deze eenmaal draait. Als je volgende replicatiefouten tegenkomt... dan was dat niet het geval.
Waarschijnlijk de veiligste optie -- maar misschien ook de meest irritante aangezien het lijkt alsof het niet nodig zou moeten zijn -- is om te beginnen met het maken van een RDS-leesreplica van uw RDS-master. Zodra het is geactiveerd en is gesynchroniseerd met de master, kunt u de replicatie op de RDS-leesreplica stoppen door een door RDS geleverde opgeslagen procedure uit te voeren, CALL mysql.rds_stop_replication
die werd geïntroduceerd in RDS 5.6.13 en 5.5.33 waarvoor de SUPER
. niet vereist is voorrecht.
Terwijl de RDS-replica-slave is gestopt, neemt u uw mysqldump
van de RDS-leesreplica, die nu een onveranderlijke dataset zal hebben vanaf een specifieke set hoofdcoördinaten. Zet deze back-up terug op uw off-site slave en gebruik vervolgens de RDS-replica's hoofdcoördinaten van SHOW SLAVE STATUS
Exec_Master_Log_Pos
en Relay_Master_Log_File
als uw CHANGE MASTER TO
coördinaten.
De waarde getoond in Exec_Master_Log_Pos
op een slave is de start van de volgende transactie of gebeurtenis die moet worden verwerkt
, en dat is precies waar je nieuwe slave moet beginnen met lezen op de master.
Vervolgens kunt u de RDS-leesreplica buiten gebruik stellen zodra uw externe slave in gebruik is.