Как настроить таймаут соединения в зависимости от логина пользователя в MySQL
Вопрос
В настоящее время у меня более 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
- это тайм-аут для автоматических подключений (на мой взгляд, более 30 на веб-сервере - это слишком много ).
interactive_timeout
- это тайм-аут взаимодействия с консолью для неактивного сеанса.
Еще одна возможность: MySQL поддерживает две разные переменные тайм-аута: wait_timeout
для неинтерактивных клиентов и interactive_timeout
для интерактивных клиентов.
Разница между интерактивными и неинтерактивными клиентами заключается в том, что вы указали параметр CLIENT_INTERACTIVE
при подключении.
Я не знаю, поможет ли это вам, потому что вам нужно как-то заставить mysql_real_connect ()
передать эту опцию в свой параметр client_flag
. Я не уверен, какой язык или интерфейс вы используете, поэтому я не знаю, позволяет ли вам указать этот флаг подключения. Р>
В любом случае, если вы можете передать этот флаг клиента и вам нужны только два разных типа пользователей, то вы можете настроить wait_timeout
и interactive_timeout
по-разному в конфигурации сервера MySQL, а затем используйте тот, который имеет более короткое значение, если вы хотите, чтобы время для данного сеанса истекло.
Если вы используете Connector / J , вы можете использовать sessionVariables в URL-адресе JDBC клиента следующим образом: jdbc: mysql: // имя хоста: 3306 / схема? sessionVariables = wait_timeout = 600
р>
Другие соединители для других языков, вероятно, позволят то же самое.
init_connect будет выполняться всякий раз, когда пользователь входит в систему, поэтому мы можем написать небольшой оператор case и установить значение на основе пользователя.Обратите внимание, что init_connect не будет выполняться для суперпользователя.
mysql> SET GLOBAL init_connect="SET @@wait_timeout = CASE WHEN CURRENT_USER() LIKE 'app1@%' THEN '30' ELSE @@wait_timeout END";
Я проверил таблицу 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 = новый PDO ($ dsn, $ user, $ pass, Array (PDO :: ATTR_PERSISTENT = > false));
Если вы хотите, чтобы ваши сценарии использовали постоянные соединения, но у вас слишком много соединений, открытых к вашей базе данных в спящем режиме, вам следует подумать о настройке MaxServers
, MaxSpareServers
, MinSpareServers
и StartServers
, чтобы не так много зависало, когда они не нужны.
http://www.percona.com/doc/ Percona-инструментарий / 2,1 / PT-kill.html р>
С помощью pt-kill можно уничтожать соединения для каждого пользователя. Вы можете запланировать это или настроить фоновое задание, чтобы справиться с этим. Р>