Le WordPress d'aujourd'hui, décodé pour les développeurs

Hébergement & serveurs

« 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.

Par WordPress Développement • 31 janvier 2023 • 4 min de lecture • Aucun commentaire
« error: too many open files » côté MySQL cette fois, pas côté PHP-FPM

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.

Laisser un commentaire

Votre adresse e-mail ne sera pas publiée. Les champs obligatoires sont indiqués avec *

Partager :

À propos de l'auteur

WordPress Développement

Développeur WordPress, passionné par Elementor, le FSE et l’automatisation par IA.

Voir tous ses articles

Dans la même veine

À lire aussi