J'ai actuellement plus de 100 connexions en état de veille.
Certaines connexions doivent rester en état de veille (et ne pas fermer) car il s'agit d'une connexion permanente, mais d'autres (avec un nom d'utilisateur différent) proviennent d'un script php et je souhaite qu'elles expirent très rapidement.
Est-il possible de configurer un wait_timeout par utilisateur? et si oui, comment?
Il n'y a pas de configuration de délai d'attente par utilisateur, mais vous pouvez définir la valeur wait_timeout
de manière dynamique. C'est-à-dire qu'après avoir établi une connexion en tant qu'utilisateur donné, vous pouvez émettre une instruction pour modifier la valeur du délai d'attente en la définissant comme vous le souhaitez pour la session de cet utilisateur.
Essayez l'expérience suivante dans le client en ligne de commande mysql:
mysql> SHOW VARIABLES LIKE 'wait_timeout';
... indique 28800 (soit 8 heures), qui correspond au wait_timout
par défaut.
mysql> SET SESSION wait_timeout = 60;
mysql> SHOW VARIABLES LIKE 'wait_timeout';
... montre 60.
Ensuite, vous pouvez quitter la session, vous reconnecter et encore une fois, le wait_timeout
par défaut est 28800. Il est donc limité à la portée de la session en cours.
Vous pouvez également ouvrir une seconde fenêtre et démarrer une session client mysql distincte pour prouver que la modification du wait_timeout
au cours d'une session n'affecte pas les autres sessions simultanées.
Vous devez définir les variables suivantes dans votre my.conf
:
[mysqld]
interactive_timeout=180
wait_timeout=180
wait_timeout
est un délai d'attente pour les connexions automatisées ( à mon avis, plus de 30 sur un serveur Web, c'est trop ).interactive_timeout
est un délai d’interaction de la console pour une session inactive.
Une autre possibilité: MySQL prend en charge deux variables de délai d'expiration différentes, wait_timeout
pour les clients non interactifs et interactive_timeout
pour les clients interactifs.
La différence entre les clients interactifs et non interactifs semble être simplement le fait que vous ayez spécifié l'option CLIENT_INTERACTIVE
lors de la connexion.
Je ne sais pas si cela vous aide, car vous devez faire en sorte que mysql_real_connect()
transmette cette option dans son paramètre client_flag
. Je ne suis pas sûr de la langue ou de l'interface que vous utilisez, donc je ne sais pas si cela vous permet de spécifier cet indicateur de connexion.
Quoi qu'il en soit, si vous pouvez passer cet indicateur de client et que vous n'avez besoin que de deux types d'utilisateurs différents, vous pouvez configurer wait_timeout
et interactive_timeout
différemment dans la configuration du serveur MySQL, puis utiliser celui avec la valeur la plus courte pour définir une session donnée. sortir rapidement.
Si vous utilisez Connector/J , vous pouvez utiliser sessionVariables dans l'URL JDBC du client, comme suit: jdbc:mysql://hostname:3306/schema?sessionVariables=wait_timeout=600
D'autres connecteurs pour d'autres langues permettront probablement la même chose.
J'ai vérifié la table mysql.user
et il ne semble pas y avoir de paramètre pour cela:
+-----------------------+-----------------------------------+------+-----+---------+-------+
| 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)
Selon que vous utilisiez MySQLi ou PDO, vos connexions PHP MySQL doivent soit raccrocher lorsque la demande le permet, soit être partagées dans un pool du processus Apache.
Par exemple, avec PDO, pour désactiver les connexions persistantes (je pense que c'est la valeur par défaut), connectez-vous à votre base de données avec:
$ pdo = new PDO ($ dsn, $ user, $ pass, Array (PDO :: ATTR_PERSISTENT => false));
Si vous voulez que vos scripts utilisent des connexions persistantes, mais que vous avez trop de connexions ouvertes dans votre base de données en mode veille, vous devriez envisager de configurer les variables MaxServers
, MaxSpareServers
, MinSpareServers
et StartServers
de votre Apache nécessaire.
http://www.percona.com/doc/percona-toolkit/2.1/pt-kill.html
Il est possible de tuer les connexions par utilisateur avec pt-kill. Vous pouvez planifier cela ou configurer un travail en arrière-plan pour le gérer.
init_connect sera exécuté chaque fois qu'un utilisateur se connectera afin que nous puissions écrire une petite instruction case et définir la valeur en fonction de l'utilisateur. Veuillez noter que init_connect ne sera pas exécuté pour le super utilisateur.
mysql> SET GLOBAL init_connect="SET @@wait_timeout = CASE WHEN CURRENT_USER() LIKE 'app1@%' THEN '30' ELSE @@wait_timeout END";