When is wait_timeout not wait_timeout?

Sheeri

Over the weekend I came across an extremely curious issue with MySQL. It seemed that no matter how many times I tried to set the wait_timeout, it would always show the value of interactive_timeout. I even tried restarting mysql, to no avail.

Eventually I figured it out. When I was in an *interactive session*, wait_timeout displays as the value of interactive_timeout. Otherwise, it showed the appropriate value. Here’s what I found, when interactive_timeout was set to 600 and wait_timeout was set to 14400 (this is on an analytics server, so setting the value that high actually makes sense):

[root@mysql1 ~]# mysql -e "show variables like 'interactive_timeout'"
+---------------------+-------+
| Variable_name | Value |
+---------------------+-------+
| interactive_timeout | 600 |
+---------------------+-------+

[root@mysql1 ~]# mysql -e "show variables like 'wait_timeout'"
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| wait_timeout | 14400 |
+---------------+-------+

When using non-interactive logins, like mysql -e “COMMAND”, wait_timeout has the appropriate value. However, in an interactive session, wait_timeout had the same value as interactive_timeout:

[root@mysql1 ~]# mysql
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 23814
Server version: 5.1.61-rel13.2-log Percona Server (GPL), 13.2, Revision 430

Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

mysql> show variables like 'interactive_timeout';
+---------------------+-------+
| Variable_name | Value |
+---------------------+-------+
| interactive_timeout | 600 |
+---------------------+-------+
1 row in set (0.00 sec)

mysql> show variables like 'wait_timeout';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| wait_timeout | 600 |
+---------------+-------+
1 row in set (0.00 sec)

I observed this behavior with Percona Server 5.5.21-55, and with Oracle’s MySQL 5.1.61 and 5.0.77, so it is neither a new feature, nor is it limited to Percona only.

Putting on my “reverse engineering” hat, my guess is that MySQL looks at the value of “wait_timeout” to decide when to timeout, and when you use an interactive session, wait_timeout is set to the value of interactive_timeout. In other words, I guess that interactive_timeout serves only to set wait_timeout for interactive sessions.

I am not sure if this is a bug or a feature, but I have seen plenty of these kinds of “subtle hacks” in MySQL so it would not surprise me if this is the way it was intended to work. It’s extremely confusing to figure out though, when you try to set the variable and then check it….here is one of my frustrating sessions, where the change didn’t seem to “stick”:

mysql> set global wait_timeout=14400;
Query OK, 0 rows affected (0.00 sec)

mysql> show variables like 'wait_timeout';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| wait_timeout | 600 |
+---------------+-------+
1 row in set (0.00 sec)

mysql> exit
Bye
[root@mysql1 ~]# mysql
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 23810
Server version: 5.1.61-rel13.2-log Percona Server (GPL), 13.2, Revision 430

Type 'help;' or '\h' for help. Type '\c' to clear the buffer.

mysql> show variables like 'wait_timeout';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| wait_timeout | 600 |
+---------------+-------+
1 row in set (0.00 sec)

Edited to add: – My guesses were correct! Many people have pointed out that this is a documented way that this works.