Be a happy coder

You are here

Importando vistas entre bases de datos MySQL (II)

21 Jun 2012

Continuamos con los problemas que nos podemos encontrar en estas migraciones.

En el CiviCRM migrado, aparentemente todo funciona bien, pero al intentar guardar un dato en uno de los formularios de configuración aparece el siguiente error:

Sorry. A non-recoverable error has occurred.
DB Error: unknown error
Additional Details:
[user_info] => INSERT INTO civicrm_option_group_en_US (name , title , is_reserved , is_active ) VALUES ('currencies_enabled' , 'currencies_enabled' ,  1 ,  1 )  [nativecode=1449 ** The user specified as a definer ('civicrmuser'@'localhost') does not exist]

El error hace referencia a que el usuario con el que se creó la base de datos y que teníamos en el anterior sistema, no existe en el servidor MySQL actual. Esto nos da dos posibilidades: podemos crear el usuario al que hace referencia y darle permisos sobre estas tablas o bien podemos cambiar el usuario "creador" de estas tablas/vistas/procedimientos por el usuario que actualmente tenemos.

Si se tratara de un procedimiento almacenado, con un usuario con los permisos necesarios, accedemos a Mysql y vemos que Procedures tenemos definidos, y para eso lanzamos ésta consulta:

 SELECT * FROM mysql.proc; 

Así veremos todos los que tengamos definidos, sin importar ninguna condición. Buscamos concretamente el que nos da problema, utilizando los datos del error.

SELECT * FROM mysql.proc WHERE definer = 'civicrmuser@localhost';

Ahora, para cambiarlo, hacer un update a esos registros. Lanzamos otra consulta.

UPDATE mysql.proc SET definer = 'user123@test.com' WHERE definer = 'civicrmuser@localhost';

Y para finalizar, hacemos efectivos los cambios en los privilegios.

FLUSH PRIVILEGES;

En mi caso se trata de una vista. Accedemos a Mysql y obtenemos información sobre las vistas y su definer:

SELECT table_schema, table_name, definer FROM information_schema.views; 

Actualizaríamos:

UPDATE information_schema.views SET definer = 'user123@test.com' WHERE definer = "civicrmuser@localhost"; 

pero por desgracia esto no funciona ya que Mysql no permite este tipo de alteración.

Otra opción para corregir el problema es exportar la vista, modificar el dato del definer y volver a importar la vista. Solución obvia.

Se podría hacer también con un ALTER VIEW, pero no permite cambiar sólo el definer, hay que volver a indicar los campos de la vista. Aquí tenemos una solución para hacerlo de este modo:

SELECT CONCAT("ALTER DEFINER=`youruser`@`host` VIEW ",table_name," AS ", view_definition,";") 
FROM information_schema.views WHERE table_schema='databasename'

añadir a un fichero y mezclar con un par de órdenes en el shell linux:

> mysql -uuser -p < consultaanterior.sql > alterView.sql
> mysql -uuser -p databasename < alterView.sql

Pero en mi caso el definer es correcto y entonces, ¿donde está el problema?.

mysql> INSERT INTO civicrm_option_group_en_US (name , title , is_reserved , is_active ) VALUES ('currencies_enabled' , 'currencies_enabled' ,  1 ,  1 );
ERROR 1449 (HY000): The user specified as a definer ('civicrmuser'@'localhost') does not exist

Bueno pues viene de que además de procedures y views, los trigger de Mysql también utilizan definer, y mi tabla está asociada a un trigger que se dispara al intentar modificarla.

select definer,trigger_schema,trigger_name from information_schema.triggers;

Para modificar un trigger hay que borrar y recrear, por tanto sólo queda hacer un mysqldump y modificar el definer en el fichero generado.

Y ya con esto tenemos arreglado este problema de permisos.