RDS tillåter inte ens huvudanvändaren SUPER
privilegium, och detta krävs för att FLUSH TABLES WITH READ LOCK
ska kunna köras . (Detta är en olycklig begränsning av RDS).
Den misslyckade satsen genereras av --master-data
alternativet, vilket naturligtvis är nödvändigt om du vill kunna lära dig de exakta binlogkoordinaterna där säkerhetskopieringen börjar. FLUSH TABLES WITH READ LOCK
skaffar ett globalt läslås på alla tabeller, vilket gör att mysqldump kan START TRANSACTION WITH CONSISTENT SNAPSHOT
(som det gör med --single-transaction
) och sedan SHOW MASTER STATUS
för att erhålla de binära loggkoordinaterna, varefter den släpper det globala läslåset eftersom det har en transaktion som kommer att hålla den synliga datan i ett tillstånd som överensstämmer med den loggpositionen.
RDS bryter denna mekanism genom att neka SUPER
privilegium och ger ingen uppenbar lösning.
Det finns några hackiga alternativ tillgängliga för att komma runt detta på rätt sätt, och inget av dem kan vara särskilt attraktivt:
-
gör säkerhetskopieringen under en period med låg trafik. Om binlog-koordinaterna inte har ändrats mellan det att du startar säkerhetskopieringen och efter att säkerhetskopieringen har börjat skriva data till utdatafilen eller destinationsservern (förutsatt att du använde
--single-transaction
) så kommer detta att fungera eftersom du vet att koordinaterna inte ändrades medan processen kördes. -
observera binlogpositionen på mastern precis innan du startar säkerhetskopieringen och använd dessa koordinater med
CHANGE MASTER TO
. Om din mastersbinlog_format
är inställd påROW
då borde detta fungera, även om du troligen kommer att behöva hoppa över några initiala fel, men du bör inte behöva ha några fel senare. Detta fungerar eftersom radbaserad replikering är mycket deterministisk och kommer att sluta om den försöker infoga något som redan finns där eller ta bort något som redan är borta. När du har passerat felen kommer du att vara vid de sanna binlog-koordinaterna där den konsekventa ögonblicksbilden faktiskt började. -
som i föregående punkt, men efter att ha återställt säkerhetskopian försök att bestämma rätt position genom att använda
mysqlbinlog --base64-output=decode-rows --verbose
för att läsa befälhavarens binlog på koordinaterna du fick, kontrollera din nya slav för att se vilka av händelserna som redan måste ha utförts innan ögonblicksbilden faktiskt startade, och använda koordinaterna som fastställts på detta sätt för attCHANGE MASTER TO
. -
använd en extern process för att få ett läslås på varje tabell på servern, vilket kommer att stoppa alla skrivningar; observera att binlogpositionen från
SHOW MASTER STATUS
har slutat öka, starta säkerhetskopieringen och släpp dessa lås.
Om du använder någon av dessa metoder förutom kanske den sista, är det särskilt viktigt att du gör tabelljämförelser för att vara säker på att din slav är identisk med mastern när den väl är igång. Om du träffar efterföljande replikeringsfel... så var det inte det.
Förmodligen det säkraste alternativet -- men kanske också det mest irriterande eftersom det verkar som att det inte borde vara nödvändigt -- är att börja med att skapa en RDS-läsreplika av din RDS-master. När den väl är uppe och synkroniserad med mastern kan du stoppa replikering på RDS-läsrepliken genom att köra en RDS-försedd lagrad procedur, CALL mysql.rds_stop_replication
som introducerades i RDS 5.6.13 och 5.5.33 som inte kräver SUPER
privilegium.
Med RDS-replikslaven stoppad, ta din mysqldump
från RDS-läsreplika, som nu kommer att ha en oföränderlig datauppsättning på sig som en specifik uppsättning masterkoordinater. Återställ denna säkerhetskopia till din off-site slav och använd sedan RDS-läs replikans huvudkoordinater från SHOW SLAVE STATUS
Exec_Master_Log_Pos
och Relay_Master_Log_File
som din CHANGE MASTER TO
koordinater.
Värdet som visas i Exec_Master_Log_Pos
på en slav är starten av nästa transaktion eller händelse som ska behandlas
, och det är precis där din nya slav måste börja läsa på mastern.
Sedan kan du ta ur RDS-läsreplikan när din externa slav är igång.