Backup online no MySQL com xtrabackup

Meu último post referente a backups foi a bastante tempo atrás. Embora ainda válido, não é aconselhável para ser utilizado como backup diário, então resolvi mostrar uma outra opção, o XtraBackup.

Com XtraBackup, você pode realizar backups sem interromper leituras e escritas (ele requer lock por um período bem curto de tempo para pegar coordenadas do binlog).
Hoje vou mostrar como realizar backup completos utilizando a ferramenta.

Instalação:

Para realizar a instalação, eu aconselho utilizar os repositórios para Yum / Apt-get:

Centos / Redhat:

sudo yum install http://www.percona.com/downloads/percona-release/redhat/0.1-4/percona-release-0.1-4.noarch.rpm
sudo yum install percona-xtrabackup-24

Debian / Ubuntu

wget https://repo.percona.com/apt/percona-release_0.1-4.$(lsb_release -sc)_all.deb
sudo dpkg -i percona-release_0.1-4.$(lsb_release -sc)_all.deb
sudo apt-get update
sudo apt-get install percona-xtrabackup-24

Backup:

Para realizar o backup, vamos usar o script innobackupex:

innobackupex --user=root --password='Passw0rd!' /backups/

O script irá produzir várias mensagens, devemos verificar se ele termina com:

...
170429 21:07:12 completed OK!

Paralelismo:

O Xtrabackup permite que você configure múltiplas threads para realizar a cópia das tabelas utilizando a opção –parallel :

innobackupex --user=root --password='Passw0rd!' --parallel=8 /backups/

Podemos observar que cada thread recebe um número que é mostrado entre []:

170429 21:12:27 [05] Copying ./ibdata1 to /backups/2017-04-29_21-12-27/ibdata1
170429 21:12:27 [06] Copying ./mysql/plugin.ibd to /backups/2017-04-29_21-12-27/mysql/plugin.ibd
170429 21:12:27 [06]        ...done
170429 21:12:27 [02] Copying ./mysql/servers.ibd to /backups/2017-04-29_21-12-27/mysql/servers.ibd
170429 21:12:27 [02]        ...done
170429 21:12:27 [03] Copying ./mysql/help_topic.ibd to /backups/2017-04-29_21-12-27/mysql/help_topic.ibd
170429 21:12:27 [07] Copying ./mysql/help_category.ibd to /backups/2017-04-29_21-12-27/mysql/help_category.ibd
170429 21:12:27 [07]        ...done

Compactando:

O Xtrabackup também permite que você compacte o backup utilizando –compress e –compress-threads (normalmente utiliza-se o mesmo numero de threads que –parallel):

innobackupex --user=root --password='Passw0rd!' --parallel=8 --compress --compress-threads=8 /backups/

Por exemplo, um backup que ocupava 702M passa a ocupar 387M compactado:

702M	/backups/2017-04-29_21-12-27
387M	/backups/2017-04-29_21-15-53

Restaurando:

Para restaurar o backup, temos que (1) descompactar com –decompress caso nosso backup seja compactado(você precisa ter o qpress instalado) e (2) aplicar as transações que ocorreram enquanto o backup estava sendo realizado (Basicamente um crash recovery que o InnoDB faz ao iniciar o MySQL):

innobackupex --decompress /backups/2017-04-29_21-18-04/
innobackupex --apply-log --use-memory=4G /backups/2017-04-29_21-18-04

Para agilizar o processo de aplicar os logs, podemos configurar –use-memory que vai se comportar como se fosse o InnoDB Buffer Pool.
Os arquivos .qp vao continuar no diretório, você pode remove-los manualmente executando o comando abaixo:

find /backups/2017-04-29_21-18-04  -name "*.qp" -exec rm -f {} \;

É isso aí. Agora só precisamos copiar os arquivos para o datadir do MySQL e configurar o usuário mysql para ser o owner e group owner da pasta e de todos os arquivos.

Por hoje é só. E lembrem, Backup que não é testado, NÃO É BACKUP!

Gostou ? Ajude e Compartilhe!
Publicado em backup, MySQL | Deixe um comentário

MySQL 8.0 – SET PERSIST

Fala galera. MySQL 8 DMR foi disponibilizado hohe e ele traz algumas novas funcionalidades bem legais. Uma delas é a habilidade de persistir variáveis/configurações entre restart’s. Essa opção é bastante interessante se trocamos variáveis dinâmicas. Isso nos poupa de ter que editar o arquivo .cnf toda a vez que executamos um SET no MySQL(Ou mesmo quando não temos acesso aos arquivos no disco).
A nova sintaxe para o comando é a seguinte:

SET PERSIST option=value;
SET @@persist.option=value;

O MySQL vai criar um arquivo chamado mysqld-auto.cnf. Este arquivo estará localizado na pasta do datadir. Este arquivo irá conter todas as variáveis que foram setadas com o PERSIST e este arquivo será carregado depois de todos os outos (my.cnf / –defaults-file / ~/.my.cnf / …). Isto quer dizer que as variáveis configuradas neste arquivo vão prevalecer perante as demais.

Estas configurações podem ser removidas restaurando seu valor para o valor padrão ou editando o arquivo manualmente no disco(não recomendado).

A funcionalidade pode ser controlada pela configuração persisted-globals-load. Ela é ativado por default. Case seja setada para off (persisted-globals-load=OFF) o MySQL irá ignorar as variáveis presentes no arquivo mysqld-auto.cnf.

As variáveis poderão ser listadas na tabela performance_schema.variables_info . Na coluna variable_source podemos filtrar a origem do valor:

  • COMPILED – Compilada no source do MySQL(Valores padrões)
  • GLOBAL – Parte do arquivo glogal
  • SERVER – Parte do arquivo $MYSQL_HOME/my.cnf file
  • EXPLICIT – Parte do arquivo setado pela opção –defaults-file
  • EXTRA – Parte do arquivo setado pela opçãodefaults-extra-file
  • USER – Parte do arquivo ~/.my.cnf
  • LOGIN – Parte da opção de login path
  • COMMAND_LINE – Opções setadas na linha de comando
  • PERSISTED – Parte das configurações do arquivo mysqld-auto.cnf
  • DYNAMIC – Configurações alteradas dinamicamente

Com estas opções, podemos extrair informações importantes da tabela, como por exemplo, todas as configurações alteradas depois que o servidor foi iniciado:

select * from performance_schema.variables_info where variable_source like 'DYNAMIC';

MySQL 8.0 está disponível para Download no http://dev.mysql.com/downloads/mysql/8.0.html. Tenha em mente que está é uma versão que deve ser usada para teste e não deve ser utilizada em produção. AINDA!

Testem o MySQL 8.0 e digam o que acharam.

Gostou ? Ajude e Compartilhe!
Publicado em MySQL | 1 Comentário

MySQL 5.7 utilizando vagrant

Fala galera.
Hoje vou escrever um post rapidinho pra mostrar uma maneira facil de configurar uma vm com mysql 5.7 usando vagrant.

Vagrant é um utilitário de linha de comando que disponibiliza ferramentas para administrar softwares de máquinas virtuais, como por exemplo o virtualbox. Você pode encontrar mais detalhes sobre o Vagrant na documentação. Clique no link installation, se tiver dúvidas quanto a sua instalação.

Eu escrevi um script que está disponível no github. Ele cria uma máquina virtual usando centos 7 e instala o mysql 5.7 nela:

git clone https://github.com/altmannmarcelo/mysql-vagrant.git
cd mysql-vagrant
vagrant up
vagrant ssh mysql57
mysql

Se você olhar nos arquivos que foram clonados do git, vai ver um arquivo chamado bootstrap.sh. Este arquivo vai configurar o repositório do mysql, instalar o pacote do mysql 5.7 e resetar o password do usuário root.

Qualquer dúvida é só postar nos comentários.

Gostou ? Ajude e Compartilhe!
Publicado em MySQL | Deixe um comentário

Incorrect datetime value – convertendo para timestamp

Fala pessoal.
Hoje eu passei por um problema que em um primeiro momento parecia claramente um bug. Mas olhando um pouco melhor para ele, fez todo sentido.

Eu tenho uma tabela, que aqui vou chamar de t1. Essa tabela tem um campo usando datetime. Durante um projeto de normalização do banco, estamos trocando alguns campos de datetime para timestamp.
Quando eu tentei converter a tabela eu recebi o seguinte erro:

mysql> show create table t1;
+-------+-------------------------------------------------------------------------------------------+
| Table | Create Table                                                                              |
+-------+-------------------------------------------------------------------------------------------+
| t1    | CREATE TABLE `t1` (
  `date` datetime DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1 |
+-------+-------------------------------------------------------------------------------------------+
1 row in set (0,00 sec)

mysql> select * from t1;
+---------------------+
| date                |
+---------------------+
| 2010-03-28 01:28:20 |
+---------------------+
1 row in set (0,00 sec)

mysql> alter table t1 modify date timestamp not null default current_timestamp;
ERROR 1292 (22007): Incorrect datetime value: '2010-03-28 01:28:20' for column 'date' at row 1

Olhando o formato da data, ela parece uma data valida. Depois de um tempo me dei por conta de que nosso timezone é Europe/Dublin. Quando fui pesquisar quando que o horario de verão entrou no ano de 2010, adivinha o que eu achei ???

Isso mesmo, esse foi exatamente o dia que o horario de verão entrou em Dublin naquele ano. Basicamente a 1 da manhã os relógios adiantaram uma hora. Isso que dizer que 01:28:20 nunca existiu no meu timezone. Por que esse valor estava no banco em primeiro lugar é outra discução. Mas por que o banco não reclamou sobre isso antes ?

Segundo a documentação: http://dev.mysql.com/doc/refman/5.6/en/datetime.html

MySQL converts TIMESTAMP values from the current time zone to UTC for storage, and back from UTC to the current time zone for retrieval. (This does not occur for other types such as DATETIME.)

MySQL converte campos TIMESTAMP do timezone original para UTC no caso de armazenamento, e converte de volta de UTC para o timezone do servidor no caso de consulta. (Isso não ocorre para outros tipos de campos, como DATETIME.)

Então, como arrumar ?
Primeiro vamos identificar as linhas que tem uma data invalida e arrumar elas (No meu caso, adicionar uma hora nela). Uma maneira de fazer isso é usando as queries abaixo:

mysql> SELECT date FROM t1 WHERE FROM_UNIXTIME(UNIX_TIMESTAMP(date)) <> date;
+---------------------+
| date |
+---------------------+
| 2010-03-28 01:28:20 |
+---------------------+
1 row in set (0,00 sec)

mysql> UPDATE t1 SET date=DATE_ADD(date, INTERVAL 1 hour) WHERE FROM_UNIXTIME(UNIX_TIMESTAMP(date)) <> date;
Query OK, 1 row affected (0,10 sec)
Rows matched: 1 Changed: 1 Warnings: 0

mysql> SELECT date FROM t1 WHERE FROM_UNIXTIME(UNIX_TIMESTAMP(date)) <> date;
Empty set (0,00 sec)

mysql> alter table t1 modify date timestamp not null default current_timestamp;
Query OK, 1 row affected (0,05 sec)
Records: 1 Duplicates: 0 Warnings: 0

mysql> SELECT * FROM t1;
+---------------------+
| date |
+---------------------+
| 2010-03-28 02:28:20 |
+---------------------+
1 row in set (0,00 sec)

Identificamos as linhas, arrumamos elas e o MySQL permitiu a conversão para TIMESTAMP.

Por hoje é só.

Gostou ? Ajude e Compartilhe!
Publicado em MySQL | 1 Comentário

Forçando transação vitima de rollback em deadlock

Se você utiliza uma Storage Engine que suporta transações, você provavelmente já enfrentou ou ouviu falar de deadlock's.

Na Documentação do MySQL podemos ver:
“Always be prepared to re-issue a transaction if it fails due to deadlock. Deadlocks are not dangerous. Just try again.”
“Sempre esteja preparado para re-executar uma transação se ela falhar por causa de deadlock. Deadlocks não são perigosos. Apenas re-execute a transação.”

Na empresa em que trabalho, temos um importante processo que de vez em quando falha por causa de deadlock. Decidi então melhorar este processo e fazer o que a documentação diz (re-executar a transação).
Para fazer isso, Eu queria poder reproduzir o scenario do deadlock e a transação vitima do rollback teria que ser a do processo em questão.

Criar um deadlock é simples, você só precisa de 2 sessões em que cada uma esteja segurando o “lock” que a outra está esperando. Por exemplo:
Temos uma tabela que possui 4 linhas (linha 1, linha 2, linha 3, linha 4) e temos duas transações que fazem o seguinte:

T1: travar (lock) linha 1;
T2: travar (lock) linha 4;
T1: tentar travar linha 4 (este comando irá aguardar até que T2 destrave a linha 4);
T2: tentar travar linha 1 (este comando irá aguardar até que T1 destrave a linha 1);

Neste momento, ambas transações estarão esperando entre si o destravamento das duas linhas e neste momento o MySQL irá detectar o deadlock. Vamor ver isso em prática:

T1 > CREATE TABLE t (i INT, PRIMARY KEY(i)) ENGINE = InnoDB;
Query OK, 0 rows affected (0.08 sec)

T1 > INSERT INTO t VALUES (1),(2),(3),(4);
Query OK, 4 rows affected (0.00 sec)
Records: 4  Duplicates: 0  Warnings: 0

T1 > START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)

T1 > UPDATE t SET i = 1 WHERE i = 1;
Query OK, 0 rows affected (0.01 sec)
Rows matched: 1  Changed: 0  Warnings: 0

T2 > START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)

T2 > UPDATE t SET i = 4 WHERE i = 4;
Query OK, 0 rows affected (0.00 sec)
Rows matched: 1  Changed: 0  Warnings: 0

T1 >  UPDATE t SET i = 4 WHERE i = 4;
Query OK, 0 rows affected (9.54 sec)
Rows matched: 1  Changed: 0  Warnings: 0

T2 > UPDATE t SET i = 1 WHERE i = 1;
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction

Como o MySQL escolhe a transação vitima do rollback ?

O MySQL faz um calculo interno baseado no “peso” da transação. Este peso é calculado levando em consideração o numero de linhas alterada e o numero de linhas travadas(locked) por cada transação.
Este valor pode ser verificado na coluna trx_weight da tabela information_schema.innodb_trx:

T1 > SELECT * FROM  information_schema.innodb_trx\G
*************************** 1. row ***************************
                    trx_id: 23326
                 trx_state: RUNNING
               trx_started: 2016-02-19 10:10:45
     trx_requested_lock_id: NULL
          trx_wait_started: NULL
                trx_weight: 3
       trx_mysql_thread_id: 5
                 trx_query: SELECT * FROM  information_schema.innodb_trx
       trx_operation_state: NULL
         trx_tables_in_use: 0
         trx_tables_locked: 1
          trx_lock_structs: 3
     trx_lock_memory_bytes: 1136
           trx_rows_locked: 2
         trx_rows_modified: 0
   trx_concurrency_tickets: 0
       trx_isolation_level: REPEATABLE READ
         trx_unique_checks: 1
    trx_foreign_key_checks: 1
trx_last_foreign_key_error: NULL
 trx_adaptive_hash_latched: 0
 trx_adaptive_hash_timeout: 0
          trx_is_read_only: 0
trx_autocommit_non_locking: 0
1 row in set (0.00 sec)

A Dica:
Um fator muito importante na hora do calculo acima, é se alguma transação alterou dados em tabelas não-transacionais. Caso alguma transação tenha alterado dados nestas tabelas, ela é considerada mais pesada que as outras.
Para o meu teste, eu criei uma tabela MyISAM e inseri uma linha nesta tabela para fazer ela “pesar mais”:

T2 > CREATE TABLE t2 (i INT, PRIMARY KEY(i)) ENGINE = MyISAM;
Query OK, 0 rows affected (0.02 sec)

T1 > START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)

T1 > UPDATE t SET i = 1 WHERE i = 1;
Query OK, 0 rows affected (0.01 sec)
Rows matched: 1  Changed: 0  Warnings: 0

T2 > START TRANSACTION;
Query OK, 0 rows affected (0.00 sec)

T2 > UPDATE t SET i = 4 WHERE i = 4;
Query OK, 0 rows affected (0.00 sec)
Rows matched: 1  Changed: 0  Warnings: 0

T2 > INSERT INTO t2 VALUES (1);
Query OK, 1 row affected (0.00 sec)

T1 > UPDATE t SET i = 4 WHERE i = 4;  -- este comando vai esperar até que T2 destrave a linha 4 ...

T2 > UPDATE t SET i = 1 WHERE i = 1;
Query OK, 0 rows affected (0.00 sec)
Rows matched: 1  Changed: 0  Warnings: 0

T1 >
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction

Como vocês podem ver, T1 foi a vitima do rollback neste caso.

Por hoje é só pessoal. Espero que tenham gostado.

Gostou ? Ajude e Compartilhe!
Publicado em InnoDB, MySQL | 4 Comentários

MySQL 5.7 senha root gerada automaticamente

Fala pessoal.

Vocês devem ter notado algo diferente quando instalaram o MySQL 5.7 do zero, seja via yum ou pelos binários que o MySQL disponibiliza. O password do usuário root é gerado automaticamente.
Ok, e aonde eu posso encontra-lo ?

Centos
cat /var/log/mysqld.log | grep "A temporary password is generated for" | awk '{print $NF}'
Examplo:

[root@master ~]# cat /var/log/mysqld.log | grep "A temporary password is generated for" | awk '{print $NF}'
a3BGf#TY.pBj

Versão binária
Quando você rodou o comando para inicializar o datadir mysqld --initialize você verá a seguinte mensagem na sua tela:

. . .
2016-01-13T21:05:03.070322Z 1 [Note] A temporary password is generated for root@localhost: vL8n>Hs%kr>s
. . .

Você terá que alterar a senha do usuário no primeiro login. Você pode fazer isso seguindo o passo 2 deste artigo.

É isso aí.
Agora vocês já sabem aonde encontrar a senha do root que foi gerada automaticamente na instalação.

Até a próxima.

Gostou ? Ajude e Compartilhe!
Publicado em instalação, MySQL, password, Security | 11 Comentários

Adicionando nova collation no MySQL

Eu sou do tipo de DBA que prefere manter as coisas mais simples possíveis, mas, tem vezes em que não é possível. Alguns dias atrás, me deparei com um problema no qual, nenhuma das collations presentes no MySQL iria garantir a integridade do meu banco de dados, e para evitar uma grande re-escrita do código fonte, me deparei com uma opção até então desconhecida.
Adicionar minha própria collation no MySQL

Esta opção está descrita nesta sessão da documentação.
Neste artigo, vou mostrar como fazer o MySQL identificar vogais com acento agudo como uma letra diferente.

Primeiro, precisamos descobrir onde está o nosso diretório com os charset’s:


mysql [localhost] {msandbox} ((none)) > SHOW VARIABLES LIKE 'character_sets_dir';
+--------------------+---------------------------------------+
| Variable_name | Value |
+--------------------+---------------------------------------+
| character_sets_dir | /mysql/sources/5.6.26/share/charsets/ |
+--------------------+---------------------------------------+
1 row in set (0.00 sec)

Neste caso, vou estar trabalhando com a pasta /mysql/sources/5.6.26/share/charsets/, ela provavelmente será diferente no seu ambiente.
Nós vamos achar um arquivo chamado Index.xml dentro desta pasta, e vamos trabalhar nele.

Neste arquivo, vamos estar utilizando a sintaxe chamada de locate data markup language (LDML), mais especificamente os elementos reset / p / t.
Você pode achar mais informação sobre a implementação de LDML no mysql neste link.

Vamos editar o arquivo e adicionar nossa collation:

<charset name="utf8">
  <family>Unicode</family>
  <description>UTF-8 Unicode</description>
  <alias>utf-8</alias>
 . . .
  <collation name="utf8_test_ci" id="1122" version="5.2.0">
    <rules>
      <reset>A</reset>
      <p>\u00c1</p>
      <t>\u00e1</t>
      <reset>E</reset>
      <p>\u00c9</p>
      <t>\u00e9</t>
      <reset>I</reset>
      <p>\u00cd</p>
      <t>\u00ed</t>
      <reset>O</reset>
      <p>\u00d3</p>
      <t>\u00f3</t>
      <reset>U</reset>
      <p>\u00da</p>
      <t>\u00fa</t>
    </rules>
  </collation>
</charset>

Explicando um pouco o que cada linha representa:

<reset>A</reset>
<p>\u00c1</p>
<t>\u00e1</t>
  • reset – está resetando a ordem e regras da letra A (e também da letra a)
  • p – está dizendo que \u00c1 (Á) será tratada como uma letra diferente
  • t – está dizendo que \u00e1 (á) será tratada como a versão minuscula de \u00c1 (Á)

A mesma lista de regras se aplica as demais letras que temos no arquivo (E / I / O / U). Agora, tudo o que precisamos é re-iniciar o serviço do MySQL.

Vamos agora testar e verificar como isto funciona na prática, vou criar 2 tabelas, uma com a collation padrão do utf8 e outra tabela com a nossa nova collation:


mysql [localhost] {msandbox} (test) > CREATE TABLE `utf8` ( `name` varchar(50), PRIMARY KEY (`name`) ) ENGINE=InnoDB DEFAULT CHARSET utf8;
Query OK, 0 rows affected (0.04 sec)

mysql [localhost] {msandbox} (test) > INSERT INTO utf8 VALUES ('A');
Query OK, 1 row affected (0.01 sec)

mysql [localhost] {msandbox} (test) > INSERT INTO utf8 VALUES ('Á');
ERROR 1062 (23000): Duplicate entry 'Á' for key 'PRIMARY'
mysql [localhost] {msandbox} (test) > INSERT INTO utf8 VALUES ('a');
ERROR 1062 (23000): Duplicate entry 'a' for key 'PRIMARY'
mysql [localhost] {msandbox} (test) > INSERT INTO utf8 VALUES ('á');
ERROR 1062 (23000): Duplicate entry 'á' for key 'PRIMARY'
mysql [localhost] {msandbox} (test) > SELECT * FROM utf8;
+------+
| name |
+------+
| A |
+------+
1 row in set (0.00 sec)

O MySQL só aceitou uma variação da letra A, todas as próximas falharam por serem consideradas iguais. Vamos ver como funciona na nossa collation:


mysql [localhost] {msandbox} (test) > CREATE TABLE `utf8_test` ( `name` varchar(50) CHARACTER SET utf8 COLLATE utf8_test_ci , PRIMARY KEY (`name`)) ENGINE=InnoDB DEFAULT CHARSET utf8;
Query OK, 0 rows affected (0.03 sec)

mysql [localhost] {msandbox} (test) > INSERT INTO utf8_test VALUES ('A');
Query OK, 1 row affected (0.01 sec)

mysql [localhost] {msandbox} (test) > INSERT INTO utf8_test VALUES ('Á');
Query OK, 1 row affected (0.01 sec)

mysql [localhost] {msandbox} (test) > INSERT INTO utf8_test VALUES ('a');
ERROR 1062 (23000): Duplicate entry 'a' for key 'PRIMARY'
mysql [localhost] {msandbox} (test) > INSERT INTO utf8_test VALUES ('á');
ERROR 1062 (23000): Duplicate entry 'á' for key 'PRIMARY'
mysql [localhost] {msandbox} (test) > SELECT * FROM utf8_test;
+------+
| name |
+------+
| A |
| Á |
+------+
2 rows in set (0.00 sec)

Neste caso, o MySQL aceitou 2 variações, A / Á. “a” foi bloqueada pois é idêntica a letra “A” e “á” foi bloqueada pois é idêntica a letra “Á”.

Por hoje é isso, espero que tenham gostado.

Gostou ? Ajude e Compartilhe!
Publicado em Charset, Collation, MySQL | Deixe um comentário

MySQL & NoSQL – Memcached Plugin

Muita gente já deve ter ouvido falar nos bancos de dados NoSQL e uma das ferramentas NoSQL muito utilizada é o memcached, no qual adicionamos uma camada de cache entre a aplicação e o banco de dados. Desde a versão 5.6 do MySQL, foi disponibilizado um plugin de integração entre o MySQL e o Memcached. Neste artigo publicado no iMasters eu mostro como instalar e configurar esta integração.

Gostou ? Ajude e Compartilhe!
Publicado em InnoDB, instalação, MySQL, optimização, performance | Deixe um comentário

Estratégia de Backup MySQL – Slides

Fala pessoal, em Novembro do ano passado estive em Londres falando sobre backups na Percona Live London 2014, abaixo estão os slides da apresentação (está em inglês), fiquem a vontade para comentar.

Versão em PDF


Gostou ? Ajude e Compartilhe!
Publicado em backup, MySQL, Security | Deixe um comentário

MySQL Fabric – Parte 1 Instalação

MySQL Fabric é uma ferramenta que está inclusa no MySQL Utilities que ajuda a gerenciar servidores MySQL.
Ele funciona basicamente adicionando uma nova camada entre a aplicação e os servidores MySQL, que auxilia no processo de sharding e alta disponibilidade.

Para mais informações referente ao que é MySQL Fabric, leia a documentação.

Para instalar nosso ambiente com MySQL Fabric, vamos precisar de 4 servidores, eu utilizei os seguintes nomes e IPs:

fabric1 (192.168.0.200) - fabric
mysql1 (192.168.0.201) - mysql master
mysql2 (192.168.0.202) - mysql slave
mysql3 (192.168.0.203) - mysql slave

Obs.: Estou rodando CentOS 6.5 em todos os servidores.

1. Adicione o repositório mysql nos 4 servidores, leia Instalar a versão mais recente do MySQL via yum para mais informações:

rpm -i http://dev.mysql.com/get/mysql-community-release-el6-5.noarch.rpm
yum update

2. Instale os pacotes mysql mysql-server mysql-utilities:

yum install mysql mysql-server mysql-utilities
chkconfig mysqld on
/etc/init.d/mysqld start

3. Nos servidores mysql1,mysql2,mysql3 adicione as seguintes configurações no arquivo my.cnf:

[mysqld]
...
binlog-format=ROW
log-slave-updates=true
gtid-mode=on
enforce-gtid-consistency=true
master-info-repository=TABLE
relay-log-info-repository=TABLE
sync-master-info=1
report-host=192.168.0.201
report-port=3306
server-id=1
log-bin=mysql1-bin.log

4. No servidor mysql1, adicione os usuários para a replicação (um para cada servidor mysql):


GRANT REPLICATION SLAVE ON *.* TO replication@192.168.0.201 IDENTIFIED BY 'reppwd';
GRANT REPLICATION SLAVE ON *.* TO replication@192.168.0.202 IDENTIFIED BY 'reppwd';
GRANT REPLICATION SLAVE ON *.* TO replication@192.168.0.203 IDENTIFIED BY 'reppwd';

[root@mysql1 ~]# mysql -u root -e "GRANT REPLICATION SLAVE ON *.* TO replication@192.168.0.201 IDENTIFIED BY 'reppwd'; "
[root@mysql1 ~]# mysql -u root -e "GRANT REPLICATION SLAVE ON *.* TO replication@192.168.0.202 IDENTIFIED BY 'reppwd'; "
[root@mysql1 ~]# mysql -u root -e "GRANT REPLICATION SLAVE ON *.* TO replication@192.168.0.203 IDENTIFIED BY 'reppwd'; "

5. No servidor mysql1 adicione o usuário MySQL para o servidor fabric:


GRANT ALL ON *.* TO 'replication'@'192.168.0.200' IDENTIFIED BY 'reppwd';

[root@mysql1 ~]# mysql -u root -e "GRANT ALL ON *.* TO 'replication'@'192.168.0.200' IDENTIFIED BY 'reppwd';"

6. Nos servidores mysql2 and mysql3, configure a replicação:

CHANGE MASTER TO MASTER_HOST='192.168.0.201', MASTER_USER='replication', MASTER_PASSWORD='reppwd', MASTER_AUTO_POSITION=1;
START SLAVE;

7. No servidor fabric1 adicione o usuário fabric no MySQL:


GRANT ALL ON fabric.* TO 'fabric'@'localhost' IDENTIFIED BY 'fabricpwd';

[root@fabric1 ~]# mysql -u root -e "GRANT ALL ON fabric.* TO 'fabric'@'localhost' IDENTIFIED BY 'fabricpwd';"

8. No servidor fabric1, configure o usuário e password no grupos [storage] and [servers] no arquivo /etc/mysql/fabric.cfg :


[storage]
...
password = fabricpwd
...
[servers]
password = reppwd
user = replication

9. No servidor fabric1, configure o banco de dados que será utilizado pelo MySQL Fabric, será perguntado para configurar uma senha, esta senha será utilizada nas próximas vezes que utilizarmos o mysqlfabric:


mysqlfabric manage setup

[root@fabric1 ~]# mysqlfabric manage setup
[INFO] 1406131468.176740 - MainThread - Initializing persister: user (fabric), server (localhost:3306), database (fabric).
Finishing initial setup
=======================
Password for admin user is not yet set.
Password for admin/xmlrpc: 
Repeat Password:
Password set.

10. No servidor fabric1, inicie o fabric:


mysqlfabric manage start &

11. No servidor fabric1, adicione um grupo:

mysqlfabric group create GLOBAL1

[root@fabric1 ~]# mysqlfabric group create GLOBAL1
Password for admin: 
Procedure :
{ uuid        = 5e4a6bdb-60f0-4e34-87ba-4c56b7616b35,
  finished    = True,
  success     = True,
  return      = True,
  activities  = 
}

12. No servidor fabric1, adicione mysql1, mysql2 e mysql3 ao grupo GLOBAL1:


mysqlfabric group add GLOBAL1 192.168.0.201
mysqlfabric group add GLOBAL1 192.168.0.202
mysqlfabric group add GLOBAL1 192.168.0.203

[root@fabric1 ~]# mysqlfabric group add GLOBAL1 192.168.0.201
Password for admin: 
Procedure :
{ uuid        = 39efb9c4-6195-4c41-aa02-0bfdc228bfe2,
  finished    = True,
  success     = True,
  return      = True,
  activities  = 
}
[root@fabric1 ~]# mysqlfabric group add GLOBAL1 192.168.0.202
Password for admin: 
Procedure :
{ uuid        = c8babfb9-d836-44c0-b4fd-015cd1df8298,
  finished    = True,
  success     = True,
  return      = True,
  activities  = 
}
[root@fabric1 ~]# mysqlfabric group add GLOBAL1 192.168.0.203
Password for admin: 
Procedure :
{ uuid        = c86bba70-69ac-4923-9c54-1a8aaab6d97e,
  finished    = True,
  success     = True,
  return      = True,
  activities  = 
}

13. No servidor fabric1, pegue o uuid do servidor master:

mysqlfabric group lookup_servers GLOBAL1

[root@fabric1 ~]# mysqlfabric group lookup_servers GLOBAL1
Password for admin: 
Command :
{ success     = True
  return      = [{'status': 'SECONDARY', 'server_uuid': '2e157d1e-1281-11e4-80dc-080027aa0242', 'mode': 'READ_ONLY', 'weight': 1.0, 'address': '192.168.0.201'}, {'status': 'SECONDARY', 'server_uuid': '41d85bee-1281-11e4-80dc-080027e87bc6', 'mode': 'READ_ONLY', 'weight': 1.0, 'address': '192.168.0.202'}, {'status': 'SECONDARY', 'server_uuid': '472734d8-1281-11e4-80dc-0800274a710c', 'mode': 'READ_ONLY', 'weight': 1.0, 'address': '192.168.0.203'}]
  activities  = 
}

14. No servidor fabric1, adicione o seu master como master do grupo GLOBAL1:

mysqlfabric group promote GLOBAL1 --slave_id='2e157d1e-1281-11e4-80dc-080027aa0242'

[root@fabric1 ~]# mysqlfabric group promote GLOBAL1 --slave_id='2e157d1e-1281-11e4-80dc-080027aa0242'
Password for admin: 
[WARNING] 1406131951.712366 - Executor-2 - Error () trying to process transactions in the relay log for candidate (('Command (START SLAVE SQL_THREAD, ()) failed: 1200 (HY000): The server is not configured as slave; fix in config file or with CHANGE MASTER TO', 1200)).
[INFO] 1406131951.824763 - Executor-2 - Master has changed from None to 2e157d1e-1281-11e4-80dc-080027aa0242.
Procedure :
{ uuid        = 733ae69d-fb12-447b-b86b-041703491315,
  finished    = True,
  success     = True,
  return      = True,
  activities  = 
}
[root@fabric1 ~]# mysqlfabric group lookup_servers GLOBAL1
Password for admin: 
Command :
{ success     = True
  return      = [{'status': 'PRIMARY', 'server_uuid': '2e157d1e-1281-11e4-80dc-080027aa0242', 'mode': 'READ_WRITE', 'weight': 1.0, 'address': '192.168.0.201'}, {'status': 'SECONDARY', 'server_uuid': '41d85bee-1281-11e4-80dc-080027e87bc6', 'mode': 'READ_ONLY', 'weight': 1.0, 'address': '192.168.0.202'}, {'status': 'SECONDARY', 'server_uuid': '472734d8-1281-11e4-80dc-0800274a710c', 'mode': 'READ_ONLY', 'weight': 1.0, 'address': '192.168.0.203'}]
  activities  = 
}
[root@fabric1 ~]# 

Agora temos nosso ambiente MySQL Fabric funcionando .
Não perca os próximos post para aprender mais sobre essa nova ferramenta.

Gostou ? Ajude e Compartilhe!
Publicado em instalação, MySQL, performance, replicacao | 3 Comentários