在许多视图上修改DEFINER


25

更新后备份我的数据库时遇到问题。我一直在寻找系统原因,以找出原因。我运行的一个查询返回了此结果。

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

经过调查后,这些视图的定义者似乎是已从系统中清除的旧开发者帐户。带有此问题的数据库和视图很少使用,并且大多数用于存档目的。

带有定义器的视图大约不存在40个。是否有一种简单的方法可以一次将定义器更改为其他帐户?有没有一种方法可以使mysqldump简单地将所有视图转储到文件中,以便我可以编辑该文件并重新创建视图?


对我来说,我只是将丢失的帐户添加到数据库中,错误消失了。
user1794918 18/12/29

Answers:


13

创建具有所有视图定义的文本文件:

mysql -uusername -ppassword -A --skip-column-names -e"SELECT CONCAT('SHOW CREATE VIEW ',table_schema,'.',table_name,'\\G') FROM information_schema.tables WHERE engine IS NULL" | mysql -uusername -ppassword -A --skip-column-names > AllMyViews.sql

您从那里编辑AllMyViews.sql。然后,删除视图

mysql -uusername -ppassword -A --skip-column-names -e"SELECT CONCAT('DROP VIEW ',table_schema,'.',table_name,';') FROM information_schema.tables WHERE engine IS NULL" | mysql -uusername -ppassword -A

编辑AllMyViews.sql后,重新加载它们

mysql -uusername -ppassword -A < AllMyViews.sql

试试看 !!!


如果未显示information_schema的view_definition,但SHOW CREATE VIEW工作正常,则+1是一个很好的选择。
德里克·唐尼

从理论上来说,我更喜欢DTest的解决方案,但是我的系统出现了一些问题,阻止了它的正常运行。我基本上使用上面的方法将show create语句转储到文件中,并且必须手动对其稍加编辑然后运行它们。
Zoredache

当定义者用户不存在时,SHOW CREATE VIEW不起作用-它引发与mysqldump相同的错误:The user specified as a definer ('abc'@'1.2.3.4') does not exist
Marki555

@ Marki555然后,您必须临时创建该用户。运行CREATE USER 'abc'@'1.2.3.4';。然后,再试一次。
RolandoMySQLDBA 2014年

我只是注意到View使用了一些存储过程,并且该错误消息被实现给该过程的定义者,而不是视图本身
Marki555 2014年

25

您可以将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 "*abovequery*" | mysql -uuser -p > alterView.sql
> mysql -uuser -p databasename < alterView.sql

旁注:您不能直接更改information_schema条目。注意2:一次仅适用于一个数据库,如果不使用WHERE table_schema,则需要在每个数据库之间插入USE命令。


我喜欢这一点,因为它看起来比我的参与程度更少,更简洁。+1 !!! (我忘记了ALTER VIEW)
RolandoMySQLDBA 2011年

知道为什么view_definition字段为空吗? SELECT table_name,view_definition FROM information_schema.views WHERE table_schema='cittmp'; 返回| Staff | |
Zoredache

从聊天中的讨论看来,这是超级特权的权限问题。bugs.mysql.com/bug.php?id=39733
Derek Downey

完美的解决方案!+1
Pablo Martinez

至少在RedHat上,如果要输出到文件,则必须转义回去,例如echo "SELECT CONCAT("ALTER DEFINER=\`youruser\`@\`host\` VIEW...
clav

3

自动执行Derek的解决方案,这会将DEFINER更改为root@localhostSQL SECURITY INVOKER在所有数据库的所有视图中设置(确保首先要这样做!):

mysql -BNe 'show databases' | \
egrep -v '^(information_schema|performance_schema)$' | \
while read DB
do 
    mysql -BNe "SELECT CONCAT(\"ALTER DEFINER=\`root\`@\`localhost\` SQL SECURITY INVOKER VIEW \",table_name,\" AS \", view_definition,\";\") FROM information_schema.views WHERE table_schema=\"$DB\"" | \
    mysql $DB
done

警告:在运行它之前,请确保已进行了完整的mysql备份(例如,通过停止mysqld并备份/ var / lib / mysql中的所有文件),以防万一...它对我有用,但是YMMV 。

您还应该使用以下方法检查所有表格/视图:

mysql -BNe 'show databases' | \
egrep -v '^(information_schema|performance_schema)$' | \
while read DB
do 
   mysql -BNe 'show tables' $DB | \
   while read t
   do
      echo "check table $t;"
   done | mysql -BN $DB
done | \
egrep -v 'status\s*OK'

它不再应该抱怨视图中的无效定义器。


无耻地将此添加到了我的摘要中。谢谢!
stefgosselin

3

导出数据库的所有视图<DB>

mysql -BNe "SELECT TABLE_NAME FROM TABLES WHERE TABLE_SCHEMA = '<DB>' AND TABLE_TYPE = 'VIEW'" \
    information_schema | xargs mysqldump --single-transaction --no-data <DB> >views.sql

要么:

mysql -BNe "SELECT TABLE_NAME FROM VIEWS WHERE TABLE_SCHEMA = '<DB>'" \
    information_schema | xargs mysqldump --single-transaction --no-data <DB> >views.sql

编辑views.sql(更改定义器)并重新创建它们:

cat views.sql | mysql <DB>

指定-u-p根据需要进行切换。


VIEWS应该以什么方式views.sql进行编辑?另外,如何重新创建它们?
SherylHohman

@SherylHohman更改DEFINER = olduser@oldhostDEFINER = newuser@newhostcat views.sql | mysql <DB>重新创建视图。
x-yuri
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.