Replicacion MySQL maestro-esclavo

MySQLEn este artículo vamos a continuar con la alta disponibilidad de MySQL creando un sencilla arquitectura de replicación maestro-esclavo (master-slave). Nuestro sistema va a contar con dos servidores MySQL, uno que hará la función de maestro, que recibirá todos los UPDATES de tablas y los enviará mediante un log binario a otro servidor MySQL esclavo (podríamos poner tantos como quisieramos).

Partimos de la base que tenemos instalado MySQL en ambos servidores, sino toca instalarlo como si de una instalación estándar se tratara (por yum, compilando, por paquetes precompilados, etc). También utilizaremos la base de datos world para hacer pruebas, disponible en:

http://downloads.mysql.com/docs/world.sql.zip

# yum install mysql-server

Vamos a utilizar la siguiente nomenclatura para los hosts:

mysql-master
mysql-slave

Lo primero que debemos saber a la hora de configurar los dos nodos es que:

  1. El servidor Master debe tener activado el log binario (log-bin).
  2. Ambos deben tener un identificador único (server-id).
  3. El servidor maestro deberá tener un usuario con privilegio REPLICATION SLAVE.

 

Puesta en marcha del Master (mysql-master)

Para activar el log binario, accedemos al fichero de configuración /etc/my.cnf y añadimos log-bin dentro de la sección [mysqld].

[mysqld]
log-bin

En la misma sección [mysqld] debemos asignar un número único a modo de identificador tanto al Master como al Slave, en este caso asignamos 1 al Master:

Master my.cnf:

[mysqld]
log-bin
server-id=1

Reiniciamos el servidor maestro y verificamos que los logs binarios se han creado en el directorio de datos:

mysql-master# /etc/init.d/mysqld restart && ls -l /var/lib/mysql/*bin*
-rw-rw---- 1 mysql mysql 98 Jul 30 23:28 /var/lib/mysql/mysqld-bin.000001
-rw-rw---- 1 mysql mysql 20 Jul 30 23:28 /var/lib/mysql/mysqld-bin.index

Accedemos por shell a la consola MySQL y creamos el usuario con el privilegio REPLICATION SLAVE, 192.168.1.129 es la IP del servidor esclavo:

mysql-master> GRANT REPLICATION SLAVE ON *.* TO 'replicacion'@'192.168.1.129' IDENTIFIED BY 'password';
Query OK, 0 rows affected (0.01 sec)

mysql-master> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.00 sec)

Aprovechamos para volcar la base de datos world sobre la que haremos algunas pruebas:

mysql-master> create database world;
mysql-master> use world
mysql-master> SOURCE world.sql

 

Puesta en marcha del Slave (mysql-slave)

En la sección [mysqld] del fichero de configuración /etc/my.cnf debemos asignar  el id 2 al Slave:

[mysqld]
server-id=2

Reiniciamos el servidor MySQL esclavo:

mysql-master# /etc/init.d/mysqld restart

 

Copia inicial de la base de datos (directorio data)

Antes de activar la replicación ambos servidores deben tener la misma información (bases de datos) y en el mismo punto de restauración. Lo primero que haremos antes de hacer la copia es hacer un flush de las tablas y bloquear las escrituras, de este modo podemos hacer el ‘snapshot’ sin tener que apagar el servidor MySQL. Todo esto lo hacemos en el Master:

mysql-master> FLUSH TABLES WITH READ LOCK;

Ahora podemos hacer la copia de muchas formas, con mysqldump, rsync de los datos, comprimiendo el directorio de datos donde se alojan las bases de datos con .tar.gz, etc

mysql-master# cd /var/lib && tar czvf /tmp/data-mysql.tar.gz mysql
mysql-master# scp /tmp/data-mysql.tar.gz root@mysql-slave:/tmp
data-mysql.tar.gz                                                                100%  417KB 416.9KB/s   00:00

Una vez realizado podemos volver a desbloquear las tablas, no sin antes abrir una nueva shell de mysql y apuntar por un lado el fichero de log binario que se está usando y la posición en la que se ha quedado pues será la que se usará posteriormente para comenzar la replicación en el esclavo:

mysql-master> SHOW MASTER STATUS;
+-------------------+----------+--------------+------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+-------------------+----------+--------------+------------------+
| mysqld-bin.000002 |   724514 |              |                  |
+-------------------+----------+--------------+------------------+
1 row in set (0.01 sec)

Ahora sí que podemos desbloquearlas:

mysql-master> UNLOCK TABLES;

Llega el momento de movernos al esclavo, lo primero que debemos hacer es asegurarnos de parar la replicación en caso de que estuviera activa:

mysql-slave> slave stop;
Query OK, 0 rows affected, 1 warning (0.00 sec)

En este momento los datos del master que hemos comprimido tendríamos que restaurarlos en la carpeta de datos del esclavo, simplemente los descomprimimos sobre la ruta /var/lib/mysql o la que tenga vuestra instalación.

Ahora llega el momento clave, tenemos que indicarle al esclavo quien es el servidor maestro y establacer la comunicación. Especificaremos el hostname del master, el usuario creado anteriormente para la replicación, su clave, el fichero de log binario a utilizar y su posición. Recordad que esto último lo hemos apuntado al hacer un SHOW MASTER STATUS;

mysql-slave> CHANGE MASTER TO
    ->     MASTER_HOST='192.168.1.130',
    ->     MASTER_USER='replicacion',
    ->     MASTER_PASSWORD='password',
    ->     MASTER_LOG_FILE='mysqld-bin.000002',
    ->     MASTER_LOG_POS=724514;
Query OK, 0 rows affected (0.04 sec)

Llego el momento de arrancar la replicación, para ello reactivamos el esclavo:

mysql-slave> START SLAVE;
Query OK, 0 rows affected (0.01 sec)

 

Revisar el estado de la replicación

Una vez puesta en marcha la replicación, deberían existir unos procesos concretos tanto en el master como el slave. En el master debería aparecer una conexión del servidor esclavo con el usuario usado en la replicación esperando a recibir actualizaciones a través del bin-log:

mysql-master> show processlist;
+----+-------------+-----------------+------+-------------+------+----------------------------------------------------------------+------------------+
| Id | User        | Host            | db   | Command     | Time | State                                                          | Info             |
+----+-------------+-----------------+------+-------------+------+----------------------------------------------------------------+------------------+
|  2 | replicacion | mysql-slave:59928 | NULL | Binlog Dump |    7 | Has sent all binlog to slave; waiting for binlog to be updated | NULL             |
|  3 | root        | localhost       | NULL | Query       |    0 | NULL                                                           | show processlist |
+----+-------------+-----------------+------+-------------+------+----------------------------------------------------------------+------------------+
2 rows in set (0.00 sec)

Y el slave debería tener dos conexiones relacionadas con la replicación, un thread SQL y otro de I/O relacionado con las lecturas de relay log:

mysql-slave> show processlist;
+----+-------------+-----------+------+---------+------+-----------------------------------------------------------------------+------------------+
| Id | User        | Host      | db   | Command | Time | State                                                                 | Info             |
+----+-------------+-----------+------+---------+------+-----------------------------------------------------------------------+------------------+
|  1 | system user |           | NULL | Connect |   11 | Waiting for master to send event                                      | NULL             |
|  2 | system user |           | NULL | Connect |   11 | Has read all relay log; waiting for the slave I/O thread to update it | NULL             |
|  4 | root        | localhost | NULL | Query   |    0 | NULL                                                                  | show processlist |
+----+-------------+-----------+------+---------+------+-----------------------------------------------------------------------+------------------+

 

Monitorización de la replicación

Ahora que ya tenemos la replicación funcionando tenemos que conocer la forma de monitorizar su funcionamiento, el comando más importante lo podemos ejecutar en el esclavo (SHOW SLAVE STATUS), nos indicará el estado detallado de la replicación:

mysql-slave> SHOW SLAVE STATUS\G
*************************** 1. row ***************************
             Slave_IO_State: Waiting for master to send event
                Master_Host: 192.168.1.130
                Master_User: replicacion
                Master_Port: 3306
              Connect_Retry: 60
            Master_Log_File: mysqld-bin.000002
        Read_Master_Log_Pos: 724601
             Relay_Log_File: mysqld-relay-bin.000002
              Relay_Log_Pos: 323
      Relay_Master_Log_File: mysqld-bin.000002
           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: 724601
            Relay_Log_Space: 323
            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
1 row in set (0.00 sec)

Los puntos más importantes:

  • Slave_IO_State: Monitoriza el estado del servidor esclavo respecto al master, en este caso está esperando a recibir eventos (actualizaciones del log binario por parte del master.
  • Master_log_File: Especifica el log binario en el servidor maestro que se está utilizando en la replicación.
  • Read_Master_Log_Pos: Indica la posición hasta la cual se ha leído del log binario del master, debería coincidir con la que nos da el SHOW MASTER STATUS en el servidor maestro y con el valor del parámetro Exec_Master_Log_Pos
  • Relay_Master_log_File: Especifica el log binario en el servidor esclavo que se está utilizando en la replicación.
  • Slave_IO_Running y Slave_SQL_Running: Monitorizan si los dos procesos mencionados antes están corriendo, los threads IO_THREAD y SQL_THREAD. Es crítico que ambos estén siempre corriendo.
  • Seconds_Behind_Master: Este parámetro puede ser un indicativo claro de problemas de carga, conectividad de red, etc. Indica el número de segundos de retardo respecto al servidor maestro. Lo ideal, 0.

 

Probando la replicación

A partir de aquí podemos verificar de una forma muy sencilla el funcionamiento de la replicación. Si añadimos, modificamos o borramos registros en una tabla de una base de datos del master automáticamente se replicará en la slave. Si creamos una base de datos en el master automáticamente se creará en el slave, etc:

mysql-master:

mysql-master> create database test01;
Query OK, 1 row affected (0.00 sec)

mysql-master> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| test               |
| test01             |
| world              |
+--------------------+
5 rows in set (0.00 sec)

Inmediatamente en el mysql-slave:

mysql-slave> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| test |
| test01 |
| world |
+--------------------+
5 rows in set (0.01 sec)

 

Bueno, de momento esto podría ser suficiente para una primera aproximación a la replicación maestro-esclavo de MySQL. En futuros artículos si os resulta interesante podemos indagar y detalladar algunas de las cosas tratadas en el artículo y/o revisar otros tipos de replicación, como la circular, la de doble sentido, etc.

5 comentarios en “Replicacion MySQL maestro-esclavo

  1. Pingback: # rm-rf.es
  2. ……….Replication enables data from one MySQL database server called the master to be replicated to one or more MySQL database servers slaves . Replication is asynchronous your replication slaves do not need to be connected permanently to receive updates from the master which means that updates can occur over long-distance connections and even temporary solutions such as a dial-up service. This setup is for linux boxes since thats the only boxes I know how to use ..Pre Requisites.Master Server.

  3. Para quien le interese, he hecho un pequeño script para dumpear todas las bases de datos del mysql, y generar el fitxero de informacion de posicion en el log binario, de forma rapida, para intentar evitar tener el minimo tiempo possible el mysql con las tablas en read only.

    Es un script hecho bastante rapido.

    #!/bin/sh

    listDataBases=$(mysql -uroot -p{password} -e «show databases»);
    mkdir -p clone/
    mysql -uroot -p{password} -e «FLUSH TABLES WITH READ LOCK»;
    for database in $listDataBases; do
    mysqldump -uroot -p{password} $database > clone/$database.sql
    done
    mysql -uroot -p{password} -e «show master status \G» > clone/masterStatus
    mysql -uroot -p{password} -e «UNLOCK TABLES»;

    Dracks.

  4. Hola gente..

    Un cliente me ha pedido esto y lo estoy estudiando, pero hay un punto que no llego a entender.
    Haciendo esto de crear un master y un slave. el server slave tiene acceso a TODAS las bases de datos del server MASTER ? Porque mi cliente tiene alojados algunos sitios en uno de mis servidores, pero en el mismo servidor, hay alojados muchos otros sitios con bases de datos que pertenecen a otros clientes.

    O sea esta replicacion solo es util entre un servidor dedicado y otro donde ambos servers pertenecen al mismo cliente y no por base de datos ? O se puede crear un maestro y un esclavo solo con acceso a una base de datos en particular del servidor maestro?

    Saludos y gracias
    Fabian

Comments are closed.