ERROR 1045 (28000): Access denied for user xxx & ERROR 1449 (HY000): The user specified as a definer xxx does not exists
今天在一个修改过权限的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地址都可以访问该数据库,如下所示:
mysql> GRANT ALL PRIVILEGES ON `MyDB`.* TO 'mydbadmin'@'%' IDENTIFIED BY 'mydbadmin13s5';
Query OK, 0 rows affected (0.03 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
然后以这个mydbadmin登录数据库,创建一个视图v_student. 当然,你也可以创建存储过程或是函数等其他对象,它们也都会遇到这个错误。
mysql> desc student;
+----------+-------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+----------+-------------+------+-----+---------+-------+
| stu_id | int(11) | YES | | NULL | |
| stu_name | varchar(12) | YES | | NULL | |
| sex | int(11) | YES | | NULL | |
| grade | int(11) | YES | | NULL | |
| age | int(11) | YES | | NULL | |
+----------+-------------+------+-----+---------+-------+
5 rows in set (0.00 sec)
mysql> create or replace view v_student
-> as
-> select stu_name, sex, age
-> from student
-> where grade >=3;
Query OK, 0 rows affected (0.02 sec)
假如现在检查时发现任意IP都可以访问这个账号是不符合安全规范的,然后删除了这个账号(如果你用rename user 也会遇到这个问题),重建了该账号。此时你在较大权限的用户下就会遇到“ERROR 1449 (HY000): The user specified as a definer ('mydbadmin'@'%') does not exist”错误。如下所示:
mysql> select user();
+----------------+
| user() |
+----------------+
| root@localhost |
+----------------+
1 row in set (0.00 sec)
mysql> select user,host from mysql.user where user='mydbadmin';
+-----------+------+
| user | host |
+-----------+------+
| mydbadmin | % |
+-----------+------+
1 row in set (0.00 sec)
mysql>
mysql> drop user mydbadmin@'%';
Query OK, 0 rows affected (0.02 sec)
mysql> select count(*) from v_student;
ERROR 1449 (HY000): The user specified as a definer ('mydbadmin'@'%') does not exist
mysql>
mysql> select user,host from mysql.user where user='mydbadmin';
Empty set (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
mysql> GRANT ALL PRIVILEGES ON `MyDB`.* TO 'mydbadmin'@'192.168.%' IDENTIFIED BY 'mydbadmin135';
Query OK, 0 rows affected (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
mysql>
然后你以在客户端使用mydbadmin登录后,查询视图就会报“ERROR 1045 (28000): Access denied for user 'mydbadmin'@'192.168.%' (using password: YES)”
mysql> select user();
+-------------------------+
| user() |
+-------------------------+
| mydbadmin@192.168.7.43 |
+-------------------------+
1 row in set (0.01 sec)
mysql> select * from v_student;
ERROR 1045 (28000): Access denied for user 'mydbadmin'@'192.168.%' (using password: YES)

原因分析
出现这个问题,是因为账号mydbadmin@`%`已经不存在了。而视图指定DEFINER为mydbadmin@`%`,此时创建者不存在了。而SQL SECURITY也是DEFINER,所以MySQL认为现在的用户无权限访问该视图。所以有下面一些方法来解决这个错误。
解决方案
1:重建视图(存储过程或函数)即可解决问题。不过对于数据库视图很多的情况,这个方法略显笨拙和繁琐。
mysql> show create view v_student;
mysql> create or replace view v_student
-> as
-> select stu_name, sex, age
-> from student
-> where grade >=3;
Query OK, 0 rows affected (0.00 sec)
当然可以批量生成相关SQL,类似于下面SQL
SELECT CONCAT("alter DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW ",TABLE_SCHEMA,".",TABLE_NAME," as ",VIEW_DEFINITION,";")
FROM information_schema.VIEWS
WHERE DEFINER=''mydbadmin@%';
2:如果创建视图(存储过程或函数)时,使用SQL SECURITY INVOKER,就可以避免出现这种情况。

如下所示,创建视图时指定SQL SECURITY INVOKER.
SQL SECURITY { DEFINER | INVOKER } :指明谁有权限来执行。默认情况下,系统指定为DEFINE.
DEFINER 表示按定义者拥有的权限来执行
INVOKER 表示用调用者的权限来执行。
mysql> use MyDB;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> select user();
+-------------------------+
| user() |
+-------------------------+
| mydbadmin@192.168.7.218 |
+-------------------------+
1 row in set (0.00 sec)
mysql> create or replace definer='mydbadmin'@'%'
-> sql security invoker
-> view v_student
-> as
-> select stu_name, sex, age
-> from student
-> where grade >=3;
Query OK, 0 rows affected (0.00 sec)
删除用户mydbadmin@'%',此时你会发现还能执行。
mysql> select user();
+----------------+
| user() |
+----------------+
| root@localhost |
+----------------+
1 row in set (0.00 sec)
mysql> drop user mydbadmin@'%';
Query OK, 0 rows affected (0.00 sec)
mysql> select count(*) from v_student;
+----------+
| count(*) |
+----------+
| 0 |
+----------+
1 row in set (0.00 sec)
mysql>

mysql> select user();
+----------------+
| user() |
+----------------+
| root@localhost |
+----------------+
1 row in set (0.00 sec)
mysql> GRANT ALL PRIVILEGES ON `MyDB`.* TO 'mydbadmin'@'192.168.%' IDENTIFIED BY 'mydbadmin135';
Query OK, 0 rows affected (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
mysql> select user();
+-------------------------+
| user() |
+-------------------------+
| mydbadmin@192.168.7.218 |
+-------------------------+
1 row in set (0.00 sec)
mysql> select count(*) from v_student;
+----------+
| count(*) |
+----------+
| 0 |
+----------+
1 row in set (0.00 sec)
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'
mysql> select user();
+-------------------------+
| user() |
+-------------------------+
| mydbadmin@192.168.7.34 |
+-------------------------+
1 row in set (0.00 sec)
mysql> use MyDB;
Database changed
mysql> DELIMITER &&
mysql> CREATE DEFINER='mydbadmin'@'%' PROCEDURE prc_my_test()
-> BEGIN
-> SELECT COUNT(*) FROM student;
-> END &&
Query OK, 0 rows affected (0.03 sec)
mysql> DELIMITER ;
mysql>
mysql> select user();
+----------------+
| user() |
+----------------+
| root@localhost |
+----------------+
1 row in set (0.00 sec)
mysql> select db, name, type ,security_type, definer
-> from mysql.proc
-> where name='prc_my_test';
+------+-------------+-----------+---------------+-------------+
| db | name | type | security_type | definer |
+------+-------------+-----------+---------------+-------------+
| MyDB | prc_my_test | PROCEDURE | DEFINER | mydbadmin@% |
+------+-------------+-----------+---------------+-------------+
1 row in set (0.00 sec)
mysql> call prc_my_test();
+----------+
| COUNT(*) |
+----------+
| 0 |
+----------+
1 row in set (0.00 sec)
Query OK, 0 rows affected (0.00 sec)
mysql> drop user mydbadmin@'%';
Query OK, 0 rows affected (0.01 sec)
mysql> call prc_my_test();
ERROR 1449 (HY000): The user specified as a definer ('mydbadmin'@'%') does not exist
mysql> update mysql.proc set definer='root@localhost' where name='prc_my_test';
Query OK, 1 row affected (0.02 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select db, name, type ,security_type, definer
-> from mysql.proc
-> where name='prc_my_test';
+------+-------------+-----------+---------------+----------------+
| db | name | type | security_type | definer |
+------+-------------+-----------+---------------+----------------+
| MyDB | prc_my_test | PROCEDURE | DEFINER | root@localhost |
+------+-------------+-----------+---------------+----------------+
1 row in set (0.00 sec)
mysql> call prc_my_test();
ERROR 1449 (HY000): The user specified as a definer ('mydbadmin'@'%') does not exist
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
mysql> call prc_my_test();
ERROR 1449 (HY000): The user specified as a definer ('mydbadmin'@'%') does not exist
mysql> exit
Bye
如上所示,必须退出重新登录,才能生效,如果更新完mysql.proc后,不退出当前会话,依然会报“ERROR 1449 (HY000): The user specified as a definer ('mydbadmin'@'%') does not exist”错误。
root@DB-Server ~]# mysql -u root -p
Enter password:
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 43
Server version: 5.6.20-enterprise-commercial-advanced-log MySQL Enterprise Server - Advanced Edition (Commercial)
Copyright (c) 2000, 2014, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> use MyDB;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A
Database changed
mysql> call prc_my_test();
+----------+
| COUNT(*) |
+----------+
| 0 |
+----------+
1 row in set (0.01 sec)
Query OK, 0 rows affected (0.01 sec)
这种方法,对于存储过程或函数,意义在于可以批量修改,非常快捷方便。唯一比较遗憾的是对于VIEW,无法使用。
4: 重新创建账号'mydbadmin'@'%' ,不过像这个案例,本身是处于安全考虑,限制能够访问数据库的IP,那么此时这种方案就不太可行,如果只是误删用户,那么这种方案就比较有效。
mysql> drop user 'mydbadmin'@'%';
Query OK, 0 rows affected (0.00 sec)
mysql> select count(*) from v_student;
ERROR 1449 (HY000): The user specified as a definer ('mydbadmin'@'%') does not exist
mysql> GRANT ALL PRIVILEGES ON `MyDB`.* TO 'mydbadmin'@'%' IDENTIFIED BY 'mydbadmin13s5';
Query OK, 0 rows affected (0.00 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
mysql> select count(*) from v_student;
+----------+
| count(*) |
+----------+
| 0 |
+----------+
1 row in set (0.00 sec)
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的更多相关文章
- ERROR 1045 (28000): Access denied for user 'xxx'@'localhost' (using password: YES)【奇葩的bug】
# Bug描述 今天周末,在家里学点新技术,虽然公司分配的任务没有完成(滑稽滑稽) 我先创建了一个mysql数据库,用root用户创建一个新用户,毕竟项目中使用root是非常危险的,尤其是我这样的实 ...
- ERROR 1045 (28000): Access denied for user 'xxx'@'localhost' (using password: YES)
# Bug描述 今天周末,在家里学点新技术,虽然公司分配的任务没有完成(滑稽滑稽) 我先创建了一个mysql数据库,用root用户创建一个新用户,毕竟项目中使用root是非常危险的,尤其是我这样的实 ...
- 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 ...
- 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 ...
- 升级到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' ...
- 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)) 修改: # ...
- 安装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 ...
- 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 ' ...
- 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 ...
随机推荐
- python自动化运维常用模块安装
1.系统信息性能模块:psutil 源码安装: wget https://pypi.python.org/packages/source/p/psutil/psutil-2.0.0.tar.gz -- ...
- 模块dll和lib
一.dll动态链接库 1.dll 没有 main 函数 2.不能直接执行,可以注入exe中让它间接执行.只有把它编译到应用程序中才可以. 3.编写dll 函数前加上 _declspec(dllexpo ...
- JavaWeb项目架构之Kafka分布式日志队列
架构.分布式.日志队列,标题自己都看着唬人,其实就是一个日志收集的功能,只不过中间加了一个Kafka做消息队列罢了. kafka介绍 Kafka是由Apache软件基金会开发的一个开源流处理平台,由S ...
- JBOD
JBOD(Just a Bunch Of Disks)不是RAID,它是可以把不同容量的硬盘串连成一个大的逻辑盘,与RAID0不同的是在写入数据时是向一个硬盘写入,写满后再向下一个硬盘写. 尽管建议采 ...
- 夏令营讲课内容整理 Day 2.
本日主要内容是并查集和堆. 并查集 并查集是一种树型的数据结构,通常用来处理不同集合间的元素之间的合并与查找问题.一个并查集支持三个基本功能:合并.查找和判断.举一个通俗的例子,我和lhz认识,lhz ...
- BZOJ 3879: SvT [虚树 后缀树]
传送门 题意: 多次询问,给出一些后缀,求两两之间$LCP$之和 哈哈哈哈哈哈哈竟然$1A$了,刚才还在想如果写不好这道题下节数学就不上了,看来是上天让我上数学课啊 $Suffix\ Virtual\ ...
- 【转】我读过最好的epoll讲解(来自知乎)
首先我们来定义流的概念,一个流可以是文件,socket,pipe等等可以进行I/O操作的内核对象.不管是文件,还是套接字,还是管道,我们都可以把他们看作流.之后我们来讨论I/O的操作,通过read,我 ...
- js中的this和箭头函数中的this
一.ES6 允许使用"箭头"(=>)定义函数. // var f = v => v;// 上面的箭头函数等同于: // var f = function(v) {// ...
- Windows Azure Virtual Machine (34) Azure VM挂载WebDAV
<Windows Azure Platform 系列文章目录> 之前使用Azure VM,挂载box网盘.发现不能正常挂载,这里简单记录一下. 1.WebDAV的网络映射,需要WebCli ...
- 读书共享 Primer Plus C-part 12
第十四章 结构和其他数据形式 1.关于上struct与union 的区别 #include<stdio.h> typedef union Book_u { int pags; int mo ...