Как установить таймаут соединения в зависимости от входа пользователя в MySQL
У меня в настоящее время более 100 подключений в режиме сна.
Некоторое соединение должно оставаться в состоянии сна (и не закрываться), потому что это постоянное соединение, но некоторые другие (с другим именем пользователя) относятся к некоторым php script, и я хочу, чтобы они были очень быстрыми.
Можно ли настроить wait_timeout для каждого пользователя? и если да, то как?
Ответы
Ответ 1
Нет никакой конфигурации тайм-аута для каждого пользователя, но вы можете установить значение 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
в одном сеансе не влияет на другие параллельные сеансы.
Ответ 2
Вы должны установить следующие переменные в my.conf
:
[mysqld]
interactive_timeout=180
wait_timeout=180
wait_timeout
- это таймаут для автоматизированных подключений (по моему мнению, более 30 на веб-сервере слишком много).
interactive_timeout
- время ожидания взаимодействия консоли для сеанса бездействия.
Ответ 3
Другая возможность: MySQL поддерживает две разные переменные таймаута, wait_timeout
для неинтерактивных клиентов и interactive_timeout
для интерактивных клиентов.
Разница между интерактивными и неинтерактивными клиентами, по-видимому, проста: вы указали опцию CLIENT_INTERACTIVE
при подключении.
Я не знаю, поможет ли это вам, потому что вам нужно как-то сделать mysql_real_connect()
передать эту опцию в параметре client_flag
. Я не уверен, какой язык или интерфейс вы используете, поэтому я не знаю, разрешает ли вам указывать этот флаг соединения.
В любом случае, если вы можете передать этот флаг клиента, и вам нужны только два разных типа пользователей, тогда вы можете настроить wait_timeout
и interactive_timeout
по-разному в конфигурации сервера MySQL, а затем использовать тот, который имеет более короткое значение, когда вы хотите, чтобы данный сеанс быстро выходил из строя.
Ответ 4
Если вы используете Connector/J, вы можете использовать sessionVariables в URL-адресе JDBC клиента так: jdbc:mysql://hostname:3306/schema?sessionVariables=wait_timeout=600
Другие соединители для других языков, вероятно, позволят использовать те же самые.
Ответ 5
Я проверил таблицу 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 = > false));
Если вы хотите, чтобы ваши скрипты использовали постоянные подключения, но у вас слишком много подключений, открытых для вашей базы данных в спящем режиме, вы должны подумать о настройке своих Apache MaxServers
, MaxSpareServers
, MinSpareServers
и StartServers
, поэтому что не так много вокруг, когда они не нужны.
Ответ 6
http://www.percona.com/doc/percona-toolkit/2.1/pt-kill.html
Можно убить соединения для каждого пользователя с помощью pt-kill. Вы можете запланировать это или настроить фоновое задание, чтобы справиться с этим.
Ответ 7
init_connect будет выполняться всякий раз, когда пользователь входит в систему, поэтому мы можем написать небольшой оператор case и установить значение на основе пользователя. Обратите внимание, что init_connect не будет выполнен для суперпользователя.
mysql> SET GLOBAL init_connect="SET @@wait_timeout = CASE WHEN CURRENT_USER() LIKE '[email protected]%' THEN '30' ELSE @@wait_timeout END";