“Reemplazo directo” es una expresión que corresponde al marketing y a informes posteriores. En producción, el reemplazo siempre elimina algo: un plugin, una pista del optimizador, una suposición sobre replicación o tu fin de semana.
Si estás decidiendo entre MariaDB y Percona Server (o intentando intercambiar uno por el otro en una aplicación existente), no necesitas filosofía. Necesitas una lista de verificación que detecte las incompatibilidades silenciosas antes de que se conviertan en incidentes estruendosos.
Qué significa realmente “reemplazo directo” (y por qué duele)
Para fines operativos, “reemplazo directo” solo significa esto: tu aplicación se conecta, ejecuta migraciones, atiende tráfico, sobrevive a un failover y puedes respaldarla y restaurarla bajo presión. No significa “arranca” y tampoco “pasa los tests unitarios”.
MariaDB y Percona Server llevan la insignia de “compatible con MySQL”, pero son compatibles en direcciones y capas diferentes:
- Compatibilidad de protocolo: los clientes normalmente pueden conectarse. “Normalmente” oculta plugins de autenticación y matices de TLS.
- Compatibilidad de dialecto SQL: el SQL común funciona, pero los casos límite (JSON, funciones de ventana en versiones antiguas, hints del optimizador) pueden desviarse.
- Compatibilidad de comportamiento: el mismo esquema y la misma consulta pueden devolver las mismas filas… con distinto rendimiento y distinto bloqueo.
- Compatibilidad operativa: las herramientas de backup, la semántica de replicación y las tablas del sistema importan más de lo que la mayoría de equipos admiten.
Si estás intercambiando entre MariaDB y Percona Server, la trampa es asumir que ambos son “solo MySQL”. Percona Server tiende a seguir de cerca a MySQL upstream (porque es fundamentalmente MySQL con extras). MariaDB tomó su propio camino bifurcado hace tiempo y siguió evolucionando la etiqueta “MySQL” mientras cambiaba internos y funcionalidades.
Broma #1: “Reemplazo directo” es como “hot swap” en una solicitud de cambio: significa que lo cambiarás mientras está caliente.
Aquí está la postura que salva equipos: trata un movimiento MariaDB ↔ Percona Server como una migración de motor mayor, no como un parche menor. Planéalo como lo harías para PostgreSQL ↔ MySQL? No. Pero es más cercano de lo que quieres creer.
Linaje y contexto histórico (los hechos que la gente olvida)
Un poco de historia breve, porque explica las minas de compatibilidad actuales. Esto no es trivia; predice cómo se comportará tu actualización/migración.
- MariaDB se bifurcó de MySQL en 2009 tras preocupaciones por la adquisición de Sun Microsystems por Oracle y la administración de MySQL.
- Percona Server nació como una distribución enfocada en rendimiento que se mantiene cercana a MySQL upstream mientras añade instrumentación y características de nivel empresarial.
- MariaDB divergió intencionalmente: mantuvo la compatibilidad del protocolo cliente de MySQL pero introdujo sus propias funcionalidades y motores de almacenamiento (notablemente Aria) y su propio trabajo en el optimizador.
- GTID no es “un solo GTID”: la implementación de GTID en MariaDB difiere de MySQL/Percona GTID, afectando herramientas de failover y topologías mixtas.
- Mariabackup es un fork de la línea XtraBackup en términos de linaje, pero el comportamiento, acoplamiento por versión y casos límite difieren lo suficiente como para que “usar cualquiera” sea arriesgado.
- Las tablas del sistema y el diccionario de datos evolucionaron de forma distinta: MySQL 8 introdujo cambios importantes en el diccionario; MariaDB tomó otra ruta. Las herramientas que raspan
mysql.*pueden fallar. - JSON es un punto recurrente de dolor: MariaDB históricamente implementó JSON como una cadena con funciones; MySQL lo trata como un tipo nativo con semánticas de indexado diferentes.
- Los plugins de autenticación divergieron: MySQL/Percona pasaron por
caching_sha2_password; MariaDB se apoyó en conjuntos de plugins diferentes y en distintos valores por defecto según la versión. - Las rutas del optimizador no son intercambiables: ambos tienen modelos de costo y heurísticas que cambian planes de consulta de formas “legales” pero operativamente explosivas.
Estas diferencias no significan que uno sea “malo”. Significan que el mismo playbook no siempre funcionará. Tu trabajo es saber cuáles supuestos estás haciendo y luego eliminar los que no son ciertos.
Una cita que debería estar grapada a todo plan de migración: “La esperanza no es estrategia.”
— James Cameron.
Mapa de compatibilidad: dónde divergen MariaDB y Percona Server
1) Versionado y objetivo de características
Percona Server generalmente sigue las versiones upstream de MySQL (y sus semánticas), por lo que su objetivo de compatibilidad es “comportamiento MySQL + extras.” MariaDB apunta al “comportamiento MariaDB”, manteniéndose parecido a MySQL para casos de uso comunes.
Si tu proveedor de la aplicación dice “compatible con MySQL 8”, eso suele mapearse más naturalmente a Percona Server para MySQL 8 que a MariaDB. Si tu proveedor dice “soportado MariaDB”, no lo interpretes como “soportado MySQL”. Son dos promesas diferentes.
2) Tablas del sistema, metadatos y supuestos de herramientas
Muchos scripts corporativos cometen delitos contra la base de datos mysql. Consultan tablas de sistema legadas directamente. O parsean la salida de SHOW PROCESSLIST como si fuera una API estable. O asumen que las columnas de information_schema existen igual en todos lados.
Eso funciona—hasta que deja de hacerlo. En migraciones, a menudo son las herramientas las que fallan primero, no la base de datos.
3) Plugins y funciones que suenan similares pero no lo son
Plugins de autenticación, plugins de auditoría, validación de contraseñas, cifrado—los nombres se solapan, el comportamiento no. “Usamos el plugin de auditoría” no es un requisito; es un hueco en la especificación a menos que puedas nombrar cuál, qué eventos y dónde van los logs.
4) InnoDB: “mismo nombre de motor”, parches distintos
Ambos mundos usan InnoDB, pero con distintos parches, valores por defecto y a veces distinta instrumentación. Percona es famoso por métricas adicionales y cambios relacionados con el rendimiento. MariaDB históricamente distribuyó XtraDB en algunas versiones, luego convergió hacia InnoDB otra vez. Operacionalmente, esto se manifiesta como valores por defecto distintos, puntos óptimos de ajuste diferentes y distintos umbrales de “está bien”.
La conclusión práctica: no asumas que tu archivo de afinamiento de InnoDB es portable. Puedes mantener el espíritu, no los valores literales.
Replicación y HA: GTID, failover y los bordes filosos
GTID: la gran bifurcación de compatibilidad en el camino
Si llevas una cosa de este artículo, que sea esta: GTID de MariaDB y GTID de MySQL/Percona son sistemas diferentes. Resuelven problemas similares con formatos distintos y comportamientos operativos diferentes.
Eso importa para:
- Automatización de failover: las herramientas que asumen las semánticas de GTID de MySQL pueden hacer promociones inseguras en MariaDB, y viceversa.
- Clústeres mixtos: “Ejecutaremos réplicas MariaDB de un primario Percona por un tiempo” no es una decisión casual. Normalmente es un puente de corta duración con restricciones estrictas, no una arquitectura para estado estable.
- Recuperación punto en el tiempo: tu flujo de recuperación basado en binlogs puede necesitar ajustes, especialmente en torno a la estricticidad y consistencia de GTID.
Filtros de replicación y comportamiento basado en filas
La replicación basada en sentencias es la tierra donde viven los fantasmas. Si estás migrando, obligate a usar replicación basada en filas a menos que tengas una razón fuerte para no hacerlo. Las diferencias en la determinismo de funciones, comportamiento de colaciones o modo SQL pueden hacer que la replicación por sentencias sea “técnicamente exitosa” mientras corrompe datos lentamente.
Replicación de grupo y expectativas de Galera
Percona Server se despliega a menudo con topologías de replicación al estilo MySQL o con Percona XtraDB Cluster (basado en Galera). MariaDB también tiene variantes con Galera. La similitud termina cuando te das cuenta de que cada ecosistema tiene sus propios valores por defecto, herramientas operativas y manejo de casos límite.
Si tu historia de HA depende de “Galera lo manejará”, estás subcontratando la corrección a un sistema que aún necesita que definas comportamiento ante conflictos, patrones de escritura y decisiones de quórum.
Copia de seguridad y restauración: XtraBackup vs mariabackup y la realidad de restaurar
Las copias de seguridad son donde las afirmaciones de compatibilidad van a morir en silencio. La base de datos arranca, las consultas funcionan, todos se relajan—hasta que una prueba de restauración revela que tu herramienta de backup era “casi compatible” con el servidor que realmente ejecutas.
XtraBackup (Percona) vs mariabackup (MariaDB)
Operativamente, ambos buscan hacer copias físicas calientes de InnoDB. En la práctica:
- Acoplamiento por versión: las herramientas de backup son exigentes con las versiones del servidor. “Suficientemente cercano” se convierte en “no podrá preparar la copia”.
- Diferencias en cifrado/compresión: las opciones y valores por defecto varían; las canalizaciones de restauración fallan si asumes que las flags son portables.
- Incrementales: funcionan, hasta que no lo hacen—especialmente a través de upgrades o cambios en la configuración de redo logs.
Mi regla dura: las pruebas de restauración son parte de la migración. No después. No “lo haremos más tarde”. Si no puedes restaurar, no tienes una base de datos, tienes un rumor.
Broma #2: Las copias de seguridad son como los paracaídas: si solo las pruebas una vez, suele ser la última vez que las necesitas.
Seguridad y autenticación: plugins, TLS y sorpresas del cliente
Los plugins de autenticación pueden hacer que clientes “compatibles” fallen
Las librerías cliente a menudo incorporan supuestos sobre plugins de autenticación por defecto. Cuando MySQL cambió valores por defecto (notablemente alrededor de caching_sha2_password en MySQL 8), desencadenó un desfile de años de problemas de conexión en distintos lenguajes y paquetes OS.
MariaDB tomó decisiones distintas y ofreció plugins distintos. Percona sigue de cerca el comportamiento de MySQL. Eso significa que la misma imagen de contenedor de la aplicación podría conectarse bien a uno y fallar con el otro—sin cambios en el código.
Desajustes de TLS y políticas de cifrado
TLS “funciona” hasta que tu equipo de cumplimiento exige nuevos conjuntos de cifrado o versiones mínimas. Las compilaciones de servidor y paquetes de las distribuciones pueden enlazar OpenSSL distinto, tener valores por defecto distintos y conjuntos de cifrado aceptados distintos.
Haz explícita la seguridad: define versión TLS, expectativas de cifrados y versiones de librerías cliente como parte de tu runbook.
Optimizador y rendimiento: el problema de “misma consulta, plan distinto”
Los incidentes más costosos son aquellos donde nada está roto. Simplemente está más lento. Lo suficientemente lento como para que se produzca una cascada.
Por qué cambian los planes
Aun cuando la sintaxis SQL es compatible, el optimizador puede elegir órdenes de join, índices y estrategias de tabla temporal diferentes. Las razones incluyen:
- Diferentes modelos de costo y manejo de estadísticas
- Diferentes valores por defecto para tablas temporales, límites de memoria y buffers de ordenación
- Diferentes interpretaciones de hints o sintaxis de hints disponible
- Diferente comportamiento de colaciones que afecta el uso de índices
Guía práctica
Antes de migrar, captura planes de consulta representativos y el comportamiento real en tiempo de ejecución. No solo EXPLAIN—también la distribución de latencia, filas examinadas y contención. Después de migrar, compara de nuevo con la misma forma de datos.
Si no vas a hacer esto, sé honesto: estás apostando, no ingenierizando.
Observabilidad y herramientas: lo que tus paneles no te dirán
La mayoría de las configuraciones de “monitorización MySQL” son un montón de supuestos: qué variables de estado existen, qué tablas de performance_schema están habilitadas, cómo se ven los slow logs y qué usuario tiene permisos para leer todo.
Los ecosistemas Percona suelen apoyarse en convenciones de Percona Toolkit y métricas extendidas. Los entornos MariaDB pueden tener valores por defecto de instrumentación distintos y distinta madurez de performance_schema según la versión. Ambos pueden volverse observables, pero no asumiendo que tu configuración de exporter sea portable.
Además: revisa tus scripts administrativos. Cualquier cosa que raspe SHOW ENGINE INNODB STATUS y haga grep de cadenas en inglés es una responsabilidad. Funcionará hasta que no, y entonces te despertará a las 03:12 con tonterías.
Guion de diagnóstico rápido
Este es el protocolo “acabamos de migrar y ahora está lento/inestable”. La meta es encontrar el cuello de botella en minutos, no ganar una discusión sobre qué base de datos es mejor.
Primero: identifica si el límite es CPU, IO, bloqueos o replicación
- CPU: CPU de usuario alta, muchas threads ejecutables, planes de consulta cambiados, índices faltantes o nuevo comportamiento de sort/tmp.
- IO: tiempos de espera altos, fallos de buffer pool, presión de redo/flush, almacenamiento lento,
innodb_flush_methodinapropiado. - Bloqueos: picos en esperas de locks, deadlocks, transacciones largas, distintos valores por defecto de aislamiento.
- Replicación: lag de réplicas, cuellos de botella en apply del relay log, desajuste de GTID, cambios en formato de fila.
Segundo: revisa las 3 consultas principales y sus planes
No navegues mil métricas. Identifica a los mayores culpables (por tiempo total y p95). Compara planes con la línea base.
Tercero: valida los básicos operativos
- ¿Los binlogs están configurados como se espera?
- ¿El servidor está en el modo SQL correcto?
- ¿Los cambios de autenticación forzaron a los clientes a oleadas de reconexión?
- ¿El camino de backup/restore cambió el layout de datos (por ejemplo, settings de file-per-table diferentes)?
Cuarto: decide si hacer rollback, tunear o parchear consultas
Rollback no es fracaso; es control. Si tu restauración y recorte de corte están ensayados, rollback es una operación de rutina. Si no lo están, quedas “tuneando en vivo” mientras sangras.
Errores comunes: síntomas → causa raíz → solución
1) La app no puede conectarse tras la migración
Síntomas: “Authentication plugin not supported”, fallos de handshake o errores TLS desde clientes.
Causa raíz: valores por defecto de plugins de auth distintos; librería cliente demasiado antigua; desajuste de política TLS.
Solución: alinea el plugin de auth a lo que los clientes soportan; actualiza librerías cliente; configura TLS explícitamente y verifica con un cliente conocido bueno.
2) Las consultas son correctas pero más lentas 5–50×
Síntomas: picos de latencia p95, CPU arriba, slow log lleno de consultas que antes estaban bien.
Causa raíz: deriva del plan del optimizador; diferencias en estadísticas; distinto comportamiento de tablas temporales; cambio en uso de colaciones/índices.
Solución: captura y compara EXPLAIN/EXPLAIN ANALYZE (donde esté disponible), actualiza estadísticas, añade o ajusta índices, considera hints de consulta solo como último recurso.
3) La replicación “funciona” pero el failover falla
Síntomas: la herramienta de failover se niega a promover, o promueve pero las réplicas no se reconectan limpiamente.
Causa raíz: desajuste semántico de GTID; supuestos de topología en modo mixto; diferentes ajustes de binlog.
Solución: elige un único universo GTID; estandariza ajustes de replicación; prueba promoción y reingreso bajo carga en staging.
4) Los backups terminan, las restauraciones fallan
Síntomas: trabajo de backup en verde; prueba de restauración falla en la fase de prepare o el servidor no arranca.
Causa raíz: desajuste entre versión de herramienta y servidor; flags erróneas; desajuste en cifrado/compresión; expectativas de redo logs faltantes.
Solución: fija versiones de herramientas de backup con las versiones del servidor; ejecuta simulacros de restauración periódicos; valida que el backup preparado arranque limpiamente.
5) Contención de locks repentina tras la migración
Síntomas: aumento de esperas de locks, deadlocks, caída de throughput a pesar de mezcla de consultas similar.
Causa raíz: valores por defecto distintos (aislamiento, patrones de autocommit expuestos), planes ejecutivos cambiados que escanean/bloquean más filas, transacciones largas de jobs por lotes.
Solución: identifica transacciones bloqueantes, acorta el scope de transacciones, añade índices para reducir filas escaneadas, revisa el nivel de aislamiento y patrones de carga.
6) La monitorización falla o muestra tonterías
Síntomas: paneles sin métricas, exporters con errores, spam de alertas sobre “unknown variable”.
Causa raíz: nombres y disponibilidad de métricas distintos; configuración de performance_schema distinta; diferencias de privilegios.
Solución: actualiza exporters y consultas; habilita instrumentación requerida de forma intencional; deja de raspar internals inestables.
Tres microhistorias corporativas desde la trinchera
Microhistoria 1: el incidente causado por una suposición equivocada
Una compañía SaaS de tamaño medio decidió “estandarizar” bases de datos. Un producto usaba MariaDB, otro Percona Server. El plan sonaba simple: mover todo a un motor para que el equipo on-call dejara de cambiar de contexto.
El equipo de migración se concentró en esquema y movimiento de datos. Validaron que la app arrancaba, que CRUD funcionaba y que las pruebas de humo pasaban. Asumieron que el failover de replicación se comportaría igual porque “todo es MySQL”.
Dos semanas después, un nodo primario murió. La automatización de failover promovió una réplica y la app volvió. Luego el primario viejo regresó, y su reingreso falló de una manera que la automatización no manejó. El clúster se dividió en campos de “creo que estoy por delante”, y el equipo descubrió que sus supuestos de GTID no eran portables entre los motores que habían mezclado durante la transición.
La solución no fue un tuning heroico. Fue honestidad arquitectónica: congelaron topologías mixtas, reconstruyeron réplicas desde backups limpios y permitieron un solo modelo GTID en cualquier dominio de replicación. La lección real no fue sobre sintaxis de GTID. Fue sobre no tratar la semántica de HA como un detalle de implementación.
Microhistoria 2: la optimización que salió mal
Una gran empresa migró de una variante MySQL a otra para obtener mejor instrumentación de rendimiento y menor latencia. Tras el corte, notaron mayor IO y peores latencias tail. Así que hicieron lo que muchos equipos hacen: giraron perillas.
Alguien aumentó tamaños de buffers y elevó ajustes relacionados con concurrencia porque “más threads igual más throughput”. También ajustaron comportamiento de flushing para reducir la frecuencia de fsync. En papel, parecía tuning clásico.
Durante aproximadamente un día, el throughput mejoró. Luego llegó un pico de tráfico. El servidor empezó a quedarse bloqueado en ráfagas: periodos cortos de comportamiento normal, seguidos por pausas horribles donde todo se encolaba. La causa raíz fue un patrón de presión en flush/redo: habían cambiado latencia consistente por caídas periódicas. El tuning amplificó el peor momento del motor en lugar de suavizarlo.
Revirtieron los cambios, perfilaron de nuevo y descubrieron la verdadera regresión: un puñado de consultas había cambiado a planes que usaban tablas temporales grandes. Corregir índices y patrones de consulta redujo IO más que cualquier cambio de buffers. La “optimización” había sido una distracción y casi se convirtió en la configuración permanente porque brevemente parecía buena.
Microhistoria 3: la práctica aburrida pero correcta que salvó el día
Una compañía relacionada con finanzas tenía una regla que molestaba a todos: ejercicios trimestrales de restauración, no opcionales. Cada simulacro incluía restaurar un backup completo, aplicar binlogs hasta una marca de tiempo objetivo y ejecutar un conjunto simple de verificaciones de consistencia.
Cuando migraron de MariaDB a Percona Server, el simulacro sacó a la luz un problema sutil temprano. El job de backup estaba en verde, pero el backup preparado fallaba intermitentemente al iniciar después de la restauración debido a un desajuste de versiones entre el contenedor de la herramienta de backup y la versión del servidor en producción.
Como el simulacro ocurrió antes del corte, la solución fue mundana: fijar versiones, construir una imagen de backup probada y agregar una verificación de compatibilidad en CI que ejecutara un pequeño ciclo backup/prepare/restore en cada cambio de versión.
Meses después tuvieron un incidente real: eliminación accidental de datos. El equipo restauró limpiamente, aplicó binlogs hasta el minuto y devolvió el servicio sin improvisar. Nadie celebró, porque fue aburrido. Ese es el mayor elogio en operaciones.
Tareas prácticas (comandos + salidas + decisiones)
Estas son tareas reales que puedes ejecutar en hosts Linux y dentro de la base de datos. Cada una incluye lo que significa la salida y qué decidir después. Ejecútalas antes y después de una migración, y al diagnosticar rarezas en producción.
Tarea 1: Confirmar identidad del servidor y linaje de versión
cr0x@server:~$ mysql -NBe "SELECT VERSION(), @@version_comment, @@version_compile_machine;"
10.11.6-MariaDB MariaDB Server x86_64
Qué significa: Esto te dice a qué familia corres realmente. @@version_comment a menudo incluye “Percona Server” o “MariaDB Server”.
Decisión: Mapea tu objetivo de compatibilidad. Si esperabas semánticas MySQL/Percona y ves MariaDB, detente y vuelve a comprobar supuestos de GTID, JSON y plugins.
Tarea 2: Verificar deriva de SQL mode (cambiador de comportamiento silencioso)
cr0x@server:~$ mysql -NBe "SELECT @@sql_mode;"
STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_ENGINE_SUBSTITUTION
Qué significa: El modo SQL afecta validación de datos, conversiones implícitas y manejo de errores.
Decisión: Alinea SQL mode entre servidores antiguo y nuevo antes de comparar comportamiento. Si lo cambias durante la migración, estás cambiando las semánticas de la app.
Tarea 3: Verificar plugin de autenticación por defecto
cr0x@server:~$ mysql -NBe "SHOW VARIABLES LIKE 'default_authentication_plugin';"
default_authentication_plugin mysql_native_password
Qué significa: Los valores por defecto distintos pueden romper clientes antiguos.
Decisión: Si los clientes son legacy, conserva un plugin compatible o actualiza clientes primero. No “arregles” producción debilitando la autenticación sin registrarlo.
Tarea 4: Inspeccionar plugins que usan los usuarios
cr0x@server:~$ mysql -NBe "SELECT user, host, plugin FROM mysql.user ORDER BY plugin, user LIMIT 10;"
app % mysql_native_password
repl 10.% mysql_native_password
Qué significa: Incluso si el valor por defecto es seguro, usuarios específicos pueden usar plugins incompatibles.
Decisión: Si ves plugins no soportados en el motor objetivo, necesitas un plan de migración de credenciales (y probablemente una auditoría de librerías cliente).
Tarea 5: Comprobar básicos de InnoDB y redo/flush
cr0x@server:~$ mysql -NBe "SHOW VARIABLES WHERE Variable_name IN ('innodb_flush_method','innodb_flush_log_at_trx_commit','innodb_buffer_pool_size');"
innodb_buffer_pool_size 17179869184
innodb_flush_log_at_trx_commit 1
innodb_flush_method O_DIRECT
Qué significa: Estos ajustes influyen fuertemente en latencia, durabilidad y comportamiento de IO.
Decisión: No copies configuraciones a ciegas. Reevalúa por motor y por almacenamiento. Si cambias durabilidad (innodb_flush_log_at_trx_commit), documenta el riesgo y obtén aprobación explícita.
Tarea 6: Validar formato de binlog y row image
cr0x@server:~$ mysql -NBe "SHOW VARIABLES WHERE Variable_name IN ('log_bin','binlog_format','binlog_row_image');"
log_bin ON
binlog_format ROW
binlog_row_image FULL
Qué significa: Esto influye en la seguridad y compatibilidad de replicación.
Decisión: Para migraciones, ROW + FULL es el valor conservador. Si cambias a MINIMAL por rendimiento, prueba consumidores downstream y replicación cuidadosamente.
Tarea 7: Comprobar indicadores de modo GTID
cr0x@server:~$ mysql -NBe "SHOW VARIABLES LIKE '%gtid%';" | head
gtid_domain_id 0
gtid_strict_mode ON
gtid_binlog_pos 0-1-12345
Qué significa: Estas variables son indicadores de GTID al estilo MariaDB (dominio/servidor/secuencia).
Decisión: Si te mueves hacia/desde GTID de MySQL/Percona, planea traducción de GTID o un reinicio de topología. No improvises durante un evento de failover.
Tarea 8: Detectar lag de replicación y la razón (IO vs hilo SQL)
cr0x@server:~$ mysql -e "SHOW SLAVE STATUS\G" | egrep "Slave_IO_Running|Slave_SQL_Running|Seconds_Behind_Master|Last_SQL_Error|Retrieved_Gtid_Set|Executed_Gtid_Set" -n
3:Slave_IO_Running: Yes
4:Slave_SQL_Running: Yes
32:Seconds_Behind_Master: 18
48:Last_SQL_Error:
78:Retrieved_Gtid_Set:
79:Executed_Gtid_Set:
Qué significa: Si los hilos IO y SQL están corriendo pero el lag aumenta, el apply es lento o hay picos de carga. Los campos de error ayudan a detectar incompatibilidades.
Decisión: Si el lag es persistente tras la migración, inspecciona IO de disco y patrones de consultas en réplicas; considera ajustes de replicación en paralelo apropiados al motor/version.
Tarea 9: Capturar top waits rápidamente (proxy de presión de mutex/locks InnoDB)
cr0x@server:~$ mysql -NBe "SHOW GLOBAL STATUS LIKE 'Innodb_row_lock%';"
Innodb_row_lock_current_waits 3
Innodb_row_lock_time 89123
Innodb_row_lock_time_avg 1123
Innodb_row_lock_time_max 9000
Innodb_row_lock_waits 79
Qué significa: Aumentos en esperas/tiempo indican contención, a menudo por cambios de plan o transacciones largas.
Decisión: Si esto saltó tras la migración, encuentra transacciones bloqueantes y compara planes de ejecución para las tablas calientes.
Tarea 10: Identificar transacciones de mayor duración
cr0x@server:~$ mysql -e "SELECT trx_id, trx_started, trx_mysql_thread_id, trx_rows_locked, trx_rows_modified FROM information_schema.innodb_trx ORDER BY trx_started LIMIT 5;"
+--------+---------------------+--------------------+----------------+------------------+
| trx_id | trx_started | trx_mysql_thread_id| trx_rows_locked| trx_rows_modified|
+--------+---------------------+--------------------+----------------+------------------+
| 123ABC | 2025-12-30 01:12:09 | 9821 | 44012 | 12 |
+--------+---------------------+--------------------+----------------+------------------+
Qué significa: Las transacciones largas mantienen locks y aumentan trabajo de undo/redo.
Decisión: Si ves transacciones de larga duración tras la migración, busca el path de código de la app o job por lotes. A veces un plan cambiado hace que una transacción tarde 10× más y todo lo demás parezca “misteriosamente bloqueado”.
Tarea 11: Comparar planes de consulta para una consulta caliente conocida
cr0x@server:~$ mysql -e "EXPLAIN SELECT * FROM orders WHERE customer_id=123 AND status='OPEN' ORDER BY created_at DESC LIMIT 50;"
+----+-------------+--------+------+------------------------+--------------------+---------+-------+------+-----------------------------+
| id | select_type | table | type | possible_keys | key | key_len | ref | rows | Extra |
+----+-------------+--------+------+------------------------+--------------------+---------+-------+------+-----------------------------+
| 1 | SIMPLE | orders | ref | idx_customer_status_dt | idx_customer_status_dt | 8 | const | 120 | Using where; Using filesort |
+----+-------------+--------+------+------------------------+--------------------+---------+-------+------+-----------------------------+
Qué significa: “Using filesort” puede estar bien—o puede ser tu nuevo cuello de botella si antes no estaba.
Decisión: Si el plan cambió, considera un índice covering que soporte el ORDER BY. Valida con latencia real y filas examinadas, no solo con la estética de EXPLAIN.
Tarea 12: Comprobar comportamiento de tablas temporales y spills
cr0x@server:~$ mysql -NBe "SHOW GLOBAL STATUS LIKE 'Created_tmp%';"
Created_tmp_disk_tables 12409
Created_tmp_tables 70211
Created_tmp_files 88
Qué significa: Las tablas temporales en disco y los tmp files a menudo correlacionan con ralentizaciones súbitas tras cambios del optimizador.
Decisión: Si las tablas temporales en disco se disparan tras la migración, enfócate en planes e índices primero. Solo después considera cambios en tamaños de tmp.
Tarea 13: Confirmar juego de caracteres y colación por defecto
cr0x@server:~$ mysql -NBe "SHOW VARIABLES WHERE Variable_name IN ('character_set_server','collation_server');"
character_set_server utf8mb4
collation_server utf8mb4_general_ci
Qué significa: Cambios de colación pueden romper supuestos de unicidad y uso de índices.
Decisión: Si los valores por defecto difieren de tu línea base, fíjalos explícitamente y verifica expectativas de la app (especialmente sobre ordenación y sensibilidad a mayúsculas).
Tarea 14: Validar almacenamiento y latencia de IO del filesystem (realidad a nivel host)
cr0x@server:~$ iostat -x 1 3
Linux 6.5.0 (server) 12/30/2025 _x86_64_ (8 CPU)
avg-cpu: %user %nice %system %iowait %steal %idle
32.10 0.00 6.20 7.80 0.00 53.90
Device r/s w/s r_await w_await aqu-sz %util
nvme0n1 220.0 480.0 2.10 8.70 4.20 92.0
Qué significa: Alto w_await y %util apuntan a presión de escritura. Las migraciones suelen cambiar patrones de escritura (comportamiento distinto de redo/log, distinto uso de tmp tables).
Decisión: Si el almacenamiento está saturado, deja de “tunear la base de datos” y arregla capacidad de IO o reduce amplificación de escritura (correcciones de consultas/índices, batching, ajustes de flush solo con conciencia de durabilidad).
Tarea 15: Chequeo rápido de opciones de montaje del filesystem que sabotean bases de datos
cr0x@server:~$ findmnt -no TARGET,FSTYPE,OPTIONS /var/lib/mysql
/var/lib/mysql ext4 rw,relatime
Qué significa: Algunas opciones de montaje pueden impactar la latencia. relatime generalmente está bien; otras opciones (o setups exóticos) pueden no serlo.
Decisión: Si ves opciones sorprendentes (o filesystems de red), trátalo como sospechoso principal para problemas de rendimiento y durabilidad.
Tarea 16: Validar alineación de versión de herramienta de backup y servidor
cr0x@server:~$ xtrabackup --version
xtrabackup version 8.0.35 based on MySQL server 8.0.35 Linux (x86_64)
Qué significa: Las herramientas de backup anuncian su objetivo de compatibilidad. La falta de coincidencia es una falla de restauración esperando suceder.
Decisión: Fija la versión de la herramienta a la que corres. Si estás en MariaDB, prefiere mariabackup alineado con esa línea mayor de MariaDB.
Listas de verificación / plan paso a paso
Plan A: Quieres Percona Server porque necesitas compatibilidad “MySQL real”
- Inventario de expectativas de la app: matriz de soporte del proveedor, características SQL usadas (JSON, funciones de ventana, columnas generadas) y versiones de librerías cliente.
- Estandarizar SQL mode y juego de caracteres: establece valores explícitos; no heredes valores por defecto.
- Decisión sobre modelo de replicación: elige semánticas GTID y mantente con ellas. No mezcles GTID MariaDB con GTID MySQL en estado estable.
- Auditoría de herramientas: exporters de monitorización, scripts de backup, automatización de failover, herramientas de migración de esquema—pruébalas en el motor objetivo.
- Línea base de rendimiento: captura consultas top, latencia p95/p99, filas examinadas, tasas de tmp tables, tasas de hit del buffer pool.
- Restore en seco: crea una restauración completa desde backups en un entorno aislado y ejecuta checks de consistencia.
- Corte por etapas: dual-write si puedes justificarlo; de lo contrario usa promoción de réplicas y un rollback ensayado.
Plan B: Quieres MariaDB porque te comprometes con su ecosistema
- Deja de llamarlo “MySQL” internamente: etiquétalo como MariaDB en runbooks y paneles. Eso reduce suposiciones incorrectas.
- Confirma uso de características: si dependes de semánticas específicas de MySQL 8, ten cuidado. Prueba la versión exacta de MariaDB que vas a usar.
- Adopta herramientas nativas de MariaDB: especialmente para backup/restore y automatización basada en GTID.
- Valida uso de JSON: revisa tipos de columna y expectativas de indexado; evita asumir comportamiento nativo JSON si vienes de MySQL.
- Retunea para tu almacenamiento: especialmente comportamiento de tmp tables y patrones de flushing; no portes configs como si fueran variables de entorno.
- Ensayo de failover: simula pérdida de nodo, promoción y reingreso. Hazlo dos veces: una en silencio y otra bajo carga.
Criterios mínimos de aceptación “sin sorpresas” para la migración
- Puedes restaurar a un host nuevo y el servidor arranca limpiamente.
- El failover funciona y las réplicas se reanudan sin cirugía manual.
- Las 20 consultas principales mantienen planes estables y latencia tail aceptable.
- La monitorización y las alertas funcionan sin ruido de “unknown variable”.
- La autenticación de clientes y TLS funcionan con todas las variantes de clientes en producción.
Preguntas frecuentes
1) ¿Es Percona Server un reemplazo directo para MySQL?
Usualmente, sí—dentro de la misma línea mayor de MySQL—porque sigue de cerca a MySQL upstream. Aun así valida plugins, valores por defecto y herramientas de backup.
2) ¿Es MariaDB un reemplazo directo para MySQL?
A veces para aplicaciones básicas, pero es más arriesgado a medida que MySQL avanza. Si necesitas “comportamiento MySQL 8”, trata a MariaDB como una base de datos distinta y pruébala en consecuencia.
3) ¿Es MariaDB un reemplazo directo para Percona Server?
No de manera fiable. El protocolo puede funcionar, pero GTID, tablas del sistema, plugins y comportamiento del optimizador pueden divergir lo suficiente como para romper la automatización y las expectativas de rendimiento.
4) ¿Puedo replicar desde Percona Server a MariaDB (o al revés)?
A veces puedes hacerlo como un puente temporal con restricciones estrictas (formato de binlog, SQL soportado, planificación cuidadosa de GTID). No asumas que es seguro a largo plazo sin validación explícita.
5) ¿Cuál es la mayor trampa oculta en migraciones MariaDB ↔ Percona?
GTID y semánticas de failover. No es el SQL. Es lo que pasa a las 2 a.m. cuando un nodo muere y tu automatización hace suposiciones.
6) ¿Debo copiar mi tuning de my.cnf de uno a otro?
No. Empieza desde una línea base conservadora y solo porta parámetros que entiendas. Luego afina con mediciones. Copiar a ciegas es cómo obtienes stalls periódicos y “estaba bien antes”.
7) ¿Cuál es más rápido?
Pregunta equivocada. La base de datos más rápida es donde tus consultas calientes usan buenos planes y tu IO no está saturado. Cualquiera de los motores puede ganar o perder según la carga y el tuning.
8) ¿Necesito herramientas de backup distintas?
Sí, planifícalo. Usa herramientas alineadas a tu familia de servidor y versión. Y ejecuta simulacros de restauración—porque las afirmaciones de compatibilidad no restauran datos.
9) ¿Cómo elijo si mi proveedor solo soporta “MySQL”?
Pregunta qué entienden por MySQL: versión, expectativas de plugin de auth, uso de GTID, expectativas de backup. Si prueban contra Oracle MySQL 8, Percona Server para MySQL 8 suele ser la coincidencia más segura.
10) ¿Puedo evitar estos problemas usando contenedores y Kubernetes?
No. Los contenedores son excelentes para empaquetar sorpresas consistentemente. Aún necesitas compatibilidad de comportamiento, backups probados y failover ensayado.
Próximos pasos que realmente puedes hacer esta semana
- Ejecuta las tareas prácticas en tu flota actual y anota los resultados: versión, SQL mode, plugins de auth, formato de binlog, variables GTID.
- Elige un único objetivo de compatibilidad: “semánticas MySQL 8” (inclínate por Percona) o “semánticas MariaDB” (comprométete con MariaDB). Deja de esperar obtener ambos gratis.
- Haz un simulacro de restauración en un host aislado y prueba que el servidor arranque y la app ejecute una pequeña carga.
- Ensaya el failover en staging con la misma automatización que usarás en producción. Si no tienes automatización, tu primer failover será un experimento en vivo.
- Establece línea base y compara planes para tus consultas principales. Si encuentras regresiones, arregla consultas e índices antes de tocar “perillas de tuning”.
Si quieres una regla clara: Percona Server suele ser la opción más segura “compatible con MySQL”; MariaDB es una base de datos sólida cuando la tratas como MariaDB y dejas de fingir que es MySQL con otro logo.