Desarrollo y bases de datos

Convertir base de datos utf8 a utf8mb4

Revisado el 7 min de lectura mysql codificacion

Una aplicación antigua puede requerir convertir sus tablas de utf8 a utf8mb4. No hagas reemplazos globales sobre un volcado ni elimines las tablas de producción: una sustitución de texto puede modificar datos de usuario, nombres de collations no equivalentes o contenido serializado.

1. Crear y verificar una copia protegida

Trabaja desde una carpeta privada fuera de public_html, con un nombre de volcado nuevo. Detén temporalmente las escrituras de la aplicación y genera un volcado consistente. -p solicita la contraseña de forma interactiva y evita dejarla en el historial o en la lista de procesos:

umask 077
mysqldump --single-transaction --routines --triggers -u USUARIO_MYSQL -p BASE_DE_DATOS > base-antes-utf8mb4.sql &&
test -s base-antes-utf8mb4.sql &&
sha256sum base-antes-utf8mb4.sql > base-antes-utf8mb4.sql.sha256 &&
chmod 400 base-antes-utf8mb4.sql base-antes-utf8mb4.sql.sha256 &&
sha256sum -c base-antes-utf8mb4.sql.sha256

Si mysqldump devuelve un error, no continúes ni consideres válido el archivo parcial. La exportación de rutinas requiere permisos; si falla, revisa qué objetos necesita la aplicación antes de omitirlos. Los eventos, si existen, también deben inventariarse y exportarse con las opciones y permisos adecuados. El checksum detecta cambios posteriores en el archivo, pero no demuestra que la copia esté completa. Los permisos de solo lectura tampoco la hacen inmutable.

Descarga también ambos ficheros a un almacenamiento distinto del hosting. No edites este volcado: será el punto de recuperación.

2. Restaurar en una base nueva

Crea una base vacía, con otro usuario y nombre, y restaura allí la copia:

mysql -u USUARIO_NUEVO -p BASE_NUEVA < base-antes-utf8mb4.sql

Desactiva en el clon los correos, cobros, webhooks y tareas automáticas de producción. Configura un clon de la aplicación para usar BASE_NUEVA y confirma que abre, inicia sesión y ejecuta sus operaciones principales antes de convertir nada.

3. Previsualizar y convertir el clon

Consulta primero las tablas cuyo valor predeterminado sigue siendo utf8 o utf8mb3:

SELECT TABLE_NAME, TABLE_COLLATION
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'BASE_NUEVA'
  AND (
      TABLE_COLLATION LIKE 'utf8mb3\_%'
      OR TABLE_COLLATION LIKE 'utf8\_%'
  );

La codificación de una columna puede diferir de la predeterminada de su tabla. Revisa también las columnas; una tabla con valor predeterminado utf8mb4 todavía podría contener columnas antiguas:

SELECT TABLE_NAME, COLUMN_NAME, CHARACTER_SET_NAME, COLLATION_NAME
FROM information_schema.COLUMNS
WHERE TABLE_SCHEMA = 'BASE_NUEVA'
  AND CHARACTER_SET_NAME IS NOT NULL
ORDER BY TABLE_NAME, ORDINAL_POSITION;

El generador siguiente es un punto de partida para las tablas que muestra el primer listado. CONVERT TO transforma todas sus columnas de texto, incluidas las que tengan una codificación diferente; no lo ejecutes sin revisar esas excepciones. Si solo hay que cambiar algunas columnas, prepara un ALTER TABLE ... MODIFY que conserve su definición completa.

Genera las sentencias exactas que necesitarías, revísalas una a una y ejecútalas únicamente sobre BASE_NUEVA:

SELECT CONCAT(
    'ALTER TABLE `', REPLACE(TABLE_SCHEMA, '`', '``'),
    '`.`', REPLACE(TABLE_NAME, '`', '``'),
    '` CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;'
) AS sentencia_a_revisar
FROM information_schema.TABLES
WHERE TABLE_SCHEMA = 'BASE_NUEVA'
  AND TABLE_TYPE = 'BASE TABLE'
  AND (
      TABLE_COLLATION LIKE 'utf8mb3\_%'
      OR TABLE_COLLATION LIKE 'utf8\_%'
  );

MySQL 8 muestra normalmente las collations del antiguo utf8 con el nombre utf8mb3; el segundo patrón conserva compatibilidad con versiones que todavía muestran el alias anterior. La collation concreta debe ser compatible con la versión de MySQL y con la aplicación. Comprueba que la collation elegida existe en el destino. Cambiar reglas de comparación puede generar coincidencias nuevas en índices únicos; la conversión también puede ampliar tipos de texto o chocar con claves foráneas. Revisa previamente índices de columnas de texto, porque al aumentar el tamaño máximo por carácter algunos índices antiguos pueden exceder el límite admitido.

Si quieres que las tablas nuevas hereden utf8mb4, cambia además el valor predeterminado de la base clonada:

ALTER DATABASE `BASE_NUEVA`
  CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

Esto no convierte las tablas existentes. Configura también utf8mb4 en el conector de la aplicación; cambiar solo el esquema no asegura que pueda escribir caracteres de cuatro bytes. --single-transaction proporciona una instantánea consistente para tablas transaccionales, pero no protege tablas MyISAM ni cambios de esquema durante el volcado.

4. Validar y cambiar la aplicación

Compara entre la base original y el clon:

  • esquema, índices, vistas, triggers y rutinas;
  • recuento de filas de cada tabla;
  • muestras con acentos, caracteres de cuatro bytes y contenido serializado;
  • acceso, búsquedas, edición y tareas programadas de la aplicación.

Cuando todas las comprobaciones sean correctas, vuelve a detener las escrituras, repite en el clon los cambios producidos desde el primer volcado si fuese necesario y cambia las credenciales de la aplicación para apuntar a la base nueva. Mantén la base original intacta y sin escrituras durante el periodo de observación.

Reversión

Si la validación posterior falla, detén las escrituras e identifica las operaciones recibidas en la base nueva. Decide cómo conservarlas antes de volver a la original: cambiar solo las credenciales perdería esos cambios. Después restaura las credenciales anteriores y valida la aplicación. No elimines la base original ni el volcado verificado hasta cerrar expresamente el periodo de recuperación.

Si tienes dudas sobre la collation adecuada o sobre cómo sincronizar las escrituras finales, contacta con soporte antes del cambio.

También te puede ayudar

¿Algo no cuadra o ha cambiado? Cuéntanoslo y lo revisamos.