题
我目前有超过100个处于睡眠状态的连接。
某些连接必须保持睡眠状态(并且不要关闭),因为它是永久连接,但是其他一些(具有不同的用户名)来自某些PHP脚本,我希望它们能够非常快地超时。
是否可以为每个用户设置wait_timeout?如果是的话,怎么样?
解决方案
没有每用户超时配置,但您可以动态设置 wait_timeout
值。也就是说,在您作为给定用户建立连接后,您可以发出一个语句,将超时值更改为您希望该用户会话的超时值。
在mysql命令行客户端中尝试以下实验:
mysql> SHOW VARIABLES LIKE 'wait_timeout';
...显示28800(即8小时),这是默认的 wait_timout
。
mysql> SET SESSION wait_timeout = 60;
mysql> SHOW VARIABLES LIKE 'wait_timeout';
...显示60。
然后你可以退出会话,重新连接,然后默认的 wait_timeout
是28800.所以它仅限于当前会话的范围。
您还可以打开第二个窗口并启动单独的mysql客户端会话,以证明在一个会话中更改 wait_timeout
不会影响其他并发会话。
其他提示
您应该在 my.conf
中设置以下变量:
[mysqld]
interactive_timeout=180
wait_timeout=180
wait_timeout
是自动连接的超时(我认为在Web服务器上超过30个)。
interactive_timeout
是空闲会话的控制台交互超时。
另一种可能性:MySQL支持两种不同的超时变量,非交互式客户端的 wait_timeout
,以及交互式客户端的 interactive_timeout
。
交互式和非交互式客户端之间的区别似乎只是在连接时是否指定了 CLIENT_INTERACTIVE
选项。
我不知道这是否对您有所帮助,因为您需要以某种方式使 mysql_real_connect()
在其 client_flag
参数中传递该选项。我不确定你使用的是哪种语言或界面,所以我不知道它是否允许你指定这个连接标志。
无论如何,如果您可以传递该客户端标志,并且您只需要两种不同类型的用户,那么您可以在MySQL服务器配置中以不同方式配置 wait_timeout
和 interactive_timeout
,如果希望给定的会话及时超时,请使用值较短的值。
如果您使用 Connector / J ,您可以在客户端的JDBC URL中使用 sessionVariables ,如下所示: jdbc:mysql:// hostname:3306 / schema?sessionVariables = wait_timeout = 600
其他语言的其他连接器可能会允许相同的。
每当用户登录时都会执行init_connect,因此我们可以编写小案例语句并根据用户设置值。请注意,超级用户不会执行init_connect。
<代码>的MySQL&GT; SET GLOBAL init_connect =&quot; SET @@ wait_timeout = CASE WHEN CURRENT_USER()LIKE'app1 @%'THEN'30'ELSE @@ wait_timeout END&quot;;
我检查了 mysql.user
表,看起来没有设置它:
+-----------------------+-----------------------------------+------+-----+---------+-------+
| Field | Type | Null | Key | Default | Extra |
+-----------------------+-----------------------------------+------+-----+---------+-------+
| Host | char(60) | NO | PRI | | |
| User | char(16) | NO | PRI | | |
| Password | char(41) | NO | | | |
| Select_priv | enum('N','Y') | NO | | N | |
| Insert_priv | enum('N','Y') | NO | | N | |
| Update_priv | enum('N','Y') | NO | | N | |
| Delete_priv | enum('N','Y') | NO | | N | |
| Create_priv | enum('N','Y') | NO | | N | |
| Drop_priv | enum('N','Y') | NO | | N | |
| Reload_priv | enum('N','Y') | NO | | N | |
| Shutdown_priv | enum('N','Y') | NO | | N | |
| Process_priv | enum('N','Y') | NO | | N | |
| File_priv | enum('N','Y') | NO | | N | |
| Grant_priv | enum('N','Y') | NO | | N | |
| References_priv | enum('N','Y') | NO | | N | |
| Index_priv | enum('N','Y') | NO | | N | |
| Alter_priv | enum('N','Y') | NO | | N | |
| Show_db_priv | enum('N','Y') | NO | | N | |
| Super_priv | enum('N','Y') | NO | | N | |
| Create_tmp_table_priv | enum('N','Y') | NO | | N | |
| Lock_tables_priv | enum('N','Y') | NO | | N | |
| Execute_priv | enum('N','Y') | NO | | N | |
| Repl_slave_priv | enum('N','Y') | NO | | N | |
| Repl_client_priv | enum('N','Y') | NO | | N | |
| Create_view_priv | enum('N','Y') | NO | | N | |
| Show_view_priv | enum('N','Y') | NO | | N | |
| Create_routine_priv | enum('N','Y') | NO | | N | |
| Alter_routine_priv | enum('N','Y') | NO | | N | |
| Create_user_priv | enum('N','Y') | NO | | N | |
| ssl_type | enum('','ANY','X509','SPECIFIED') | NO | | | |
| ssl_cipher | blob | NO | | | |
| x509_issuer | blob | NO | | | |
| x509_subject | blob | NO | | | |
| max_questions | int(11) unsigned | NO | | 0 | |
| max_updates | int(11) unsigned | NO | | 0 | |
| max_connections | int(11) unsigned | NO | | 0 | |
| max_user_connections | int(11) unsigned | NO | | 0 | |
+-----------------------+-----------------------------------+------+-----+---------+-------+
37 rows in set (0.00 sec)
根据您使用的是MySQLi还是PDO,您的PHP MySQL连接应该在请求时挂起,或者在Apache进程的池中共享。
例如,使用PDO,要关闭持久连接(我认为这是默认设置),请使用以下命令连接到您的数据库:
$ pdo = new PDO($ dsn,$ user,$ pass,Array(PDO :: ATTR_PERSISTENT =&gt; false));
如果您希望脚本使用持久连接,但在睡眠模式下有太多连接打开数据库,则应考虑配置Apache的 MaxServers
, MaxSpareServers
, MinSpareServers
和 StartServers
,以便在不需要时不会那么多。
http://www.percona.com/doc/的Percona的工具包/ 2.1 / PT-kill.html
可以使用pt-kill杀死每个用户的连接。您可以安排此操作或设置后台作业来处理此问题。