P>

Capa SQl 33

Clique aqui para ler todos os artigos desta edição

Técnicas avançadas de replicação no MySQL

Giuseppe Maxia

Você já deve ter ouvido falar a respeito do MySQL Cluster, que é uma arquitetura para se conseguir disponibilidade e desempenho elevados. Uma das vantagens do MySQL Cluster é que cada nó é par de um outro nó, visto que em um sistema de replicação normal, temos um nó mestre e muitos “escravos”, e as aplicações devem escrever somente para o nó mestre.

As principais desvantagens do MySQL Cluster (assim como do MySQL 5.0) são:

·         O banco de dados trabalha somente em memória, requerendo assim mais recursos do que um banco de dados normal MySQL (o MySQL 5.1 introduz table spaces com a capacidade de armazenamento de dados não indexados no disco);

·         Algumas características como buscas full-text, integridade referencial e níveis da isolação da transação mais elevados do que o READ COMMITTED, não estão disponíveis.  

 

Existem alguns casos onde o MySQL Cluster é a solução perfeita, porém na maioria, a replicação ainda é a melhor escolha. A replicação, no entanto, também tem seus problemas:

·         Há uma distinção entre o nó mestre e os nós escravos. As aplicações devem estar alertas às replicações, de modo que escreverão no mestre e lerão dos escravos.

·         Existe o problema do fail-over. Quando o nó mestre falha, teremos os nós escravos prontos para substituí-los, porém o processo de detectar a falha e agir de forma correta requer a intervenção do administrador.

 

Este artigo objetiva apresentar meios de lidar com estas características falhas. Utilizando as características introduzidas no MySQL 5.0 e 5.1, é possível construir um sistema de replicação onde todos os nós trabalhem como mestre e escravo ao mesmo tempo, com um mecanismo de fail-over embutido.

Configurando um sistema de replicação Multimaster

Vamos considerar a situação em que configuramos um sistema de replicação com mais de um nó mestre. Um problema difícil de resolver em uma replicação multimaster é o conflito que pode acontecer com chaves geradas automaticamente. O AUTO_INCREMENT é completamente conveniente, porém, em um ambiente de replicação, será prejudicial. Se ambos os nós A e B inserem uma chave com esta característica na mesma tabela, os conflitos surgem imediatamente.

A solução para este problema está nas versões mais recentes do MySQL. A versão 5 introduz um par de variáveis de servidor para auto-increment replicado que resolve este problema específico e permite a criação de um array de nós peer-to-peer com replicação MySQL. Citando o manual:

·         auto_increment_increment controla o incremento entre valores sucessivos de AUTO_INCREMENT;

·         auto_increment_offset determina o ponto de início para valores da coluna de AUTO_INCREMENT.  

 

Escolhendo valores não conflitantes para estas variáveis em nós mestres diferentes, os servidores em uma configuração multimaster não utilizarão valores conflitantes de AUTO_INCREMENT ao inserir novas linhas na mesma tabela. Para configurar os N servidores mestre, configuramos as variáveis da seguinte maneira:

·         Configurar o auto_increment_increment para N em cada mestre.  

·         Configurar cada um dos N nós mestres para que tenham um auto_increment_offset diferente, utilizando os valores 1, 2…, N.

 

Utilizando estas duas variáveis como descrito no manual, garantimos que todos os nós no array de replicação utilizem seqüências diferentes de números de auto-incremento. Por exemplo, utilizando auto_increment_increment = 10 e auto_increment_offset = 3, os números gerados quando inserirmos três registros serão 3, 13 e 23. Utilizando 10 e 7, obteremos 7, 17, 27 e assim por diante.

Para um array de quatro nós, configuramos o auto_increment_increment com 10 para cada nó e o auto_increment_offset para 1 no primeiro nó, 2 para o segundo nó e assim por diante.

Isto está teoricamente claro, porém, ainda não está claro como iremos transformar estes servidores em nós peer-to-peer. A resposta é uma replicação circular, onde cada nó é o mestre do nó seguinte e escravo do nó anterior.

Replicação circular com dois nós

Na sua forma mais simples, a replicação circular tem dois nós, onde cada um é ao mesmo tempo mestre e escravo do outro (Figura 1).

 

image002.gif


Figura 1. Replicação circular entre dois nós.

 

Para este teste, utilizamos dois servidores da empresa (water e air, logo serão acrescidos mais dois chamados fire e earth). Sua configuração básica é apresentada na Listagem 1.

 

Listagem 1. Configuração básica dos servidores.

# nó a - (water) setup

[mysqld]

server-id                       = 10

# auto_increment_increment      = 10

# auto_increment_offset         = 1

master-host                     = air.stardata.it

master-user                     = nodeAuser

master-password                 = nodeApass

 

# nó B - (air) setup

[mysqld]

server-id                       = 20

# auto_increment_increment      = 10

# auto_increment_offset         = 2

master-host                     = water.stardata.it

master-user                     = nodeBuser

master-password                 = nodeBpass

 

Preste atenção nas duas variáveis nos arquivos de configuração. Se omitirmos tais variáveis, ou as comentarmos, como neste exemplo, então algo incorreto pode acontecer e as circunstâncias infelizes são fáceis de demonstrar. Lembre que a replicação do MySQL é assíncrona. Isto significa que o processo de replicação no nó escravo pode acontecer em um momento diferente do que a que está ocorrendo no nó mestre. Esta característica torna a replicação mais flexível e garante que mesmo que ocorra uma quebra de conexão entre os nós mestre e escravo, a replicação continuará quando a conexão do nó escravo for restabelecida. Entretanto, esta característica tem um efeito colateral desagradável quando lidamos com valores auto-incrementados. Supondo que temos a tabela apresentada na Listagem 2.

 

Listagem 2: Tabela para teste.

CREATE TABLE x (

    id int(11) NOT NULL AUTO_INCREMENT,

    c char(10) DEFAULT NULL,

    PRIMARY KEY (id)

  ) ENGINE=MyISAM DEFAULT CHARSET=latin1

 

Supondo também que a conexão entre o nó A e o nó B é interrompida por um momento. Considere ainda que fosse executada uma declaração INSERT em ambos os servidores, enquanto a replicação não estiver funcionando e as variáveis auto_increment não estavam configuradas (Listagem 3).

 

Listagem 3. Inserção de valores nos nós A e B.

 

[nó A]   insert into x values (null, 'aaa'), (null, 'bbb'), (null, 'ccc');

 

[nó B]   insert into x values (null, 'xxx'), (null, 'yyy'), (null, 'zzz');

 

Quando a replicação for reiniciada, obteremos um erro de bloqueio em ambos os nós conforme apresenta a Listagem 4.

 

Listagem 4. Erro de bloqueio.

Error 'Duplicate entry '1' for key 'PRIMARY'' on query. Default database:

    'test'. Query: 'insert into x values (null, 'aaa')'

 

É fácil descobrir a razão, como pode ser verificado na Listagem 5.

 

Listagem 5. Resultado da inserção de novos dados.

[nó A] select * from x;

+----+------+ ...

Quer ler esse conteúdo completo? Tenha acesso completo