Drupal: Actualizar MySQL a utf8mb4

De una temporada a esta parte supongo que habréis visto el aviso en el panel de información de Drupal acerca de actualizar la base de datos para soportar UTF-8 de 4 bytes, con este mensaje:

4 byte UTF-8 for mysql is not activated, but it is supported on your system. It is recommended that you enable this to allow 4-byte UTF-8 input such as emojis, Asian symbols and mathematical symbols to be stored correctly. See the documentation on adding 4 byte UTF-8 support for more information.

Vale, ¿pero de que va todo esto? ¿Para que sirve esta actualización?

Diferencias entre UTF-8 y uft8mb4

UTF-8 es un juego de caracteres, o mejor dicho, un formato de codificación de caracteres, que implementa el estándar Unicode. Unicode está dividido en 17 códigos de área, y cada uno contiene 65,536 caracteres de 16 bits, de los que solamente está en uso alrededor del 10%. La mas importante de estas áreas o planos es el BMP (Basic Multilingual Plane), que contiene los caracteres mas usados. Entre ellos están los de Latín, alfabetos griego y cirílico, y hasta los juegos de caracteres asiáticos como los japoneses Katakana e Hiragana, o ideogramas chinos.

Además, UTF-8 es de longitud variable, y usa hasta 3 bytes como máximo para representar un carácter, por lo que soporta todos los caracteres BPM. Con utf8mb4 se pueden utilizar hasta 4 bytes, con lo que se gana un byte adicional que permite representar caracteres adicionales o suplementarios, y según el manual de MySQL:

  • Para un carácter BMPutf8 y utf8mb4 tienen el mismo almacenamiento: mismo código, misma codificación, misma longitud.
  • Para un carácter suplementario, utf8 no puede almacenarlo, mientras que utf8mb4 necesita cuatro bytes para almacenarlo.

Como utf8 no puede almacenar este tipo de caracteres, no hay problema al realizar la migración desde utf8 a utf8mb4, pero ojo, perderíamos información si queremos volver a pasar de utf8mb4 a utf8, ya que como hemos visto no se podrán almacenar todos los caracteres.

Actualizar a utf8mb4

Como tenia un rato libre me decidí a probar la actualización a utf8mb4​, eso si, sabiendo que no hay vuelta atrás, así que seguí las instrucciones de la página que nos enlaza desde Drupal:

documentation on adding 4 byte UTF-8 support

Lo primero es editar el fichero de configuración de MySQL, normalmente en Debian en /etc/mysql/my.conf y añadir las siguientes líneas en el apartado de [mysqld]:

innodb_large_prefix=true
innodb_file_format=barracuda
innodb_file_per_table=true

Y reinicamos el servidor:

service mysql restart

Ahora tenemos que convertir nuestra vieja base de datos a utf8mb4, por lo que lo primero que haremos es hacer una copia de seguridad.

¿Ya la tienes? ¿Seguro? Ok, luego no digas que no te he avisado.

Vamos a utilizar el módulo experimental que nos dicen en la ayuda: utf8mb4_convert. No es exactamente un módulo, es una extensión de Drush, de forma que no tendremos que activarlo. Lo descargamos así:

drush @none dl utf8mb4_convert-7.x
drush cc drush

Ahora, si tenemos alguna base de datos en nuestro archivo settings.php que no queramos convertir, la comentamos o la quitamos del fichero. Podemos nuestro portal en modo de mantenimiento (los programadores de verdad hacen esto a pelazo, pero vosotros veréis):

drush vset maintenance_mode 1

Y ejecutamos este comando de Drush que da un yuyu que te cagas:

drush utf8mb4-convert-databases

¿Tenías una copia de seguridad verdad?

Bueno, pues modificamos la configuración del settings.php para utf8mb4:

$databases['default']['default'] = array(
  'driver' => 'mysql',
  'database' => 'databasename',
  'username' => 'username',
  'password' => 'password',
  'host' => 'localhost',
  'charset' => 'utf8mb4',
  'collation' => 'utf8mb4_general_ci',
);

Y probamos el portal. Si todo funciona, podemos quitar el modo de mantenimiento:

drush vset maintenance_mode 0

Y una cosa mas que hemos aprendido a hacer.

Y si no funciona... bueno... pues déjame un comentario o tira de Stackoverflow...

 

Referencias