Pergunta

Eu tenho um banco de dados que tenho a intenção de replicar por motivos de backup (desempenho não é um problema no momento).

Nós criamos a replicação corretamente e testou-o e tudo estava bem.

Então percebemos que ele replica todas as gravações para as tabelas temporárias, o que na prática significava que a replicação do vale um dia de dados levou quase duas horas para o escravo ocioso.

A razão para isso é que nós recalcular alguns dos dados em nossas db via cron a cada 15 minutos para garantir que ele está em sincronia (leva ~ 3 minutos no total, por isso é inaceitável para fazer essas operações durante uma solicitação da web; em vez disso, apenas armazenar as modificações sem tentar recalcular nada enquanto no pedido web, e depois fazer todo o trabalho a granel). Para processar esses dados de forma eficiente, usamos tabelas temporárias (como há muitas interdependências).

Agora, o primeiro problema é que as tabelas temporárias não persistem se reiniciar o servidor enquanto ele está no meio de processamento de transações que usam esse tabela temporária. Isso pode ser evitado por não usar tabelas temporárias, embora isso tem seus próprios problemas.

O problema mais grave é que o escravo poderia facilmente recuperar o atraso em menos de meia hora, se não fosse por tudo o que recomputation (o que faz um após o outro, então não há nenhum benefício de reconstruir os dados a cada 15 minutos ... e você pode literalmente vê-lo preso em, digamos, 1115, só para rapidamente recuperar o atraso e ficou preso em 1130 etc).

Uma solução que surgiu com é passar tudo o que recomputation fora do db replicado, de modo que o escravo não replicá-la. Mas tem desvantagens em que teríamos que podar as tabelas que, eventualmente, atualizações, fazer o nosso escravo no efeito "castrado", ie. nós teríamos que tudo recalcular nele antes que pudéssemos realmente usá-lo.

Será que alguém tem um problema semelhante e / ou como você resolvê-lo? Estou faltando alguma coisa óbvia?

Foi útil?

Solução

Eu vim com a solução. Ele faz uso de replicar-do-db mencionado por Nick. Escrevê-la aqui no caso de alguém tinha um problema semelhante.

O problema com apenas usando replicate- (wild-) fazer opções * no presente caso (como eu disse, nós usamos tabelas temporárias para repovoar uma mesa central) é que ou você ignorar tabelas temporárias e repovoar o central sem dados (que causa mais problemas como todas as consultas baseando-se na mesa central sendo up-to-date irá produzir resultados diferentes) ou você ignorar a mesa central, que tem um problema semelhante. Para não mencionar, você tem que reiniciar mysql após a adição de qualquer uma dessas opções para my.cnf. Queríamos algo que iria cobrir todos os casos (e os futuros) sem a necessidade de qualquer outra reinicialização.

Então, o que nós decidimos fazer é dividir o banco de dados para a um banco de dados "WorkArea" "real" e. Apenas o banco de dados "real" é replicado (eu acho que você poderia decidir sobre uma convenção de nomes de tabela a ser utilizada para replicar-wild-do-table sintaxe).

Todo o trabalho tabela temporária está acontecendo em db "WorkArea", e para evitar o problema de dependência mencionado acima, não vamos preencher a tabela central (que fica no db "real") por INSERT ... SELECT ou RENAME TABLE, mas sim consultar as tabelas tmp para gerar uma espécie de diff na mesa ao vivo (ie. gerar instruções INSERT para novas linhas, DELETE para os antigos e atualização quando necessário).

Desta forma, as únicas perguntas que são replicados são exatamente as atualizações que são necessários, nada mais, ou seja. alguns (a maioria?) das consultas recálculo hapenning cada quinze minutos pode até não fazer a sua maneira de escravo, e os que fazem será mínima e não computacionalmente caro a todos, apenas INSERTs simples e exclui.

Outras dicas

Em MySQL, a partir de 5.0 acredito, você pode fazer wildcards tabela para tabelas específicas replicados. Há uma série de opções de linha de comando que podem ser definidas, mas você também pode fazer isso através de seu arquivo MySQL configuração.

[mysqld]
replicate-do-db    = db1
replicate-do-table = db2.mytbl2
replicate-wild-do-table= database_name.%
replicate-wild-do-table= another_db.%

A idéia é que você diga a ele para não replicar qualquer outro do que as que especificam tabelas.

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