{"id":2386,"date":"2026-04-24T16:18:19","date_gmt":"2026-04-24T16:18:19","guid":{"rendered":"https:\/\/dsantana.uas.edu.mx\/?p=2386"},"modified":"2026-04-24T18:27:01","modified_gmt":"2026-04-24T18:27:01","slug":"mysql-en-debian-13-4-cluster-de-alta-disponibilidad-con-drbd-y-replicacion-nativa","status":"publish","type":"post","link":"https:\/\/dsantana.uas.edu.mx\/index.php\/2026\/04\/24\/mysql-en-debian-13-4-cluster-de-alta-disponibilidad-con-drbd-y-replicacion-nativa\/","title":{"rendered":"MySQL en Debian 13.4 \u2014 Cl\u00faster de Alta Disponibilidad con DRBD y Replicaci\u00f3n Nativa"},"content":{"rendered":"\n<figure class=\"wp-block-image aligncenter size-full\"><img fetchpriority=\"high\" decoding=\"async\" width=\"1024\" height=\"1024\" src=\"https:\/\/dsantana.uas.edu.mx\/wp-content\/uploads\/2026\/04\/Guia-Tecnica-MySQL-en-Debian-134-\u2014-Cluster-de-Alt.png\" alt=\"\" class=\"wp-image-2389\" srcset=\"https:\/\/dsantana.uas.edu.mx\/wp-content\/uploads\/2026\/04\/Guia-Tecnica-MySQL-en-Debian-134-\u2014-Cluster-de-Alt.png 1024w, https:\/\/dsantana.uas.edu.mx\/wp-content\/uploads\/2026\/04\/Guia-Tecnica-MySQL-en-Debian-134-\u2014-Cluster-de-Alt-300x300.png 300w, https:\/\/dsantana.uas.edu.mx\/wp-content\/uploads\/2026\/04\/Guia-Tecnica-MySQL-en-Debian-134-\u2014-Cluster-de-Alt-150x150.png 150w, https:\/\/dsantana.uas.edu.mx\/wp-content\/uploads\/2026\/04\/Guia-Tecnica-MySQL-en-Debian-134-\u2014-Cluster-de-Alt-768x768.png 768w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">Objetivos del Laboratorio<\/h2>\n\n\n\n<p><strong>Objetivo general:<\/strong> Implementar un <strong>cl\u00faster de alta disponibilidad<\/strong> de MySQL 8.0 en <strong>Debian 13.4<\/strong> utilizando <strong>DRBD<\/strong> para replicaci\u00f3n de almacenamiento a nivel de bloque y configurando simult\u00e1neamente la <strong>replicaci\u00f3n nativa de MySQL<\/strong> (Primary\u2011Replica). El entorno final constar\u00e1 de <strong>dos nodos (nodo\u2011a y nodo\u2011b)<\/strong> capaces de garantizar continuidad del servicio de base de datos, replicaci\u00f3n s\u00edncrona de almacenamiento y sincronizaci\u00f3n a nivel de transacciones SQL.<\/p>\n\n\n\n<p><strong>Objetivos espec\u00edficos:<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><th>#<\/th><th>Objetivo<\/th><th>Alcance<\/th><\/tr><tr><td>1<\/td><td>Comprender qu\u00e9 es MySQL<\/td><td>Definici\u00f3n, caracter\u00edsticas clave, modelo relacional<\/td><\/tr><tr><td>2<\/td><td>Identificar la estructura de archivos de MySQL<\/td><td><code>datadir<\/code>, InnoDB, logs, socket, configuraci\u00f3n<\/td><\/tr><tr><td>3<\/td><td>Instalar MySQL 8.0 en Debian 13.4<\/td><td>Repositorio oficial Oracle, configuraci\u00f3n segura<\/td><\/tr><tr><td>4<\/td><td>Integrar MySQL en cl\u00faster HA<\/td><td>DRBD + Pacemaker\/Corosync, datadir sobre volumen replicado<\/td><\/tr><tr><td>5<\/td><td>Configurar replicaci\u00f3n nativa MySQL<\/td><td>Primary\u2011Replica, usuario de replicaci\u00f3n, binlog, verificaci\u00f3n<\/td><\/tr><tr><td>6<\/td><td>Validar y documentar pruebas<\/td><td>Failover, integridad de datos, problemas comunes<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><strong>Nota sobre las referencias del laboratorio previo:<\/strong> Las pr\u00e1cticas publicadas en <code>dsantana.uas.edu.mx<\/code> \u2014sobre implementaci\u00f3n de cl\u00faster HA, DRBD en Debian 13.4 y cl\u00faster de alta disponibilidad en Debian 13\u2014 no pudieron consultarse directamente durante la investigaci\u00f3n. La presente gu\u00eda se construye sobre documentaci\u00f3n oficial de MySQL (Oracle), gu\u00edas t\u00e9cnicas verificadas de instalaci\u00f3n en Debian, y referencias de configuraci\u00f3n de Pacemaker\/Corosync\/DRBD, aline\u00e1ndose con los principios y arquitectura descritos en dichas pr\u00e1cticas previas.<\/p>\n<\/blockquote>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"1024\" height=\"379\" src=\"https:\/\/dsantana.uas.edu.mx\/wp-content\/uploads\/2026\/04\/image-3-1024x379.png\" alt=\"\" class=\"wp-image-2387\" srcset=\"https:\/\/dsantana.uas.edu.mx\/wp-content\/uploads\/2026\/04\/image-3-1024x379.png 1024w, https:\/\/dsantana.uas.edu.mx\/wp-content\/uploads\/2026\/04\/image-3-300x111.png 300w, https:\/\/dsantana.uas.edu.mx\/wp-content\/uploads\/2026\/04\/image-3-768x284.png 768w, https:\/\/dsantana.uas.edu.mx\/wp-content\/uploads\/2026\/04\/image-3-1536x569.png 1536w, https:\/\/dsantana.uas.edu.mx\/wp-content\/uploads\/2026\/04\/image-3-2048x758.png 2048w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<h2 class=\"wp-block-heading\">1. \u00bfQu\u00e9 es MySQL?<\/h2>\n\n\n\n<p>MySQL es un <strong>sistema de gesti\u00f3n de bases de datos relacionales (RDBMS) de c\u00f3digo abierto<\/strong> que se utiliza para almacenar y gestionar datos. Su fiabilidad, rendimiento, escalabilidad y facilidad de uso lo han convertido en una opci\u00f3n popular para desarrolladores en aplicaciones de alto tr\u00e1fico como <strong>Facebook, Netflix, Uber, Airbnb, Shopify y Booking.com<\/strong>. En 2024, MySQL se clasifica como la <strong>segunda base de datos m\u00e1s popular en general<\/strong>, solo superada por Oracle Database seg\u00fan DB\u2011Engines, y es el <strong>RDBMS de c\u00f3digo abierto m\u00e1s popular del mundo<\/strong>.<\/p>\n\n\n\n<p>MySQL utiliza el lenguaje <strong>SQL (Structured Query Language)<\/strong> para recuperar, actualizar, suprimir y manipular datos en bases de datos relacionales. Se pronuncia oficialmente \u00abMy es\u2011kiu\u2011el\u00bb. Como base de datos relacional, almacena datos en <strong>tablas de filas y columnas organizadas en esquemas<\/strong>, donde un esquema define c\u00f3mo se organizan y almacenan los datos y describe la relaci\u00f3n entre varias tablas. Recientemente, Oracle ha a\u00f1adido soporte para el tipo de datos <strong>JSON<\/strong> y <strong>vectores<\/strong>, ampliando su versatilidad.<\/p>\n\n\n\n<p><strong>Caracter\u00edsticas fundamentales:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Transacciones ACID:<\/strong> Soporta atomicidad, consistencia, aislamiento y durabilidad, garantizando que las modificaciones de datos se realicen de manera coherente y fiable, incluso en caso de un fallo del sistema.<\/li>\n\n\n\n<li><strong>C\u00f3digo abierto:<\/strong> Disponible bajo <strong>GNU General Public License (GPL)<\/strong>, lo que permite descargarlo y usarlo sin costo. Tambi\u00e9n existe una versi\u00f3n con licencia comercial para quienes deseen incorporar c\u00f3digo MySQL en aplicaciones propietarias.<\/li>\n\n\n\n<li><strong>Rendimiento y escalabilidad:<\/strong> La arquitectura de <strong>replicaci\u00f3n nativa<\/strong> de MySQL permite a organizaciones como Facebook escalar aplicaciones para admitir miles de millones de usuarios. MySQL puede manejar un alto volumen de conexiones simult\u00e1neas.<\/li>\n\n\n\n<li><strong>Alta disponibilidad:<\/strong> Ofrece tecnolog\u00edas de replicaci\u00f3n nativas e integradas que permiten lograr un objetivo de punto de recuperaci\u00f3n cero y un objetivo de tiempo de recuperaci\u00f3n de cero segundos mediante conmutaci\u00f3n autom\u00e1tica por error.<\/li>\n\n\n\n<li><strong>Arquitectura cliente\/servidor:<\/strong> MySQL Database es un sistema que consta de un servidor SQL multihilo con diferentes backends, varios programas y bibliotecas cliente, herramientas administrativas y una amplia variedad de APIs.<\/li>\n\n\n\n<li><strong>Compatibilidad:<\/strong> Amplia compatibilidad con plataformas tecnol\u00f3gicas y lenguajes de programaci\u00f3n, incluyendo <strong>Java, Python, PHP y JavaScript<\/strong>. Admite replicaci\u00f3n entre versiones (p. ej., MySQL 5.7 a MySQL 8.0).<\/li>\n\n\n\n<li><strong>Seguridad:<\/strong> En su edici\u00f3n Enterprise incluye autenticaci\u00f3n\/autorizaci\u00f3n avanzada, cifrado transparente de datos, auditor\u00eda, enmascaramiento de datos y firewall de base de datos.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">2. Estructura del Sistema de Archivos y Componentes de MySQL<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">2.1 Directorio de datos (<code>datadir<\/code>)<\/h3>\n\n\n\n<p>El <code>datadir<\/code> es la <strong>carpeta principal donde el servidor MySQL almacena todos los archivos relacionados con las bases de datos<\/strong>. En instalaciones desde repositorios (apt, yum) en Linux, la ubicaci\u00f3n m\u00e1s com\u00fan es <strong><code>\/var\/lib\/mysql\/<\/code><\/strong>. Este valor est\u00e1 definido por la variable del sistema <code>data_dir<\/code>, cuyo valor por defecto es <code>\/var\/lib\/mysql<\/code>. Para consultar el datadir activo, puede ejecutarse dentro de MySQL la sentencia <code>SHOW VARIABLES LIKE 'datadir';<\/code>.<\/p>\n\n\n\n<p>Dentro del <code>datadir<\/code> se encuentra:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Un <strong>subdirectorio por cada base de datos<\/strong> (con nombre hom\u00f3nimo), conteniendo los archivos de tablas del motor correspondiente.<\/li>\n\n\n\n<li>Archivos globales del motor <strong>InnoDB<\/strong> (espacio de tablas compartido, logs de recuperaci\u00f3n).<\/li>\n\n\n\n<li>Archivos de definici\u00f3n de estructura de tablas.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">2.2 Motor de almacenamiento InnoDB<\/h3>\n\n\n\n<p><strong>InnoDB<\/strong> es el motor de almacenamiento predeterminado en MySQL 8.0 y act\u00faa como la capa intermedia entre el almacenamiento y el servidor MySQL, almacenando los datos en las unidades de disco. Su funcionamiento de E\/S se clasifica en dos tipos: <strong>I\/O de archivo aleatorio<\/strong> (archivos de datos) y <strong>E\/S de archivo secuencial<\/strong> (registros de recuperaci\u00f3n y binarios).<\/p>\n\n\n\n<p>Componentes clave de InnoDB en el <code>datadir<\/code>:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><th>Componente<\/th><th>Descripci\u00f3n<\/th><\/tr><tr><th><strong>Espacio de tablas compartido<\/strong> (<code>ibdata1<\/code>)<\/th><td>Contiene metadatos de InnoDB y datos de tablas que no usan <em>file\u2011per\u2011table<\/em>. Con <code>innodb_file_per_table<\/code> activado (predeterminado en MySQL 8), cada tabla se almacena en archivos <code>.ibd<\/code> independientes.<\/td><\/tr><tr><th><strong>Logs de recuperaci\u00f3n (redo logs)<\/strong><\/th><td>Registros transaccionales escritos secuencialmente para garantizar la recuperaci\u00f3n tras fallos.<\/td><\/tr><tr><th><strong>Buffer de doble escritura<\/strong><\/th><td>InnoDB escribe p\u00e1ginas primero en un buffer y luego en sus posiciones correctas en los archivos de datos, evitando la corrupci\u00f3n de p\u00e1ginas si se produce un fallo de alimentaci\u00f3n durante la escritura.<\/td><\/tr><tr><th><strong>Buffer de inserci\u00f3n<\/strong><\/th><td>Reduce operaciones de E\/S aleatorias fusionando escrituras en \u00edndices secundarios no \u00fanicos.<\/td><\/tr><tr><th><strong>Segmentos de deshacer (undo)<\/strong><\/th><td>Registran im\u00e1genes anteriores de los datos para la concurrencia multiversi\u00f3n (MVCC).<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">2.3 Archivos de registro (logs)<\/h3>\n\n\n\n<p>MySQL dispone de <strong>cuatro tipos principales de archivos de log<\/strong>:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><th>Tipo de log<\/th><th>Descripci\u00f3n<\/th><th>Ruta t\u00edpica (Debian)<\/th><th>Activado por defecto<\/th><\/tr><tr><th><strong>Registro de errores<\/strong><\/th><td>Registra problemas al iniciar, ejecutar o parar <code>mysqld<\/code><\/td><td><code>\/var\/log\/mysql\/error.log<\/code><\/td><td>S\u00ed<\/td><\/tr><tr><th><strong>Registro de consultas generales<\/strong><\/th><td>Registra todas las conexiones y sentencias ejecutadas<\/td><td><code>datadir\/&lt;hostname>.log<\/code><\/td><td>No<\/td><\/tr><tr><th><strong>Registro binario (binlog)<\/strong><\/th><td>Registra todas las sentencias que cambian datos; <strong>utilizado en la replicaci\u00f3n<\/strong><\/td><td><code>datadir\/mysql-bin.*<\/code> (si se activa <code>log_bin<\/code>)<\/td><td>No<\/td><\/tr><tr><th><strong>Registro de consultas lentas<\/strong><\/th><td>Registra sentencias que exceden el tiempo definido por <code>long_query_time<\/code> (predeterminado: <strong>10 segundos<\/strong>)<\/td><td><code>datadir\/&lt;hostname&gt;-slow.log<\/code><\/td><td>No<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Por defecto, todos los archivos de log se crean en el directorio de datos, aunque distribuciones Debian\/Ubuntu suelen redirigir el log de errores a <code>\/var\/log\/mysql\/error.log<\/code> mediante la variable <code>log_error<\/code>.<\/p>\n\n\n\n<p>El <strong>registro binario<\/strong> merece atenci\u00f3n especial para este laboratorio: es la base de la <strong>replicaci\u00f3n nativa de MySQL<\/strong>. Debe habilitarse configurando <code>log_bin<\/code> en el archivo de configuraci\u00f3n. Cada archivo binlog se escribe secuencialmente y contiene las operaciones de escritura (INSERT, UPDATE, DELETE). Los binlogs cumplen tres funciones principales: <strong>restauraci\u00f3n<\/strong> punto en el tiempo, <strong>replicaci\u00f3n<\/strong> entre servidores, y <strong>auditor\u00eda<\/strong> de seguridad.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">2.4 Archivo de socket Unix<\/h3>\n\n\n\n<p>El archivo <code>mysqld.sock<\/code> es un <strong>punto final de comunicaci\u00f3n<\/strong> que permite que el servidor MySQL y las aplicaciones cliente en la misma m\u00e1quina se comuniquen de manera local sin pasar por la red TCP\/IP. En sistemas Debian\/Ubuntu, este socket se encuentra normalmente en <strong><code>\/var\/run\/mysqld\/mysqld.sock<\/code><\/strong>. Se configura mediante la directiva <code>socket<\/code> en el archivo <code>my.cnf<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">2.5 Archivo PID y archivo de configuraci\u00f3n<\/h3>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Archivo PID<\/strong> (<code>mysqld.pid<\/code>): Contiene el ID de proceso del demonio MySQL activo; se encuentra controlado por el par\u00e1metro <code>pid_file<\/code> y por defecto reside en el directorio de la base de datos o en <code>\/var\/run\/mysqld\/<\/code>.<\/li>\n\n\n\n<li><strong>Archivo de configuraci\u00f3n principal:<\/strong> En Debian\/Ubuntu, el archivo es <strong><code>\/etc\/mysql\/mysql.conf.d\/mysqld.cnf<\/code><\/strong> (incluido desde <code>\/etc\/mysql\/my.cnf<\/code>). Aqu\u00ed se definen directivas como <code>datadir<\/code>, <code>bind-address<\/code>, <code>socket<\/code>, <code>log_error<\/code>, par\u00e1metros de InnoDB, y opciones de replicaci\u00f3n. <\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">2.6 Par\u00e1metros de configuraci\u00f3n relevantes<\/h3>\n\n\n\n<p>Los par\u00e1metros de MySQL se dividen en <strong>din\u00e1micos<\/strong> (modificables en tiempo de ejecuci\u00f3n con <code>SET<\/code>) y <strong>est\u00e1ticos<\/strong> (requieren reinicio del servicio). Algunos par\u00e1metros clave:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><th>Par\u00e1metro<\/th><th>Tipo<\/th><th>Descripci\u00f3n<\/th><\/tr><tr><td><code>innodb_buffer_pool_size<\/code><\/td><td>Est\u00e1tico<\/td><td>Tama\u00f1o del buffer de datos\/\u00edndices InnoDB en memoria<\/td><\/tr><tr><td><code>log_bin<\/code><\/td><td>Est\u00e1tico<\/td><td>Activa registro binario para replicaci\u00f3n<\/td><\/tr><tr><td><code>server_id<\/code><\/td><td>Est\u00e1tico<\/td><td>Identificador \u00fanico del servidor en topolog\u00eda de replicaci\u00f3n<\/td><\/tr><tr><td><code>bind-address<\/code><\/td><td>Est\u00e1tico<\/td><td>Direcci\u00f3n IP en la que MySQL escucha conexiones<\/td><\/tr><tr><td><code>sync_binlog<\/code><\/td><td>Din\u00e1mico<\/td><td>Frecuencia de sincronizaci\u00f3n del binlog al disco; <code>1<\/code> = m\u00e1xima seguridad<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">2.7 Permisos y AppArmor<\/h3>\n\n\n\n<p>MySQL ejecuta bajo el usuario del sistema <code>mysql<\/code>. Todos los archivos del <code>datadir<\/code> deben pertenecer a <code>mysql:mysql<\/code>. En distribuciones Debian\/Ubuntu, <strong>AppArmor<\/strong> confina el proceso <code>mysqld<\/code> mediante un perfil en <code>\/etc\/apparmor.d\/usr.sbin.mysqld<\/code>. Si se cambia la ubicaci\u00f3n del <code>datadir<\/code> (como haremos al usar DRBD), <strong>deben ajustarse las reglas de AppArmor<\/strong> para incluir las nuevas rutas; de lo contrario, MySQL podr\u00eda no iniciar por restricciones de acceso.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">3. Instalaci\u00f3n de MySQL 8.0 en Debian 13.4<\/h2>\n\n\n\n<p><strong>Debian incluye MariaDB por defecto en sus repositorios<\/strong> en lugar de MySQL. Para instalar MySQL 8 se requiere usar el <strong>repositorio oficial de MySQL de Oracle<\/strong>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Prerrequisitos del laboratorio<\/h3>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><th>Elemento<\/th><th>Valor de ejemplo<\/th><\/tr><tr><th><strong>nodo\u2011a<\/strong> (Primary)<\/th><td>IP: 192.168.1.101<\/td><\/tr><tr><th><strong>nodo\u2011b<\/strong> (Replica)<\/th><td>IP: 192.168.1.102<\/td><\/tr><tr><th><strong>Red del cl\u00faster<\/strong><\/th><td>192.168.1.0\/24<\/td><\/tr><tr><th><strong>IP virtual (flotante)<\/strong><\/th><td>192.168.1.150<\/td><\/tr><tr><th><strong>Disco DRBD<\/strong><\/th><td><code>\/dev\/sdb1<\/code> (~10 GB en cada nodo)<\/td><\/tr><tr><th><strong>Punto de montaje DRBD<\/strong><\/th><td><code>\/mysql<\/code><\/td><\/tr><tr><th><strong>SO<\/strong><\/th><td>Debian 13.4 (Trixie)<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>Las direcciones IP son ejemplos. Ajuste seg\u00fan su entorno. Aseg\u00farese de que ambos nodos se resuelvan mutuamente (v\u00eda DNS o <code>\/etc\/hosts<\/code>) y que los puertos <strong>3306<\/strong> (MySQL), <strong>7789<\/strong> (DRBD), <strong>5404\/5405 UDP<\/strong> (Corosync) y <strong>SSH<\/strong> est\u00e9n abiertos entre ellos.<\/p>\n<\/blockquote>\n\n\n\n<h3 class=\"wp-block-heading\">3.1 Paso a paso de instalaci\u00f3n<\/h3>\n\n\n\n<p><strong>Paso 1 \u2014 Actualizar el sistema e instalar dependencias.<\/strong><br>En <strong>cada nodo:<\/strong><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>sudo apt update<\/p>\n\n\n\n<p>sudo apt upgrade -y<\/p>\n\n\n\n<p>sudo apt install -y lsb-release gnupg curl<br><\/p>\n\n\n\n<p>El paquete <code>lsb-release<\/code> proporciona informaci\u00f3n sobre la distribuci\u00f3n y <code>gnupg<\/code> es necesario para verificar la autenticidad de paquetes.<\/p>\n\n\n\n<p><strong>Paso 2 \u2014 Habilitar el repositorio oficial de MySQL.<\/strong><br>Descargue el paquete de configuraci\u00f3n del repositorio MySQL APT desde la https:\/\/dev.mysql.com\/downloads\/repo\/apt\/:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>curl -OL https:\/\/dev.mysql.com\/get\/mysql-apt-config_0.8.24-1_all.deb<\/p>\n\n\n\n<p>sudo dpkg -i mysql-apt-config_0.8.24-1_all.deb<br><\/p>\n\n\n\n<p>Durante la instalaci\u00f3n interactiva, seleccione <strong>MySQL Server 8.0<\/strong>. Use las flechas del teclado para navegar y <kbd>Enter<\/kbd> para confirmar.<\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><strong>Nota:<\/strong> La versi\u00f3n del paquete (<code>0.8.24-1<\/code> en este ejemplo) puede cambiar. Verifique la versi\u00f3n vigente en la p\u00e1gina oficial de MySQL APT Repository.<\/p>\n<\/blockquote>\n\n\n\n<p>Actualice la cach\u00e9 de paquetes para incluir los nuevos repositorios:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>sudo apt update<br><\/p>\n\n\n\n<p><strong>Paso 3 \u2014 Instalar MySQL Server.<\/strong><br>En ambos nodos:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>sudo apt install mysql-server -y<br><\/p>\n\n\n\n<p>Este comando instalar\u00e1 MySQL 8 junto con sus dependencias. Durante la instalaci\u00f3n podr\u00eda solicitarse configurar la contrase\u00f1a del usuario <code>root<\/code> de MySQL. <\/p>\n\n\n\n<p><strong>Paso 4 \u2014 Asegurar la instalaci\u00f3n.<\/strong><br>Ejecute en cada nodo:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>sudo mysql_secure_installation<br><\/p>\n\n\n\n<p>Este script permite:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Establecer una contrase\u00f1a robusta para <code>root<\/code> (si no se configur\u00f3 antes).<\/li>\n\n\n\n<li>Eliminar usuarios an\u00f3nimos.<\/li>\n\n\n\n<li>Deshabilitar el acceso remoto para <code>root<\/code>.<\/li>\n\n\n\n<li>Eliminar la base de datos de prueba y recargar privilegios.<\/li>\n<\/ul>\n\n\n\n<p><strong>Paso 5 \u2014 Verificar el estado del servicio.<\/strong><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>sudo systemctl status mysql<br><\/p>\n\n\n\n<p>Si el servicio est\u00e1 activo, podr\u00e1 conectarse con:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>mysql -u root -p<br><\/p>\n\n\n\n<p>Para habilitarlo al arranque del sistema:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>sudo systemctl enable mysql<br><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">3.2 Ajustes de configuraci\u00f3n para cl\u00faster y replicaci\u00f3n<\/h3>\n\n\n\n<p>Edite <strong><code>\/etc\/mysql\/mysql.conf.d\/mysqld.cnf<\/code><\/strong> en ambos nodos:<\/p>\n\n\n\n<p><strong>En nodo\u2011a (Primary):<\/strong><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>[mysqld]<\/p>\n\n\n\n<p>bind-address = 0.0.0.0<\/p>\n\n\n\n<p>server-id = 1<\/p>\n\n\n\n<p>log_bin = mysql-bin<\/p>\n\n\n\n<p>binlog_format = ROW<\/p>\n\n\n\n<p>expire_logs_days = 7<br><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>bind-address = 0.0.0.0<\/code> permite conexiones desde cualquier interfaz de red.<\/li>\n\n\n\n<li><code>server-id<\/code> debe ser <strong>\u00fanico<\/strong> para cada servidor en la topolog\u00eda de replicaci\u00f3n.<\/li>\n\n\n\n<li><code>log_bin<\/code> activa el registro binario con nombre base <code>mysql-bin<\/code>.<\/li>\n\n\n\n<li><code>binlog_format = ROW<\/code> registra modificaciones a nivel de fila (recomendado para replicaci\u00f3n).<\/li>\n<\/ul>\n\n\n\n<p><strong>En nodo\u2011b (Replica):<\/strong><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>[mysqld]<\/p>\n\n\n\n<p>bind-address = 0.0.0.0<\/p>\n\n\n\n<p>server-id = 2<\/p>\n\n\n\n<p>log_bin = mysql-bin<\/p>\n\n\n\n<p>relay_log = mysql-relay-bin<\/p>\n\n\n\n<p>read_only = 1<br><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><code>relay_log<\/code> nombra los archivos de <em>relay log<\/em> (registros de relevo) en la r\u00e9plica.<\/li>\n\n\n\n<li><code>read_only = 1<\/code> impide escrituras por usuarios sin privilegio SUPER, protegiendo la integridad de la replicaci\u00f3n.<\/li>\n<\/ul>\n\n\n\n<p><strong>Directiva <code>datadir<\/code> para DRBD (ambos nodos):<\/strong> Se aplicar\u00e1 en la secci\u00f3n 4, una vez configurado el volumen. El cambio ser\u00e1:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>datadir = \/mysql<\/p>\n\n\n\n<p>log-error = \/mysql\/mysqld.err<br><\/p>\n\n\n\n<p>Esto redirige el almacenamiento de datos al punto de montaje del volumen DRBD, como se muestra en configuraciones de entornos similares.<\/p>\n\n\n\n<p><strong>Firewall:<\/strong> Abra el puerto 3306 en nodo\u2011a para la conexi\u00f3n del Replica:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>sudo ufw allow from 192.168.1.102 to any port 3306<br><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">4. Implementaci\u00f3n del Cl\u00faster de Alta Disponibilidad y DRBD<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">Diagrama l\u00f3gico (descripci\u00f3n textual)<\/h3>\n\n\n\n<pre class=\"wp-block-code\"><code>                  \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510          \u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n                  \u2502   nodo-a    \u2502\u25c4\u2500\u2500DRBD\u2500\u2500\u25ba\u2502   nodo-b    \u2502\n                  \u2502 192.168.1.101\u2502  (TCP    \u2502 192.168.1.102\u2502\n                  \u2502             \u2502  7789)   \u2502             \u2502\n                  \u2502  \/dev\/sdb1  \u2502          \u2502  \/dev\/sdb1  \u2502\n                  \u2502  \/dev\/drbd0 \u2502          \u2502  \/dev\/drbd0 \u2502\n                  \u2502  mount:\/mysql\u2502          \u2502 (no montado)\u2502\n                  \u2502  MySQL \u2714    \u2502          \u2502  MySQL \u2717    \u2502\n                  \u2502  VIP: .150  \u2502          \u2502             \u2502\n                  \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2518          \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n                         \u2502     Corosync\/Pacemaker  \u2502\n                         \u2514\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2518\n<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Solo el <strong>nodo activo<\/strong> (DRBD Primary) monta <code>\/dev\/drbd0<\/code> en <code>\/mysql<\/code> y ejecuta MySQL.<\/li>\n\n\n\n<li><strong>Pacemaker<\/strong> orquesta: promoci\u00f3n de DRBD \u2192 montaje de FS \u2192 asignaci\u00f3n de IP virtual \u2192 arranque de MySQL.<\/li>\n\n\n\n<li>Ante falla, los recursos migran autom\u00e1ticamente al nodo pasivo.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">4.1 Instalaci\u00f3n de paquetes<\/h3>\n\n\n\n<p>En <strong>ambos nodos:<\/strong><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>sudo apt install -y drbd-utils pacemaker corosync crmsh pcs<br><\/p>\n\n\n\n<p>Esto instala DRBD y la pila de alta disponibilidad. En Debian\/Ubuntu, los paquetes se instalan con <code>apt<\/code>:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>sudo apt-get install -y pacemaker corosync pcs fence-agents-all<br><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">4.2 Configuraci\u00f3n de DRBD<\/h3>\n\n\n\n<p><strong>Paso 1 \u2014 Definir el recurso DRBD.<\/strong><br>Cree <code>\/etc\/drbd.d\/mysqldata.res<\/code> en ambos nodos:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>resource mysqldata {\n    protocol C;\n    meta-disk internal;\n    device    \/dev\/drbd0;\n    disk      \/dev\/sdb1;\n    on nodo-a {\n        address   192.168.1.101:7789;\n    }\n    on nodo-b {\n        address   192.168.1.102:7789;\n    }\n}\n<\/code><\/pre>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>protocol C<\/strong> = replicaci\u00f3n s\u00edncrona (la m\u00e1s segura; el Primary confirma la escritura solo cuando el Secondary ha recibido el dato).<\/li>\n\n\n\n<li><strong>meta-disk internal<\/strong> = los metadatos se almacenan al final de la misma partici\u00f3n.<\/li>\n\n\n\n<li>El recurso DRBD en la referencia de CentOS sigue una estructura equivalente con <code>device \/dev\/drbd0<\/code>, <code>disk<\/code> y <code>address<\/code> por nodo.<\/li>\n<\/ul>\n\n\n\n<p><strong>Paso 2 \u2014 Crear metadatos e iniciar DRBD.<\/strong><br>En <strong>ambos nodos:<\/strong><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>sudo drbdadm create-md mysqldata<\/p>\n\n\n\n<p>sudo modprobe drbd<\/p>\n\n\n\n<p>sudo drbdadm up mysqldata<br><\/p>\n\n\n\n<p><strong>Paso 3 \u2014 Designar Primary inicial y sincronizar.<\/strong><br>En <code>nodo-a<\/code>:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>sudo drbdadm primary &#8211;force mysqldata<br><\/p>\n\n\n\n<p>Verificar estado de sincronizaci\u00f3n:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>cat \/proc\/drbd<br><\/p>\n\n\n\n<p>Espere hasta ver <code>cs:Connected<\/code> y <code>UpToDate\/UpToDate<\/code> en ambos nodos.<\/p>\n\n\n\n<p><strong>Paso 4 \u2014 Formatear y montar el volumen en nodo\u2011a.<\/strong><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>sudo mkfs.ext4 \/dev\/drbd0 -L mysqlstore<\/p>\n\n\n\n<p>sudo mkdir -p \/mysql<\/p>\n\n\n\n<p>sudo mount \/dev\/drbd0 \/mysql<br><\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><strong>No agregue esta entrada en <code>\/etc\/fstab<\/code><\/strong> con montaje autom\u00e1tico. Pacemaker gestionar\u00e1 el montaje.<\/p>\n<\/blockquote>\n\n\n\n<h3 class=\"wp-block-heading\">4.3 Migraci\u00f3n del datadir de MySQL al volumen DRBD<\/h3>\n\n\n\n<p><strong>Paso 5 \u2014 Detener MySQL y copiar datos.<\/strong><br>En <strong>ambos nodos<\/strong>, detenga MySQL:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>sudo systemctl stop mysql<\/p>\n\n\n\n<p>sudo systemctl disable mysql # Evitar arranque autom\u00e1tico; Pacemaker lo controlar\u00e1<br><\/p>\n\n\n\n<p>En <strong>nodo\u2011a<\/strong> (donde <code>\/mysql<\/code> est\u00e1 montado):<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>sudo cp -a \/var\/lib\/mysql\/. \/mysql\/<\/p>\n\n\n\n<p>sudo chown -R mysql:mysql \/mysql<br><\/p>\n\n\n\n<p><strong>Paso 6 \u2014 Ajustar AppArmor.<\/strong><br>Edite <code>\/etc\/apparmor.d\/usr.sbin.mysqld<\/code> y agregue: <a href=\"https:\/\/wiki.cifprodolfoucha.es\/index.php?title=Mysql_Ficheros_de_log\">[wiki.cifpr&#8230;lfoucha.es]<\/a><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>\/mysql\/ r,\n\/mysql\/** rwk,\n<\/code><\/pre>\n\n\n\n<p>Recargue:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>sudo apparmor_parser -r \/etc\/apparmor.d\/usr.sbin.mysqld<br><\/p>\n\n\n\n<p><strong>Paso 7 \u2014 Aplicar nueva configuraci\u00f3n de <code>mysqld.cnf<\/code>.<\/strong><br>En ambos nodos, aseg\u00farese de que la secci\u00f3n <code>[mysqld]<\/code> contenga:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>datadir = \/mysql<\/p>\n\n\n\n<p>socket = \/var\/run\/mysqld\/mysqld.sock<\/p>\n\n\n\n<p>log-error = \/mysql\/mysqld.err<\/p>\n\n\n\n<p>pid-file = \/var\/run\/mysqld\/mysqld.pid<br><\/p>\n\n\n\n<p><strong>Verificaci\u00f3n r\u00e1pida (opcional, solo en nodo\u2011a):<\/strong><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>sudo systemctl start mysql<\/p>\n\n\n\n<p>mysql -u root -p -e \u00abSHOW DATABASES;\u00bb<\/p>\n\n\n\n<p>sudo systemctl stop mysql<br><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">4.4 Configuraci\u00f3n de Corosync<\/h3>\n\n\n\n<p><strong>Paso 8 \u2014 Crear <code>\/etc\/corosync\/corosync.conf<\/code><\/strong> (mismo contenido en ambos nodos):<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>totem {\n    version: 2\n    cluster_name: mysqlcluster\n    transport: udpu\n    interface {\n        ringnumber: 0\n        bindnetaddr: 192.168.1.0\n        mcastport: 5405\n    }\n}\nnodelist {\n    node {\n        ring0_addr: nodo-a\n        nodeid: 1\n    }\n    node {\n        ring0_addr: nodo-b\n        nodeid: 2\n    }\n}\nquorum {\n    provider: corosync_votequorum\n    two_node: 1\n}\nlogging {\n    to_syslog: yes\n}\n<\/code><\/pre>\n\n\n\n<p>Genere la clave de autenticaci\u00f3n en un nodo y c\u00f3piela al otro:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>sudo corosync-keygen<\/p>\n\n\n\n<p>sudo scp \/etc\/corosync\/authkey nodo-b:\/etc\/corosync\/<br><\/p>\n\n\n\n<h3 class=\"wp-block-heading\">4.5 Configuraci\u00f3n de Pacemaker y recursos<\/h3>\n\n\n\n<p><strong>Paso 9 \u2014 Iniciar servicios de cl\u00faster.<\/strong><br>En ambos nodos: <a href=\"https:\/\/linuxmind.dev\/es\/2025\/05\/22\/implementa-un-cluster-de-alta-disponibilidad-con-pacemaker-y-corosync\/\">[linuxmind.dev]<\/a><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>sudo systemctl enable corosync pacemaker<\/p>\n\n\n\n<p>sudo systemctl start corosync pacemaker<br><\/p>\n\n\n\n<p>Establecer contrase\u00f1a del usuario <code>hacluster<\/code>:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>sudo passwd hacluster<br><\/p>\n\n\n\n<p>Autenticar nodos (usando <code>pcs<\/code>): <a href=\"https:\/\/linuxmind.dev\/es\/2025\/05\/22\/implementa-un-cluster-de-alta-disponibilidad-con-pacemaker-y-corosync\/\">[linuxmind.dev]<\/a><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>sudo pcs cluster auth nodo-a nodo-b -u hacluster -p &lt;contrase\u00f1a><br><\/p>\n\n\n\n<p>Verificar estado:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>sudo pcs status<br><\/p>\n\n\n\n<p>Deber\u00eda mostrar dos nodos online.<\/p>\n\n\n\n<p><strong>Paso 10 \u2014 Crear recursos del cl\u00faster.<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-code\"><code># 1. Recurso DRBD (Master\/Slave)\nsudo pcs resource create res_drbd_mysql ocf:linbit:drbd \\\n    drbd_resource=\"mysqldata\" \\\n    op monitor interval=\"15s\" role=\"Master\" \\\n    op monitor interval=\"30s\" role=\"Slave\"\n\nsudo pcs resource promotable res_drbd_mysql \\\n    promoted-max=1 promoted-node-max=1 \\\n    clone-max=2 clone-node-max=1 notify=true\n\n# 2. Recurso Filesystem\nsudo pcs resource create res_fs_mysql ocf:heartbeat:Filesystem \\\n    device=\"\/dev\/drbd0\" directory=\"\/mysql\" fstype=\"ext4\" \\\n    op start timeout=\"20s\" op stop timeout=\"20s\"\n\n# 3. Recurso IP Virtual\nsudo pcs resource create res_ip_mysql ocf:heartbeat:IPaddr2 \\\n    ip=\"192.168.1.150\" cidr_netmask=\"24\" nic=\"eth0\" \\\n    op monitor interval=\"30s\"\n\n# 4. Recurso MySQL\nsudo pcs resource create res_mysql ocf:heartbeat:mysql \\\n    binary=\"\/usr\/sbin\/mysqld_safe\" \\\n    config=\"\/etc\/mysql\/my.cnf\" \\\n    datadir=\"\/mysql\" user=\"mysql\" \\\n    op monitor interval=\"20s\" timeout=\"30s\"<\/code><\/pre>\n\n\n\n<p><\/p>\n\n\n\n<p><br><\/p>\n\n\n\n<p>Los tipos de agentes utilizados corresponden a los disponibles en la pila Pacemaker\/DRBD:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><th>Tipo de Agente<\/th><th>Recurso<\/th><th>Uso<\/th><\/tr><tr><td><code>ocf:linbit:drbd<\/code><\/td><td>res_drbd_mysql<\/td><td>Replicaci\u00f3n de bloque<\/td><\/tr><tr><td><code>ocf:heartbeat:Filesystem<\/code><\/td><td>res_fs_mysql<\/td><td>Montaje del FS en <code>\/mysql<\/code><\/td><\/tr><tr><td><code>ocf:heartbeat:IPaddr2<\/code><\/td><td>res_ip_mysql<\/td><td>IP flotante del servicio<\/td><\/tr><tr><td><code>ocf:heartbeat:mysql<\/code><\/td><td>res_mysql<\/td><td>Control del servicio MySQL<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p><strong>Paso 11 \u2014 Agrupar recursos y definir restricciones.<\/strong><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p># Grupo: IP + FS + MySQL se mueven juntos<\/p>\n\n\n\n<p>sudo pcs resource group add g_mysql res_ip_mysql res_fs_mysql res_mysql<\/p>\n\n\n\n<p># Orden: DRBD debe estar promovido antes de iniciar el grupo<\/p>\n\n\n\n<p>sudo pcs constraint order promote res_drbd_mysql-clone then start g_mysql<\/p>\n\n\n\n<p># Colocaci\u00f3n: el grupo corre en el nodo con DRBD Master<\/p>\n\n\n\n<p>sudo pcs constraint colocation add g_mysql with Promoted res_drbd_mysql-clone INFINITY<br><\/p>\n\n\n\n<p><strong>Paso 12 \u2014 Configuraci\u00f3n de qu\u00f3rum y STONITH.<\/strong><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p># En entorno de laboratorio, puede deshabilitarse stonith (NO en producci\u00f3n):<\/p>\n\n\n\n<p>sudo pcs property set stonith-enabled=false<\/p>\n\n\n\n<p>sudo pcs property set no-quorum-policy=ignore<br><\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p><strong>Advertencia:<\/strong> En producci\u00f3n, <strong>STONITH debe estar habilitado<\/strong> para prevenir <em>split\u2011brain<\/em> y acceso concurrente al dispositivo DRBD.<\/p>\n<\/blockquote>\n\n\n\n<p><strong>Paso 13 \u2014 Verificar estado del cl\u00faster.<\/strong><\/p>\n\n\n\n<p>Shell<\/p>\n\n\n\n<p>sudo pcs status<br>Mostrar m\u00e1s l\u00edneas<\/p>\n\n\n\n<p>La salida esperada deber\u00eda mostrar:<\/p>\n\n\n\n<pre class=\"wp-block-code\"><code>Cluster Summary:\n  * 2 nodes configured\n  * N resource instances configured\n\nNode List:\n  * Online: &#91; nodo-a nodo-b ]\n\nFull List of Resources:\n  * Clone Set: res_drbd_mysql-clone &#91;res_drbd_mysql] (promotable)\n    * Promoted: &#91; nodo-a ]\n    * Unpromoted: &#91; nodo-b ]\n  * Resource Group: g_mysql:\n    * res_ip_mysql  (ocf::heartbeat:IPaddr2):    Started nodo-a\n    * res_fs_mysql  (ocf::heartbeat:Filesystem): Started nodo-a\n    * res_mysql     (ocf::heartbeat:mysql):      Started nodo-a\n<\/code><\/pre>\n\n\n\n<p>Esto confirma que:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>nodo\u2011a<\/strong> es el Master de DRBD con el FS montado, IP virtual asignada y MySQL en ejecuci\u00f3n.<\/li>\n\n\n\n<li><strong>nodo\u2011b<\/strong> es el Slave de DRBD sin recursos activos del grupo.<\/li>\n<\/ul>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">5. Configuraci\u00f3n de la Replicaci\u00f3n Nativa de MySQL (Primary\u2011Replica)<\/h2>\n\n\n\n<p>La replicaci\u00f3n en MySQL implica que la base de datos de origen anota cada cambio en los datos en un archivo especial: el <strong>registro binario<\/strong> (binlog). La instancia de r\u00e9plica crea dos subprocesos: el <strong>subproceso IO<\/strong> (se conecta al origen, lee eventos del binlog y los copia a un <em>relay log<\/em> local) y el <strong>subproceso SQL<\/strong> (lee eventos del relay log y los aplica a la r\u00e9plica).<\/p>\n\n\n\n<p>MySQL admite dos m\u00e9todos de replicaci\u00f3n:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Basada en posici\u00f3n de archivo binlog<\/strong>: la r\u00e9plica necesita el nombre del archivo binlog y la posici\u00f3n exacta dentro de \u00e9l.<\/li>\n\n\n\n<li><strong>Basada en transacciones (GTID)<\/strong>: cada transacci\u00f3n recibe un identificador global \u00fanico; la r\u00e9plica no necesita coordenadas de binlog, facilitando cambios de topolog\u00eda.<\/li>\n<\/ul>\n\n\n\n<p>En este laboratorio usaremos <strong>replicaci\u00f3n basada en posici\u00f3n de binlog<\/strong> por su simplicidad.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Consideraci\u00f3n sobre el escenario DRBD + Replicaci\u00f3n<\/h3>\n\n\n\n<p>En un cl\u00faster activo\u2011pasivo con DRBD, normalmente <strong>solo el nodo activo ejecuta MySQL<\/strong>. DRBD ya garantiza la consistencia de datos en el nodo pasivo a nivel de bloque. La replicaci\u00f3n nativa aqu\u00ed se configura <strong>con fines educativos<\/strong> para demostrar ambas t\u00e9cnicas. En un entorno real, se elige t\u00edpicamente una de las dos:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>DRBD\/Pacemaker<\/strong>: failover autom\u00e1tico, cero p\u00e9rdida de datos (s\u00edncrono), pero un solo nodo activo.<\/li>\n\n\n\n<li><strong>Replicaci\u00f3n MySQL nativa<\/strong>: permite m\u00faltiples r\u00e9plicas para lecturas distribuidas, pero es as\u00edncrona por defecto y requiere gesti\u00f3n manual de roles.<\/li>\n<\/ul>\n\n\n\n<p>Para la demostraci\u00f3n de replicaci\u00f3n, asumiremos que <code>nodo\u2011b<\/code> tiene una instancia de MySQL operativa con un <code>datadir<\/code> inicializado (puede ser una copia restaurada desde el Primary).<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">5.1 Verificar binlogs en el Primary (nodo\u2011a)<\/h3>\n\n\n\n<p>Con\u00e9ctese al MySQL del nodo\u2011a y ejecute:<\/p>\n\n\n\n<p>SQL<\/p>\n\n\n\n<p>SHOW VARIABLES LIKE &#8216;log_bin&#8217;;<\/p>\n\n\n\n<p>&#8212; Resultado esperado: ON<\/p>\n\n\n\n<p>SHOW MASTER STATUS;<br><\/p>\n\n\n\n<p>La respuesta indicar\u00e1 el archivo binlog actual y la posici\u00f3n. Por ejemplo:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><th>File<\/th><th>Position<\/th><\/tr><tr><td>mysql-bin.000001<\/td><td>154<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Anote estos valores para configurar la r\u00e9plica.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">5.2 Crear usuario de replicaci\u00f3n en el Primary<\/h3>\n\n\n\n<p>SQL<\/p>\n\n\n\n<p>CREATE USER &#8216;replicador&#8217;@&#8217;192.168.1.%&#8217; IDENTIFIED BY &#8216;SecretaRep!2026&#8217;;<\/p>\n\n\n\n<p>GRANT REPLICATION SLAVE ON *.* TO &#8216;replicador&#8217;@&#8217;192.168.1.%&#8217;;<\/p>\n\n\n\n<p>FLUSH PRIVILEGES;<br><\/p>\n\n\n\n<p>El privilegio <strong>REPLICATION SLAVE<\/strong> permite al usuario actuar como Replica; se recomienda restringir el host al IP exacto de nodo\u2011b para mayor seguridad.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">5.3 Sincronizaci\u00f3n inicial de datos<\/h3>\n\n\n\n<p>Si el Replica no tiene los datos del Primary, debe crearse un volcado y restaurarlo. Desde nodo\u2011a:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>sudo mysqldump -u root &#8211;all-databases &#8211;master-data &gt; \/tmp\/dump.sql<\/p>\n\n\n\n<p>scp \/tmp\/dump.sql nodo-b:\/tmp\/<br><\/p>\n\n\n\n<p>En nodo\u2011b, restaurar:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>sudo mysql &lt; \/tmp\/dump.sql<br><\/p>\n\n\n\n<p>En nuestro escenario con DRBD, los datos ya est\u00e1n sincronizados a nivel de bloque, por lo que este paso puede omitirse si se ha restaurado una copia del datadir.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">5.4 Configurar y activar la Replica (nodo\u2011b)<\/h3>\n\n\n\n<p>En MySQL de nodo\u2011b:<\/p>\n\n\n\n<p>SQL<\/p>\n\n\n\n<p>CHANGE REPLICATION SOURCE TO<\/p>\n\n\n\n<p>SOURCE_HOST=&#8217;192.168.1.101&#8242;,<\/p>\n\n\n\n<p>SOURCE_USER=&#8217;replicador&#8217;,<\/p>\n\n\n\n<p>SOURCE_PASSWORD=&#8217;SecretaRep!2026&#8242;,<\/p>\n\n\n\n<p>SOURCE_LOG_FILE=&#8217;mysql-bin.000001&#8242;,<\/p>\n\n\n\n<p>SOURCE_LOG_POS=154;<\/p>\n\n\n\n<p>START REPLICA;<br><\/p>\n\n\n\n<blockquote class=\"wp-block-quote is-layout-flow wp-block-quote-is-layout-flow\">\n<p>En MySQL 8, se usa la sintaxis <code>SOURCE_*<\/code> en lugar de <code>MASTER_*<\/code> (ambas aceptadas por compatibilidad).<\/p>\n<\/blockquote>\n\n\n\n<h3 class=\"wp-block-heading\">5.5 Verificar estado de replicaci\u00f3n<\/h3>\n\n\n\n<p>SQL<\/p>\n\n\n\n<p>SHOW REPLICA STATUS\\G<br><\/p>\n\n\n\n<p>Campos clave a verificar:<\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><th>Campo<\/th><th>Valor esperado<\/th><\/tr><tr><td><code>Replica_IO_Running<\/code><\/td><td>Yes<\/td><\/tr><tr><td><code>Replica_SQL_Running<\/code><\/td><td>Yes<\/td><\/tr><tr><td><code>Seconds_Behind_Source<\/code><\/td><td>0 (o tendiendo a 0)<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<p>Si alg\u00fan campo muestra <code>No<\/code>, verifique: contrase\u00f1a incorrecta, host no accesible (firewall), <code>server-id<\/code> duplicados, o binlog no habilitado en el Primary.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">5.6 Prueba de replicaci\u00f3n<\/h3>\n\n\n\n<p>En nodo\u2011a (Primary):<\/p>\n\n\n\n<p>SQL<\/p>\n\n\n\n<p>CREATE DATABASE prueba_replicacion;<\/p>\n\n\n\n<p>USE prueba_replicacion;<\/p>\n\n\n\n<p>CREATE TABLE test (id INT PRIMARY KEY AUTO_INCREMENT, msg VARCHAR(50));<\/p>\n\n\n\n<p>INSERT INTO test (msg) VALUES (&#8216;Dato desde nodo-a&#8217;);<br><\/p>\n\n\n\n<p>En nodo\u2011b (Replica):<\/p>\n\n\n\n<p>SQL<\/p>\n\n\n\n<p>SELECT * FROM prueba_replicacion.test;<br><\/p>\n\n\n\n<p>Deber\u00eda mostrar el registro insertado en el Primary, confirmando la replicaci\u00f3n funcional.<\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">6. Pruebas de Funcionamiento<\/h2>\n\n\n\n<figure class=\"wp-block-image size-large\"><img decoding=\"async\" width=\"1024\" height=\"768\" src=\"https:\/\/dsantana.uas.edu.mx\/wp-content\/uploads\/2026\/04\/image-4-1024x768.png\" alt=\"\" class=\"wp-image-2388\" srcset=\"https:\/\/dsantana.uas.edu.mx\/wp-content\/uploads\/2026\/04\/image-4-1024x768.png 1024w, https:\/\/dsantana.uas.edu.mx\/wp-content\/uploads\/2026\/04\/image-4-300x225.png 300w, https:\/\/dsantana.uas.edu.mx\/wp-content\/uploads\/2026\/04\/image-4-768x576.png 768w, https:\/\/dsantana.uas.edu.mx\/wp-content\/uploads\/2026\/04\/image-4-1536x1152.png 1536w, https:\/\/dsantana.uas.edu.mx\/wp-content\/uploads\/2026\/04\/image-4-2048x1536.png 2048w\" sizes=\"(max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n\n<p><strong>Ejemplo detallado de Prueba 2 \u2014 Failover:<\/strong><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p># 1. Estado inicial: nodo-a activo<\/p>\n\n\n\n<p>sudo pcs status | grep -A 5 \u00abResource Group\u00bb<\/p>\n\n\n\n<p># 2. Simular falla en nodo-a<\/p>\n\n\n\n<p>sudo pcs node standby nodo-a<\/p>\n\n\n\n<p># 3. Esperar ~15-30 segundos y verificar<\/p>\n\n\n\n<p>sudo pcs status<\/p>\n\n\n\n<p># Resultado: g_mysql Started en nodo-b, DRBD Promoted en nodo-b<\/p>\n\n\n\n<p># 4. Conectar a MySQL v\u00eda IP virtual<\/p>\n\n\n\n<p>mysql -h 192.168.1.150 -u root -p -e \u00abSELECT * FROM laboratorio.saludos;\u00bb<\/p>\n\n\n\n<p># Los datos deben estar presentes<\/p>\n\n\n\n<p># 5. Recuperar nodo-a<\/p>\n\n\n\n<p>sudo pcs node unstandby nodo-a<br><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">7. Consideraciones de Seguridad<\/h2>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><th>\u00c1rea<\/th><th>Recomendaci\u00f3n<\/th><\/tr><tr><th><strong>Autenticaci\u00f3n MySQL<\/strong><\/th><td>Usar <code>mysql_secure_installation<\/code> tras cada instalaci\u00f3n\u30109\u2020L120-L125\u3011. Crear cuentas con m\u00ednimos privilegios. No usar <code>root<\/code> desde aplicaciones.<\/td><\/tr><tr><th><strong>Red y firewall<\/strong><\/th><td>Restringir el acceso al puerto 3306 solo a IPs autorizadas\u301047\u2020L75-L77\u3011. Usar <code>bind-address<\/code> para controlar en qu\u00e9 interfaces escucha MySQL.<\/td><\/tr><tr><th><strong>Comunicaci\u00f3n del cl\u00faster<\/strong><\/th><td>Corosync cifra el tr\u00e1fico con <code>authkey<\/code>. DRBD puede usar tr\u00e1fico cifrado en redes inseguras.<\/td><\/tr><tr><th><strong>STONITH<\/strong><\/th><td><strong>Obligatorio en producci\u00f3n<\/strong> para evitar <em>split\u2011brain<\/em> y corrupci\u00f3n de datos. Utilizar dispositivos IPMI, iLO\/DRAC o agentes de fencing adecuados\u301037\u2020L17\u3011.<\/td><\/tr><tr><th><strong>AppArmor<\/strong><\/th><td>Mantener activo y ajustar perfiles al cambiar rutas de archivos MySQL\u301025\u2020L56\u3011.<\/td><\/tr><tr><th><strong>Respaldos<\/strong><\/th><td>DRBD y replicaci\u00f3n no sustituyen respaldos. Implementar <code>mysqldump<\/code> o herramientas como Percona XtraBackup de manera peri\u00f3dica.<\/td><\/tr><tr><th><strong>Monitoreo<\/strong><\/th><td>Supervisar estado del cl\u00faster con <code>pcs status<\/code> y <code>crm_mon<\/code>; logs en <code>\/var\/log\/cluster\/corosync.log<\/code> y <code>\/var\/log\/messages<\/code>\u301037\u2020L90-L92\u3011.<\/td><\/tr><tr><th><strong>Sincronizaci\u00f3n horaria<\/strong><\/th><td>Configurar NTP o Chrony en ambos nodos para evitar inconsistencias en logs y timeouts de DRBD\/Corosync\u301037\u2020L23\u3011.<\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">8. Problemas Comunes y Soluciones<\/h2>\n\n\n\n<h3 class=\"wp-block-heading\">MySQL no arranca tras mover el datadir<\/h3>\n\n\n\n<p><strong>Causa probable:<\/strong> AppArmor impide el acceso al nuevo directorio. El log de errores (<code>\/var\/log\/mysql\/error.log<\/code> o la ruta configurada)\u301025\u2020L53\u3011 mostrar\u00e1 mensajes de <em>permission denied<\/em>.<br><strong>Soluci\u00f3n:<\/strong> Ajustar el perfil AppArmor como se describe en la secci\u00f3n 4.3 y recargar con <code>apparmor_parser -r<\/code>\u301025\u2020L56\u3011. Verificar tambi\u00e9n que los archivos en el nuevo <code>datadir<\/code> pertenezcan a <code>mysql:mysql<\/code>.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Split\u2011brain en DRBD<\/h3>\n\n\n\n<p><strong>Causa:<\/strong> Ambos nodos se promueven a Primary simult\u00e1neamente (p\u00e9rdida de comunicaci\u00f3n sin STONITH configurado).<br><strong>Soluci\u00f3n preventiva:<\/strong> Habilitar STONITH y configurar correctamente la pol\u00edtica de qu\u00f3rum. Si ya ocurri\u00f3, intervenir manualmente: degradar uno de los nodos a Secondary con <code>drbdadm secondary mysqldata<\/code> y reconectar con <code>drbdadm --discard-my-data connect mysqldata<\/code> en el nodo cuyos datos se descartar\u00e1n.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Replica MySQL no conecta al Primary<\/h3>\n\n\n\n<p><strong>Posibles causas y verificaciones:<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-table\"><table class=\"has-fixed-layout\"><tbody><tr><th>Verificaci\u00f3n<\/th><th>Comando<\/th><\/tr><tr><td><code>bind-address<\/code> permite conexiones remotas<\/td><td><code>grep bind-address \/etc\/mysql\/mysql.conf.d\/mysqld.cnf<\/code><\/td><\/tr><tr><td>Firewall abierto en puerto 3306<\/td><td><code>sudo ufw status<\/code><\/td><\/tr><tr><td>Usuario de replicaci\u00f3n correcto<\/td><td><code>SELECT user, host FROM mysql.user WHERE user='replicador';<\/code><\/td><\/tr><tr><td>Binlog habilitado<\/td><td><code>SHOW VARIABLES LIKE 'log_bin';<\/code> \u2192 debe ser <code>ON<\/code><\/td><\/tr><tr><td><code>server-id<\/code> \u00fanico en cada nodo<\/td><td><code>SHOW VARIABLES LIKE 'server_id';<\/code><\/td><\/tr><\/tbody><\/table><\/figure>\n\n\n\n<h3 class=\"wp-block-heading\">Socket MySQL no encontrado<\/h3>\n\n\n\n<p><strong>Causa:<\/strong> El archivo <code>\/var\/run\/mysqld\/mysqld.sock<\/code> no existe porque MySQL no est\u00e1 corriendo o el directorio no fue creado\u301032\u2020L26\u3011\u301032\u2020L54-L60\u3011.<br><strong>Soluci\u00f3n:<\/strong><\/p>\n\n\n\n<p><\/p>\n\n\n\n<p>sudo systemctl status mysql # Verificar si est\u00e1 corriendo<\/p>\n\n\n\n<p>sudo mkdir -p \/var\/run\/mysqld<\/p>\n\n\n\n<p>sudo chown mysql:mysql \/var\/run\/mysqld # Asegurar permisos correctos<\/p>\n\n\n\n<p>sudo systemctl restart mysql<br><\/p>\n\n\n\n<p>Los permisos del directorio y archivo socket deben ser 755 y propiedad de <code>mysql:mysql<\/code>\u301032\u2020L87-L94\u3011.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">Rendimiento sub\u00f3ptimo con DRBD<\/h3>\n\n\n\n<p><strong>Trade\u2011off:<\/strong> DRBD en <strong>protocol C<\/strong> (s\u00edncrono) a\u00f1ade latencia a cada escritura porque espera confirmaci\u00f3n del nodo peer antes de completar la operaci\u00f3n de I\/O. Para mitigar:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Usar red dedicada de alta velocidad (10 Gbps o superior) para tr\u00e1fico DRBD.<\/li>\n\n\n\n<li>Ajustar <code>innodb_buffer_pool_size<\/code> para aprovechar la RAM disponible (t\u00edpicamente 70\u201180% de la RAM del servidor).<\/li>\n\n\n\n<li>Considerar <code>sync_binlog = 1<\/code> para m\u00e1xima seguridad, asumiendo el impacto en rendimiento; valores m\u00e1s altos reducen la carga pero arriesgan p\u00e9rdida de eventos binlog en caso de falla\u301018\u2020L95\u3011.<\/li>\n<\/ul>\n\n\n\n<h3 class=\"wp-block-heading\">Archivos de logs crecen indefinidamente<\/h3>\n\n\n\n<p>Los logs de MySQL pueden ocupar espacio en disco si no se gestionan. Se recomienda configurar rotaci\u00f3n autom\u00e1tica y limpiar logs con la sentencia <code>FLUSH LOGS<\/code> o con <code>mysqladmin flush-logs<\/code>\u301025\u2020L37-L42\u3011. Para binlogs, la opci\u00f3n <code>expire_logs_days<\/code> controla la retenci\u00f3n autom\u00e1tica. Tambi\u00e9n puede programarse una tarea con <code>cron<\/code> para eliminar logs antiguos\u301025\u2020L14-L18\u3011:<\/p>\n\n\n\n<p><\/p>\n\n\n\n<p># Ejemplo: eliminar ficheros de log de m\u00e1s de 7 d\u00edas<\/p>\n\n\n\n<p>* * * * * find \/path\/to\/*.log -mtime +7 -exec rm -f {} \\;<br><\/p>\n\n\n\n<hr class=\"wp-block-separator has-alpha-channel-opacity\"\/>\n\n\n\n<h2 class=\"wp-block-heading\">Conclusi\u00f3n<\/h2>\n\n\n\n<p>Este laboratorio integr\u00f3 tres capas tecnol\u00f3gicas complementarias sobre Debian 13.4:<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li><strong>MySQL 8.0<\/strong> como RDBMS de c\u00f3digo abierto, instalado desde el repositorio oficial de Oracle ante la ausencia de paquetes nativos MySQL en Debian\u30109\u2020L47\u3011.<\/li>\n\n\n\n<li><strong>DRBD con Pacemaker\/Corosync<\/strong> para proveer un cl\u00faster activo\u2011pasivo con replicaci\u00f3n s\u00edncrona a nivel de bloque y conmutaci\u00f3n autom\u00e1tica del servicio. Pacemaker orquesta los recursos (DRBD, filesystem, IP virtual y MySQL) con restricciones de orden y colocaci\u00f3n que garantizan un arranque y parada coherentes\u301037\u2020L14-L17\u3011.<\/li>\n\n\n\n<li><strong>Replicaci\u00f3n nativa de MySQL<\/strong> (Primary\u2011Replica basada en binlog) como mecanismo complementario que demuestra la sincronizaci\u00f3n a nivel de transacciones SQL, independiente del almacenamiento subyacente\u301047\u2020L39\u3011.<\/li>\n<\/ol>\n\n\n\n<p><strong>Trade\u2011off principal entre enfoques:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>DRBD\/Pacemaker ofrece <strong>cero p\u00e9rdida de datos<\/strong> y failover transparente, pero solo permite <strong>un nodo activo<\/strong> a la vez.<\/li>\n\n\n\n<li>La replicaci\u00f3n nativa MySQL permite <strong>m\u00faltiples r\u00e9plicas activas para lectura<\/strong>, escalando horizontalmente las consultas, pero es as\u00edncrona por defecto y requiere gesti\u00f3n manual (o herramientas adicionales) para la conmutaci\u00f3n de roles.<\/li>\n<\/ul>\n\n\n\n<p>La combinaci\u00f3n de ambas t\u00e9cnicas en un mismo entorno \u2014aunque redundante desde el punto de vista funcional\u2014 proporciona una comprensi\u00f3n profunda de los mecanismos de alta disponibilidad disponibles en el ecosistema MySQL\/Linux, y sienta las bases para dise\u00f1ar arquitecturas adaptadas a requisitos espec\u00edficos de disponibilidad, escalabilidad y presupuesto.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Objetivos del Laboratorio Objetivo general: Implementar un cl\u00faster de alta disponibilidad de MySQL 8.0 en Debian 13.4 utilizando DRBD para replicaci\u00f3n de almacenamiento a nivel de bloque y configurando simult\u00e1neamente la replicaci\u00f3n nativa de MySQL (Primary\u2011Replica). El entorno final constar\u00e1 de dos nodos (nodo\u2011a y nodo\u2011b) capaces de garantizar continuidad del servicio de base de datos, replicaci\u00f3n s\u00edncrona de almacenamiento y sincronizaci\u00f3n a nivel de transacciones SQL. Objetivos espec\u00edficos: # Objetivo Alcance 1 Comprender qu\u00e9 es MySQL Definici\u00f3n, caracter\u00edsticas clave, modelo relacional 2 Identificar la estructura de archivos de MySQL datadir, InnoDB, logs, socket, configuraci\u00f3n 3 Instalar MySQL 8.0 en Debian 13.4 Repositorio oficial Oracle, configuraci\u00f3n segura 4 Integrar MySQL en cl\u00faster HA DRBD + Pacemaker\/Corosync, datadir sobre volumen replicado 5 Configurar replicaci\u00f3n nativa MySQL Primary\u2011Replica, usuario de replicaci\u00f3n, binlog, verificaci\u00f3n 6 Validar y documentar pruebas Failover, integridad de datos, problemas comunes Nota sobre las referencias del laboratorio previo: Las pr\u00e1cticas publicadas en dsantana.uas.edu.mx \u2014sobre implementaci\u00f3n de cl\u00faster HA, DRBD en Debian 13.4 y cl\u00faster de alta disponibilidad en Debian 13\u2014 no pudieron consultarse directamente durante la investigaci\u00f3n. La presente gu\u00eda se construye sobre documentaci\u00f3n oficial de MySQL (Oracle), gu\u00edas t\u00e9cnicas verificadas de instalaci\u00f3n en Debian, y referencias de configuraci\u00f3n de Pacemaker\/Corosync\/DRBD, aline\u00e1ndose con los principios y arquitectura descritos en dichas pr\u00e1cticas previas. 1. \u00bfQu\u00e9 es MySQL? MySQL es un sistema de gesti\u00f3n de bases de datos relacionales (RDBMS) de c\u00f3digo abierto que se utiliza para almacenar y gestionar datos. Su fiabilidad, rendimiento, escalabilidad y facilidad de uso lo han convertido en una opci\u00f3n popular para desarrolladores en aplicaciones de alto tr\u00e1fico como Facebook, Netflix, Uber, Airbnb, Shopify y Booking.com. En 2024, MySQL se clasifica como la segunda base de datos m\u00e1s popular en general, solo superada por Oracle Database seg\u00fan DB\u2011Engines, y es el RDBMS de c\u00f3digo abierto m\u00e1s popular del mundo. MySQL utiliza el lenguaje SQL (Structured Query Language) para recuperar, actualizar, suprimir y manipular datos en bases de datos relacionales. Se pronuncia oficialmente \u00abMy es\u2011kiu\u2011el\u00bb. Como base de datos relacional, almacena datos en tablas de filas y columnas organizadas en esquemas, donde un esquema define c\u00f3mo se organizan y almacenan los datos y describe la relaci\u00f3n entre varias tablas. Recientemente, Oracle ha a\u00f1adido soporte para el tipo de datos JSON y vectores, ampliando su versatilidad. Caracter\u00edsticas fundamentales: 2. Estructura del Sistema de Archivos y Componentes de MySQL 2.1 Directorio de datos (datadir) El datadir es la carpeta principal donde el servidor MySQL almacena todos los archivos relacionados con las bases de datos. En instalaciones desde repositorios (apt, yum) en Linux, la ubicaci\u00f3n m\u00e1s com\u00fan es \/var\/lib\/mysql\/. Este valor est\u00e1 definido por la variable del sistema data_dir, cuyo valor por defecto es \/var\/lib\/mysql. Para consultar el datadir activo, puede ejecutarse dentro de MySQL la sentencia SHOW VARIABLES LIKE &#8216;datadir&#8217;;. Dentro del datadir se encuentra: 2.2 Motor de almacenamiento InnoDB InnoDB es el motor de almacenamiento predeterminado en MySQL 8.0 y act\u00faa como la capa intermedia entre el almacenamiento y el servidor MySQL, almacenando los datos en las unidades de disco. Su funcionamiento de E\/S se clasifica en dos tipos: I\/O de archivo aleatorio (archivos de datos) y E\/S de archivo secuencial (registros de recuperaci\u00f3n y binarios). Componentes clave de InnoDB en el datadir: Componente Descripci\u00f3n Espacio de tablas compartido (ibdata1) Contiene metadatos de InnoDB y datos de tablas que no usan file\u2011per\u2011table. Con innodb_file_per_table activado (predeterminado en MySQL 8), cada tabla se almacena en archivos .ibd independientes. Logs de recuperaci\u00f3n (redo logs) Registros transaccionales escritos secuencialmente para garantizar la recuperaci\u00f3n tras fallos. Buffer de doble escritura InnoDB escribe p\u00e1ginas primero en un buffer y luego en sus posiciones correctas en los archivos de datos, evitando la corrupci\u00f3n de p\u00e1ginas si se produce un fallo de alimentaci\u00f3n durante la escritura. Buffer de inserci\u00f3n Reduce operaciones de E\/S aleatorias fusionando escrituras en \u00edndices secundarios no \u00fanicos. Segmentos de deshacer (undo) Registran im\u00e1genes anteriores de los datos para la concurrencia multiversi\u00f3n (MVCC). 2.3 Archivos de registro (logs) MySQL dispone de cuatro tipos principales de archivos de log: Tipo de log Descripci\u00f3n Ruta t\u00edpica (Debian) Activado por defecto Registro de errores Registra problemas al iniciar, ejecutar o parar mysqld \/var\/log\/mysql\/error.log S\u00ed Registro de consultas generales Registra todas las conexiones y sentencias ejecutadas datadir\/&lt;hostname>.log No Registro binario (binlog) Registra todas las sentencias que cambian datos; utilizado en la replicaci\u00f3n datadir\/mysql-bin.* (si se activa log_bin) No Registro de consultas lentas Registra sentencias que exceden el tiempo definido por long_query_time (predeterminado: 10 segundos) datadir\/&lt;hostname&gt;-slow.log No Por defecto, todos los archivos de log se crean en el directorio de datos, aunque distribuciones Debian\/Ubuntu suelen redirigir el log de errores a \/var\/log\/mysql\/error.log mediante la variable log_error. El registro binario merece atenci\u00f3n especial para este laboratorio: es la base de la replicaci\u00f3n nativa de MySQL. Debe habilitarse configurando log_bin en el archivo de configuraci\u00f3n. Cada archivo binlog se escribe secuencialmente y contiene las operaciones de escritura (INSERT, UPDATE, DELETE). Los binlogs cumplen tres funciones principales: restauraci\u00f3n punto en el tiempo, replicaci\u00f3n entre servidores, y auditor\u00eda de seguridad. 2.4 Archivo de socket Unix El archivo mysqld.sock es un punto final de comunicaci\u00f3n que permite que el servidor MySQL y las aplicaciones cliente en la misma m\u00e1quina se comuniquen de manera local sin pasar por la red TCP\/IP. En sistemas Debian\/Ubuntu, este socket se encuentra normalmente en \/var\/run\/mysqld\/mysqld.sock. Se configura mediante la directiva socket en el archivo my.cnf. 2.5 Archivo PID y archivo de configuraci\u00f3n 2.6 Par\u00e1metros de configuraci\u00f3n relevantes Los par\u00e1metros de MySQL se dividen en din\u00e1micos (modificables en tiempo de ejecuci\u00f3n con SET) y est\u00e1ticos (requieren reinicio del servicio). Algunos par\u00e1metros clave: Par\u00e1metro Tipo Descripci\u00f3n innodb_buffer_pool_size Est\u00e1tico Tama\u00f1o del buffer de datos\/\u00edndices InnoDB en memoria log_bin Est\u00e1tico Activa registro binario para replicaci\u00f3n server_id Est\u00e1tico Identificador \u00fanico del servidor en topolog\u00eda de replicaci\u00f3n bind-address Est\u00e1tico Direcci\u00f3n IP en la que MySQL escucha conexiones sync_binlog Din\u00e1mico Frecuencia de sincronizaci\u00f3n del binlog al disco; 1 = m\u00e1xima seguridad 2.7 Permisos y AppArmor MySQL ejecuta bajo el usuario del sistema mysql. Todos los archivos del datadir deben pertenecer a mysql:mysql. En<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[134,16,5,12,1,10,6],"tags":[],"class_list":["post-2386","post","type-post","status-publish","format-standard","hentry","category-clusters","category-debian","category-docencia","category-linux","category-sin-categoria","category-sistemas-operativos","category-talleres"],"_links":{"self":[{"href":"https:\/\/dsantana.uas.edu.mx\/index.php\/wp-json\/wp\/v2\/posts\/2386","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dsantana.uas.edu.mx\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dsantana.uas.edu.mx\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dsantana.uas.edu.mx\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/dsantana.uas.edu.mx\/index.php\/wp-json\/wp\/v2\/comments?post=2386"}],"version-history":[{"count":3,"href":"https:\/\/dsantana.uas.edu.mx\/index.php\/wp-json\/wp\/v2\/posts\/2386\/revisions"}],"predecessor-version":[{"id":2392,"href":"https:\/\/dsantana.uas.edu.mx\/index.php\/wp-json\/wp\/v2\/posts\/2386\/revisions\/2392"}],"wp:attachment":[{"href":"https:\/\/dsantana.uas.edu.mx\/index.php\/wp-json\/wp\/v2\/media?parent=2386"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dsantana.uas.edu.mx\/index.php\/wp-json\/wp\/v2\/categories?post=2386"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dsantana.uas.edu.mx\/index.php\/wp-json\/wp\/v2\/tags?post=2386"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}