首页 > 数据库 >技术分享 | MySQL 存储过程中的只读语句超时怎么办?

技术分享 | MySQL 存储过程中的只读语句超时怎么办?

时间:2022-12-20 15:07:43浏览次数:65  
标签:语句 超时 只读 max MySQL kill time execution select


作者:杨涛涛

资深数据库专家,专研 MySQL 十余年。擅长 MySQL、PostgreSQL、MongoDB 等开源数据库相关的备份恢复、SQL 调优、监控运维、高可用架构设计等。目前任职于爱可生,为各大运营商及银行金融企业提供 MySQL 相关技术支持、MySQL 相关课程培训等工作。



MySQL 有一个参数叫 max_execution_time ,用来设置只读语句执行的超时时间,但是仅对单独执行的 select 语句有效;对于非单独执行的 select 语句,比如包含在存储过程、触发器等内置事务块里则不生效。官方手册上对这个参数解释如下:

​max_execution_time​​ applies as follows:

那对这种非单独出现的 select 语句,该如何控制超时时间呢?

先来看下参数 max_execution_time 设置后的效果。此参数设置后,select 语句如果执行时间过长,会直接被 cancel 掉,并且报错,如下所示:

mysql> set @@max_execution_time=1000;
Query OK, 0 rows affected (0.00 sec)

mysql> select sleep(2) from t1 limit 1;
ERROR 3024 (HY000): Query execution was interrupted, maximum statement execution time exceeded

或者是采用直接加 Hint 的方式,也能限制 select 语句的执行时间: 下面两种方式都能起到限制 select 语句执行时间的作用。

mysql> select /*+ max_execution_time(1000) */ sleep(2) from t1 limit 2;
ERROR 3024 (HY000): Query execution was interrupted, maximum statement execution time exceeded

mysql> select /*+ set_var(max_execution_time=1000) */ sleep(2) from t1 limit 2;
ERROR 3024 (HY000): Query execution was interrupted, maximum statement execution time exceeded

那如果把这条 select 语句封装在存储过程内部,按照手册上对参数 max_execution_time 的解释,则不生效。比如新建一个存储过程 sp_test :

DELIMITER $$

USE `ytt`$$

DROP PROCEDURE IF EXISTS `sp_test`$$

CREATE DEFINER=`admin`@`%` PROCEDURE `sp_test`()
BEGIN
select sleep(2) from t1 limit 1;
END$$

DELIMITER ;

重新设置 max_execution_time 值为1秒:调用存储过程 sp_test , 可以正常执行,select 语句并没有被 cancel 掉!

mysql> call sp_test;
+----------+
| sleep(2) |
+----------+
| 0 |
+----------+
1 rows in set (2.01 sec)

Query OK, 0 rows affected (2.01 sec)

那如何解决这个问题呢?

为了更方便大家测试,把语句 select sleep(2) from t1 limit 1 改为 select sleep(2000) from t1 limit 1 。既然 MySQL 层面有这样的限制,那只能从非 MySQL 层面来想办法。最直接有效的就是写个脚本来主动 cancel 掉 select 语句。脚本如下:

root@ytt-normal:/home/ytt/script# cat kill_query 
#!/bin/sh
QUERY_ID=`mysql -ss -e "select id from information_schema.processlist where user='admin' and db='ytt' and time>10 and regexp_like(info,'^select','i')"`
if [ $QUERY_ID ];then
echo "kill query $QUERY_ID"
mysql -e "kill query $QUERY_ID"
fi

完后把脚本放到 crontab 或者 MySQL 自己的 event 里来定时执行即可。单独执行脚本效果如下:

root@ytt-normal:/home/ytt/script# ./kill_query 
kill query 50

除了自己编写脚本,还有一个工具可以实现类似的效果,它包含在我们熟知的 Percona-toolkit 工具箱里,叫 pt-kill 。

pt-kill 工具可以根据各种触发条件来执行指定动作:比如 cancel 掉指定 SQL 语句、kill 掉指定 session 等。所以完全可以使用 pt-kill 工具来实现 select 语句超时被自动 cancel 掉。如下所示:pt-kill 工具会在后台一直运行,监听 MySQL 进程,一旦触发条件被激活,即可执行相应动作。

root@ytt-normal:/home/ytt/script# pt-kill --match-db=ytt --match-user=admin --match-host=%  \--match-info='^select' --victims=all --busy-time='10s' --print --kill-query

# 2022-08-15T17:29:03 KILL QUERY 50 (Query 11 sec) select sleep(2000) from t1 limit 1

有一点需要注意:select 语句超时自动 cancel 掉这样的功能不适宜用在生产环境!因为你无法预知其执行结果的时效性、上下文是否相关等特点。


标签:语句,超时,只读,max,MySQL,kill,time,execution,select
From: https://blog.51cto.com/u_15077536/5955398

相关文章

  • 第07期:有关 MySQL 字符集的 SQL 语句
    本篇为理清字符集的续篇​​(上一篇:第06期:梳理MySQL字符集的相关概念)​​,重点讲述字符集涉及到的sql语句用法。一、characterintroducer翻译过来就是字符引导。也就是针......
  • 故障分析 | MySQL OOM 故障应如何下手
    作者:孙祚龙爱可生南区分公司交付服务部成员,实习工程师。负责公司产品问题排查及日常运维工作。。引言前阵子处理这样一个案例,某客户的实例mysqld进程内存经常持续增加导......
  • 故障分析 | MySQL 优化案例 - 字符集转换
    作者:xuty本文关键字:SQL优化、字符集一、背景Serverversion:5.7.24-logMySQLCommunityServer(GPL)开发联系我,说是开发库上有一张视图查询速度很慢,9000条数据要查10......
  • 分布式 | 从 dble 日志分析到 MySQL 源码学习
    作者:袁琳铸爱可生DBLE团队开发成员,主要负责DBLE需求开发,故障排查和社区问题解答。背景在客户的生产环境中,dble.log时常出现nohandler日志。虽然没有影响客户业务的......
  • 第08期:有关 MySQL 字符集的注意事项
    本文关键字:字符集、建库建表一、数据库和字符集1、建库时指定创建数据库时,显式指定字符集和排序规则,同时,当切换到当前数据库后,参数character_set_database,collation_databa......
  • 故障分析 | 有效解决 MySQL 行锁等待超时问题【建议收藏】
    作者:xuty本文来源:原创投稿*爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。一、背景####2019121910:10:10,234|com.alibaba.druid.filter......
  • 故障分析 | MySQL 优化案例 - select count(*)
    作者:xuty本文关键字:count、SQL、二级索引一、故事背景项目组联系我说是有一张500w左右的表做selectcount(*)速度特别慢。二、原SQL分析Serverversion:5.7.24-logMy......
  • 故障分析 | 同一条 SQL 为何在 MariaDB 正常,MySQL 5.7 却很慢?
    作者:王顺爱可生DBA团队成员,在公司负责项目中处理数据库问题,喜欢学习技术,钻研技术问题。同一条SQL在MariaDB上运行正常,为什么在MySQL5.7上运行很慢?一、问题描述客......
  • 故障分析 | MySQL 无监听端口故障排查
    作者:王向爱可生DBA团队成员,负责公司DMP产品的运维和客户MySQL问题的处理。擅长数据库故障处理。对数据库技术和python有着浓厚的兴趣。前言最近解决了一个比较基础......
  • 第02期:MySQL 数据类型的艺术-大对象字段
    我以前分享过一篇​​《MySQL大对象一例》​​,今天就来详细说下大对象的优缺点以及使用场景。我们把MySQL的大对象类型分TEXT/BLOB和JSON两部分来说明。 一、TEX......