definer引起的问题

业务从业务库A迁移到业务库B,某些存储过程、视图、触发器等在新的环境无法运行,与这些对象的definer属性定义有关。

mysql中设计definer属性的包含

1. 存储过程(procedure)

2. 函数(function)

3. 触发器(trigger)

4. 定时器(event)

5. 视图(view)

1. 对象定义时,显示指定,则为指定用户。如果指定用户不存在,也可以创建成功,但会提示warning。

注意:从一个DB导数据到另外一个DB时,要确保definer所定义的用户前后是一致的,包括用户及权限。

2. 对象定义时,没有指定,则默认为创建用户

定义一个存储过程

create table t1 (counter int(11) auto_increment primary key);

delimiter //

CREATE DEFINER = 'admin'@'localhost' PROCEDURE p2()

UPDATE t1 SET counter = counter + 1;

delimiter ;

执行对象失败原因分析

(1)definer指定用户不存在,无法执行

ERROR 1449 (HY000): The user specified as a definer ('admin'@'localhost') does not exist

(2)definer指定用户存在,但对定义对象无execute权限

ERROR 1370 (42000): execute command denied to user 'admin'@'localhost' for routine 'test_p.p2'

(3)definer指定用户存在,有定义对象execute权限,但对对象内访问的库表无相应权限

ERROR 1142 (42000): UPDATE command denied to user 'admin'@'localhost' for table 't1'

ERROR 1143 (42000): SELECT command denied to user 'admin'@'localhost' for column 'counter' in table 't1'

修改对象的definer

1. 对象重建

drop/create

2. 存储过程(procedure)

update mysql.proc set definer="user@localhost" where specific_name="p2";

3.定时器(event)

update mysql.EVENT set definer=' user@localhost ' where TABLE_NAME='v1';

4.视图(view)

alter DEFINER="admin"@"localhost" view test_p.v1 as select `test_p`.`t1`.`counter` AS `counter` from `test_p`.`t1`;

5.触发器(trigger)

目前还没有具体方便的方法,可以借助工具端如HeidiSQL、sqlyog等来一个个修改。注意改前有必要锁表,因为如果改的过程中有其它表改变而触发,会造成数据不一致。