今天在一个修改过权限的MySQL数据库遇到了“ERROR 1045 (28000): Access denied for user 'xxx'@'xxx.xxx.xxx.xxx' (using password: YES)”和“ERROR 1449 (HY000): The user specified as a definer ('xxx'@'xx') does not exist” 错误,花了点时间研究并重现该错误,并将其整理在此篇文章。

在测试数据库MyDB,我们创建了一个mydbadmin的账号,任意IP地址都可以访问该数据库,如下所示:

  1. mysql> GRANT ALL PRIVILEGES ON `MyDB`.* TO 'mydbadmin'@'%' IDENTIFIED BY 'mydbadmin13s5';

  1. Query OK, 0 rows affected (0.03 sec)

  1.  

  1. mysql> flush privileges;

  1. Query OK, 0 rows affected (0.00 sec)

然后以这个mydbadmin登录数据库,创建一个视图v_student. 当然,你也可以创建存储过程或是函数等其他对象,它们也都会遇到这个错误。

  1. mysql> desc student;

  1. +----------+-------------+------+-----+---------+-------+

  1. | Field    | Type        | Null | Key | Default | Extra |

  1. +----------+-------------+------+-----+---------+-------+

  1. | stu_id   | int(11)     | YES  |     | NULL    |       |

  1. | stu_name | varchar(12) | YES  |     | NULL    |       |

  1. | sex      | int(11)     | YES  |     | NULL    |       |

  1. | grade    | int(11)     | YES  |     | NULL    |       |

  1. | age      | int(11)     | YES  |     | NULL    |       |

  1. +----------+-------------+------+-----+---------+-------+

  1. 5 rows in set (0.00 sec)

  1.  

  1. mysql> create or replace view v_student

  1.     -> as

  1.     ->   select stu_name, sex, age

  1.     ->   from student

  1.     ->   where grade >=3;

  1. Query OK, 0 rows affected (0.02 sec)

假如现在检查时发现任意IP都可以访问这个账号是不符合安全规范的,然后删除了这个账号(如果你用rename user 也会遇到这个问题),重建了该账号。此时你在较大权限的用户下就会遇到“ERROR 1449 (HY000): The user specified as a definer ('mydbadmin'@'%') does not exist”错误。如下所示:

  1. mysql> select user();

  1. +----------------+

  1. | user()         |

  1. +----------------+

  1. | root@localhost |

  1. +----------------+

  1. 1 row in set (0.00 sec)

  1.  

  1. mysql> select user,host from mysql.user where user='mydbadmin';

  1. +-----------+------+

  1. | user      | host |

  1. +-----------+------+

  1. | mydbadmin | %    |

  1. +-----------+------+

  1. 1 row in set (0.00 sec)

  1.  

  1. mysql>

  1. mysql> drop user mydbadmin@'%';

  1. Query OK, 0 rows affected (0.02 sec)

  1.  

  1. mysql> select count(*) from v_student;

  1. ERROR 1449 (HY000): The user specified as a definer ('mydbadmin'@'%') does not exist

  1. mysql>

  1. mysql> select user,host from mysql.user where user='mydbadmin';

  1. Empty set (0.00 sec)

  1.  

  1. mysql> flush privileges;

  1. Query OK, 0 rows affected (0.00 sec)

  1.  

  1. mysql> GRANT ALL PRIVILEGES ON `MyDB`.* TO 'mydbadmin'@'192.168.%' IDENTIFIED BY 'mydbadmin135';

  1. Query OK, 0 rows affected (0.00 sec)

  1.  

  1. mysql> flush privileges;

  1. Query OK, 0 rows affected (0.00 sec)

  1.  

  1. mysql>

然后你以在客户端使用mydbadmin登录后,查询视图就会报“ERROR 1045 (28000): Access denied for user 'mydbadmin'@'192.168.%' (using password: YES)”

  1. mysql> select user();

  1. +-------------------------+

  1. | user()                  |

  1. +-------------------------+

  1. | mydbadmin@192.168.7.43 |

  1. +-------------------------+

  1. 1 row in set (0.01 sec)

  1.  

  1. mysql> select * from v_student;

  1. ERROR 1045 (28000): Access denied for user 'mydbadmin'@'192.168.%' (using password: YES)

 

原因分析

出现这个问题,是因为账号mydbadmin@`%`已经不存在了。而视图指定DEFINER为mydbadmin@`%`,此时创建者不存在了。而SQL SECURITY也是DEFINER,所以MySQL认为现在的用户无权限访问该视图。所以有下面一些方法来解决这个错误。

解决方案

1:重建视图(存储过程或函数)即可解决问题。不过对于数据库视图很多的情况,这个方法略显笨拙和繁琐。

  1. mysql> show create view v_student;

  1. mysql> create or replace view v_student

  1.     -> as

  1.     ->     select stu_name, sex, age

  1.     ->     from student

  1.     ->     where grade >=3;

  1. Query OK, 0 rows affected (0.00 sec

当然可以批量生成相关SQL,类似于下面SQL

  1. SELECT CONCAT("alter DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW ",TABLE_SCHEMA,".",TABLE_NAME," as ",VIEW_DEFINITION,";")

  1. FROM information_schema.VIEWS

  1. WHERE DEFINER=''mydbadmin@%';

2:如果创建视图(存储过程或函数)时,使用SQL SECURITY INVOKER,就可以避免出现这种情况。

如下所示,创建视图时指定SQL SECURITY INVOKER.

SQL SECURITY { DEFINER | INVOKER } :指明谁有权限来执行。默认情况下,系统指定为DEFINE.

DEFINER 表示按定义者拥有的权限来执行

INVOKER 表示用调用者的权限来执行。

  1. mysql> use MyDB;

  1. Reading table information for completion of table and column names

  1. You can turn off this feature to get a quicker startup with -A

  1.  

  1. Database changed

  1. mysql> select user();

  1. +-------------------------+

  1. | user()                  |

  1. +-------------------------+

  1. | mydbadmin@192.168.7.218 |

  1. +-------------------------+

  1. 1 row in set (0.00 sec)

  1. mysql> create or replace definer='mydbadmin'@'%' 

  1.     -> sql security invoker

  1.     -> view  v_student

  1.     -> as

  1.     ->     select stu_name, sex, age

  1.     ->     from student

  1.     ->     where grade >=3;

  1. Query OK, 0 rows affected (0.00 sec)

删除用户mydbadmin@'%',此时你会发现还能执行。

  1. mysql> select user();

  1. +----------------+

  1. | user()         |

  1. +----------------+

  1. | root@localhost |

  1. +----------------+

  1. 1 row in set (0.00 sec)

  1.  

  1. mysql> drop user mydbadmin@'%';

  1. Query OK, 0 rows affected (0.00 sec)

  1.  

  1. mysql> select count(*) from v_student;

  1. +----------+

  1. | count(*) |

  1. +----------+

  1. |        0 |

  1. +----------+

  1. 1 row in set (0.00 sec)

  1.  

  1. mysql>

  1. mysql> select user();

  1. +----------------+

  1. | user()         |

  1. +----------------+

  1. | root@localhost |

  1. +----------------+

  1. 1 row in set (0.00 sec)

  1. mysql> GRANT ALL PRIVILEGES ON `MyDB`.* TO 'mydbadmin'@'192.168.%' IDENTIFIED BY 'mydbadmin135';

  1. Query OK, 0 rows affected (0.00 sec)

  1.  

  1. mysql> flush privileges;

  1. Query OK, 0 rows affected (0.00 sec)

  1. mysql> select user();

  1. +-------------------------+

  1. | user()                  |

  1. +-------------------------+

  1. | mydbadmin@192.168.7.218 |

  1. +-------------------------+

  1. 1 row in set (0.00 sec)

  1.  

  1. mysql> select count(*) from v_student;

  1. +----------+

  1. | count(*) |

  1. +----------+

  1. |        0 |

  1. +----------+

  1. 1 row in set (0.00 sec)

  1.  

  1. mysql>

3:这种方法只针对于存储过程或函数 ,对于视图而言,由于information_schema.VIEWS是无法修改的。所以无法使用此方法。如下测试所示:

mysql> UPDATE information_schema.VIEWS

-> SET DEFINER='root@localhost'

-> WHERE TABLE_NAME='v_student';

ERROR 1044 (42000): Access denied for user 'root'@'localhost' to database 'information_schema'

  1. mysql> select user();

  1. +-------------------------+

  1. | user()                  |

  1. +-------------------------+

  1. | mydbadmin@192.168.7.34 |

  1. +-------------------------+

  1. 1 row in set (0.00 sec)

  1.  

  1. mysql> use MyDB;

  1. Database changed

  1. mysql> DELIMITER &&

  1. mysql> CREATE DEFINER='mydbadmin'@'%' PROCEDURE prc_my_test()

  1.     -> BEGIN 

  1.     ->      SELECT COUNT(*) FROM student;

  1.     -> END &&

  1. Query OK, 0 rows affected (0.03 sec)

  1.  

  1. mysql> DELIMITER ;

  1. mysql>

  1. mysql>  select user();

  1. +----------------+

  1. | user()         |

  1. +----------------+

  1. | root@localhost |

  1. +----------------+

  1. 1 row in set (0.00 sec)

  1.  

  1. mysql> select db, name, type ,security_type, definer

  1.     -> from mysql.proc

  1.     -> where name='prc_my_test';

  1. +------+-------------+-----------+---------------+-------------+

  1. | db   | name        | type      | security_type | definer     |

  1. +------+-------------+-----------+---------------+-------------+

  1. | MyDB | prc_my_test | PROCEDURE | DEFINER       | mydbadmin@% |

  1. +------+-------------+-----------+---------------+-------------+

  1. 1 row in set (0.00 sec)

  1.  

  1. mysql> call prc_my_test();

  1. +----------+

  1. | COUNT(*) |

  1. +----------+

  1. |        0 |

  1. +----------+

  1. 1 row in set (0.00 sec)

  1.  

  1. Query OK, 0 rows affected (0.00 sec)

  1.  

  1. mysql> drop user mydbadmin@'%';

  1. Query OK, 0 rows affected (0.01 sec)

  1.  

  1. mysql> call prc_my_test();

  1. ERROR 1449 (HY000): The user specified as a definer ('mydbadmin'@'%') does not exist

  1. mysql> update mysql.proc set  definer='root@localhost' where name='prc_my_test';

  1. Query OK, 1 row affected (0.02 sec)

  1. Rows matched: 1  Changed: 1  Warnings: 0

  1.  

  1. mysql> select db, name, type ,security_type, definer

  1.     -> from mysql.proc

  1.     -> where name='prc_my_test';

  1. +------+-------------+-----------+---------------+----------------+

  1. | db   | name        | type      | security_type | definer        |

  1. +------+-------------+-----------+---------------+----------------+

  1. | MyDB | prc_my_test | PROCEDURE | DEFINER       | root@localhost |

  1. +------+-------------+-----------+---------------+----------------+

  1. 1 row in set (0.00 sec)

  1.  

  1. mysql>  call prc_my_test();

  1. ERROR 1449 (HY000): The user specified as a definer ('mydbadmin'@'%') does not exist

  1. mysql> flush privileges;

  1. Query OK, 0 rows affected (0.00 sec)

  1.  

  1. mysql>  call prc_my_test();

  1. ERROR 1449 (HY000): The user specified as a definer ('mydbadmin'@'%') does not exist

  1. mysql> exit

  1. Bye

如上所示,必须退出重新登录,才能生效,如果更新完mysql.proc后,不退出当前会话,依然会报“ERROR 1449 (HY000): The user specified as a definer ('mydbadmin'@'%') does not exist”错误。

  1. root@DB-Server ~]# mysql -u root -p

  1. Enter password:

  1. Welcome to the MySQL monitor.  Commands end with ; or \g.

  1. Your MySQL connection id is 43

  1. Server version: 5.6.20-enterprise-commercial-advanced-log MySQL Enterprise Server - Advanced Edition (Commercial)

  1.  

  1. Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.

  1.  

  1. Oracle is a registered trademark of Oracle Corporation and/or its

  1. affiliates. Other names may be trademarks of their respective

  1. owners.

  1.  

  1. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

  1.  

  1. mysql> use MyDB;

  1. Reading table information for completion of table and column names

  1. You can turn off this feature to get a quicker startup with -A

  1.  

  1. Database changed

  1. mysql> call prc_my_test();

  1. +----------+

  1. | COUNT(*) |

  1. +----------+

  1. |        0 |

  1. +----------+

  1. 1 row in set (0.01 sec)

  1.  

  1. Query OK, 0 rows affected (0.01 sec)

这种方法,对于存储过程或函数,意义在于可以批量修改,非常快捷方便。唯一比较遗憾的是对于VIEW,无法使用。

4: 重新创建账号'mydbadmin'@'%' ,不过像这个案例,本身是处于安全考虑,限制能够访问数据库的IP,那么此时这种方案就不太可行,如果只是误删用户,那么这种方案就比较有效。

  1. mysql> drop user 'mydbadmin'@'%';

  1. Query OK, 0 rows affected (0.00 sec)

  1.  

  1. mysql> select count(*) from v_student;

  1. ERROR 1449 (HY000): The user specified as a definer ('mydbadmin'@'%') does not exist

  1. mysql> GRANT ALL PRIVILEGES ON `MyDB`.* TO 'mydbadmin'@'%' IDENTIFIED BY 'mydbadmin13s5';

  1. Query OK, 0 rows affected (0.00 sec)

  1.  

  1. mysql> flush privileges;

  1. Query OK, 0 rows affected (0.00 sec)

  1.  

  1. mysql> select count(*) from v_student;

  1. +----------+

  1. | count(*) |

  1. +----------+

  1. |        0 |

  1. +----------+

  1. 1 row in set (0.00 sec)

  1.  

  1. mysql>

另外,对于存储过程、函数、定时事件、视图,都可以参考上面方法进行,其中定时事件主要修改mysql.event下的表。

update mysql.event set definer='root@localhost';

参考资料:

http://kedar.nitty-witty.com/blog/solutions-mysql-error-1449-the-user-specified-as-a-definer-does-not-exist

ERROR 1045 (28000): Access denied for user xxx & ERROR 1449 (HY000): The user specified as a definer xxx does not exists的更多相关文章

  1. ERROR 1045 (28000): Access denied for user 'xxx'@'localhost' (using password: YES)【奇葩的bug】

    #  Bug描述 今天周末,在家里学点新技术,虽然公司分配的任务没有完成(滑稽滑稽) 我先创建了一个mysql数据库,用root用户创建一个新用户,毕竟项目中使用root是非常危险的,尤其是我这样的实 ...

  2. ERROR 1045 (28000): Access denied for user 'xxx'@'localhost' (using password: YES)

    #  Bug描述 今天周末,在家里学点新技术,虽然公司分配的任务没有完成(滑稽滑稽) 我先创建了一个mysql数据库,用root用户创建一个新用户,毕竟项目中使用root是非常危险的,尤其是我这样的实 ...

  3. Linux mysql 5.6: ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)

    案例环境: 操作系统 :Red Hat Enterprise Linux Server release 5.7 (Tikanga) 64 bit 数据库版本 : Mysql 5.6.19 64 bit ...

  4. MySQL ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)的真正原因

    在博客Linux mysql 5.6: ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: N ...

  5. 升级到macOS 10.12 mysqlb报错ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)

    系统升级到macOS 10.12后启动mysql后,在终端输入mysql 报错ERROR 1045 (28000): Access denied for user 'root'@'localhost' ...

  6. mysql 链接失败(ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES))

    mysql链接失败(ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)) 修改: # ...

  7. 安装mysql因为/tmp权限不足而导致ERROR 1045 (28000): Access denied for user root@localhost (using password: NO)的解决方案

    本机是centos 6.5  安装的mysql是5.1的版本. 在安装mysql之后,第一次启动mysql服务的时候,需要/tmp有777(rwxrwxrwx)的权限,然而楼主的/tmp是755(rw ...

  8. MySQL5.5出面ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)问题的解决办法

    问题描述 安装完MySQL5.5数据库,使用Navicat Premium以及命令窗口连接数据库都报以下错误: ERROR 1045 (28000): Access denied for user ' ...

  9. MySQL学习笔记——ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO)

    ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: NO) Enter password: E ...

随机推荐

  1. Eralng的常用数据结构

    1.记录(record) 适用于小数据,并且用属性名方便查找 2.Key/Value 类型 a.属性列表 就是类似[{Key, Value}]的列表,可以通过proplists模块来处理这样的列表 当 ...

  2. openstack开发基础

  3. Linq to SQL 中实现模糊查询

    list = list.Where(i => i.Name.Contains(empName)).ToList();

  4. Oracle Rac创建表空间及用户

    1. 创建表空间: BEGIN DECLARE cnt integer := 0; BEGIN SELECT 1 INTO cnt FROM dual WHERE exists(SELECT * FR ...

  5. HTML基础知识概括

    1.html的概念 HTML是用来描述网页的一种语言. HTML指的是超文本标记语言(HyperText Markup Language) HTML不是一种编程语言,而是一种标记语言(markup l ...

  6. 《Python网络编程》学习笔记--从例子中收获的计算机网络相关知识

    从之前笔记的四个程序中(http://www.cnblogs.com/take-fetter/p/8278864.html),我们可以看出分别使用了谷歌地理编码API(对URL表示地理信息查询和如何获 ...

  7. ConcurrentHashMap、CopyOnWriteArrayList、LinkedHashMap

    HashMap中未进行同步考虑,而Hashtable在每个方法上加上了synchronized,锁住了整个Hash表,一个时刻只能有一个线程操作,其他的线程则只能等待,在并发的环境下,这样的操作导致H ...

  8. BZOJ 4034: [HAOI2015]树上操作 [欧拉序列 线段树]

    题意: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中所有点的点权都增加 a . 操作 3 :询问某个节点 x 到根的路径中所有点的点权和. 显然树链剖分可做 ...

  9. MDT 2013 从入门到精通之概念扫盲

    从今日开始为大家带来微软MDT 2013批量部署操作系统从入门到精通系列教程,旨在为大家以后的工作.学习提供一个便利的参考教程,以便大家更好.更深入的了解微软MDT,从而减轻企业工程师.IT从业人员及 ...

  10. Python数据结构之三——dict(字典)

    Python版本:3.6.2  操作系统:Windows  作者:SmallWZQ 知识源于生活.Python也是如此. 提到字典,我首先想到的是数学大师--高斯. 为何想起他呢?这主要是因为高斯算法 ...