Conceptos y ventajas de la multi-instancia
La ejecución de múltiples enstancias de MySQL en un único servidor físico o virtual permite segmentar servicios sin la necesidad de desplegar múltiples sistemas operativos. Esta arquitectura es ideal para optimizar el uso de hardware infrautilizado y para entornos donde se requiere aislamiento lógico de bases de datos con presupuestos limitados.
- Optimización de hardware: Aprovecha ciclos de CPU y memoria RAM residuales.
- Aislamiento de servicios: Permite realizar tareas de mantenimiento o reinicios en una instancia sin afectar a las demás.
- Consideraciones de rendimiento: Es crucial monitorear la contienda de recursos (I/O de disco y CPU), ya que una instancia con consultas pesadas puede degradar el rendimiento de las instancias adyacentes.
Preparación del entorno y estructura de directorios
Antes de comenzar, se asume que los binarios de MySQL ya han sido compilados o instalados en el sistema. Para este ejemplo, utilizaremos los puertos 3306 y 3307 para diferenciar los servicios.
# Creación de la estructura de datos
mkdir -p /opt/mysql_instances/{3306,3307}/data
# Asignación de permisos al usuario del servicio
chown -R mysql:mysql /opt/mysql_instances
Configuración de variables de entorno
Para facilitar la administración, es recomendable añadir el directorio de binarios al PATH del sistema.
echo 'export PATH=/usr/local/mysql/bin:$PATH' >> /etc/profile
source /etc/profile
Inicialización de las instancias
Cada instancia reuqiere su propio diccionario de datos inicial. Utilizaremos el script mysql_install_db apuntando a los directorios específicos.
# Inicializar instancia 3306
mysql_install_db --user=mysql --basedir=/usr/local/mysql --datadir=/opt/mysql_instances/3306/data
# Inicializar instancia 3307
mysql_install_db --user=mysql --basedir=/usr/local/mysql --datadir=/opt/mysql_instances/3307/data
Archivo de configuración (my.cnf) por instancia
Cada instancia debe tener un archivo de configuración único donde se definan sockets y puertos distintos. A continuación, se muestra un ejemplo para la instancia 3306 (ubicado en /opt/mysql_instances/3306/my.cnf):
[mysqld]
port = 3306
socket = /opt/mysql_instances/3306/mysql.sock
basedir = /usr/local/mysql
datadir = /opt/mysql_instances/3306/data
pid-file = /opt/mysql_instances/3306/mysql.pid
log-error = /opt/mysql_instances/3306/error.log
# Parámetros de rendimiento básicos
max_connections = 500
table_open_cache = 512
innodb_buffer_pool_size = 64M
innodb_log_file_size = 16M
server-id = 101
Script de control personalizado
Para gestionar el ciclo de vida de cada base de datos, podemos implementar un script de shell dinámico dentro de cada directorio de instancia.
#!/bin/bash
# Script de gestión de instancia
INST_PORT=3306
DB_USER="root"
DB_PASS="admin_secret"
BIN_PATH="/usr/local/mysql/bin"
SOCK_FILE="/opt/mysql_instances/${INST_PORT}/mysql.sock"
CONF_FILE="/opt/mysql_instances/${INST_PORT}/my.cnf"
start_service() {
if [ ! -S "$SOCK_FILE" ]; then
echo "Iniciando MySQL en puerto ${INST_PORT}..."
/bin/sh ${BIN_PATH}/mysqld_safe --defaults-file=${CONF_FILE} > /dev/null 2>&1 &
else
echo "La instancia ya se encuentra activa."
fi
}
stop_service() {
if [ -S "$SOCK_FILE" ]; then
echo "Deteniendo instancia ${INST_PORT}..."
${BIN_PATH}/mysqladmin -u ${DB_USER} -p${DB_PASS} -S ${SOCK_FILE} shutdown
else
echo "No se encontró el socket de la instancia."
fi
}
case "$1" in
start) start_service ;;
stop) stop_service ;;
restart) stop_service; sleep 3; start_service ;;
*) echo "Uso: $0 {start|stop|restart}" ;;
esac
Gestión y Acceso
Al tener múltiples procesos escuchando, la conexión local debe especificar el socket, mientras que las conexiones remotas deben indicar el puerto TCP correspondiente.
Acceso local mediante Socket:
mysql -u root -p -S /opt/mysql_instances/3306/mysql.sock
Acceso remoto mediante Puerto:
mysql -u root -p -h 192.168.1.50 -P 3307
Resolución de problemas comunes
Si una instancia no inicia y el mensaje indica que el servicio ya está en ejecución ("MySQL is running"), pero no hay respuseta, es probable que existan archivos residuales de un cierre inesperado. Verifique y elimine los archivos de bloqueo si el proceso no existe en el sistema:
rm -f /opt/mysql_instances/3306/mysql.sock
rm -f /opt/mysql_instances/3306/mysql.pid