Got error: 1449: The user specified as a definer ('cittool'@'%') does not exist when using LOCK TABLES
经过一番调查,看来这些视图的定义者是一个已从系统中清除的旧开发人员帐户。带有此问题的数据库和视图很少使用,并且大多数用于存档目的。
大约有40个带有定义器的视图不再存在。是否有一种简单的方法可以一次将定义器更改为其他帐户?有没有办法让mysqldump轻松地将所有视图转储到文件中,以便我可以编辑该文件并重新创建视图?
#1 楼
创建具有所有视图定义的文本文件: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是一个很好的选择。
–德里克·唐尼(Derek Downey)
2011年7月26日在21:01
从理论上来说,我更喜欢DTest的解决方案,但是我的系统出现了一些问题,阻止了它的正常运行。我基本上使用上面的方法将show create语句转储到文件中,并且我不得不手动对其稍加编辑然后运行它们。
– Zoredache
2011年7月26日在21:10
当定义者用户不存在时,SHOW CREATE VIEW不起作用-它引发与mysqldump相同的错误:指定为定义者的用户('abc'@'1.2.3.4')不存在
– Marki555
2014年4月30日19:42
@ Marki555然后,您必须临时创建该用户。运行CREATE USER'abc'@'1.2.3.4';。然后,再试一次。
– RolandoMySQLDBA
2014年4月30日19:44
我只是注意到View使用了一些存储过程,并且该错误消息被实现给该过程的定义者,而不是视图本身
– Marki555
2014年4月30日在20:24
#2 楼
您可以将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:如果您不进行此操作,则一次仅适用于一个数据库。在table_schema中,您需要在每个表之间插入USE命令。
评论
我喜欢这一点,因为它看起来比我的参与程度更少,更简洁。 +1 !!! (我忘记了ALTER VIEW)
– RolandoMySQLDBA
2011年7月26日19:12
知道为什么view_definition字段为空吗?从information_schema.views中选择table_name,view_definition,其中table_schema ='cittmp';返回|员工| |
– Zoredache
2011年7月26日20:02
从聊天中的讨论看来,这是超级特权的权限问题。 bugs.mysql.com/bug.php?id=39733
–德里克·唐尼(Derek Downey)
2011年7月26日在20:49
完美的解决方案! +1
–巴勃罗·马丁内斯(Pablo Martinez)
2014年5月22日12:50
至少在RedHat上,如果要输出到文件,则必须转义回跳号,例如echo“ SELECT CONCAT(” ALTER DEFINER = \`您的用户\`@ \`主机\`视图...
–clav
16 Jan 14'20:41
#3 楼
自动执行Derek的解决方案,这会将DEFINER更改为root@localhost
,并在所有数据库的所有视图中设置SQL 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。 br />
还应该使用以下方法检查所有表/视图:
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
19年7月27日在1:02
#4 楼
导出数据库的所有视图<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
19年8月24日在18:57
@SherylHohman将DEFINER = olduser @ oldhost更改为DEFINER = newuser @ newhost,cat views.sql | mysql
–x-yuri
19-09-3在5:50
#5 楼
我创建了一个简单的python脚本,将生产db定义器替换为本地db定义器。此脚本将修改转储文件并自动导入指定的数据库。GIT存储库:https://github.com/mjakal/db-auto-import
评论
对我来说,我只是将丢失的帐户添加到数据库中,错误消失了。