Migrar de MySQL 5.6 a 8.0 no es un trámite cosmético. El salto toca compatibilidad, comportamiento del optimizador, collations, autenticación y expectativas de aplicaciones que llevan años asumiendo un comportamiento que cambia.

Nota importante: MySQL no soporta salto directo de 5.6 a 8.0 mediante upgrade in-place. El camino obligado es 5.6 → 5.7 → 8.0.

Paso previo obligatorio: el inventario

-- Listar engines por tabla
SELECT TABLE_SCHEMA, TABLE_NAME, ENGINE
FROM information_schema.TABLES
WHERE TABLE_SCHEMA NOT IN ('mysql','information_schema','performance_schema','sys');

-- Revisar collations mixtas
SELECT TABLE_SCHEMA, TABLE_NAME, TABLE_COLLATION
FROM information_schema.TABLES
WHERE TABLE_COLLATION NOT LIKE 'utf8mb4%'
  AND TABLE_SCHEMA NOT IN ('mysql','information_schema','performance_schema','sys');

-- Examinar routines y triggers
SELECT ROUTINE_SCHEMA, ROUTINE_NAME, ROUTINE_TYPE
FROM information_schema.ROUTINES
WHERE ROUTINE_SCHEMA NOT IN ('sys');

SELECT TRIGGER_SCHEMA, TRIGGER_NAME FROM information_schema.TRIGGERS;

Tipos de datos y diseño heredado

El límite de ancho de fila en InnoDB es 65,535 bytes. Columnas VARCHAR con caracteres multibyte (utf8mb4 usa hasta 4 bytes por carácter) pueden superar este límite al migrar si las tablas tenían charset latin1 original.

-- Detectar tablas con potencial desbordamiento
SELECT TABLE_NAME, SUM(CHARACTER_MAXIMUM_LENGTH * 4) AS estimated_row_bytes
FROM information_schema.COLUMNS
WHERE DATA_TYPE IN ('varchar','char')
  AND TABLE_SCHEMA = 'tu_base'
GROUP BY TABLE_NAME
HAVING estimated_row_bytes > 65535;

Routines, triggers y sótanos técnicos

Los procedimientos almacenados conservan el sql_mode de su creación original. Si fueron creados en 5.6 con un sql_mode permisivo, al recrearlos en 8.0 (con modo más estricto por defecto) pueden fallar o comportarse diferente.

Charset, collation y restores mal queridos

MySQL 8.0 cambia el collation por defecto de utf8mb4_unicode_ci a utf8mb4_0900_ai_ci. Esto rompe comparaciones y JOINs entre tablas con collations distintos. La estrategia segura es normalizar todo a utf8mb4_unicode_ci explícitamente antes de migrar.

Engines heredados: MyISAM y el olvido

MyISAM pierde soporte de transacciones y crash recovery confiable en 8.0. Todas las tablas MyISAM deben convertirse a InnoDB antes de la migración. Una tabla MyISAM en 8.0 puede corromperse sin posibilidad de recovery transaccional.

-- Convertir tabla a InnoDB
ALTER TABLE nombre_tabla ENGINE=InnoDB;

-- Script masivo (generar los ALTER)
SELECT CONCAT('ALTER TABLE `', TABLE_SCHEMA, '`.`', TABLE_NAME, '` ENGINE=InnoDB;')
FROM information_schema.TABLES
WHERE ENGINE = 'MyISAM' AND TABLE_SCHEMA NOT IN ('mysql','information_schema');

SQL mode: el comportamiento que cambia sin avisar

MySQL 8.0 activa por defecto modos más estrictos: STRICT_TRANS_TABLES, NO_ZERO_DATE, ERROR_FOR_DIVISION_BY_ZERO. Esto rompe patrones comunes en aplicaciones antiguas como insertar '0000-00-00' en campos DATE o dividir por cero en queries calculadas.

Conclusión

Una migración bien planificada entre versiones mayores de MySQL tiene un camino conocido. El problema no es que sea imposible; es que requiere inventario honesto, pruebas funcionales reales y un rollback probado antes de tocar producción.