【问题标题】:How to set a timeout for MySQL query using C API如何使用 C API 为 MySQL 查询设置超时
【发布时间】:2011-05-14 08:01:49
【问题描述】:

我知道这里有很多类似的问题,也有很多结果,当我用谷歌搜索时,但没有一个回答我的问题。我读过thisthisthisthis,但它们都不适合我。我不谈论任何锁,我不想使用 MySQL c++ 连接器来做到这一点,只是 C API。

此外,这里非常重要的是:我在 LINUX 上执行此操作。为什么我提到这个?因为在 mysql_options 的文档中:

MYSQL_OPT_READ_TIMEOUT - ...此选项仅适用于
TCP/IP 连接,在 MySQL 5.0.25 之前,仅适用于 Windows。

MYSQL_OPT_WRITE_TIMEOUT- ...此选项仅适用于
TCP/IP 连接,在 MySQL 5.0.25 之前,仅适用于 Windows

那么,有没有办法为 5.0.25 之前的版本设置查询超时?

我的 MySQL 版本:

[root@xxx kiril]# mysql --version
mysql Ver 14.12 Distrib 5.0.22,用于 redhat-linux-gnu (i686) 使用 readline 5.0

编辑:至少,有什么方法可以取消查询吗?我可以将计时器作为不同的线程启动,但是当它到期时……我可以以某种方式取消查询吗?

【问题讨论】:

  • 你使用的是什么 MySQL 版本?
  • @Kiril Kirov - 您可以在 mysql 中使用 kill 命令终止正在运行的查询 - dev.mysql.com/doc/refman/5.0/en/kill.html
  • @ajreal - 谢谢!我试试看
  • @Kiril Kirov - PS:不要杀死写入命令,它会损坏您的数据表

标签: c++ mysql c api


【解决方案1】:

我从未尝试过这样做,但我一直在阅读,我认为这可能意味着 MYSQL_OPT_WRITE_TIMEOUT 和 MYSQL_OPT_READ_TIMEOUT 仅适用于 MySQL 5.0.25 之前的 Windows,但现在应该适用于每个 TCP/IP 连接。采取look here

问候

编辑:我会尝试将我的 mysql 服务器更新到较新的版本并尝试它是否有效。

【讨论】:

  • 请放在上面的cmets下,OP已经清楚地说明了他的问题
  • 这篇文章(链接)所说的唯一内容是文档中的引用,与我在帖子中发布的内容完全相同。
  • 对不起,这件事我已经尽力了。
【解决方案2】:

我想您可以为 C 函数调用实现超时(如该线程 C++: How to implement a timeout for an arbitrary function call? 中所述),但您需要仔细考虑将数据库置于何种状态 - 大概这些只是为了读取数据库,而不是插入/更新。

【讨论】:

  • 我在 OCCI 上遇到过类似的问题,并且通过这种方式“解决”了 - 使用计时器。但是那里的问题更大 - 所以,当计时器到期时,我打电话给exit(1);(我知道,这很糟糕,但没有找到其他解决方案,即使是 Oracle 的开发人员也帮不上忙)。无论如何,这是一个糟糕的解决方案,我正在寻找一个更智能的解决方案。无论如何感谢您的想法(Y)
  • 我认为这是在不锁定的情况下处理外部资源的一般方式。如果操作系统没有内置该功能,这基本上就是处理任何阻塞资源调用的方式。请参阅套接字编程。
【解决方案3】:

如果您不介意使用线程,您可以从一个新线程开始查询,并让主线程为新线程执行一个简短的pthread_cond_timedwait,以设置它建立连接的条件变量。然后你可以让线程徘徊,直到实际的 mysql 调用超时。只要确保它是分离的,这样当它最终超时时它的资源就会被释放。这个解决方案并不漂亮,但至少应该可以工作。

【讨论】:

  • 我不能对每个查询都这样做,因为这会减慢应用程序的工作速度,这应该每秒处理 1000 多条消息。还是谢谢
  • 这不应该是每秒 1000 个线程的性能问题,但是如果它们不快速退出,您可能会很快耗尽内核资源来创建那么多线程。 :(
【解决方案4】:

好的,我找到了解决方案。感谢WillPRR(我的同事)。

不能在每个查询上启动一个新线程,因为这是一个实时应用程序,它应该每秒处理 1000 多条消息..(无论如何,感谢R..这个想法)。

此外,无法通过库终止连接,也无法取消/终止查询,因为问题出在数据库服务器中..

这是一个蛮力解决方案,但仍然比_EXIT( FAILURE ) 好得多:这是相关问题:"How to force closing socket on Linux?" - 所以,我只是使用系统调用关闭了套接字。

重要提示:(感谢 Will)- 结果表明,我们的 MySQL 库包装器具有“故障安全”标志,因此在关闭套接字(或其他严重错误)时,它会尝试来“解决”问题,因此在我的情况下,它会自行重新打开套接字。所以,我刚刚关闭了这个选项,现在一切都很好 - 执行因异常而终止 - 这是执行此操作的“最软”方式。
当然,这应该通过另一个线程来完成 - 例如计时器。

编辑:超时确实适用于 5.0.25 之后的版本。但是,至少在 RHEL4 和 RHEL5 上,由于某种原因,超时时间增加了三倍!例如,如果某些超时设置为 20 秒,则实际超时约为 60 秒。
此外,另一个重要的事情是,这些超时(与任何其他选项一样)必须设置为 after mysql_initbefore mysql_connectmysql_real_connect

【讨论】:

  • 来自 MYSQL_OPT_READ_TIMEOUT_DOCS:“每次尝试从服务器读取的超时时间(以秒为单位)。必要时会重试,因此总有效超时值是选项值的三倍。”这就是为什么实际间隔是超时的 3 倍。
猜你喜欢
  • 2011-07-25
  • 1970-01-01
  • 1970-01-01
  • 2021-10-15
  • 1970-01-01
  • 2023-01-03
  • 1970-01-01
  • 1970-01-01
  • 2011-09-15
相关资源
最近更新 更多