Domanda

Sono attualmente in esecuzione mysqldump su uno slave Mysql per il backup nostro database. Questo ha funzionato bene per il backup dei nostri dati in sé, ma quello che vorrei integrare con è la posizione log binario del master che corrisponde con i dati generati dal mysqldump.

In questo ci consentirebbe di ripristinare il nostro schiavo (o Imposta nuovi schiavi) senza dover fare un mysqldump separato sul database principale dove ci afferra la posizione log binario del master. Ci sarebbe solo prendere i dati generati dal mysqldump, si combinano con le informazioni log binario abbiamo generato, e voilà ... essere risincronizzate.

Finora, la mia ricerca ha ottenuto me molto vicino ad essere in grado di raggiungere questo obiettivo, ma io non riesco a capire un metodo automatico per tirarlo fuori. Qui ci sono i "almosts" ho scoperto:

  • Se stavamo correndo mysqldump dal database principale, potremmo usare il parametro "--master-data" con mysqldump per registrare la posizione binario del master insieme ai dati di dettaglio (Presumo che questo sarebbe probabilmente funzionerà anche se abbiamo iniziato a generare i log binari dal nostro schiavo, ma che sembra eccessivo per quello che vogliamo realizzare)
  • Se volessimo fare questo in modo non automatizzato, potremmo accedere al database del servo ed eseguire "STOP SLAVE SQL_THREAD;" seguito da "SHOW SLAVE STATUS;" ( http://dev.mysql.com/doc/refman/5.0/ it / mysqldump.html ). Ma questo non ha intenzione di fare noi nulla di buono se non sappiamo in anticipo che vogliamo eseguire qualcosa dal salve.
  • Se avessimo 500 $ / anno a soffiare, potremmo usare il plugin backup a caldo InnoDB e basta eseguire i nostri mysqldumps dal DB principale. Ma non abbiamo quei soldi, e non voglio aggiungere alcun I / O in più sul nostro principale DB comunque.

Questo mi sembra una cosa abbastanza comune che qualcuno deve aver capito prima, si spera che qualcuno sta usando Stack Overflow?

È stato utile?

Soluzione

Il seguente script di shell verrà eseguito in cron o periodica, sostituire le variabili come necessario (default sono scritte per FreeBSD):

# MySQL executable location
mysql=/usr/local/bin/mysql

# MySQLDump location
mysqldump=/usr/local/bin/mysqldump

# MySQL Username and password
userpassword=" --user=<username> --password=<password>"

# MySQL dump options
dumpoptions=" --quick --add-drop-table --add-locks --extended-insert"

# Databases
databases="db1 db2 db3"

# Backup Directory
backupdir=/usr/backups

# Flush and Lock
mysql $userpassword -e 'STOP SLAVE SQL_THREAD;'

set `date +'%Y %m %d'`

# Binary Log Positions
masterlogfile=`$mysql $userpassword -e 'SHOW SLAVE STATUS \G' | grep '[^_]Master_Log_File'`
masterlogpos=`$mysql $userpassword -e 'SHOW SLAVE STATUS \G' | grep 'Read_Master_Log_Pos'`

# Write Binlog Info
echo $masterlogfile >> ${backupdir}/info-$1-$2-$3.txt
echo $masterlogpos >> ${backupdir}/info-$1-$2-$3.txt

# Dump all of our databases
echo "Dumping MySQL Databases"
for database in $databases
do
$mysqldump $userpassword $dumpoptions $database | gzip - > ${backupdir}/${database}-$1-$2-$3.sql.gz
done

# Unlock
$mysql $userpassword -e 'START SLAVE'

echo "Dump Complete!"

exit 0

Altri suggerimenti

Anche se la sceneggiatura di Ross è sulla strada giusta, @joatis ha ragione quando dice che per fermare lo schiavo prima di verificare la posizione di registro master. Il motivo è la LEGGI blocco non manterrà la Read_Master_Log_Pos che viene recuperato con SHOW SLAVE STATUS.

Per vedere che questo è il caso, accedere al MySQL sul vostro schiavo ed eseguire:

FLUSH TABLES WITH READ LOCK

SHOW SLAVE STATUS \G

Si noti la Read_Master_Log_Pos

Attendere qualche secondo e ancora una volta eseguire:

SHOW SLAVE STATUS \G

Si dovrebbe notare che il Read_Master_Log_Pos è cambiato.

Dato che il backup viene avviato subito dopo che controlliamo lo stato, la posizione di registro registrata dallo script può essere accurata. Tuttavia, la sua prefereable invece di seguire la procedura qui: http://dev.mysql.com/doc /refman/5.0/en/replication-solutions-backups-mysqldump.html

E correre STOP SLAVE SQL_THREAD; invece di FLUSH TABLES WITH READ LOCK per tutta la durata del backup.

Una volta fatto, ripartire la replica con START SLAVE

Inoltre, se si desidera eseguire il backup dei bin-log per i backup incrementali o come misura di sicurezza in più, è utile per aggiungere --flush-log per la variabile $ dumpoptions sopra

Sei seconda opzione sembra la strada giusta.

Ho dovuto trovare un modo per fare i backup differenziali utilizzando mysqldump. Ho finito per scrivere uno script che ha scelto ciò che database per eseguire il backup e quindi eseguito mysqldump. Non potreste creare uno script che ha seguito le fasi di cui al http://dev.mysql.com/doc/refman/5.1/en/mysqldump.html#option_mysqldump_master-data e chiamare che da un lavoro cron?

  1. connettersi a MySQL e "stop slave"
  2. execute SHOW SLAVE STATUS
  3. negozio nome_file, file_pos nelle variabili
  4. discarica e riavviare lo schiavo.

Solo un pensiero ma credo si possa aggiungere il "CHANGE MASTER TO" linea al file di dump e sarebbe ottenere eseguito quando è stato ripristinato / impostare il nuovo schiavo.

Utilizzo Read_Master_Log_Pos come la posizione di continuare dal master significa che è possibile finire con dati mancanti.

La variabile Read_Master_Log_Pos è la posizione nel file di log binario padrone che lo schiavo filo IO è fino a.

Il problema è che, anche in piccola quantità di tempo tra l'arresto processi SQL slave e retreiving le Read_Master_Log_Pos il filo IO eventualmente ricevute più dati dal master che non è stato applicato dal filo SQL essendo stato fermato.

Si ottengono così i Read_Master_Log_Pos essendo più avanti rispetto ai dati restituiti nel mysqldump, lasciando un vuoto nei dati quando importato e continua alla altro schiavo.

Il valore corretto da utilizzare nello slave è Exec_Master_Log_Pos, che è la posizione nel file di registro binario master che il filo SQL schiavo ultimo eseguito, significa che non c'è divario dati tra il mysqldump ei Exec_Master_Log_Pos.

Utilizzando lo script di Ross sopra l'uso corretto sarebbe:

# MySQL executable location
mysql=/usr/bin/mysql

# MySQLDump executable location
mysqldump=/usr/bin/mysqldump

# MySQL Username and password
userpassword=" --user=<username> --password=<password>"

# MySQL dump options
dumpoptions=" --quick --add-drop-table --add-locks --extended-insert"

# Databases to dump
databases="db1 db2 db3"

# Backup Directory
# You need to create this dir
backupdir=~/mysqldump


# Stop slave sql thread

echo -n "Stopping slave SQL_THREAD... "
mysql $userpassword -e 'STOP SLAVE SQL_THREAD;'
echo "Done."

set `date +'%Y %m %d'`

# Get Binary Log Positions

echo "Logging master status..."
masterlogfile=`$mysql $userpassword -e 'SHOW SLAVE STATUS \G' | grep '[^_]Master_Log_File'`
masterlogpos=`$mysql $userpassword -e 'SHOW SLAVE STATUS \G' | grep 'Exec_Master_Log_Pos'`

# Write log Info

echo $masterlogfile
echo $masterlogpos
echo $masterlogfile >> ${backupdir}/$1-$2-$3_info.txt
echo $masterlogpos >> ${backupdir}/$1-$2-$3_info.txt

# Dump the databases

echo "Dumping MySQL Databases..."
for database in $databases
do
echo -n "$database... "
$mysqldump $userpassword $dumpoptions $database | gzip - > ${backupdir}/$1-$2-$3_${database}.sql.gz
echo "Done."
done

# Start slave again

echo -n "Starting slave... "
$mysql $userpassword -e 'START SLAVE'
echo "Done."

echo "All complete!"

exit 0

mysqldump (su 5.6) sembra avere un'opzione --dump-slave che, quando eseguito su uno slave registra i binari di registro co-ords del maestro che il nodo era uno schiavo di. L'intento di tale discarica è esattamente ciò che si sta descrivendo.

(sono in ritardo, lo so)

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top