MySQL错误1449:指定为定义者的用户不存在


352

当我运行以下查询时,我得到一个错误:

SELECT
  `a`.`sl_id`                     AS `sl_id`,
  `a`.`quote_id`                  AS `quote_id`,
  `a`.`sl_date`                   AS `sl_date`,
  `a`.`sl_type`                   AS `sl_type`,
  `a`.`sl_status`                 AS `sl_status`,
  `b`.`client_id`                 AS `client_id`,
  `b`.`business`                  AS `business`,
  `b`.`affaire_type`              AS `affaire_type`,
  `b`.`quotation_date`            AS `quotation_date`,
  `b`.`total_sale_price_with_tax` AS `total_sale_price_with_tax`,
  `b`.`STATUS`                    AS `status`,
  `b`.`customer_name`             AS `customer_name`
FROM `tbl_supplier_list` `a`
  LEFT JOIN `view_quotes` `b`
    ON (`b`.`quote_id` = `a`.`quote_id`)
LIMIT 0, 30

错误消息是:

#1449 - The user specified as a definer ('web2vi'@'%') does not exist

为什么会出现该错误?我如何解决它?


7
让我们看看你的SHOW CREATE VIEW 'view_quotes'
jordeu

错误必须在view_quotes查看条件下。
壳牌

考虑了一下之后,最简单的操作就是将丢失的帐户添加到数据库中,错误消失了。无需复杂的过程。如果可以添加该帐户,请先尝试。
user1794918 18/12/29

Answers:


539

当将视图/触发器/过程从一个数据库或服务器导出到另一个数据库或服务器时,通常会发生这种情况,因为创建该对象的用户不再存在。

您有两种选择:

1.更改定义

通过DEFINER从转储中删除任何语句,这在最初导入数据库对象时最容易做到。

稍后更改定义器比较棘手:

如何更改视图的定义器

  1. 运行此SQL生成必要的ALTER语句

    SELECT CONCAT("ALTER DEFINER=`youruser`@`host` VIEW ", 
    table_name, " AS ", view_definition, ";") 
    FROM information_schema.views 
    WHERE table_schema='your-database-name';
    
  2. 复制并运行ALTER语句

如何更改存储过程的定义器

例:

UPDATE `mysql`.`proc` p SET definer = 'user@%' WHERE definer='root@%'

注意,因为这将更改所有数据库的所有定义器。

2.创建丢失的用户

如果在使用MySQL数据库时发现以下错误:

The user specified as a definer ('someuser'@'%') does not exist`

然后,您可以使用以下方法解决此问题:

GRANT ALL ON *.* TO 'someuser'@'%' IDENTIFIED BY 'complex-password';
FLUSH PRIVILEGES;

http://www.lynnnayko.com/2010/07/mysql-user-specified-as-definer-root.html

这就像一种魅力-只需更改someuser为丢失用户的名称即可。在本地开发服务器上,您通常可以使用root

还要考虑您是否实际上需要授予用户ALL权限,或者他们是否可以减少权限。


1
和Grant选项不是必需的。
helpe 2014年

@Simon East:您进行了漂亮的编辑,非常感谢您改善了答案。
Chococroc

我建议在运行后加入,重启MySQL实例“UPDATE mysqlprocp将定义者=‘用户名@%’WHERE定义者=‘根@%’”查询自定义者的程序只刷新即可。
约翰·

1
我认为添加无意义的用户会更容易,因为下次您执行dbdump并将其导入时,您将不需要再次执行视图/过程编辑
DarkMukke

1
谢谢,我刚刚删除了有问题的表格,删除了该表格,然后将其DEFINER=`user`@`host`重新导入。像魅力一样工作。:ok_hand:
giovannipds

139

最初创建SQL视图或过程的用户已被删除。如果您重新创建该用户,它应该解决您的错误。


3
另外,您将需要至少向添加的用户授予SELECTEXECUTE特权。我将数据库备份从一台服务器导出到另一台服务器时遇到了这种情况,在该服务器上创建例程的用户不存在于测试服务器上。
drew010

5
谢谢,这很有帮助。通常,在使用mysqldump进行迁移或部署时,创建VIEW,TRIGGER或PROCEDURE(定义程序)的用户在目标系统上可能并不相同。在那种情况下,只需使用目标系统上的有效用户DROP重新创建过程,触发或查看(然后重新CREATE)即可。
埃里克·基加西

38
您还可以将定义者更改为现有用户:UPDATE mysql.proc SET definer = 'my_new_user@localhost' WHERE db = 'mydatatbase';

1
就我而言,我有一个带有触发器的表,该表指向已删除的DEFINER用户。更新触发器用户解决了该问题。
Miguel

您还需要授予该用户许可:) GRANT ALL ON *.* TO 'someuser'@'%' IDENTIFIED BY 'complex-password'; FLUSH PRIVILEGES;
Victor,

50

更新mysql后,我得到了同样的错误。

此命令后已修复错误:

mysql_upgrade -u root

每次升级MySQL时应执行mysql_upgrade。它检查所有数据库中的所有表是否与当前版本的MySQL Server不兼容。如果发现表可能不兼容,请检查该表。如果发现任何问题,则修复表。mysql_upgrade还会升级系统表,以便您可以利用可能已添加的新特权或功能。


不知道为什么这对我不起作用,我不得不手动删除mySQL工作台中的所有触发器。
user752746 '19


34

创建删除的用户,如下所示:

mysql> create user 'web2vi';

要么

mysql> create user 'web2vi'@'%';

3
创建该丢失的用户后,遇到另一个错误:创建用户后ERROR 1142 (42000): TRIGGER command denied to user 'web2vi'@'%' for table 'foo'应添加此命令grant all on *.* to 'web2vi'@'%' identified by ''
zhuguowei

31

按着这些次序:

  1. 转到PHPMyAdmin
  2. 选择您的数据库
  3. 选择你的桌子
  4. 在顶部菜单上,单击“触发器”
  5. 点击“编辑”以编辑触发器
  6. 将定义器从[user @ localhost]更改为root @ localhost

希望能帮助到你


1
这是问题的实际解决方案,而不是创建用户和授予权限。只需更改定义器。
Ankit Chauhan,

有什么办法可以找到数据库中的所有触发器?
Mrugesh Mistry

1
查找所有触发因素:SHOW
TRIGGERS

在命令行“显示触发器”中,从PhpMyAdmin中选择数据库,然后在导航栏的右上角单击触发器
hussainfrotan

21

解决方案只是单行查询,如下所示:

grant all on *.* to 'ROOT'@'%' identified by 'PASSWORD' with grant option;

替换ROOT为您的mysql用户名。替换PASSWORD为您的mysql密码。


1
注意:MySQL用户区分大小写。
Alessio Cantarella

我需要这样做flush privileges之后,它才能起作用。谢谢。
Victor

14

通过运行以下注释修复。

grant all on *.* to 'web2vi'@'%' identified by 'root' with grant option;
FLUSH PRIVILEGES;

如果some_other不是,web2vi则必须相应地更改名称。


13

对于将来的Google员工:我收到类似的消息,试图更新不包含视图的数据库中的表。经过一番挖掘,结果发现我已经在该表上导入了触发器,而这些触发器是由不存在的用户定义的。放下触发器即可解决问题。


触发器是问题,我在触发器部分更新了定义器。没有更多的问题。
Darius

谢谢,这非常有帮助。还需要更新视图。
toxxxa

确实非常有帮助:)我永远都找不到。
ElChupacabra


7

快速解决方法可以转储文件:

mysqldump --single-transaction -u root -p xyz_live_db > xyz_live_db_bkup110116.sql

1
这行不通。定义器包含在转储中。
phil294

如果您将mysqlpump与“ p”而不是“ d”一起使用,则可以使用--skip-definer
Wouter

@lyhong我没有详细的解释,但是显然--single-transaction改变了转储期间实现锁表的方式。或类似的东西。我不记得在哪里读过书,但这使我对“随便扔旗子”感到自在。对于无法解释的“只是这样做”的“答案”,我也感到不安。无论哪种方式,它都适合我的情况。
SherylHohman

7
grant all on *.* to 'username'@'%' identified by 'password' with grant option;

例:

grant all on *.* to 'web2vi'@'%' identified by 'password' with grant option;

如果我将所有特权授予“用户” @“所有ips”,那么安全性又如何呢?
Mohsen Abasi

@MohsenAbasi这是开发环境的示例。该用户可以是系统管理员。产品环境需要更加小心。
mesutpiskin

7

将数据库从一台服务器移到另一台服务器后,这发生在我身上。最初,定义器使用的是localhost和用户。在新服务器上,我们没有该用户,并且主机也已更改。我备份了该特定表,并从phpmyadmin中手动删除了所有触发器。之后,它对我来说一直很好。


感谢您的提示,我能够手动删除mySQL工作台中的所有触发器。
user752746 '19

对我而言,这确实是一个触发问题,我必须删除并重新创建所有内容
paul.ago

除了重新创建触发器,还有其他解决方案吗?我有时每天两次使用测试转储。这会破坏我的主要流程
重新构造

@TS Guhan是否在手动删除触发器后重新添加了触发器?
MailBlade

6

我的root用户ans遇到了同样的问题,当我更换时

root@%

通过

root@localhost

因此,如果允许用户'web2vi'从'localhost'连接,则可以尝试:

web2vi@localhost

我远程连接到数据库。


4

我的5美分。

尝试从视图中选择时出现相同的错误。

但是,问题似乎在于,该视图是从从其他服务器的备份还原的另一个视图中选择的。

实际上,是的,用户是无效的,但是从初次看时不明显。


4

我在几分钟前遇到了同样的问题,我从mysql.user表中删除了一个未使用的用户后遇到了这个问题,但是通过alter view对其进行了修复,这是一个非常方便的命令,它非常简单:

SELECT CONCAT("ALTER DEFINER=`youruser`@`host` VIEW ",
table_name," AS ", view_definition,";") FROM 
information_schema.views WHERE table_schema='databasename'

将此与mysql命令行混合使用(假设* nix,不熟悉Windows):

> echo above_query | mysql -uuser -p > alterView.sql
> mysql -uuser -ppass databasename < alterView.sql

注意:该命令将在文件上生成额外的SELECT CONCAT,mysql -uuser -ppass databasename < alterView.sql如果不删除它,将失败。

资料来源:https : //dba.stackexchange.com/questions/4129/modify-definer-on-many-views


4

尝试将您的程序设置为 SECURITY INVOKER

Mysql默认将过程安全性设置为“ DEFINER”(创建者)..必须将安全性设置为“调用者”。


3

您的视图“ view_quotes”可能已经从“ web2vi”是有效用户的另一个数据库复制到了“ web2vi”不是有效用户的数据库中。
将“ web2vi”用户添加到数据库或更改视图(通常删除DEFINER ='web2vi'@'%'部分并执行脚本即可解决问题)


3

在我的情况下,该表具有不带DEFINER用户的触发器。


2
特别是当应用程序从服务器转移到另一台服务器时
zardilior

2

MySQL的参考CREATE VIEW

DEFINER和SQL SECURITY子句​​指定在视图调用时检查访问特权时要使用的安全上下文。

该用户必须存在,并且最好使用“ localhost”作为主机名。因此,我认为,如果您检查用户是否存在并将其在创建视图上更改为“ localhost”,则不会出现此错误。


2

问题很明显-MySQL无法找到指定为定义者的用户。

从开发服务器同步数据库模型,将其应用于本地主机,对模型进行更改然后将其重新应用于本地主机之后,我遇到了此问题。显然,已定义了一个视图(我已修改),因此无法更新本地版本。

如何修复(轻松)

注意:它涉及删除,因此对视图来说效果很好,但是如果在表上尝试此操作,请确保已备份了数据。

  1. 以root用户身份登录数据库(或具有足够权限进行更改的权限)。
  2. 删除视图,表或任何您遇到的麻烦。
  3. 同步新模型-它不会抱怨现在还不存在的东西。您可能要从遇到问题的项目定义中删除SQL SECURITY DEFINER部分。

PS这既不是适当的解决方案,也不是全方位的解决方案。我只是将其发布为可能(非常简单)的解决方案。


我正在使用蟾蜍,中国我删除和重新创建使用,只有OS我应该从终端登录为Rooy,然后才这样做?
Vasanth Nag KV 2014年


2

为什么会出现该错误?我如何解决它?

我花了一个小时才找到解决此类问题的决定。但是,就我而言,我运行了此命令:

mysql> UPDATE `users` SET `somefield` = 1 WHERE `user_id` = 2;
ERROR 1449 (HY000): The user specified as a definer ('root'@'%') does not exist

如果您真的想找到问题,只需一个命令一个命令地运行:

SHOW PROCEDURE STATUS;
SHOW FUNCTION STATUS;
SHOW TRIGGERS;
SHOW FULL TABLES IN database_name WHERE TABLE_TYPE LIKE 'VIEW';

...,然后在每一个之后查找“定义者”字段。

在我的情况下,这是有胡子的旧触发器,开发人员忘记将其删除。


1

进入“编辑例程”部分,然后在底部将“安全性类型”从“定义者”更改为“调用者”。


4
去哪里 在哪个软件中?
kenorb

@kenorb,在phpMyAdmin中,您可以更改MySQL存储的例程(过程和函数),例如Security Type。
米克2015年

1

您的一个或几个视图是由另一个用户创建/注册的。您必须检查视图的所有者,并:

  1. 重新创建用户;如其他答案所说。要么
  2. 重新创建用户'web2vi'使用ALTER VIEW创建的视图

我曾经有这个问题。

我试图使用SQLYog将视图从BD1迁移到BD2。SQLYog在另一个数据库(DB2)中重新创建了视图,但它保留了BD1的用户(两者不同)。后来我意识到我在查询中使用的视图与您有相同的错误,即使我没有创建任何视图也是如此。

希望能有所帮助。


1

如果这是一个存储过程,则可以执行以下操作:

UPDATE `mysql`.`proc` SET definer = 'YournewDefiner' WHERE definer='OldDefinerShownBefore'

但这是不建议的。

对我来说,更好的解决方案是创建定义器:

create user 'myuser' identified by 'mypass';
grant all on `mytable`.* to 'myuser' identified by 'mypass';

您的SQL语法有误;检查与您的MySQL服务器版本相对应的手册以获取正确的语法,以在'mytable'上授予所有权限。在1号线
Cerin

@Cerin,只需将mytable周围的``更改为''即可。我的回答旨在帮助人们解决这个问题..想想你重新考虑的downvote ..
helpse

1

当mysql.proc为空,但系统始终会注意到table_name不存在的“ user@192.168.%”,您只需以mysql命令行为根,然后键入:

CHECK TABLE `database`.`table_name` QUICK FAST MEDIUM CHANGED;
flush privileges;

过度!


1

我在使用MYSQL Workbench 6.3社区在Windows 10上以“ root @%不存在”导入转储后发生了这种情况。即使用户存在。首先,我尝试将DEFINER注释掉,但这没有用。然后,我在“ root @%”上“ root @ localhost”替换了一个字符串,然后重新导入了转储。这帮了我大忙。



0

数据库用户似乎也区分大小写,因此当我有root'@'%用户时,我没有ROOT'@'%用户。我通过工作台将用户更改为大写,问题已解决!

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.