P: Como eu configuro um slave se o master já estiver em execução e eu não quiser pará-lo?
R: Existem diversas opções.
Se você tirou um backup do master em alguns pontos e gravou o
nome e offset do log binário (da saída do SHOW MASTER
STATUS
) correspondente à cópia, faça o seguinte:
Esteja certo de que o slave possuí um ID server único.
Execute as seguintes instruções no slave, preenchendo os valores apropriados para cada parâmetro:
mysql>CHANGE MASTER TO
->MASTER_HOST='master_host-name',
->MASTER_USER='master_user_name',
->MASTER_PASSWORD='master_pass',
->MASTER_LOG_FILE='recorded_log_name',
->MASTER_LOG_POS=recorded_log_pos;
Execute START SLAVE
no slave.
Se você já não tiver um backup do master, aqui está um modo rápido de fazê-lo de forma consistente:
FLUSH TABLES WITH READ LOCK
gtar zcf /tmp/backup.tar.gz
/var/lib/mysql
( ou uma variação disto)
SHOW MASTER STATUS
- esteja certo de
gravar a saída - você precisará dela mais tarde
UNLOCK TABLES
Uma alternativa é tirar um dump do SQL do master em vez de uma
cópia binária como acima; para isto você podee usar
mysqldump --master-data
em seu master e
posteriormente executar este dump SQL em seu slave. Isto é, no
entanto, mais lento que fazer uma cópia binária.
Não importa qual dos dois métodos você usa, mais tarde siga as instruções para o caso em que você tem uma cópia e gravou o nome e offset dos logs Você pode usar a mesma cópia para configurar diversos slaves. Uma vez que os logs binários do master estão intáctos, você pode esperar por dias ou meses para configurar um slave uma vez que você possui a cópia do master. Em teoria a lacuna de espera pode ser infinita. As duas limitações práticas é o espaço em disco do master sendo preenchido com logs antigos e a quantidade de tempo que o slave gastará para buscá-los.
Você também pode usar LOAD DATA FROM
MASTER
. Este é um comando conveniente que tira uma
cópia, a restaurá no slave e ajustar o nome e offset do log no
slave, todos de uma vez. No futuro, LOAD DATA FROM
MASTER
será o modo recomendado de configurar um
slave. Esteja avisado, no entanto, que o lock de leitura pode
ser mantido por um longo tempo se você usar este comando. Ele
ainda não está implementado de forma tão eficiente quanto
gostariamos. Se você tiver tabelas grandes, o método
preferível neste momento ainda é com uma cópia
tar
local depois de executar FLUSH
TABLES WITH READ LOCK
.
P: O slave precisa estar conectado ao master o tempo todo?
R: Não, ele não precisa. O slave pode ser desligado ou permanecer desconectado por horas ou mesmo dias, então reconecta e busca as atualizações. Por exemplo, você pode usar uma relação master/slave sobre uma conexão dial-up que está ligada esporádicamente apenas por um curto período de tempo. A implicação disto é que a uma hora dada qualquer não temos garantias de que o slave está sincronizado com o master a menos que você tire algumas medidas especiais. No futuro, teremos a opção de bloquear o master até que pelo menos um slave esteja sincronizado.
P: Como posso saber se um slave está atrasado comparado ao master? Em outra palavras, como eu sei que o dado da última consulta replicada pelo escravo?
R: Se o slave for 4.1.1 ou mais
novo, leia a coluna Seconds_Behind_Master
de
SHOW SLAVE STATUS
. Para versão mais antigas
o seguinte se aplica. Isto só é possível se a thread salve de
SQL existir (p.ex. se ele for exibida em SHOW
PROCESSLIST
, see
Secção 4.11.3, “Detalhes de Implementação da Replicação”) (no MySQL
3.23: se a thread slave existir, p.ex. e mostrada em
SHOW PROCESSLIST
), e se ela executou pelo
menos um evento do master. Realmente, quando a thread slave de
SQL executa um evento lido do master, esta thread modifica seu
próprio tempo do timestamp do evento (é por isto que
TIMESTAMP
é bem replicado). Assim é
indicado na coluna Time
na saída de
SHOW PROCESSLIST
, o número de segundos entre
o timestamp do último evento replicado e o tempo real da
máquina slave. Vopcê podee usar isto para determinar a data do
último evento replicado. Note que se o seu slave foi
desconectado do master por uma hora e então reconectado, você
poderá ver uma vlaor de 3600 na coluna Time
para a thread slave de SQL em SHOW
PROCESSLIST
... Isto ocorreria porque o slave está
executando consultas de uma hora atrás.
P: Como eu forço o master a bloquear as atualizações até que o slave as busque?
R: Use o seguinte procedimento:
No master, execute estes comandos:
mysql>FLUSH TABLES WITH READ LOCK;
mysql>SHOW MASTER STATUS;
Grave o nome do log e o offset da saída da instução
SHOW
.
No slave, execute este comando, onde as coordenadas da
replicação que são os argumentos da função
MASTER_POS_WAIT()
são os valores
gravados nos passos anteriores:
mysql> SELECT MASTER_POS_WAIT('log_name', log_offset);
A instrução SELECT
será bloqueada até
que o slave alcance o arquivo de log e offset especificados.
Neste ponto, o slave estará em sincronia com o master e a
instrução irá retornar.
No master, execute a seguinte instrução para permitir que o master comece a processar atualizações novamente:
mysql> UNLOCK TABLES;
P: Sobre quais assuntos eu devo estar ciente ao configurar uma replicação de duas vias?
R: Atualmente a replicação do MySQL não suporta nenhum protocolo de locking entre master e slave para garantir a atomicidade de uma atualização distribuída (entre servidores). Em outras palavras, é possível para um cliente A fazer uma atualização para um co-master 1, e neste tempo, antes de propagar para o co-master 2, o cliente B pode fazer uma atualização para o co-master 2 que fará a atualização do cliente A funcionar diferentemente da que ele fez no co-master 1. Assim, quando a atualização do cliente A fizer a atualização para o co-master, ele produzirá tabelas que são diferentes daquelas que você tem no co-master 1, mesmo depois de todas as atualizações do co-master2 também terem sido propagadas. Por isso você não deve co-encadear dois servidores em uma replicação de duas vias, a menos que você possa assegurar que suas atualizações possem seguramente ocorrer em qualquer ordem, ou que de alguma forma você cuide de alguma forma a atualização fora de ordem no código do cliente.
Você também deve perceber que replicação de duas vias não melhorar em muito o desempenho, já que temos atualizações envolvidas. Ambos os servidores precisam fazer a mesma quantidade de atualizações cada, como se tivesse um servidor. A única diferença é que haverá uma pouco menos de contenção de lock, porque as atualizações originando em outro servidor serão serializadas em uma thread slave. mesmo assim, este benefício pode ser por atrasos de rede.
P: Como eu posso usar replicação para melhorar a performance do meu sistema?
R: Você devev configurar um
servidor como master e direcionar todas as escritas para ele.
Então configure tantos slaves quantos você pode comprar e
instalar, e distribua as leituras entre o master e os slaves.
Você também pode iniciar os slaves com
--skip-bdb
,
--low-priority-updates
e
--delay-key-write=ALL
para conseguir aumento de
velocidade para o slave. Neste caso o slave usará tabelas
MyISAM
não transacionais em vez de tabelas
BDB
para conseguir mais velocidade.
Q: O que eu devo fazer para preparar o código do cliente em minhas próprias aplicações para usar replicação para melhora de performance?
A: Se a parte do seu código que for responsável pela acesso ao banco de dados tiver sido abstaído/modularizado apropriadamente, converte-lo para executar com uma configuração de replicação deve ser bem fácil. Apenas altere a implementação de seu acesso a banco de dados para enviar todas as escritas para o master e todas as leituras para o master e o slave. Se o seu código não tiver este nível de abstração, configurar um sistema de replicação lhe dará a oportunidade e motivação de limpá-lo. Você deve iniciar criando uma biblioteca ou módulo wrapper com as seguites funções:
safe_writer_connect()
safe_reader_connect()
safe_reader_query()
safe_writer_query()
safe_
no nome de cada função significa que
a função cuidará do tratamento de todas as condições de
erro.
Você pode, é claro, usar diferentes nomes para as funções. O importante é ter uma interface unificada para conexão para leitura, conexão para escrita, fazer uma leitura e fazer uma escrita.
Você deve então converter o código do seu cliente para usar a biblioteca wrapper. Este pode ser um processo doloroso e assustador a princípio, mas será gratificante a longo prazo. Todas as aplicações que usam a abordagem descrita poderão tirar vantagem de uma configuração master/slave, mesmo envolvendo vários slaves. O código será muito mais fácil de manter, e adicionar opções para soluções de problemas será trivial. Você só precisará modificar uma ou duas funções, por exemplo, para registrar quanto tempo uma consulta gastou ou qual consulta, entre todas elas, retornou um erro.
Se você já tiver escrito muito código, você pode querer
automatizar a conversão de tarefas usando o utilitário
replace
, que vem com a distribuição padrão
do MySQL, ou simplesmente escrever seu próprio script Perl.
Provavelmente, o seu código segue algum padrão de
reconhecimento. Se não, então talvez sejá melhor
reescrevê-lo ou pelo menos colocá-lo dentro de um padrão.
Q: Quando e em quanto a replicação do MySQL pode aumentar a performance do meu sistema?
A: A replicação do MySQL é mais benéfica para um sistema com leituras frequentes e escritas infrequentes. Em teoria, usando uma configuração um mastre/vários slaves você pode escalar o sistema adicionando mais slaves até que você fique sem largura de banda na rede, ou a sua carga de atualizações cresça ao ponto que o master não possa tratá-la.
Para determinar quantos slaves você pode ter antes dos
benefícios adicionados começarem a estabilzar e quanto você
pode melhorar o desempenho do seu site, você precisa saber o
padrão de suas consultas e determinar empiricamente (pelo
benchmark) a ralação entre a taxa nas leituras (leituras por
segundo, ou max_reads
) e nas escritas
(max_writes
) em um master e um slave comum. O
exemplo aqui lhe mostrará um calculo simplificado do que você
pode obter com replicação para o nosso sistema hipotético.
Vamos dizer que o sistema de cargas consiste de 10% de escrita e
90% de leitura, e determinamos max_reads
para
ser 1200 - 2 * max_writes
. Em outras
palavras, nosso sistema pode fazer 1200 leituras por segundo sem
nenhuma escrita, a escrita média é duas vezes mais lenta que a
leitura média e a realação é linear. Vamos supor que o
master e cada slave possuem a mesma capacidade, e temos 1 master
e N slaves. Então temos para cada servidor (master ou slave):
leituras = 1200 - 2 * escritas
(a partir do
benchmark)
leituras = 9* escritas / (N + 1)
(as
leituras são separadas, mas a escrita deve ir para todos os
servidores)
9*escritas/(N+1) + 2 * escritas = 1200
escritas = 1200/(2 + 9/(N+1)
Esta análise leva as seguintes conclusões:
Se N = 0 (que significa que não temos replicação) nosso sistema pode tratar 1200/11, cerca de 109, escritas por segundos (o que significa que teremos 9 vezes mais leituras devidos a natureza de nossa aplicação)
Se N = 1, podemos aumentar para 184 escritas por segundos.
Se N = 8, conseguimos 400.
Se N = 17, 480 escritas.
Eventualmente, a medida que N se aproxima de infinito (e seu orçamento de menos infinito), podemos chegar próximo a 600 escritas por segundo, aumentando o throughput do sistema em cerca de 5,5 vezes. No entanto, com apenas 8 servidores, já o aumentamos em quase 4 vezes.
Note que nossos calculos assumem uma largura de banda de rede infinita, e negligencia vários outros fatores que podiam se tornar significante em seu sistema. Em muitos casos, você pode não conseguir fazer um cálculo similar ao acima que irá predizer exatamente o que acontecerá em seus sistema se você adicionar N slaves de replicação. No entanto, responder as seguintes questões deve ajudá-lo a decidir quando e quanto a replicação aumentará a performance do seu sistema:
Qual a razão da leitura/escrita no seu sistema?
Quanto mais de carga de escrita um servidor pode tratar se você reduzir a leitura?
Para quantos slaves você tem largura de banda disponíovel em sua rede?
P: Como eu posso usar replicação para fornecer redundância/alta disponibilidade?
R: Com os recursos disponíveis atualmente, você teria que configurar um master e um slave (ou diversos slaves) e escrever um script que monitoraria o master para ver se ele está no ar e instruir as suas aplicações e os slaves do master a alterar no caso de falha. Sugestões:
Para dizer para um slave para alterar o master, use o
comando CHANGE MASTER TO
.
Um bom modo de manter sua aplicação informadas sobre a
localização do master é tendo uma entrada DNS dinâmica
para o master. Com bind
você pode usar
nsupdate
para atualizar dinamicamente o
seu DNS.
Você deve executar seus escravos com a opção
--log-bin
e sem
--log-slave-updates
. Deste modo o slave
estará pronto para se tornar um master assim que você
executar STOP SLAVE
; RESET
MASTER
, e CHANGE MASTER TO
em
outros slaves.
Por exemplo, considere que voceê tenha a seguinte configuração (``M'' representa o master, ``S'' o slave, ``WC'' o cliente que faz a leitura e escrita do banco de dados; clientes que fazem apenas a leitura do banco de dados bão são representadas já que elas não precisam trocar):
WC \ v WC----> M / | \ / | \ v v v S1 S2 S3
S1 (como S2 e S3) é um slave executando com
--log-bin
e sem
--log-slave-updates
. Como as únicas
escritas executada em S1 são aquelas replicadas de M, o log
binário em S1 é empty
(lembre-se, que S1 é executado sem
--log-slave-updates
). Então, por alguma
razão, M se torna indisponível, e você quer que o S1 se
torne o novo master (isto é, direciona todos os WC para S1
e faça S2 e S3 replicar em S1).
Certifique-se que todos os slaves processaram aqulquer
consulta em seus relay log. Em cada slave, execute
STOP SLAVE IO_THREAD
, então verifique a
saída de SHOW PROCESSLIST
até você ver
Has read all relay log
. Quando isto
ocorrer para todos os slaves, eles podem ser reconfigurados
para a nova configuração. Envie STOP
SLAVE
para todos os slaves, RESET
MASTER
no slave sendo promovido para master, e
CHANGE MASTER
nos outros slaves.
Nenhum WC acessa M. Instru todos os WCs a direcionar as suas
consultas para S1. De agora em diante, todas as consultas
enviadas por WC para S1 são escritas no log binário de S1.
O log binário de S1 contém exatamente todas as consultas
de escrita enviada para S1 desde que M foi finalizado. Em S2
(e S3) faça STOP SLAVE
, CHANGE
MASTER TO MASTER_HOST='S1'
(onde
'S1'
é substituido pelo nome de máquina
real de S1). Para CHANGE MASTER
, adicione
todas as informações sobre como conectar a S1 de S2 ou S3
(usuário, senha, porta). Em CHANGE
MASTER
, não é necessário especificar o nome do
log binário de S1 ou a sua posição: nós sabemos que ele
é o primeiro log binário, na posição 4, e estes são os
padrões de CHANGE MASTER
. Finalmente
faça START SLAVE
em S2 e S3, e agora
você terá isto:
WC / | WC | M(indisponível) \ | \ | v v S1<--S2 S3 ^ | +-------+
Quando M estiver ativo novamente, você só precisa enviar a
ele o mesmo CHANGE MASTER
enviado a S2 e
S3, assim que M se tornar um slave de S1 e pegar tudo que WC
gravou enquando ele estava desativado. Agora para tornarmos
M como master novamente (por exemplo, porque ela é a melhor
máquina), siga os procedimentos como se S1 estivesse
indisponível e M fosse o novo master; então durante o
procedimento não esqueça d executar RESET
MASTER
em M antes de tornar S1, S2, S3 como slaves
de M ou eles podem buscar escritas antigas de WC, antes da
indisponibilidade de M.
Atualmente estamos trabalhando na integração de um sistema de eleição de master autmotico dentro do MySQL, mas até que ele esteja pronto, você terá que criar suas próprias ferramentas de monitoramento.
This is a translation of the MySQL Reference Manual that can be found at dev.mysql.com. The original Reference Manual is in English, and this translation is not necessarily as up to date as the English version.