一次mysql 用户不存在的报错

    前阵回收生产帐号的访问范围,即之前是xxx@"%"的帐号命名方式,修改成若干个以前端应用部署的机器IP为准,修改成xxx@"IP address"。尽量减少不可信客户端连接数据库的情况发生,加强数据安全。

    但是回收xxx@"%"帐号后发现,生产一子系统一直报错,xxx@"%"帐号不存在的异常。一开始通过检查生产代码的jdbc数据库连接串的配置,发现地址配置成服务器的主机名。怀疑是由于域名被错误解析成外网的IP地址导致,将其修改为内网的IP后重新发版本后仍然存在相同报错。

    后来经过排查后最终发现,由于该子系统还采用触发器,只不过之前写触发器的时候没有定义definer,导致该触发器的definer认为当前编写该触发器的用户,即:xxx@"%"。

    原来,mysql删除用户的时候,只会影响到MysqL系统库的user表、db表和tables_priv表,而该用户创建的触发器是不会被连带删除掉的,因为触发器的信息都保存在information.schema库的triggers表里面。所以,其他普通用户(没有管理员权限)想要调用其他用户的触发器的时候,就会报错。

    问题定位出来了,就容易解决了:

    1、删掉原先的xxx@"%"的触发器,重新定义definer为xxx@"IP address"的触发器

    2、普通帐号能调用触发器,需要配置triggers的权限,要不会报trigger权限报错。

    总结一下:

    数据库之所以为数据库,就是其存储数据和检索数据的能力强大,虽然数据库也有触发器、自定义函数和存储过程这类functions,但是functions的执行是牺牲了数据库部分性能来实现的。而且也会导致前端应用同后端服务紧耦合,前端有变更,后续服务也要跟着变。所以,除非是一些特殊的场景如BI、数据分析等,一般生产环境都禁用trigger、functions和 stored procedure。将其功能实现在代码层面,减少数据库负载

    

    

相关文章

MySQL 死锁 是指两个或多个事务互相等待对方持有的锁,从而导...
在MySQL中,InnoDB引擎通过Next-Key Locking技术来解决幻读问...
在数据库事务管理中,Undo Log 和 Redo Log 是两种关键日志,...
case when概述 sql语句中的case语句与高级语言中的switch语句...
其实很简单,只是为了忘记,做个记录,用的时候方便。 不管是...
1.进入服务,找到mysql服务,在属性里找到mysql的安装路径 2...