背景
最近在做一个项目的数据库迁移,把数据库迁移倒腾讯云mysql,所以需要将原有服务器的mysql数据库做一个迁移。于是在腾讯云后台做了DTS ,导入完成之后还是遇到了一些莫名其妙的问题。
登录的时候,报错:
1449-The user specified as a definer ('db_user'@'%') does not exist
我们项目换了新的数据库用户名字和密码,各个项目中的配置也都改成新的了,但是登录的时候,保存用户信息的地方报错,提示还用的老的数据库用户名,刚开始怀疑没改全,找了半天再三确认还是都改全了,于是仔细分析该错误提示,是提示 definer ,于是想到用户表中有触发器,于是查看触发器的 DEFINER 用户还是老的用户,于是删掉原有触发器,重新创建了一个,功能就正常了
其他存储过程或者函数也可能有类似的问题
存储过程、视图、函数等 设置的安全性为definer
【definer和invoker的解释】
创建存储过程的时候可以指定 SQL SECURITY属性,设置为 DEFINER 或者INVOKER,用来告诉mysql在执行存储过程的时候,是以DEFINER用户的权限来执行,还是以调用者的权限来执行。
默认情况下,使用DEFINER方式,此时调用存储过程的用户必须有存储过程的EXECUTE权限,并且DEFINER指定的用户必须是在mysql.user表中存在的用户。
DEFINER模式下,默认DEFINER=CURRENT_USER,在存储过程执行时,mysql会检查DEFINER定义的用户'user_name'@'host_name'的权限;
INVOKER模式下,在存储过程执行时,会检查存储过程调用者的权限。
如果SQL SECURITY子句指定为DEFINER,存储过程将使用存储过程的DEFINER执行存储过程,验证调用存储过程的用户是否具有存储过程的execute权限和DEFINER用户是否具有存储过程引用的相关对象的权限;
如果SQL SECURITY子句指定为INVOKER,那么MySQL将使用当前调用存储过程的用户执行此过程,并验证用户是否具有存储过程的execute权限和存储过程引用的相关对象的权限;
解决方案如下
保持definer安全性
1)在navicat上进行修改,高级=>安全性
将定义者从test改为在该服务器存在的用户(一般每个服务器都有root@localhost)
2)通过sql语句修改
update mysql.proc set DEFINER='root@localhost' WHERE NAME='' AND db='mydb';
其中,mysql.proc是固定的,definer即要改为的用户名,name为存储过程名,db为数据库名
将安全性修改为invoker
1)在navicat上进行修改
2)通过sql语句进行修改
ALTER PROCEDURE proc_name SQL SECURITY INVOKER
mysql如何查看数据库中哪些表有触发器
假设数据库名为 test
SELECT DISTINCT EVENT_OBJECT_TABLE FROM information_schema.`TRIGGERS` WHERE EVENT_OBJECT_SCHEMA='test'
查看更详细的触发器明细
SELECT * FROM information_schema.`TRIGGERS`
《本文》有 0 条评论