最近在做一个项目,由于服务器切换,所以需要将原有服务器的mysql数据表以及存储过程导入到另一个服务器的mysql数据库中。导入完成之后以为一切是那么的简单,却没有想到总还是出现了一些莫名其妙的问题。

我在用程序调用存储过程时,总是提示错误:

 The user specified as a definer ('test'@'%') does not exist 1449

查看了自己mysql的用户表后,发现确实没有test这个用户,但是我程序用的是root登录的,所以感觉有些莫名其妙。

后来通过查资料发现,是由于自己存储过程设置的安全性为definer,而当时的那个数据库存在test这个用户且用的test用户创建的存储过程。

所以解决方法主要有以下两种:

保持definer安全性

1)在navicat上进行修改

将定义者从test改为在该服务器存在的用户(一般每个服务器都有root@localhost)

2)通过sql语句修改

 mysql>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
ALTER PROCEDURE proc_name SQL SECURITY DEFINER

引申阅读:mysql存储过程的definer和invoker

【用户操作存储过程的权限】

 ALTER ROUTINE -- 编辑或删除存储过程

 CREATE ROUTINE -- 创建存储过程

 EXECUTE          -- 运行存储过程

【存储过程的创建语法】

 delimiter //    -- 声明分隔符(命令结束符)

 create 

  definer = user@hostname | current_user 

  procedure 存储过程名 (参数)

  comment '注释'

  sql security definer | invoker   -- sql 的安全设置

 begin

   存储过程的body

 end

 //

 delimiter ;    -- 声明分隔符(命令结束符)

【函数的创建语句】

 delimiter //    -- 声明分隔符(命令结束符)

 create

  definer = user@hostname | current_user

  function 函数名(参数)

  return 返回值类型

  comment '注释'

  sql security definer | invoker   -- sql 的安全设置

 begin

   函数的body

 end
// delimiter ; -- 声明分隔符(命令结束符)

【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

 CREATE DEFINER = 'admin'@'localhost' PROCEDURE account_count()
BEGIN
SELECT 'Number of accounts:', COUNT(*) FROM mysql.user;
END;

在这个案例中,不论哪个用户A调用存储过程,存储过程都会以'admin'@'localhost'的权限去执行,即使这个用户A没有查询mysql.user表的权限。

 案例二:INVOKER

 CREATE DEFINER = 'admin'@'localhost' PROCEDURE account_count()
SQL SECURITY INVOKER
BEGIN
SELECT 'Number of accounts:', COUNT(*) FROM mysql.user;
END;

在这个案例中,虽然存储过程语句中仍然带有DEFINER参数,但是由于SQL SECURITY指定了INVOKER,所以在存储过程执行的时候,会以调用者的额身份去执行。此时这个存储过程是否能成功执行,取决于调用者是否有mysql.user表的查询权限。

【案例】

案例一:调用存储过程

存储过程的调用者是   : admin@192.168.1.1

存储过程的DEFINER是   : admin@%

MySQL中存在的用户是 : admin@192.168.%.%

此时admin@192.168.1.1是可以访问数据库的,因为它符合admin@192.168.%.%的授权规则,但是当它调用DEFINER='admin@%'的存储过程的时候,mysql会检查mysql.user用户表中是否存在admin@%这个用户,mysql的检查结果是admin@%这个用户不存在,此时就会返回报错,提示“Ther user specified as a definer ('admin@%') does not exist.。

案例二:创建存储过程

使用用户admin@192.168.1.1连接mysql,该用户有test库的all privileges,执行创建存储过程的操作:

存储过程中定义的DEFINER是    : admin@%

MySQL中存在的用户是     : admin@192.168.%.%

此时,会遇到报错,提示”ERROR 1227 (42000): Access denied; you need (at least one of) the SUPER privilege(s) for this operation“

修复DEFINER='admin@192.168.%.%',或者去掉 DEFINER参数,都可以恢复正常。

说明:

案例一中是存在问题的,存储过程的调用者和拥有者都是admin@192.168.1.1,但是DEFINER却是admin@%,这是由于创建存储过程的命令是由root用户执行的,所以没有遇到案例二中的报错。

【存储过程常用命令】

 -- 查看存储过程的创建语句:

 show create procedure 存储过程名;

 -- 查看存储过程的信息:

 show procedure status like '存储过程名'G

 -- 查看存储过程的Definer信息:

 select db,name,type,sql_security,definer from mysql.proc where  type='PROCEDURE' and db='数据库名' ;

 -- 修改存储过程的DEFINER:

 update  mysql.proc  set `definer` ='admin@192.168.%.%' where db like 'db_%';

1449 - The user specified as a definer ('test'@'%') does not exist的更多相关文章

  1. 错误代码: 1449 The user specified as a definer ('root'@'%') does not exist

    1. 错误描述 1 queries executed, 0 success, 1 errors, 0 warnings 查询:call analyse_use('20150501','20150601 ...

  2. [Err] 1449 - The user specified as a definer ('student'@'%') does not exist

    1.错误描述 [SQL]use student; 受影响的行: 0 时间: 0.001s [SQL] call alter_student('t_student','MODIFY COLUMN `we ...

  3. Got error: 1449: The user specified as a definer ('root'@'%') does not exist when using LOCK TAB

    在linux下,用mysql的导出语句: mysqldump -hlocalhost -uroot -pPasswd table >/home/ftp/test.sql 出现了 mysqldum ...

  4. mysqldump: Got error: 1449: The user specified as a definer ('xxx'@'%') does not exist when using LOCK TABLES

    开发同学说在测试环境使用mysqldump导出数据的时候遇到以下错误: # mysqldump -uroot -p --all-databases --routines --events --trig ...

  5. mysqldump: Got error: 1449: The user specified as a definer ('user'@'%') does not exist when using LOCK TABLES

    报错:一个库用mysqldump -u -p --opt --force -e --max_allowed_packet= --net_buffer_length= --databases备份时报错如 ...

  6. [Err] 1449 - The user specified as a definer ('rybhe'@'%') does not exist

    转载: 最近在做一个项目,由于服务器切换,所以需要将原有服务器的mysql数据表以及存储过程导入到另一个服务器的mysql数据库中.导入完成之后以为一切是那么的简单,却没有想到总还是出现了一些莫名其妙 ...

  7. 1449 - The user specified as a definer('xxx'@'%') does not exist

    指定的用户不存在,创建相应的账户即可,注意主机那里填的内容,我的这个是@'%'所以不用填任何内容.

  8. 错误代码: 1449 The user specified as a definer ('root'@'%') does not exist

    1. 错误描写叙述 1 queries executed, 0 success, 1 errors, 0 warnings 查询:call analyse_use('20150501','201506 ...

  9. 【转】 The user specified as a definer ('root'@'') does not exist when using LOCK TALBE

    在linux下,用mysql的导出语句: mysqldump -u root -pPasswd table >/home/lsf/test.sql 出现了 Got error: 1449: Th ...

随机推荐

  1. MySQL 的数据类型,有哪些?

    table th:first-of-type { width: 100px; } MySQL数据类型选择指南:https://www.awaimai.com/1146.html 实数: 数据类型 多少 ...

  2. JFrame包含的容器(JRootPane)

    JFrame对象创建后,此对象包含JRootPane类型的容器.JRootPane 下有GlassPane,  和  LayeredPane,LayeredPane下又有ContentPane ,   ...

  3. linux curl 命令的使用

    有时候需要内网访问接口地址,使用curl命令,带上-v参数 -v 参数可以显示一次 http 通信的整个过程,包括端口连接和 http request 头信息 curl -v http://172.9 ...

  4. golang 如何查看channel通道中未读数据的长度

    可以通过内建函数len查看channel中元素的个数. 内建函数len的定义如下: func len(v Type) int The len built-in function returns the ...

  5. windows 下 Anaconda 安装 TensorFlow

    转自: https://www.cnblogs.com/nosqlcoco/p/6923861.html 什么是 Anaconda? Anaconda is the leading open data ...

  6. ecstore开启发送邮件日志,并且排查邮件发布出去原因

    config.php里 define("MAIL_LOG", true);//发送邮件日志开启2017-04-19 10:29:31 解决sendmail connection r ...

  7. Linux常用命令之定时任务

    定时任务的实现,可以让我们把很多重复的,有规律的事情交给机器做.我们就不用苦逼的烦躁做同一件事,这样也让我们做程序的有更多的乐趣和价值.用技术的手段解决常人花时间精力解决的问题.在Linux下实现定时 ...

  8. 利用event为z数据表定期添加和删除分区

    我们去年就开始把zabbix数据库改成用TokuDB来支撑,并且启用了表分区(详情见:迁移Zabbix数据库到TokuDB).这样做的好处很明显,较早的历史数据可以通过删除分区快速废弃掉.要知道,za ...

  9. dom实例,模态框,全选,反选,取消

    <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...

  10. sql server 安装时提示要重启

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager 打开“Session Manager”文件夹之后在右侧的区域中单 ...