Mysql-cluster


Este tópico ira descrever como fazer um cluster mysql (master/master ou master/slave) no Linux, nesse exemplo utilizaremos o Ubuntu 12.04 Server, o mesmo pode ser aplicado em outras distribuição (com algumas singelas modificações).

Hardware necessário

Para fazer um cluster utilizando mysql é necessário pelo menos 2 computadores (ou vms), nessa página eu estarei usando as seguintes configurações:

* VMware - Ubuntu Server 12.04 LTS - 1 Processador - 1 GB de Ram - 10 GB espaço em disco - dbactive
* VMware - Ubuntu Server 12.04 LTS - 1 Processador - 1 GB de Ram - 10 GB espaço em disco - dbslave

Eu configurei manualmente o arquivo de hosts para:

bruce@dbactive:~$ cat /etc/hosts 127.0.0.1 localhost dbactive 169.254.254.11 dbstandby

e

bruce@dbactive:~$ cat /etc/hosts 127.0.0.1 localhost dbstandby 169.254.254.11 dbactive

Softwares instalados

Para realizar esse tutorial eu tive de instalar os seguintes pacotes - e suas respectivas dependências:

  • VIM (editor de texto, pode usar o nano se preferir - ou qualquer outro)
    • sudo apt-get install vim
  • Mysql Server
    • sudo apt-get install mysql-server

A configuração de IP foi fixa, para isso tive de alterar as configurações no arquivo:

/etc/network/intefaces

Usuários & Bancos de Dados

Bom vamos lá, para subirmos o cluster/replicação é necessário ter 2 coisas:

  • usuário com permissões de replicação
  • um ou mais bancos de dados para replicarmos as inforamções

Usuários

A permissão de replicação é dada com o seguinte comando

grant replication slave on DB.* to 'A'@'B';

Se voce não manjar de MySQL aqui vai a explicação:

  • on DB.* - quer dizer no banco DB em todas as tabelas, se quiser liberar para tudo basta por *.*
  • to ‘A’@‘B’ quer dizer: para o usuário A vindo do servidor B, troque B por % se quiser permitir que o usuário tenha essa permissão de qualquer localidade

Porém para essa página estaremos criando um usuário exclusivo para replicação, questões de boas práticas de segurança!

mysql> create user 'repB'@'%' identified by 'repB';
Query OK, 0 rows affected (0.00 sec)

mysql> grant replication slave on *.* to 'repB'@'%';
Query OK, 0 rows affected (0.00 sec)

Resolvi colocar para qualquer banco porque ainda não criamos o banco :P ps. identified by ‘inserir a senha aqui’

Banco de Dados

Sem segredos nessa parte, basta criarmos o nosso banco de dados, nesse caso ele será chamado de escola:

root@dbactive:/home/bruce# mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 37
Server version: 5.5.37-0ubuntu0.12.04.1-log (Ubuntu)

Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> create database escola;
Query OK, 1 row affected (0.00 sec)

Vamos criar uma tabela de teste, só para termos algum conteúdo

mysql> use escola
Database changed
mysql> create table professores (id int (11) auto_increment, nome varchar (200), email varchar (200), data_cadatro datetime, primary key(id));
Query OK, 0 rows affected (0.00 sec)
mysql> insert into professores values ('', 'Diego Ragazzi', 'd@ragazzid.com.br', now());
Query OK, 1 row affected, 1 warning (0.00 sec)

mysql> insert into professores values ('', 'Albert', 'contato@ragazzid.com.br', now());
Query OK, 1 row affected, 1 warning (0.00 sec)

mysql> show tables;
+------------------+
| Tables_in_escola |
+------------------+
| professores      |
+------------------+

mysql> select * from professores
    -> ;
+----+---------------+-------------------------+---------------------+
| id | nome          | email                   | data_cadatro        |
+----+---------------+-------------------------+---------------------+
|  1 | Diego Ragazzi | d@ragazzid.com.br       | 2014-07-14 19:19:18 |
|  2 | Albert        | contato@ragazzid.com.br | 2014-07-14 19:19:29 |
+----+---------------+-------------------------+---------------------+

Por hora isso basta, mais a frente vamos configura o cluster e sincronizar o backup!

Configurando a Replicação/Cluster

Com o banco de dados escolhido (escola) precisamos realizar as seguintes tarefas

  • editar a configuração do mysql para replicação / cluster
  • replicar o banco de dados no active para o standby

Habilitando a replicação

FAÇA ISSO PARA AMBOS OS SERVERS

Para habilitar a replicação é necessário editar o arquivo de configuração do mysql, no ubuntu server fica na em:

/etc/mysql/my.cnf

Comente a linha:

bind-address           = 127.0.0.1

Descomente as linhas:

  • server-id - coloque o server ID que quiser, basta ser um valor número e diferente de qualquer outro da sua rede
  • log_bin - pode mudar o local se quiser, mas recomendo que deixe como está para um primeiro contato
  • server-id mude para o nome do banco que deseja incluir na replicação
server-id              = 1002
log_bin                        = /var/log/mysql/mysql-bin.log
binlog_do_db            = escola

Salve os arquivos e reinicie o mysql:

sudo service mysql restart

ou

sudo /etc/init.d/mysql restart

ou

sudo /etc/init.d/mysqld restart

Replicando o banco de dados

Para fazer a replicação, basta um processo bem simples que é muito utilizado em backups, porém é comendável bloquear o banco de futuras altearções até que nosso cluster esteja em pé! Para isso, vamos bloquear as tabelas do nosso banco de edição e gerar um backup.

Bloquear as tabelas de edição:

mysql> use escola
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> FLUSH TABLES WITH READ LOCK;
Query OK, 0 rows affected (0.01 sec)

mysql> SET GLOBAL read_only = ON;
Query OK, 0 rows affected (0.00 sec)

Vamos agora criar um backup do nosso banco de dados para inserir o banco atual no standby

root@dbactive:/home/bruce# mysqldump -uroot -p escola > escola.sql
Enter password: 

Mande esse arquivo de alguem jeito pro standby, no meu caso vou usar scp

bruce@dbstanby>/home/bruce# scp escola.sql bruce@dbactive:/home/bruce/

Agora vamos criar o banco no standby e importar as tabelas e informações

bruce@dbstandby:~$ mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 37
Server version: 5.5.37-0ubuntu0.12.04.1-log (Ubuntu)

Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> create database escola;
Query OK, 1 row affected (0.00 sec)

mysql> exit
Bye
bruce@dbstandby:~$ mysql -uroot -p escola < escola.sql 
Enter password: 
bruce@dbstandby:~$ 

Pronto, agora é só subir o cluster :)

Subindo o Cluster

Para subir o cluster, basta definir quem vai ser quem (master / slave), nesse caso será:

  • dbactive será o master
  • dbslave será o slave

porém você pode deixar os 2 como master/master para ter um balanceamento de carga (se quiser), nesse tutorial eu escolhi os nomes active / standby por que vou usar esse mesmo cenário para um outro tutorial de MHA (Mysql High Availability)

Configurando o Master

No master, basta configurar uma sequência gigante de comandos de replicação para que o mysql receba qualquer modificação do master, portanto vamos fazer as alterações baixo no dbstandby

  • Primeiro, com o usuário e senha criados de replicação no dbactive, vamos inserir os seguintes comandos

    CHANGE MASTER TO MASTER_HOST='dbactive’, MASTER_USER='repA’, MASTER_PASSWORD='repA’, MASTER_LOG_FILE='mysql-bin.000002’, MASTER_LOG_POS=107;

Comando dado:

mysql> CHANGE MASTER TO
    ->    MASTER_HOST='dbactive',
    ->    MASTER_USER='repA',
    ->    MASTER_PASSWORD='repA',
    ->    MASTER_LOG_FILE='mysql-bin.000002',
    ->    MASTER_LOG_POS=107;
Query OK, 0 rows affected (0.02 sec)

mysql> slave start;
Query OK, 0 rows affected (0.00 sec)

Você obtem as informaçẽos acima digitando o seguinte comando no dbactive:

mysql> show master status;
+------------------+----------+--------------+------------------+
| File             | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000002 |      107 | compras      |                  |
+------------------+----------+--------------+------------------+
1 row in set (0.00 sec)

Do jeito que está a comunicação não será criptografada, porém você pode adicionar alguns recursos e SSL a brincadeira :)

Vamos liberar as tabelas para que possamos escrever coisas no dbactive

bruce@dbactive:~$ mysql -uroot -p
password:
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 39
Server version: 5.5.37-0ubuntu0.12.04.1-log (Ubuntu)

Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> SET GLOBAL read_only = off;
Query OK, 0 rows affected (0.00 sec)

Agora vamos deixar o ready_only no dbslave para evitar informações descontíguas

bruce@dbstandby:~$ mysql -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 43
Server version: 5.5.37-0ubuntu0.12.04.1-log (Ubuntu)

Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> set global read_only = on;
Query OK, 1 rows affected (0.00 sec)

Se quiser ver a replicação acontecendo, digite

mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: dbactive
                  Master_User: repA
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.000004
          Read_Master_Log_Pos: 107
               Relay_Log_File: mysqld-relay-bin.000002
                Relay_Log_Pos: 253
        Relay_Master_Log_File: mysql-bin.000004
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 107
              Relay_Log_Space: 410
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: 0
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 101
1 row in set (0.00 sec)