ProxySQL es un proxy para bases de datos MySQL que mejora el rendimiento, la escalabilidad y la disponibilidad del sistema. Actúa como una capa intermedia entre la aplicación y los servidores de bases de datos, gestionando las conexiones y optimizando la ejecución de consultas.
Una base de datos MySQL puede enfrentar problemas de rendimiento y disponibilidad.
Para entender su funcionamiento, imagina que es un intermediario entre la aplicación y MySQL:
Nos conectamos al nodo y entramos a la consola de mysql, en caso de que nos pida contraseña utilizaremos "root", por ejemplo:
vagrant ssh pxc-node-1
sudo mysql
En el nodo 1 creamos el usuario SST
CREATE USER 'sstuser'@'%' IDENTIFIED BY 'temporal1';
GRANT RELOAD, LOCK TABLES, PROCESS, REPLICATION CLIENT ON *.* TO 'sstuser'@'%';
FLUSH PRIVILEGES;
En cada nodo cambiamos la configuracion para agregarlo al cluster.
Editar el siguiente archivo:
sudo nano /etc/mysql/percona-xtradb-cluster.conf.d/wsrep.cnf
Cambiamos unicamente la siguiente informacion:
wsrep_cluster_address=gcomm://192.168.56.11,192.168.56.12,192.168.56.13
wsrep_node_address=<ip_nodo>
# Nombre del nodo de preferencia la terminacion de la ip
wsrep_node_name=pxc-cluster-node-1
pxc_strict_mode=PERMISSIVE
# La misma contraseña del usuario SST
wsrep_sst_auth="sstuser:temporal1"
Nuestro archivo deberia verse de la siguiente manera pero con las configuraciones correspondientes al nodo actual,
[mysqld]
# Path to Galera library
wsrep_provider=/usr/lib/galera3/libgalera_smm.so
# Cluster connection URL contains IPs of nodes
#If no IP is found, this implies that a new cluster needs to be created,
#in order to do that you need to bootstrap this node
wsrep_cluster_address=gcomm://192.168.56.11,192.168.56.12,192.168.56.13
# In order for Galera to work correctly binlog format should be ROW
binlog_format=ROW
# MyISAM storage engine has only experimental support
default_storage_engine=InnoDB
# Slave thread to use
wsrep_slave_threads=2
wsrep_log_conflicts
# This changes how InnoDB autoincrement locks are managed and is a requirement for Galera
innodb_autoinc_lock_mode=2
# Node IP address
wsrep_node_address=192.168.56.11
# Cluster name
wsrep_cluster_name=pxc-cluster
#If wsrep_node_name is not specified, then system hostname will be used
wsrep_node_name=pxc-cluster-node-1
#pxc_strict_mode allowed values: DISABLED,PERMISSIVE,ENFORCING,MASTER
pxc_strict_mode=PERMISSIVE
# SST method
wsrep_sst_method=xtrabackup-v2
#Authentication for SST method
wsrep_sst_auth="sstuser:temporal1"
3.1 Iniciar el primer nodo
En todos los nodos detenemos mysql:
Una vez que hemos finalizado al configuración de nuestros 3 nodos, accedemos al nodo 1 y lo inicializamos usando el siguiente comando
sudo /etc/init.d/mysql bootstrap-pxc
Este comando iniciara nuestro nodo pero ademas indicara que es nuestro nodo principal
3.2 Iniciar el segundo y tercer nodo
Accedemos a los nodos 2 y 3 respectivamente y ejecutamos el siguiente comando
sudo /etc/init.d/mysql start
Eso inicializara nuestro nodo y deberia sincrinizarse con nuestro nodo principal, nodo 1
Una vez hecho esto accedemos a mysql
Y vamos a verificar el estado de nuestro cluster usando el siguiente comando
show status like 'wsrep%';
La salida de nuestro comando deberia mostrarnos que el tamaño del cluster es de 3 nodos, podemos observarlo en la variable wsrep_cluster_size.
+----------------------------+--------------------------------------+
| Variable_name | Value |
+----------------------------+--------------------------------------+
| wsrep_local_state_uuid | b598af3e-ace3-11e2-0800-3e90eb9cd5d3 |
| wsrep_local_state | 4 |
| wsrep_local_state_comment | Synced |
| wsrep_cluster_size | 2 |
| wsrep_cluster_status | Primary |
| wsrep_connected | ON |
| wsrep_ready | ON |
+----------------------------+--------------------------------------+
40 rows in set (0.01 sec)
3.3 Crear base de datos
Para poder realizar las pruebas podemos crear una base de datos con datos de prueba, para el ejercicio trabajaremos con la siguiente base de datos: CompanyDB
Creamos una base de datos desde cualquier nodo del cluster.
sudo mysql -e "CREATE DATABASE companydb;"
En el mismo nodo descargamos el archivo backup para crear las tablas y los registros.
sudo apt install unzip
wget https://ahkinws.s3.amazonaws.com/media/chat/media/nowe/1035335611310920-2024-08-29-15-59-27.zip
unzip 1035335611310920-2024-08-29-15-59-27.zip -d $(pwd)
Mandamos a aplicar el backup.
sudo mysql companydb < backup.sql
Si te da error importar la base de datos, porque el collation no corresponde a tu version de MySQL, puede ejecutar lo siguiente:
sed -i 's/utf8mb4_0900_ai_ci/utf8mb4_unicode_ci/g' backup.sql # Actualizar la bd
3.4 Comprobación
Esto nos importara la información de la base de datos que creamos previamente, ademas, al tener configurados nuestros nodos deberia replicarse la información de nuestra base de datos, para ello podemos comprobarlo accediendo a mysql en alguno de nuestros nodos
sudo mysql -e "use companydb; show tables;"
La salida del comando deberia mostrarnos las tablas de la base de datos que creamos.
+---------------------+
| Tables_in_companydb |
+---------------------+
| Companies |
| Customers |
| Invoices |
| Purchases |
+---------------------+
Una vez hecho esto en ambos nodos nuestro cluster deberia estar configurado correctamente por lo que ya podriamos realizar nuestras pruebas de replicación.
5.1. Instalación
Ingresamos a la maquina del proxy
Añadimos el repositorio para la instalación
sudo apt-get install -y --no-install-recommends net-tools lsb-release wget apt-transport-https ca-certificates gnupg
wget -O - 'https://repo.proxysql.com/ProxySQL/proxysql-2.5.x/repo_pub_key' | sudo apt-key add -
sudo echo deb https://repo.proxysql.com/ProxySQL/proxysql-2.5.x/$(lsb_release -sc)/ ./ | sudo tee /etc/apt/sources.list.d/proxysql.list
sudo apt-get update
sudo apt-get install proxysql
Una vez instalado tenemos que inicializarlo:
sudo systemctl start proxysql
Podemos ver que está activo y escuchando en dos puertos TCP y dos sockets
sudo netstat -lpn | grep proxysql
El puerto 6032 es para administrar ProxySQL, mientras que el 6033 es para conexiones de clientes a servicios backend de MySQL. Por supuesto, el segundo aún no está listo, pero ya podemos iniciar sesión en la consola de administración de ProxySQL.
tcp 0 0 0.0.0.0:6032 0.0.0.0:* LISTEN 8003/proxysql
tcp 0 0 0.0.0.0:6033 0.0.0.0:* LISTEN 8003/proxysql
tcp 0 0 0.0.0.0:6033 0.0.0.0:* LISTEN 8003/proxysql
tcp 0 0 0.0.0.0:6033 0.0.0.0:* LISTEN 8003/proxysql
tcp 0 0 0.0.0.0:6033 0.0.0.0:* LISTEN 8003/proxysql
Para acceder al servicio de proxysql necesitaremos instalar el cliente de MySQL
sudo apt install -y mysql-client-core-8.0
Acceder a la consola de administración de ProxySQL usando el cliente de MySQL.
mysql -u admin -padmin -h 127.0.0.1 -P 6032
5.2. Configurar los nodos del cluster
Para configurar los nodos backend del clúster Percona XtraDB en ProxySQL, inserte los registros correspondientes en la tabla mysql_servers.
Antes de agregar cualquier cosa, vamos a ver que servers estan en el runtime
SELECT * from mysql_servers;
SELECT * from runtime_mysql_servers;
Este ejemplo agrega tres nodos del clúster Percona XtraDB al grupo de hosts predeterminado 1, 2 y 3, y decidiremos cuál es el lector HG y cuál es el grupo de hosts RW.
INSERT INTO mysql_servers
(hostgroup_id, hostname, port, status, weight, max_connections) VALUES
-- Servidores para lectura
(1, '192.168.56.12', 3306, 'ONLINE', 1000, 10000),
(1, '192.168.56.13', 3306, 'ONLINE', 1000, 10000),
-- Servidores para escritura
(2, '192.168.56.11', 3306, 'ONLINE', 1000, 10000),
-- Servidores para backup escritura
(3, '192.168.56.13', 3306, 'ONLINE', 1000, 10000);
-- Debemos cargarlo en el runtime para que ProxySQL empiece a usarlo
LOAD MYSQL SERVERS TO RUNTIME;
-- Tambien debemos agregarlo al disco para que sea persistente en los reinicios.
SAVE MYSQL SERVERS TO DISK;
Podemos consultamos que los servidores se allan configurado con los siguiente comandos
SELECT * FROM mysql_servers;
SELECT * FROM runtime_mysql_servers;
5.3. Configurar los Host Groups
Ahora podemos configurar el comportamiento de ProxySQL para nuestro clúster PXC. Configuramos max_writers=1 y queremos un escritor dedicado, que no manejaría el tráfico SELECT (writer_is_also_reader=0) en la configuración actual.
INSERT INTO mysql_galera_hostgroups (
reader_hostgroup,
writer_hostgroup,
backup_writer_hostgroup,
offline_hostgroup,
active,
max_writers,
writer_is_also_reader,
max_transactions_behind,
comment
) VALUES (
1, -- Hostgroup de nodos en modo lectura (pxc-node-2 y pxc-node-3)
2, -- Hostgroup de nodos en modo escritura (pxc-node-1)
3, -- Hostgroup de nodos en modo escritura backup (pxc-node-3)
99, -- Hostgroup de nodos offline
1, -- Activo
1, -- Solo 1 nodo puede estar en modo escritura
0, -- Los nodos de escritura NO atenderán lecturas
100,-- Límite de transacciones en espera antes de marcar un nodo como saturado
'Pycun Galera Conf' --
);
select * from mysql_galera_hostgroups;
+------------------+-------------------------+------------------+-------------------+--------+-------------+-----------------------+-------------------------+-------------------+
| writer_hostgroup | backup_writer_hostgroup | reader_hostgroup | offline_hostgroup | active | max_writers | writer_is_also_reader | max_transactions_behind | comment |
+------------------+-------------------------+------------------+-------------------+--------+-------------+-----------------------+-------------------------+-------------------+
| 2 | 3 | 1 | 99 | 1 | 1 | 0 | 100 | Pycun Galera Conf |
+------------------+-------------------------+------------------+-------------------+--------+-------------+-----------------------+-------------------------+-------------------+
1 row in set (0.00 sec)
5.4. Crear un usuario de monitoreo ProxySQL
Para habilitar la supervisión de los nodos del clúster Percona XtraDB en ProxySQL, cree un usuario con privilegios de USO en cualquier nodo del clúster y configure el usuario en ProxySQL.
Agrega un usuario de monitoreo en cualquier nodo del cluster
vagrant ssh pxc-node-2
sudo mysql
Como esta la replicación el usuario se creara en todos los nodos del cluster
CREATE USER 'proxysql_monitor'@'%' IDENTIFIED WITH mysql_native_password by 'ProxySQLPa55';
GRANT USAGE ON *.* TO 'proxysql_monitor'@'%';
Configura este usuario en el nodo ProxySQL:
UPDATE global_variables SET variable_value='proxysql_monitor' WHERE variable_name='mysql-monitor_username';
UPDATE global_variables SET variable_value='ProxySQLPa55' WHERE variable_name='mysql-monitor_password';
-- Debemos cargarlo en el runtime para que ProxySQL empiece a usarlo
LOAD MYSQL VARIABLES TO RUNTIME;
-- Tambien debemos agregarlo al disco para que sea persistente en los reinicios.
SAVE MYSQL VARIABLES TO DISK;
5.5. Definir las reglas de consulta para la división R/W
Ahora es el momento de definir las reglas de consulta, que manejarán la división de lectura/escritura. El default_hostgroup para el usuario de la aplicación en la tabla mysql_users está configurado en 1, es decir, el grupo de hosts del escritor.
Primera regla: el procesador de consultas escanea la regla de consulta para encontrar una coincidencia para el patrón ^SELECT.*
y, si se encuentra una coincidencia, proxysql reenviará estas consultas a destino_hostgroup=1;
Segunda regla: las consultas con un patrón ^(INSERT|UPDATE|DELETE).*
siempre deben entregarse desde el grupo de hosts del escritor, por lo que configuramos el destino_hostgroup=2;
INSERT INTO mysql_query_rules
(active, match_digest, destination_hostgroup, apply) VALUES
-- Enviar SELECT a nodos de Lectura con el grupo 1
(1, '^SELECT.*', 1, 0),
-- Enviar INSERT, UPDATE y DELETE a nodos de escritura con el grupo 2
(1, '^(INSERT|UPDATE|DELETE).*',2, 1);
-- Debemos cargarlo en el runtime para que ProxySQL empiece a usarlo
LOAD MYSQL QUERY RULES TO RUNTIME;
-- Tambien debemos agregarlo al disco para que sea persistente en los reinicios.
SAVE MYSQL QUERY RULES TO DISK;
5.6 Importar usuarios de MySQL a ProxySQL
Importante: asegúrese de utilizar el complemento de autenticación predeterminado = mysql_native_password, ya que proxysql no admite caching_sha2_password en el momento de escribir este artículo. Para mas información puede consultar [ProxySQL Support for MySQL caching_sha2_password]https://www.percona.com/blog/proxysql-support-for-mysql-caching_sha2_password/(http://)
INSERT INTO mysql_users (username, password, active, default_hostgroup, transaction_persistent) VALUES ('apps', 'It_is_so_Secure1', 1, 2, 1);
-- Debemos cargarlo en el runtime para que ProxySQL empiece a usarlo
LOAD MYSQL USERS TO RUNTIME;
-- Tambien debemos agregarlo al disco para que sea persistente en los reinicios.
SAVE MYSQL USERS TO DISK;
Crear el usuario igual en el cluster
CREATE USER 'apps'@'%' IDENTIFIED BY 'It_is_so_Secure1';
GRANT ALL PRIVILEGES ON *.* TO 'apps'@'%' WITH GRANT OPTION;
FLUSH PRIVILEGES;
5.7 Ahora desde la maquina pxc-app nos conectamos como cliente a la instancia de ProxySQL
Instalamos el cliente de MySQL
sudo apt update
sudo apt install -y mysql-client-core-8.0
Nos conectamos como cliente de la aplicación
mysql -h 192.168.56.14 -P 6033 -u apps -pIt_is_so_Secure1
5.8 Pruebas
En este comando solo debe consultar pxc-node-2 y pxc-node-3
mysql companydb -u apps -pIt_is_so_Secure1 -h 192.168.56.14 -P 6033 -e "select @@hostname;"
En este comando solo debe insertart pxc-node-1
mysql companydb -u apps -pIt_is_so_Secure1 -h 192.168.56.14 -P 6033 -e "INSERT INTO Companies (Name, Address, Phone, Email) VALUES (CONCAT('Empresa por: ', @@hostname), 'Calle Falsa 123, Ciudad X', '555-1234', '[email protected]'); SELECT CompanyID, Name from Companies order by CompanyID desc limit 3"