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等来一个个修改。注意改前有必要锁表,因为如果改的过程中有其它表改变而触发,会造成数据不一致。