服务器之家:专注于服务器技术及软件下载分享
分类导航

Mysql|Sql Server|Oracle|Redis|

服务器之家 - 数据库 - Mysql - SQL查询超时的设置方法(关于timeout的处理)

SQL查询超时的设置方法(关于timeout的处理)

2019-12-21 16:37MYSQL教程网 Mysql

为了优化OceanBase的query timeout设置方式,特调研MySQL关于timeout的处理,下面与大家分享下处理记录,感兴趣的朋友可以参考下哈

为了优化OceanBase的query timeout设置方式,特调研MySQL关于timeout的处理,记录如下。 

复制代码代码如下:


mysql> show variables like '%time%'; 
+----------------------------+-------------------+ 
| Variable_name | Value | 
+----------------------------+-------------------+ 
| connect_timeout | 10 | 
| datetime_format | %Y-%m-%d %H:%i:%s | 
| delayed_insert_timeout | 300 | 
| flush_time | 1800 | 
| innodb_lock_wait_timeout | 50 | 
| innodb_old_blocks_time | 0 | 
| innodb_rollback_on_timeout | OFF | 
| interactive_timeout | 28800 | 
| lc_time_names | en_US | 
| lock_wait_timeout | 31536000 | 
| long_query_time | 10.000000 | 
| net_read_timeout | 30 | 
| net_write_timeout | 60 | 
| slave_net_timeout | 3600 | 
| slow_launch_time | 2 | 
| system_time_zone | | 
| time_format | %H:%i:%s | 
| time_zone | SYSTEM | 
| timed_mutexes | OFF | 
| timestamp | 1366027807 | 
| wait_timeout | 28800 | 
+----------------------------+-------------------+ 
21 rows in set, 1 warning (0.00 sec) 


重点解释其中几个参数: 
connect_timeout: 
The number of seconds that the mysqld server waits for a connect packet before respondingwith Bad handshake. The default value is 10 seconds as of MySQL 5.1.23 and 5 seconds before that. Increasing the connect_timeout value might help if clients frequently encounter errors of the form Lost connection to MySQL server at ‘XXX', system error: errno. 
解释:在获取链接时,等待握手的超时时间,只在登录时有效,登录成功这个参数就不管事了。主要是为了防止网络不佳时应用重连导致连接数涨太快,一般默认即可。 
interactive_timeout: 
The number of seconds the server waits for activity on an interactive connection before closing it. An interactive client is defined as a client that uses the CLIENT_INTERACTIVE option to mysql_real_connect(). See alsowait_timeout. 
解释:一个持续SLEEP状态的线程多久被关闭。线程每次被使用都会被唤醒为acrivity状态,执行完Query后成为interactive状态,重新开始计时。wait_timeout不同在于只作用于TCP/IP和Socket链接的线程,意义是一样的。 
MySQL可以配置连接的超时时间,这个时间如果做得太长,甚至到了10min,那么很可能发生这种情况,3000个链接都被占满而且sleep在哪,新链接进不来,导致无法正常服务。因此这个配置尽量配置一个符合逻辑的值,60s或者120s等等。 
说人话: 
命令行下面敲一个命令后,直至下一个命令到来之前的时间间隔为interactive_time,如果这个时间间隔超过了interactive_timeout,则连接会被自动断开,下一个命令失败。不过一般的mysql客户端都有自动重连机制,下一个命令会在重连后执行。 

复制代码代码如下:


mysql> set interactive_timeout = 1; 
Query OK, 0 rows affected (0.00 sec) 
mysql> show session variables like '%timeout%'; 
+----------------------------+----------+ 
| Variable_name | Value | 
+----------------------------+----------+ 
| connect_timeout | 10 | 
| interactive_timeout | 1 | 
| wait_timeout | 28800 | 
+----------------------------+----------+ 
10 rows in set (0.00 sec) 

 

复制代码代码如下:


mysql> set wait_timeout = 1; 
Query OK, 0 rows affected (0.00 sec) 
【去泡杯茶,等会儿】 
mysql> show session variables like '%timeout%'; 
ERROR 2006 (HY000): MySQL server has gone away 
No connection. Trying to reconnect... 
Connection id: 7 
Current database: *** NONE *** 
+----------------------------+----------+ 
| Variable_name | Value | 
+----------------------------+----------+ 
| connect_timeout | 10 | 
| interactive_timeout | 28800 | 
| wait_timeout | 28800 | 
+----------------------------+----------+ 
10 rows in set (0.01 sec) 


wait_timeout: 
The number of seconds the server waits for activity on a noninteractive connection (连接上没有活动命令,可能是客户端喝咖啡去了。)before closing it. Before MySQL 5.1.41, this timeout applies only to TCP/IP connections, not to connections made through Unix socket files, named pipes, or shared memory. 
On thread startup, the session wait_timeout value is initialized from the global wait_timeout value or from the global interactive_timeout value, depending on the type of client 
这里顺带解释一下什么是non-interactive connection 
> Non-Interactive Commands 
Just do a quick look up on a table without logging into the client, running the query then logging back out again. 
You can instead just type one line using the ' -e ' flag. 

复制代码代码如下:


c:\mysql\bin\mysql -u admin -p myDatabase -e 'SELECT * FROM employee' 


net_read_timeout / net_write_timeout 
The number of seconds to wait for more data from a connection before aborting the read. Before MySQL 5.1.41, this timeout applies only to TCP/IP connections, not to connections made through Unix socket files, named pipes, or shared memory. When the server is reading from the client, net_read_timeout is the timeout value controlling when to abort. When the server is writing to the client, net_write_timeout is the timeout value controlling when to abort. See also slave_net_timeout. 
On Linux, the NO_ALARM build flag affects timeout behavior as indicated in the description of the net_retry_count system variable. 
解释:这个参数只对TCP/IP链接有效,分别是数据库等待接收客户端发送网络包和发送网络包给客户端的超时时间,这是在Activity状态下的线程才有效的参数 
JDBC setQueryTimeout函数: 
为了避免查询出现死循环,或时间过长等现象,而导致线程阻塞,在获得Statement的实例后,stmt.setQueryTimeout(10); 避免因为查询导致程序出现线程阻塞。 
但昨天发现程序出现了,“ORA-01013: 用户请求取消当前的操作”的异常。手工执行出错SQL语句发现,这个语句耗时20多秒。因为setQueryTimeout(10),所以还没有执行完查询语句就抛出异常了。使用setQueryTimeout(10)时一定要把时间设置的长一些,如60秒以上。只要不导致线程长期阻塞,就可以。太短了容易抛出,“ORA-01013: 用户请求取消当前的操作”的异常 
JDBC实现setQueryTimeout的原理: 

复制代码代码如下:


class IfxCancelQueryImpl extends TimerTask 
implements IfmxCancelQuery 

IfxStatement stmt; 
Timer t = null; 
public void startCancel(IfxStatement paramIfxStatement, int paramInt) 
throws Exception 

this.stmt = paramIfxStatement; 
this.t = new Timer(true); 
this.t.schedule(this, paramInt * 1000); 

public void run() 

try 

this.stmt.cancel(); 
this.t.cancel(); 

catch (SQLException localSQLException) 

this.t.cancel(); 
throw new Error(localSQLException.getErrorCode() + ":" + localSQLException.getMessage()); 



可见,query timeout是通过客户端解决方案来做的,服务器端无需知晓。通过一个timer线程来监控执行时间,如果执行时间超时,则会schedule run()函数。 
Reference: 
http://wangwei.cao.blog.163.com/blog/static/10236252620111119115540534/ 
http://sls8204.blog.163.com/blog/static/62979632200741683453114/ 
OceanBase可以通过server端支持query timeout,可以设置query timeout并且不中断当前session。这一点比MySQL先进。

延伸 · 阅读

精彩推荐
  • Mysqlnavicat 8 创建数据库与创建用户分配权限图文方法

    navicat 8 创建数据库与创建用户分配权限图文方法

    navicat是一款不错的图形化管理mysql的工具,大家一般都是用phpmyadmin或直接命令行操作,对于不是很熟悉命令的朋友,就可以使用navicat这个工具了,方便操...

    mysql教程网1402019-11-16
  • MysqlMySQL数据库存储引擎和分支现状分析

    MySQL数据库存储引擎和分支现状分析

    在MySQL经历了2008年Sun的收购和2009年Oracle收购Sun的过程中,基本处于停滞发展的情况,在可以预见的未来,MySQL是肯定会被Oracle搁置并且逐步雪藏消灭掉的。...

    mysql教程网3062019-11-15
  • Mysql超越MySQL 对流行数据库进行分支的知识小结

    超越MySQL 对流行数据库进行分支的知识小结

    尽管MySQL是最受欢迎的程序之一,但是许多开发人员认为有必要将其拆分成其他项目,并且每个分支项目都有自己的专长。该需求,以及 Oracle 对核心产品增...

    MYSQL教程网1682019-11-28
  • Mysqlphp 读取mysql数据库三种方法

    php 读取mysql数据库三种方法

    mysql 读取数据库三种方法,需要的朋友可以参考下。 ...

    mysql教程网2932019-11-04
  • Mysqlgetdata table表格数据join mysql方法

    getdata table表格数据join mysql方法

    今天小编就为大家分享一篇关于getdata table表格数据join mysql方法,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小...

    我是高手高手高高手2042019-06-04
  • MysqlMySQL里实现类似SPLIT的分割字符串的函数

    MySQL里实现类似SPLIT的分割字符串的函数

    SQL对字符串的处理能力比较弱,比如我要循环遍历象1,2,3,4,5这样的字符串,如果用数组的话,遍历很简单,但是T-SQL不支持数组,所以处理下来比较麻烦 ...

    MYSQL教程网3282019-12-07
  • MysqlMySQL 密码设置

    MySQL 密码设置

    本文介绍了如何修改一个用户的密码,你可以使用三种方法,GRANT语句、SET PASSWORD语句、直接修改授权表以及使用管理工具mysqladmin。 ...

    mysql教程网1572019-10-26
  • Mysqlmysql 让一个存储过程定时作业的代码

    mysql 让一个存储过程定时作业的代码

    以下例子主要是实现简单的mysq 定时作业,需要的朋友可以参考下。 ...

    mysql教程网2672019-11-19