Desenvolvimento e bases de dados
Converter uma base de dados de utf8 para utf8mb4
Uma aplicação antiga pode exigir a conversão das suas tabelas de utf8 para utf8mb4. Não faça substituições globais num dump nem elimine as tabelas de produção: uma substituição de texto pode alterar dados de utilizadores, nomes de collations não equivalentes ou conteúdo serializado.
1. Criar e verificar uma cópia protegida
Trabalhe a partir de uma pasta privada fora de public_html, com um nome de dump novo. Pare temporariamente as escritas da aplicação e gere um dump consistente. -p pede a palavra-passe de forma interativa e evita deixá-la no histórico ou na lista de processos:
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
Se o mysqldump devolver um erro, não continue nem considere válido o ficheiro parcial. A exportação de rotinas exige permissões; se falhar, reveja que objetos a aplicação precisa antes de os omitir. Os eventos, se existirem, também têm de ser inventariados e exportados com as opções e permissões adequadas. O checksum deteta alterações posteriores no ficheiro, mas não demonstra que a cópia está completa. As permissões só de leitura também não a tornam imutável.
Descarregue também ambos os ficheiros para um armazenamento diferente do alojamento. Não edite este dump: será o ponto de recuperação.
2. Restaurar numa base de dados nova
Crie uma base de dados vazia, com outro utilizador e outro nome, e restaure aí a cópia:
mysql -u USUARIO_NUEVO -p BASE_NUEVA < base-antes-utf8mb4.sql
Desative no clone os emails, cobranças, webhooks e tarefas automáticas de produção. Configure um clone da aplicação para usar BASE_NUEVA e confirme que abre, inicia sessão e executa as suas operações principais antes de converter o que quer que seja.
3. Pré-visualizar e converter o clone
Consulte primeiro as tabelas cujo valor predefinido continua a ser utf8 ou 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\_%' );
A codificação de uma coluna pode ser diferente da predefinida da sua tabela. Reveja também as colunas; uma tabela com valor predefinido utf8mb4 ainda pode conter colunas antigas:
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;
O gerador seguinte é um ponto de partida para as tabelas que a primeira lista mostra. CONVERT TO transforma todas as suas colunas de texto, incluindo as que tenham uma codificação diferente; não o execute sem rever essas exceções. Se só for preciso alterar algumas colunas, prepare um ALTER TABLE ... MODIFY que mantenha a sua definição completa.
Gere as instruções exatas de que precisaria, reveja-as uma a uma e execute-as apenas 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\_%' );
O MySQL 8 mostra normalmente as collations do antigo utf8 com o nome utf8mb3; o segundo padrão mantém a compatibilidade com versões que ainda mostram o alias anterior. A collation concreta tem de ser compatível com a versão do MySQL e com a aplicação. Verifique que a collation escolhida existe no destino. Mudar as regras de comparação pode gerar coincidências novas em índices únicos; a conversão também pode alargar tipos de texto ou entrar em conflito com chaves estrangeiras. Reveja previamente os índices de colunas de texto, porque, ao aumentar o tamanho máximo por carácter, alguns índices antigos podem exceder o limite admitido.
Se quiser que as tabelas novas herdem utf8mb4, altere também o valor predefinido da base de dados clonada:
ALTER DATABASE `BASE_NUEVA` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
Isto não converte as tabelas existentes. Configure também utf8mb4 no conector da aplicação; alterar apenas o esquema não garante que consiga escrever caracteres de quatro bytes. --single-transaction proporciona um instantâneo consistente para tabelas transacionais, mas não protege tabelas MyISAM nem alterações de esquema durante o dump.
4. Validar e mudar a aplicação
Compare entre a base de dados original e o clone:
- esquema, índices, vistas, triggers e rotinas;
- contagem de linhas de cada tabela;
- amostras com acentos, caracteres de quatro bytes e conteúdo serializado;
- acesso, pesquisas, edição e tarefas agendadas da aplicação.
Quando todas as verificações estiverem corretas, volte a parar as escritas, repita no clone as alterações produzidas desde o primeiro dump, se for necessário, e altere as credenciais da aplicação para apontar para a base de dados nova. Mantenha a base de dados original intacta e sem escritas durante o período de observação.
Reversão
Se a validação posterior falhar, pare as escritas e identifique as operações recebidas na base de dados nova. Decida como as guardar antes de voltar à original: alterar apenas as credenciais perderia essas alterações. Depois, reponha as credenciais anteriores e valide a aplicação. Não elimine a base de dados original nem o dump verificado até encerrar expressamente o período de recuperação.
Se tiver dúvidas sobre a collation adequada ou sobre como sincronizar as escritas finais, contacte o suporte antes da mudança.
Também lhe pode ser útil
- MySQL 8, mudança da codificação de carateres de latin1 para utf8mb4 Corrija carateres estranhos em aplicações antigas depois da passagem para o MySQL 8, definindo latin...
- Clonar uma base de dados Duplique uma base de dados MySQL criando primeiro o destino e as suas permissões no cPanel e copiand...
- Criar bases de dados MySQL, utilizadores e permissões no cPanel Crie uma base de dados MySQL no cPanel, adicione o respetivo utilizador, atribua-lhe todos os privil...
- Criar uma base de dados e o respetivo utilizador com o assistente do cPanel Crie uma base de dados MySQL, o seu utilizador e a associação de permissões com o assistente do cPan...
Algo não bate certo ou mudou? Diga-nos e revemos.