En esta página se describen los problemas e incompatibilidades conocidos que pueden surgir al actualizar de la versión principal de Cloud SQL para MySQL 5.7 a Cloud SQL para MySQL 8.0.
Para obtener más información sobre la actualización de la versión principal, consulta los artículos sobre cómo actualizar la versión principal de la base de datos in situ y ver los registros de errores.
Cambios de SQL incompatibles
En esta sección se enumeran las incompatibilidades de SQL en Cloud SQL 5.7 y Cloud SQL 8.0 que pueden surgir al ejecutar la utilidad de comprobación previa y durante la actualización.
Palabras clave reservadas
A continuación, se muestra un ejemplo de mensaje de error:
Warning: The following objects have names that conflict with new reserved keywords. Ensure queries sent by your applications use `quotes` when referring to them or they will result in errors.
Algunas palabras clave, como GROUPS
, LEAD
o RANK
, ahora se clasifican como reservadas en la versión 8.0 de MySQL. Esto significa que algunas palabras que antes se usaban como identificadores ahora pueden considerarse no válidas. Para corregir las
instrucciones afectadas, utilice comillas para el identificador o cambie el nombre del identificador.
Para ver una lista completa de palabras clave, consulta Palabras clave y palabras reservadas.
Se ha quitado ASC/DESC con la cláusula GROUP BY
A continuación, se muestra un ejemplo de mensaje de error:
[ERROR] [MY-013235] [Server] Error in parsing Routine db_name.routine_name during upgrade. You may have an error in your SQL syntax; check the manual that corresponding to your MySQL server version for the right syntax to use near 'some_text'
A continuación, se muestra otro ejemplo de mensaje de error:
[ERROR] [MY-013235] [Server] Unknown trigger has an error in its body: 'You have an error in you SQL syntax; [ERROR] [MY-010198] [Server] Error in parsing Triggers from trigger_name.TRG file.
Las consultas que antes se basaban en la ordenación GROUP BY
pueden producir resultados diferentes a los de versiones anteriores de MySQL. Para conservar un orden concreto, proporciona una cláusula ORDER BY
.
Si una definición de procedimiento almacenado, de activador o de evento contiene una consulta que usa ASC
o DESC
con la cláusula GROUP BY
, la consulta de ese objeto necesita una cláusula ORDER BY
.
Para obtener más información, consulta Eliminar la sintaxis de GROUP BY ASC y DESC.
Mezcla de datos espaciales con otros tipos como clave
A continuación, se muestra un ejemplo de mensaje de error:
[ERROR] [MY-013140] [Server] Incorrect prefix key; the used key part isn't a string, the used length is longer than the key part, or the storage engine doesn't support unique prefix keys [ERROR] [MY-013140] [Server] Too many key parts specified; max 1 parts allowed
En MySQL 8.0 y versiones posteriores, un índice no puede contener una combinación de tipos de datos espaciales y de otro tipo. Debes quitar la clave y crear otra compatible con la versión 8.0 de MySQL o una posterior. Para obtener más información, consulta Índices espaciales. Para identificar los índices de datos espaciales, usa una consulta similar a la siguiente:
SELECT s.TABLE_SCHEMA, s.TABLE_NAME, s.INDEX_NAME, s.COLUMN_NAME, s.INDEX_TYPE, c.DATA_TYPE FROM information_schema.STATISTICS s JOIN information_schema.COLUMNS c ON s.TABLE_SCHEMA = c.TABLE_SCHEMA AND s.TABLE_NAME = c.TABLE_NAME AND s.COLUMN_NAME = c.COLUMN_NAME WHERE c.DATA_TYPE IN ( 'geometry', 'point', 'linestring', 'polygon', 'multipoint', 'multilinestring', 'multipolygon', 'geometrycollection' ) AND s.INDEX_TYPE = 'BTREE';
Caracteres UTF8 no válidos
A continuación, se muestra un ejemplo de mensaje de error:
[ERROR] [MY-010765] [Server] Error in Creating DD entry for %s.%s [ERROR] [MY-013140] [Server] Invalid utf8 character string: invalid_string
Si una definición de tabla contiene caracteres UTF8 no válidos, es posible que no se puedan convertir las definiciones de tabla en el diccionario de datos. Para solucionar este problema, sustituya los caracteres no válidos por los caracteres UTF8 correspondientes o elimínelos por completo.
Para identificar y corregir los caracteres no válidos, puedes usar una consulta similar a la siguiente:
SHOW CREATE TABLE table_name; ALTER TABLE table_name MODIFY COLUMN column_name data_type comment=''; // removing invalid utf8 character from comment
Transacciones XA no confirmadas
A continuación, se muestra un ejemplo de mensaje de error:
[ERROR] [MY-013527] [Server] Upgrade cannot proceed due to an existing prepared XA transactions
Si hay transacciones XA sin confirmar, se producirá un error en la actualización de la versión principal in situ. Para solucionar este problema, ejecuta una instrucción XA RECOVER antes de completar la actualización. Esta instrucción comprueba si hay transacciones XA sin confirmar. Si se devuelve una respuesta, confirma las transacciones XA emitiendo un XA COMMIT
o revierte las transacciones XA emitiendo una instrucción XA ROLLBACK
. Para comprobar las transacciones XA, puedes ejecutar un comando similar al siguiente:
mysql> XA RECOVER CONVERT xid; +----------+--------------+--------------+-------------------------- | formatID | gtrid_length | bqual_length | data | +----------+--------------+--------------+-------------------------- | 787611 | 9 | 9 | 0x787887111212345678812676152F12345678 | +----------+--------------+--------------+-------------------------- 1 row in set (0.00 sec)
En este ejemplo, podemos ver que los valores de gtrid
y bqual
se proporcionan en formato hexadecimal, pero se concatenan por error. Para solucionar este problema, debe crear estos valores manualmente con los siguientes campos:
gtrid = 0x787887111212345678
bqual = 0x812676152F12345678
Para confirmar o revertir estas transacciones XA, puedes crear un xid
a partir de esta información con un comando similar al siguiente:
xid: gtrid [, bqual [, formatID ]] mysql> XA ROLLBACK|COMMIT 0x787887111212345678,0x812676152F12345678,787611;
Supera la longitud máxima de la clave
A continuación, se muestra un ejemplo de mensaje de error:
[ERROR] [MY-013140] [Server] Specified key was too long; max key length is [INTEGER] bytes
Este problema puede deberse a la configuración de sql_mode
. En MySQL 5.7, la ausencia de modos estrictos significaba que los índices se podían crear con restricciones en la longitud del prefijo o del índice.
Sin embargo, en la versión 8.0 de MySQL se introdujeron modos estrictos, como STRICT_ALL_TABLES
o STRICT_TRANS_TABLES
, que aplicaban reglas más estrictas
a la longitud de los índices, lo que provoca este error.
Para solucionar el problema, actualice la longitud del prefijo del índice para que no supere el número máximo de bytes indicado en el mensaje de error. Con el protocolo predeterminado UTFMB4, cada carácter puede ocupar hasta 4 bytes, lo que significa que el número máximo de caracteres se puede determinar dividiendo el número máximo de bytes entre 4.
Información de metadatos no coincidente
A continuación, se muestra un ejemplo de mensaje de error:
[ERROR] [MY-012084] [InnoDB] Num of Indexes in InnoDB doesn't match with Indexes from server [ERROR] [MY-012069] [InnoDB] table: TABLE_NAME has xx columns but InnoDB dictionary has yy columns
A continuación, se muestra otro ejemplo de mensaje de error:
[ERROR] [MY-010767] [Server] Error in fixing SE data for db_name.table_name
Si intentas actualizar tablas con metadatos que no coinciden entre el archivo .frm y el diccionario de InnoDB, la actualización fallará. En este caso, es posible que el archivo frm esté dañado. Para solucionar el problema, debe volcar y restaurar las tablas afectadas antes de intentar actualizar.
Para obtener más información, consulta Intentar actualizar tablas con metadatos que no coinciden.
Para volcar y restaurar las tablas afectadas, puedes ejecutar un comando similar al siguiente:
mysqldump --databases database_name --host=$host --user=$user --password=$password > database_dump.sql mysql> source database_dump.sql;
El nombre de la clave externa tiene más de 64 caracteres
A continuación, se muestra un ejemplo de mensaje de error:
[ERROR] [MY-012054] [InnoDB] Foreign key name:key_name is too long
Este error indica que los nombres de las restricciones de clave externa de las tablas no pueden tener más de 64 caracteres. Para identificar tablas con nombres de restricciones demasiado largos, puedes usar un comando similar al siguiente:
SELECT CONSTRAINT_NAME, TABLE_NAME FROM information_schema.REFERENTIAL_CONSTRAINTS WHERE CHAR_LENGTH(CONSTRAINT_NAME) > 64;
Si una tabla contiene un nombre de restricción que supera los 64 caracteres, utiliza el comando ALTER TABLE
para cambiar el nombre de la restricción dentro de este límite de caracteres:
ALTER TABLE your_table RENAME CONSTRAINT your_long_constraint_name TO your_new_constraint_name;
Las mayúsculas y minúsculas de los nombres de las tablas no coinciden
A continuación, se muestra un ejemplo de mensaje de error:
[ERROR] [MY-013521] [Server] Table name 'SCHEMA_NAME.TABLE_NAME' containing upper case characters is not allowed with lower_case_table_names = 1.
Si las instancias de MySQL 5.7 requieren nombres de tabla en minúsculas (lower_case_table_names=1
),
todos los nombres de tabla deben convertirse a minúsculas antes de actualizar a MySQL 8.0.
También puedes inhabilitar el requisito (lower_case_table_names=0
)
y, a continuación, actualizar la instancia. Recuerda que, si cambias el valor del campo lower_case_table_names
de 1
a 0
, no podrás volver a cambiarlo en la versión 8.0 de MySQL.
Tablas reconocidas por InnoDB que pertenecen a otro buscador
A continuación, se muestra un ejemplo de mensaje de error:
Error: Following tables are recognized by InnoDB engine while the SQL layer believes they belong to a different engine. Such situation may happen when one removed InnoDB files manually from the disk and creates a table with same name by using different engine.
Si hay tablas en la base de datos que el motor InnoDB reconoce y que la capa SQL no reconoce, la actualización fallará.
Busca todas las tablas de la base de datos que no utilicen el motor de almacenamiento InnoDB:
SELECT * FROM INFORMATION_SCHEMA.TABLES WHERE TABLE_SCHEMA = 'db_name' AND ENGINE != 'InnoDB'
En cada tabla identificada, ejecuta un comando ALTER TABLE
para cambiar su motor de almacenamiento a InnoDB.
ALTER TABLE db_name.table_name ENGINE='INNODB';
Partición de motor de almacenamiento desconocida
A continuación, se muestra un ejemplo de mensaje de error:
[System] [MY-011012] [Server] Starting upgrade of data directory. [ERROR] [MY-013140] [Server] Unknown storage engine 'partition'
La versión 8.0 de MySQL no permite particiones en el motor que no sean InnoDB
y ndbcluster
. Debes buscar tablas con particiones cuyo motor no sea InnoDB. Para identificar estas tablas, ejecuta esta consulta:
SELECT TABLE_SCHEMA, TABLE_NAME FROM INFORMATION_SCHEMA.TABLES WHERE ENGINE NOT IN ('innodb', 'ndbcluster') AND CREATE_OPTIONS LIKE '%partitioned%';
Todas las tablas que devuelva la consulta deben actualizarse para usar InnoDB o configurarse para que no estén particionadas. Para cambiar el motor de almacenamiento de una tabla a InnoDB, ejecuta esta instrucción:
ALTER TABLE db_name.table_name ENGINE = INNODB;
Operación de MVU que se ejecuta durante más tiempo
Hay dos tareas subyacentes asociadas a la actualización de una versión principal:
- Operación de comprobación previa: devuelve un error de tiempo de espera si no se completa en tres horas.
- Operación de actualización: devuelve un error de tiempo de espera si no se completa en seis horas.
Si la instancia tiene una operación MAJOR_VERSION_UPGRADE
en curso durante un periodo más largo de lo esperado, puedes investigar los registros de errores de MySQL para comprobar si está bloqueada en una actualización de metadatos o si se ha quedado atascada en algún paso de comprobación previa. Las causas más habituales de este problema son las siguientes:
- Un número muy elevado de tablas, vistas o índices
- Recursos insuficientes, como la CPU o la memoria
- Transacciones importantes que impiden que se cierren las bases de datos para que empiece el proceso de actualización. Puedes usar la Google Cloud consola para comprobar los procesos actuales.
Demasiados archivos abiertos en el sistema
A continuación, se muestra un ejemplo de mensaje de error:
[ERROR] [MY-012592] [InnoDB] Operating system error number 23 in a file operation [ERROR] [MY-012596] [InnoDB] Error number 23 means 'Too many open files in system'
Si la instancia contiene más de 2 millones de tablas, es posible que recibas un error que indique que hay demasiados archivos abiertos en el sistema. Es posible que tengas que reducir el número de tablas a menos de 2 millones antes de actualizar.
Error de falta de memoria
Al actualizar de MySQL 5.7 a 8.0, se necesita memoria adicional para convertir los metadatos antiguos al nuevo diccionario de datos. Para evitar que se produzca un error de falta de memoria durante la actualización de la versión principal, Cloud SQL recomienda tener al menos 100 KB de memoria por tabla.
Para encontrar el número de tablas, usa la siguiente consulta:
SELECT table_schema AS 'Database Name', COUNT(*) AS 'Number of Tables' FROM information_schema.tables
Para solucionar el problema, antes de iniciar la actualización, puedes aumentar temporalmente la memoria cambiando el tipo de máquina.
En el caso de las instancias de núcleo compartidas (por ejemplo, los núcleos micro o small, incluidos db-f1-micro
, db-g1-small
, HA db-f1-micro
y HA db-g1-small
), actualiza a una instancia de núcleo dedicada durante la operación de actualización para evitar posibles problemas relacionados con los recursos. Puedes
cambiar a una versión anterior una vez que se haya completado la operación de actualización.
Error de cierre de MySQL
A continuación, se muestra un ejemplo de mensaje de error:
[ERROR] [MY-012526] [InnoDB] Upgrade after a crash is not supported.
Cloud SQL realiza un cierre limpio antes de actualizar la versión principal. Las instancias con cargas de trabajo pesadas o transacciones de larga duración pueden experimentar un proceso de apagado prolongado, lo que puede provocar un tiempo de espera y que la actualización falle. Para asegurarte de que la actualización se lleva a cabo correctamente, planifícala durante un periodo de poco tráfico y sin transacciones de larga duración.