Pergunta

Atualmente estou executando mysqldump em um escravo MySQL para backup de nosso banco de dados. Isso tem funcionado muito bem para fazer backup de nossos dados em si, mas o que eu gostaria de completá-lo com é a posição do log binário do mestre que corresponde com os dados gerados pelo mysqldump.

Fazendo isso nos permitiria restaurar nosso escravo (ou configuração novos escravos) sem ter que fazer um mysqldump separada no banco de dados principal onde se agarrar a posição do log binário do mestre. Nós só iria pegar os dados gerados pelo mysqldump, combiná-lo com as informações de log binário geramos, e voila ... ser resynced.

Até agora, minha pesquisa tem me muito perto de ser capaz de atingir esta meta, mas eu não consigo descobrir uma maneira automatizada para retirá-la. Aqui estão os "almosts" eu descobri:

  • Se nós estávamos correndo mysqldump do banco de dados principal, poderíamos usar o parâmetro "--master-data" com mysqldump para fazer logon posição binária do mestre, juntamente com os dados de despejo (presumo que isso provavelmente também trabalho se começou a gerar logs binários de nosso escravo, mas que parece um exagero para o que nós queremos realizar)
  • Se quiséssemos fazer isso de uma forma não automatizada, poderíamos entrar em banco de dados do escravo e executar "STOP SLAVE SQL_THREAD;" seguido por "SHOW SLAVE STATUS;" ( http://dev.mysql.com/doc/refman/5.0/ en / mysqldump.html ). Mas isso não vai nos fazer nenhum bom a menos que sabemos de antemão que queremos de volta algo acima da pomada.
  • Se tivéssemos US $ 500 / ano para golpe, que poderia usar o InnoDB Plugin hot backup e basta executar nossos mysqldumps do DB principal. Mas não temos esse dinheiro, e eu não quero adicionar qualquer extra de I / O em nosso DB principal de qualquer maneira.

Este parece ser o suficiente algo comum que alguém deve ter descoberto antes, espero que alguém está usando Stack Overflow?

Foi útil?

Solução

A seguinte shell script será executado no cron ou periódica, substitua variáveis ??conforme necessário (defaults são escritos para 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

Outras dicas

Embora o roteiro de Ross está no caminho certo, @joatis é certo quando diz para parar o escravo antes de verificar a posição log mestre. A razão de ser é o READ LOCK não vai preservar a Read_Master_Log_Pos que é recuperado com SHOW SLAVE STATUS.

Para ver que este é o caso, entrar em MySQL em seu escravo e execute:

FLUSH TABLES WITH READ LOCK

SHOW SLAVE STATUS \G

Observe o Read_Master_Log_Pos

Aguarde alguns segundos e mais uma vez executar:

SHOW SLAVE STATUS \G

Você deve perceber que o Read_Master_Log_Pos mudou.

Uma vez que a cópia de segurança é iniciada rapidamente depois de verificar o estado, a posição log gravado pelo script pode ser preciso. No entanto, sua prefereable em vez de seguir o procedimento aqui: http://dev.mysql.com/doc /refman/5.0/en/replication-solutions-backups-mysqldump.html

E STOP SLAVE SQL_THREAD; execução em vez de FLUSH TABLES WITH READ LOCK para a duração do backup.

Quando terminar, iniciar a replicação novamente com START SLAVE

Além disso, se você deseja fazer o backup os bin-logs para backups incrementais ou como uma medida de segurança extra, é útil para anexar --flush-logs para a variável $ dumpoptions acima

Você é segunda opção parece com o caminho certo.

Eu tive que descobrir uma maneira de fazer backups diferenciais usando mysqldump. Acabei escrevendo um script que escolheu quais bancos de dados para backup e mysqldump então executado. você não poderia criar um script que seguiu os passos mencionados no http://dev.mysql.com/doc/refman/5.1/en/mysqldump.html#option_mysqldump_master-data e chamada que de um trabalho cron?

  1. conectar ao MySQL e "parada escravo"
  2. executar SHOW SLAVE STATUS
  3. loja file_name, file_pos nas variáveis ??
  4. despejo e reiniciar o escravo.

Apenas um pensamento, mas eu estou supondo que você pode adicionar a linha "CHANGE MASTER TO" para o dumpfile e seria obter executado quando restaurado / setup o novo escravo.

Usando Read_Master_Log_Pos como a posição para continuar a partir do meio mestre você pode acabar com dados em falta.

A variável Read_Master_Log_Pos é a posição no arquivo de log mestre binário que o escravo IO fio é até.

O problema aqui é que, mesmo na pequena quantidade de tempo entre o termo do processo SQL escravo e retreiving os Read_Master_Log_Pos o fio IO pode ter recebido mais dados do mestre que não tenha sido aplicado pela thread de SQL ter sido interrompido.

Isso resulta na Read_Master_Log_Pos estar mais à frente do que os dados retornados na mysqldump, deixando uma lacuna nos dados quando importados e continuou em outro escravo.

O valor correto para uso no escravo é Exec_Master_Log_Pos, que é a posição no arquivo de log mestre binário que a thread de SQL escravo última executada, significando que não há diferença de dados entre o mysqldump e os Exec_Master_Log_Pos.

Usando o roteiro de Ross acima do uso correto seria:

# 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 (em 5.6) parece ter uma opção --dump-escravo que, quando executado em um escravo registra os log co-ords binários do mestre que o nó era um escravo de. A intenção de tal despejo um é exatamente o que você está descrevendo.

(estou atrasado, eu sei)

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top