A la hora de hacer copias de seguridad de nuestras bases de datos MySQL, una opción muy común suele ser la de usar una réplica maestro-esclavo, de manera que nuestro servidor en producción hace de maestro y otro servidor de backup hace de esclavo. Podemos hacer copias desde el servidor de backup sin que se vea afectado el rendimiento del sistema en producción y sin interrupciones de servicio. Tener una réplica en otro servidor también añade fiabilidad ante fallos totales del sistema en producción, los cuales, tarde o temprano, ocurrirán. Por ejemplo, podemos tener un pequeño servidor actuando como backup en nuestra oficina sincronizado mediante réplicas con nuestro sistema en producción.
Esta opción, además, añade fiabilidad ante posibles secuestros o interrupciones de servicio permanentes del servidor maestro, bien si quiebra de nuestro proveedor de servicios desapareciendo de la noche al dío o hay una intervención de servidores por parte de fuerzas del estado o cualquier otro escenario catastrófico que nos podamos imaginar. En cualquiera de estos eventos, tendremos posiblemente decenas de clientes y servicios parados sin posibilidad de recuperar sus datos si no hemos preparado un buen plan de contingencias. La regla de oro aquí es: no tengas tu único backup en la misma red que el proveedor de servicios. Tener un servidor de backup con MySQL actuando como esclavo de replicación "en casa" es una solución asequible y no consume demasiado ancho de banda en un sitio web de tráfico normal, además de que no afecta al rendimiento del maestro en el sistema en producción.
Otra cuestión es que podemos tener más de una instalación MySQL de la que replicar, ya que podemos tener varios sistemas en producción con diferentes bases de datos. MySQL no puede actuar como esclavo de replicación de más de un maestro a la vez, así que una instalación convencional no es suficiente. Para poder realizar esta tarea necesitaremos tener diferentes servidores esclavos, cada uno de ellos conectado a un máster o bien instalar múltiples instancias de MySQL en en mismo host, usando cada instancia como esclavo de un máster diferente.
Para ello utilizaremos la utilidad que viene por defecto en cualquier instalación de MySQL llamada mysqld_muti:
1) Crear los diferentes directorios de datos para cada instancia de MySQL
2) Crear el fichero de configuración
3) Definir el script de arranque / parada de servicios
Esta opción, además, añade fiabilidad ante posibles secuestros o interrupciones de servicio permanentes del servidor maestro, bien si quiebra de nuestro proveedor de servicios desapareciendo de la noche al dío o hay una intervención de servidores por parte de fuerzas del estado o cualquier otro escenario catastrófico que nos podamos imaginar. En cualquiera de estos eventos, tendremos posiblemente decenas de clientes y servicios parados sin posibilidad de recuperar sus datos si no hemos preparado un buen plan de contingencias. La regla de oro aquí es: no tengas tu único backup en la misma red que el proveedor de servicios. Tener un servidor de backup con MySQL actuando como esclavo de replicación "en casa" es una solución asequible y no consume demasiado ancho de banda en un sitio web de tráfico normal, además de que no afecta al rendimiento del maestro en el sistema en producción.
Otra cuestión es que podemos tener más de una instalación MySQL de la que replicar, ya que podemos tener varios sistemas en producción con diferentes bases de datos. MySQL no puede actuar como esclavo de replicación de más de un maestro a la vez, así que una instalación convencional no es suficiente. Para poder realizar esta tarea necesitaremos tener diferentes servidores esclavos, cada uno de ellos conectado a un máster o bien instalar múltiples instancias de MySQL en en mismo host, usando cada instancia como esclavo de un máster diferente.
Para ello utilizaremos la utilidad que viene por defecto en cualquier instalación de MySQL llamada mysqld_muti:
mysqld_multi(1) is designed to manage several mysqld processes that listen for connections on different Unix socket files and TCP/IP ports. It can start or stop servers, or report their current status.En un sistema Debian GNU/Linux estándar, no tenemos herramientas para configurar un entorno mysqld_multi de forma automática, así que tendremos que hacerlo a mano. Para ello necesitamos:
1) Crear los diferentes directorios de datos para cada instancia de MySQL
2) Crear el fichero de configuración
3) Definir el script de arranque / parada de servicios
Crear directorios de datos
Supongamos que queremos tener dos instancias de MySQL ejecutándose. Cada instancia se comportará de forma independiente y deberá tener su propio directorio de datos. Para crear los directorios de datos usamos la utilidad mysql_install_db, tantas veces como instancias vayamos a crear y pasando como argumento datadir el directorio de destino que se creará:
# mysql_install_db --user=mysql --basedir=/usr --datadir=/var/mysql-2
# mysql_install_db --user=mysql --basedir=/usr --datadir=/var/mysql-3
Con esto tendremos creados los dos directorios de datos en /var/mysql-2 y /var/mysql-3
Fichero de configuración para mysqld_multi
Este fichero tendrá la configuración para mysqld_multi, así como para cada una de las instancias. Almacenamos este archivo en /etc/mysql/conf.d/multi.cnf (cualquier otra localización también vale):
[mysqld_multi]
mysqld = /usr/bin/mysqld_safe
mysqladmin = /usr/bin/mysqladmin
user = multi_admin
password = un_secreto
[mysqld2]
socket = /var/run/mysqld/mysqld.sock-2
port = 3307
pid-file = /var/run/mysqld/mysqld.pid-2
datadir = /var/lib/mysql-2
language = /usr/share/mysql/english
user = mysql
server-id = 101
report-host= instancia-2
[mysqld3]
socket = /var/run/mysqld/mysqld.sock-3
port = 3308
pid-file = /var/run/mysqld/mysqld.pid-3
datadir = /var/lib/mysql-3
language = /usr/share/mysql/english
user = mysql
server-id = 102
report-host= instancia-3
En la zona [mysqld_multi] hemos definido el usuario y contraseña para el administrador de múltiples instancias, el cual tendremos que añadir a cada una de las instancias particulares para que el script de parada pueda funcionar correctamente. Ademñas, hemos definido las instancias [mysql2] y [mysql3] con las rutas a los ficheros de datos, PIDs, sockets de conexión e ids para que puedan actuar como esclavos.
Script de arranque y parada de servicios en /etc/init.d
Este es el script (adaptado del que aparece en el comentario de Tim Young en http://dev.mysql.com/doc/refman/5.0/en/mysqld-multi.html) que nos servirá para arrancar y parar las múltiples instancias de MySQL configiradas en multi.cnf de forma individual o todas en bloque. Lo guardamos en /etc/init.d/mysql_multi:
#!/bin/bash
# mysqld This shell script takes care of starting and stopping
# the MySQL subsystem (mysqld) using mysql_multi
### BEGIN INIT INFO
# Provides: mysql_multi
# Required-Start: $remote_fs $syslog $time
# Required-Stop: $remote_fs $syslog $itme
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start/stop mysqld_multi instances
### END INIT INFO
PATH=/sbin:/usr/sbin:/bin:/usr/bin
# Load the VERBOSE setting and other rcS variables
. /lib/init/vars.sh
conffile="/etc/mysql/conf.d/multi.cnf"
opts="--defaults-extra-file=$conffile"
mysqld_start() {
echo "Starting mysqld..."
mysqld_multi $opts start $* $pass
}
mysqld_stop() {
echo "Stopping mysqld..."
mysqld_multi $opts stop $* $pass
}
mysqld_restart() {
mysqld_stop $*
sleep 1
mysqld_status $*
sleep 1
mysqld_start $*
sleep 1
mysqld_status $*
}
mysqld_which() {
b=`egrep -h "\[mysqld[0-9]+\]" $conffile | sed 's/[^A-Za-z0-9]//g' | wc -l`
echo "The following $b instances are configured:"
egrep -h "\[mysqld[0-9]+\]" $conffile | sed 's/[^A-Za-z0-9]//g'
}
mysqld_status() {
mysqld_multi $opts report $*
}
#Set these variables so mysqld finds the right information
export PATH=/usr/bin:/usr/sbin:$PATH
option=${1:-''}
shift
case "$option" in
'start') mysqld_start $*;;
'stop') mysqld_stop $*;;
'restart') mysqld_restart $*;;
'which') mysqld_which $*;;
'status') mysqld_status $* ;;
*)
echo "Usage: $0 [start|stop|restart|status|which]"
echo "Optional info: "
echo " This uses mysql_multi, which allows control of individual mysqld "
echo " instances. Do this by specifying a list of numbers following the"
echo " command (start/stop/etc.). For example:"
echo " $0 stop 1,3"
echo " $0 stop 1-3"
echo " $0 stop 1"
echo " $0 stop 1-3,5"
echo
echo " do $0 which to list the mysql instances that are configured"
echo
echo " Instances information must be in $conffile"
echo
esac
Para instalarlo como servicio del sistema, de manera que se ejecute de forma automática con los scripts de arranque y parada de servicios, tenemos que ejecutar adicionalmente el comando:
# insserv -v mysql_multi
Si lo ejecutamos sin argumentos, nos muestra la ayuda:
# /etc/init.d/mysql_multi
Usage: /etc/init.d/mysql_multi [start|stop|restart|status|which]
Optional info:
This uses mysql_multi, which allows control of individual mysqld
instances. Do this by specifying a list of numbers following the
command (start/stop/etc.). For example:
/etc/init.d/mysql_multi stop 1,3
/etc/init.d/mysql_multi stop 1-3
/etc/init.d/mysql_multi stop 1
/etc/init.d/mysql_multi stop 1-3,5
do /etc/init.d/mysql_multi which to list the mysql instances that are configured
Instances information must be in /etc/mysql/conf.d/multi.cnf
Podemos usarlo para que nos diga qué instancias están configuradas:
# /etc/init.d/mysql_multi which
The following 2 instances are configured:
mysqld2
mysqld3
Arrancar instancias individuales (en este caso arrancamos [mysql2]):
# /etc/init.d/mysql_multi start 2
Starting mysqld...
etc.
Una vez arrancadas todas las instancias, lo único que nos falta es añadir al usuario administrador mysql_multy a cada una de las instancias. Para ello, nos conectamos a cada instancia usando su propio socket con el comando:
# mysql -S /var/run/mysql/mysqld.sock-2 -u root
y creamos el usuario con los privilegios necesarios:
mysql > GRANT SHUTDOWN , SUPER , REPLICATION CLIENT ON * . * TO 'multi_admin'@'localhost' IDENTIFIED BY PASSWORD 'un_secreto';
El resto de la configuración de las instancias correspondiente a la asignación de una clave para el root, configuración de los esclavos de réplica, etc. se hará de la forma habitual.
¿Tienes alguna solución mejor? Os esperamos en el próximo artículo.
Mario J. Barchéin Molina.
Mario, como siempre, sencillamente ¡genial! Vamos a probarlo.
ResponderEliminarUn abrazo.
Una maravilla :D
ResponderEliminarSe puede que un servidor-A replique tabla uno en servidor-C y servidor-B replique tabla dos en servidor-C?
ResponderEliminarMucho agradecere que me puedas ayudas.
Si, se puede hacer con esta opción:
Eliminarhttp://dev.mysql.com/doc/refman/5.1/en/replication-options-slave.html#option_mysqld_replicate-do-table
Además de configurar los servidores A y B para que sean esclavos de C, la línea que tienes que incluir en el fichero de configuración de cada uno de los esclavos A y B sería
replicate-do-table=NombreBD.NombreTabla
Donde NombreBD será la base de datos y NombreTabla la tabla dentro de esa base de datos que deseas replicar. Ten en cuenta que si utilizas esta opción sólo replicarás la tabla indicada.
Un saludo.