# « error: too many open files » côté MySQL cette fois, pas côté PHP-FPM

> Le réglage ulimit du système avait déjà été corrigé une première fois pour PHP-FPM. MySQL, lui, gère son propre plafond de descripteurs, indépendamment du système.

- Auteur : WordPress Développement
- Publié le : 2023-01-31
- Mis à jour le : 2023-01-31
- Catégorie : Hébergement &amp; serveurs
- URL : https://www.wpmoderne.fr/hebergement/too-many-open-files-mysql-descripteurs/

## L’essentiel

- MySQL fixe son propre plafond via la variable open_files_limit
- ce plafond peut rester bas même après correction du ulimit système
- un plafond insuffisant se traduit par des tables qui refusent de s'ouvrir

`ERROR 24 (HY000) at line 1: Too many open files (errno: 24)`. Ce message, remonté cette fois directement par le client MySQL lors d'une requête sur une base volumineuse, ressemble à s'y méprendre à l'incident déjà résolu quelques mois plus tôt sur ce même serveur, où PHP-FPM saturait ses propres descripteurs de fichiers sous forte charge.

Ce billet documente pourquoi la correction déjà appliquée au niveau du système, via le `ulimit` global, n'a eu aucun effet sur ce nouveau plantage : MySQL gère son propre plafond de descripteurs de fichiers ouverts, indépendamment de la limite système, et ce plafond doit être ajusté séparément.

## Le symptôme : un plantage identique en apparence, différent en cause

Le message d'erreur affiché côté client MySQL mentionne le même code d'erreur système, `errno 24`, que celui déjà rencontré côté PHP-FPM. Cette similitude a d'abord orienté le diagnostic vers une régression du réglage système déjà corrigé : la commande `ulimit -n` exécutée dans un terminal confirmait pourtant une limite correctement relevée à 65 535 descripteurs pour l'utilisateur système concerné.

Le plantage survenait précisément lors de requêtes touchant un grand nombre de tables simultanément, sur une base WordPress multisite comportant plusieurs centaines de tables distinctes (une conséquence directe de l'architecture multisite, qui duplique un jeu de tables par sous-site).

## Diagnostic : MySQL fixe son propre plafond, séparé du système

MySQL dispose d'une variable système dédiée, `open_files_limit`, qui détermine combien de descripteurs de fichiers le processus `mysqld` peut ouvrir simultanément, indépendamment de la limite système générale que `ulimit` configure pour l'ensemble des processus de l'utilisateur.

```
mysql> SHOW VARIABLES LIKE 'open_files_limit';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| open_files_limit | 1024  |
+------------------+-------+
```

La valeur affichée, 1024, correspondait à une valeur historique héritée d'une installation ancienne du paquet MySQL sur cette distribution, jamais relevée depuis. Ce plafond, largement suffisant pour une base WordPress classique à quelques dizaines de tables, devenait clairement insuffisant face à une base multisite comptant plusieurs centaines de tables ouvertes simultanément lors de requêtes transversales.

> L'essentiel à retenir : MySQL fixe son propre plafond via la variable open_files_limit ; ce plafond peut rester bas même après correction du ulimit système ; un plafond insuffisant se traduit par des tables qui refusent de s'ouvrir

## Le correctif : ajuster open_files_limit dans la configuration MySQL

Le correctif consiste à relever explicitement cette variable dans le fichier de configuration de MySQL, généralement `/etc/mysql/mysql.conf.d/mysqld.cnf` selon la distribution utilisée, avant de redémarrer le service pour que la nouvelle valeur soit prise en compte.

```
[mysqld]
open_files_limit = 20000
```

Un point de vigilance mérite d'être signalé : la valeur effectivement appliquée par MySQL au démarrage reste plafonnée par la limite système du processus qui le lance, généralement gérée par le service `systemd`. Sur les distributions récentes, la directive `LimitNOFILE` du fichier d'unité `systemd` du service MySQL doit donc, elle aussi, autoriser une valeur au moins égale à celle demandée dans `mysqld.cnf`, sans quoi MySQL applique silencieusement une valeur inférieure à celle configurée.

```
# /etc/systemd/system/mysql.service.d/override.conf
[Service]
LimitNOFILE=24000
```

## Vérification après redémarrage du service

- Relancer `SHOW VARIABLES LIKE 'open_files_limit';` après redémarrage et confirmer que la nouvelle valeur est bien appliquée, et non silencieusement plafonnée.
- Consulter le journal d'erreurs MySQL au démarrage, qui signale explicitement si la valeur demandée dépasse la limite autorisée par le système, avec la valeur réellement retenue à la place.
- Rejouer, en environnement de test, la requête transversale qui avait initialement déclenché l'erreur, afin de confirmer que le plafond relevé suffit désormais à la charge réelle observée.

## Prévention : ne pas confondre les deux plafonds à l'avenir

Cet incident illustre un principe qui dépasse le seul cas de MySQL : sur un serveur exécutant plusieurs services distincts (PHP-FPM, MySQL, serveur web), chaque service peut appliquer son propre plafond de descripteurs de fichiers, en plus de la limite système générale. Corriger l'un ne corrige jamais automatiquement l'autre.

> Un même message d'erreur système peut avoir des causes distinctes selon le service qui l'affiche ; vérifier systématiquement si le service concerné dispose de son propre réglage avant de supposer que la limite déjà corrigée ailleurs s'applique de la même façon ici.

## En résumé

Le réglage `ulimit` du système ne suffit pas toujours à éliminer les erreurs de descripteurs de fichiers ouverts : MySQL, via sa variable `open_files_limit`, maintient son propre plafond, lui-même conditionné par la configuration `systemd` du service. Corriger l'un sans vérifier l'autre laisse le problème intact, malgré une correction en apparence déjà appliquée au niveau du système.
