为MySQL设置查询超时

昨天有人在群里问, MySQL是否可以设置读写超时(非连接超时), 如果可以就可以避免一条SQL执行过慢, 导致PHP超时错误. 这个, 其实可以有. 只不过稍微要麻烦点.

首先, 在libmysql中, 是提供了MYSQL_OPT_READ_TIMEOUT设置项的, 并且libmysql中提供了设置相关设置项的API, mysql_options:

  1. int STDCALL
  2. mysql_options(MYSQL *mysql,enum mysql_option option, const void *arg)
  3. {
  4.   DBUG_ENTER("mysql_option");
  5.   DBUG_PRINT("enter",("option: %d",(int) option));
  6.   switch (option) {
  7.   case MYSQL_OPT_CONNECT_TIMEOUT:
  8.     mysql->options.connect_timeout= *(uint*) arg;
  9.     break;
  10.   /** 读超时时间 */
  11.   case MYSQL_OPT_READ_TIMEOUT:
  12.     mysql->options.read_timeout= *(uint*) arg;
  13.     break;
  14.   case MYSQL_OPT_WRITE_TIMEOUT:
  15.     mysql->options.write_timeout= *(uint*) arg;
  16.     break;
  17.   case MYSQL_OPT_COMPRESS:
  18.     mysql->options.compress= 1;
  19.  
  20.    /* 以下省略 */

但是, 可惜的是, 目前只有mysqli扩展, 把mysql_options完全暴露给了PHP:

  1. PHP_FUNCTION(mysqli_options)
  2. {
  3.  /** 有省略 */
  4.      switch (Z_TYPE_PP(mysql_value)) {
  5.         /** 没有任何限制, 直接传递给mysql_options */
  6.         case IS_STRING:
  7.             ret = mysql_options(mysql->mysql, mysql_option, Z_STRVAL_PP(mysql_value));
  8.             break;
  9.         default:
  10.             convert_to_long_ex(mysql_value);
  11.             l_value = Z_LVAL_PP(mysql_value);
  12.             ret = mysql_options(mysql->mysql, mysql_option, (char *)&l_value);
  13.             break;
  14.     }
  15.  
  16.     RETURN_BOOL(!ret);
  17. }

但是因为Mysqli并没有导出这个常量, 所以我们需要通过查看MySQL的代码, 得到MYSQL_OPT_READ_TIMEOUT的实际值, 然后直接调用mysql_options:

  1. enum mysql_option
  2. {
  3.   MYSQL_OPT_CONNECT_TIMEOUT, MYSQL_OPT_COMPRESS, MYSQL_OPT_NAMED_PIPE,
  4.   MYSQL_INIT_COMMAND, MYSQL_READ_DEFAULT_FILE, MYSQL_READ_DEFAULT_GROUP,
  5.   MYSQL_SET_CHARSET_DIR, MYSQL_SET_CHARSET_NAME, MYSQL_OPT_LOCAL_INFILE,
  6.   MYSQL_OPT_PROTOCOL, MYSQL_SHARED_MEMORY_BASE_NAME, MYSQL_OPT_READ_TIMEOUT,
  7.   MYSQL_OPT_WRITE_TIMEOUT, MYSQL_OPT_USE_RESULT,
  8.   MYSQL_OPT_USE_REMOTE_CONNECTION, MYSQL_OPT_USE_EMBEDDED_CONNECTION,
  9.   MYSQL_OPT_GUESS_CONNECTION, MYSQL_SET_CLIENT_IP, MYSQL_SECURE_AUTH,
  10.   MYSQL_REPORT_DATA_TRUNCATION, MYSQL_OPT_RECONNECT,
  11.   MYSQL_OPT_SSL_VERIFY_SERVER_CERT
  12. };

可以看到, MYSQL_OPT_READ_TIMEOUT为11.

现在, 我们就可以设置查询超时了:

  1. <?php
  2. $mysqli = mysqli_init();
  3. $mysqli->options(11 /*MYSQL_OPT_READ_TIMEOUT*/, 1);
  4. $mysql->real_connect(***);

不过, 因为在libmysql中有重试机制(尝试一次, 重试俩次), 所以, 最终我们设置的超时阈值都会三倍于我们设置的值.

也就是说, 如果我们设置了MYSQL_OPT_READ_TIMEOUT为1, 最终会在3s以后超时结束. 也就是说, 我们目前能设置的最短超时时, 就是3秒…

虽说大了点,, 不过总比没有好, 呵呵

PS: 写了一半的时候, 就发现小黑已经写过一篇了, 所以大家也可以参看这篇PHP访问MySQL查询超时处理

 

原文地址:http://www.laruence.com/2011/04/27/1995.html

posted on   咚..咚  阅读(2008)  评论(0编辑  收藏  举报

编辑推荐:
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 记一次.NET内存居高不下排查解决与启示
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· .NET10 - 预览版1新功能体验(一)
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

导航

统计

点击右上角即可分享
微信分享提示