当前位置: 代码网 > it编程>数据库>Mysql > MySQL存储过程未执行的问题排查过程

MySQL存储过程未执行的问题排查过程

2025年02月13日 Mysql 我要评论
1. 问题背景最近部署了一套测试环境,同事发现以前遗留的一个存储过程未运行,需要我帮忙排查下。下面说一下我的排查过程。列出每种可能得原因以及考虑。2. 问题排查2.1. 数据库版本升级的问题之前我们用

1. 问题背景

最近部署了一套测试环境,同事发现以前遗留的一个存储过程未运行,需要我帮忙排查下。下面说一下我的排查过程。列出每种可能得原因以及考虑。

2. 问题排查

2.1. 数据库版本升级的问题

之前我们用的是 8.0.x 版本的 mysql,最近运维将数据库升级到了 8.4.3 版本。刚开始怀疑是数据库升级导致的,查了相关的版本说明,并没有发现会导致存储过程不执行的问题。

2.2. 用户权限不足的问题

检查了存储过程中定义的用户为root@%,并查看了权限,发现没有问题。

这里记录下涉及到的查询:

用户权限查询

确保执行存储过程的用户有足够的权限。你可以使用如下命令查看权限:

show grants for 'your_username'@'your_host';

并确保有 execute 和 alter routine 权限。如果没有,你可以通过以下命令授予权限:

grant execute, alter routine on your_database_name.* to 'your_username'@'your_host';

查询命令解析

show grants for `root`@`%`;

这条 sql 命令在 mysql 数据库中用来展示用户名为 root,且可以从任意主机(由%表示)连接到 mysql 服务器的用户的权限。

  • root 用户:root 是 mysql 的默认超级用户,拥有对数据库的完全访问权限,包括创建、修改、删除数据库和数据表,以及管理用户权限等。
  • % 的含义:%在 mysql 中表示任意主机,即 root 用户可以从任何主机连接到 mysql 服务器。

如果在执行 show grants for 'root'@'%'; 后发现结果中缺少 execute 权限,表示 root 用户当前没有被授予执行存储过程或函数的权限。execute 权限是 mysql 中用于执行存储过程和存储函数的权限。

可以使用 grant 语句为 root 用户添加 execute 权限:

grant execute on *.* to 'root'@'%';
flush privileges;

这条命令做了以下几件事:

  • grant execute on *.* to 'root'@'%';:为 root 用户授予在所有数据库和所有表上的 execute 权限。*.* 表示所有数据库和所有表,你也可以根据需要指定特定的数据库或表。
  • flush privileges;:刷新 mysql 的权限缓存,使新的权限设置立即生效。

2.3. 存储过程本身的问题

首先这个存储过程在生产环境还有其他环境都是可以正常运行的。因为是复制过来的,所以一开始我就没想到这个错误。但是排查到这里后,还是使用call()去手动调度了一下该存储过程,竟然执行报错了,报错如下:

1055 - expression #1 of select list is not in group by clause and contains nonaggregated column 'newton.imsi_transaction_cdr_raw_cn.carrier_id' which is not functionally dependent on columns in group by clause; this is incompatible with sql_mode=only_full_group_by

这下感觉终于有眉目了,这明显是 sql 模式导致的问题。查看了下存储过程的语句,里面还真有group by,并且不符合only_full_group_by模式的要求。存储过程未执行的原因找到了,我想着接下来去除掉该 sql 模式应该就能解决问题了。

我赶紧去查了一下当前的全局 sql 模式和当前会话 sql 模式,傻眼了,sql 模式中并没有only_full_group_by模式,这时我想起来了,当时环境部署完后,我就要求运维将该only_full_group_by模式去掉了,那为啥现在还会报这种错误,不应该啊,想不明白。

这里记录下 mysql 查询 sql 模式并去除 only_full_group_by 的语句:

查询全局 sql 模式,全局sql模式影响所有新的会话(连接),但不影响已经存在的会话

select @@global.sql_mode;

查询当前会话sql模式,当前会话 sql 模式仅影响当前连接

select @@session.sql_mode;

或者,更简洁地:

select @@sql_mode;

临时去除 only_full_group_by(仅影响当前会话)

使用set session语句来更改当前会话的 sql 模式:

set session sql_mode = replace(@@session.sql_mode, 'only_full_group_by', '');

永久去除 only_full_group_by(影响所有新会话)

要永久更改全局 sql 模式,需要编辑 mysql 的配置文件(如my.cnfmy.ini),然后重启 mysql 服务。但是,直接修改全局 sql 模式可能会影响其他用户和应用,因此通常建议只在必要时进行此类更改。

操作步骤:

  • 打开mysql配置文件。
  • 找到[mysqld]部分。
  • 修改或添加sql_mode行,确保不包含only_full_group_by
  • 保存文件并重启 mysql 服务。

例如,配置文件中的设置可能如下所示:

[mysqld]
sql_mode = "strict_trans_tables,error_for_division_by_zero,...(其他模式,但不包括only_full_group_by)"

3. 问题解决

目前情况是 mysql 8.4.3 版本,我明明之前已经去掉了 only_full_group_by 模式,为什么调用存储的时候还会报 1055 的错误?

错误提示很明显,肯定是 only_full_group_by 模式导致的,现在就是要找到为什么明明没有该模式,怎么还会报这个错误。

在网上查资料的过程中,就在百思不解的时候,不经意看到了一处说明:

‌存储过程内部的 sql_mode‌:存储过程在创建时可能会捕获当前的 sql_mode 设置,并在每次执行时使用该设置。如果存储过程是在 only_full_group_by 模式启用时创建的,那么即使你在之后禁用了该模式,存储过程内部仍然可能使用旧的 sql_mode。要解决这个问题,需要重新创建存储过程,确保在创建时 only_full_group_by 模式是禁用的。

好吧,问题明朗了,当时是这样的,运维那边创建好数据库后,我进行库表和存储过程的初始化,服务部署后,通过服务日志发现有group by报错,才找的运维去掉了 only_full_group_by 模式,也就是说存储过程创建的时候,数据库的 sql 模式中是含有 only_full_group_by 模式的。所以存储过程内部的 sql_mode‌ 肯定也是含有 only_full_group_by 模式的,所以会报 1055 错误。

那解决办法就很简单了,删除掉当前的存储过程,重新创建即可,我试了下,重新创建后,手动调用了下,果然正常执行了。至此,问题解决!

以上就是mysql存储过程未执行的问题排查过程的详细内容,更多关于mysql存储过程未执行的资料请关注代码网其它相关文章!

(0)

相关文章:

版权声明:本文内容由互联网用户贡献,该文观点仅代表作者本人。本站仅提供信息存储服务,不拥有所有权,不承担相关法律责任。 如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 2386932994@qq.com 举报,一经查实将立刻删除。

发表评论

验证码:
Copyright © 2017-2025  代码网 保留所有权利. 粤ICP备2024248653号
站长QQ:2386932994 | 联系邮箱:2386932994@qq.com