MySQL: Impossible de créer / écrire dans le fichier ‘/tmp/#sql_3c6_0.MYI’ (Errcode: 2) – Que signifie-t-il même?

Pour une raison quelconque, ma firebase database de production a décidé de diffuser ce message. Tous les appels d’application échouent dans la firebase database avec l’erreur:

PreparedStatementCallback; SQL [ /*long sql statement here*/ ]; Can't create/write to file '/tmp/#sql_3c6_0.MYI' (Errcode: 2); nested exception is java.sql.SQLException: Can't create/write to file '/tmp/#sql_3c6_0.MYI' (Errcode: 2) 

Je n’ai aucune idée de ce que cela signifie. Il n’y a pas de fichier #sql_3c6_0.MYI dans /tmp et je ne peux pas en créer un avec un caractère # pour une raison quelconque. Est-ce que quelqu’un en a entendu parler ou a vu cette erreur? Qu’est-ce qui pourrait être faux et certaines choses possibles à regarder?

La firebase database MySQL semble être opérationnelle et peut être interrogée via la console, mais l’application ne semble pas pouvoir y accéder. Le code / les fichiers de l’application n’a pas été modifié. C’est juste arrivé par le bleu. Donc, je ne sais même pas par où commencer ou quelles tactiques de résolution appliquer. Des idées?

Cela signifie souvent que votre partition /tmp est à court d’espace et que le fichier ne peut pas être créé, ou pour une raison quelconque, le processus mysqld ne peut pas écrire dans ce répertoire à cause de problèmes de permission. Parfois, c’est le cas lorsque selinux pleut sur votre défilé.

Toute opération nécessitant un “fichier temporaire” ira dans le /tmp par défaut. Le nom que vous voyez est juste un nom aléatoire interne.

Je rencontre également cette erreur lorsque je lance un wordpress sur mon système Fedora.

Je l’ai googlé et j’ai trouvé un moyen de résoudre ce problème.

Peut-être que cela vous aidera aussi.

  1. vérifier mysql config: my.cnf

      cat /etc/my.cnf | grep tmpdir 

    Je ne vois rien dans my.cnf

  2. Ajouter tmpdir=/tmp à my.cnf sous [mysqld]

  3. redémarrer web / app et mysql server

    /etc/init.d/mysqld restart

Sur Fedora avec systemd MySQL obtient un répertoire privé / tmp. Dans / proc / PID_of_MySQL / mountinfo, vous trouverez la ligne comme:

156 129 8: 1 / tmp / systemd-namespace-AN7vo9 / private / tmp rw, relatime – ext4 / dev / sda1 rw, seclabel, données = ordonnées

Cela signifie qu’un dossier temporaire / tmp / systemd-namespace-AN7vo9 / private est monté en tant que / tmp dans un espace de noms privé du processus MySQL. Malheureusement, ce dossier est supprimé par tmpwatch s’il n’est pas utilisé fréquemment.

J’ai modifié /etc/cron.daily/tmpwatch et inséré le modèle d’exclusion -X '/tmp/systemd-namespace*' comme ceci:

 /usr/sbin/tmpwatch "$flags" -x /tmp/.X11-unix -x /tmp/.XIM-unix \ -x /tmp/.font-unix -x /tmp/.ICE-unix -x /tmp/.Test-unix \ -X '/tmp/systemd-namespace*' \ -X '/tmp/hsperfdata_*' 10d /tmp 

L’effet secondaire est que les dossiers d’espaces de noms privés non utilisés ne seront pas supprimés automatiquement.

Merci à ArturZ pour m’avoir orienté dans cette direction. Je n’ai pas installé tmpwatch sur mon système, ce n’est donc pas la cause du problème dans mon cas. Mais le résultat final est le même: le fichier privé / tmp créé par systemd est supprimé. Voici ce qui se passe:

  1. systemd crée un nouveau processus via clone () avec l’indicateur CLONE_NEWNS pour obtenir un espace de noms privé. Ou peut-être appelle-t-il unshare () avec CLONE_NEWNS. Même chose.

  2. systemd crée un sous-répertoire dans / tmp (par exemple / tmp / systemd-namespace-XRiWad / private) et le monte sur / tmp. Comme CLONE_NEWNS a été défini dans # 1, ce sharepoint assembly est invisible pour tous les autres processus.

  3. systemd appelle alors mysqld dans cet espace de noms privé.

  4. Certaines opérations spécifiques de la firebase database (par exemple “describe”) créent et suppriment des fichiers temporaires, ce qui a pour effet secondaire de mettre à jour l’horodatage sur / tmp / systemd-namespace-XRiWad / private. Les autres opérations de firebase database sont exécutées sans utiliser / tmp.

  5. Au bout de 10 jours, même si la firebase database elle-même rest active, aucune opération ne met à jour l’horodatage sur / tmp / systemd-namespace-XRiWad / private.

  6. / bin / systemd-tmpfiles arrive et supprime le “vieux” répertoire / tmp / systemd-namespace-XRiWad / private, ce qui rend le private / tmp inutilisable pour mysqld, alors que public / tmp rest disponible pour tout le rest du système.

Le redémarrage de mysqld fonctionne car tout recommence à l’étape 1, avec un nouveau répertoire privé / tmp. Cependant, le problème revient finalement. Et encore.

La solution simple consiste à configurer / bin / systemd-tmpfiles pour qu’il conserve tout ce qui se trouve dans / tmp sous le nom / tmp / systemd-namespace- *. Je l’ai fait en créant /etc/tmpfiles.d/privatetmp.conf avec le contenu suivant:

 x /tmp/systemd-namespace-* x /tmp/systemd-namespace-*/private 

Problème résolu.

Le nom de fichier ressemble à une table temporaire créée par une requête dans MySQL. Ces fichiers ont souvent une durée de vie très courte, ils sont créés lors d’une requête spécifique et nettoyés immédiatement après.

Pourtant, ils peuvent devenir très volumineux, en fonction de la quantité de données que la requête doit traiter dans une table temporaire. Vous pouvez également avoir plusieurs requêtes simultanées créant des tables temporaires, et si suffisamment de ces requêtes s’exécutent en même temps, elles peuvent épuiser l’espace disque.

Je fais de la consultation MySQL et j’ai aidé un client qui avait des erreurs de disque intermittentes sur sa partition racine, même si à chaque fois il avait environ 6 Go d’espace libre. Après avoir examiné ses journaux de requêtes, nous avons découvert qu’il y avait parfois quatre requêtes ou plus exécutées simultanément, chacune créant une table temporaire de 1,5 Go dans / tmp, qui se trouvait sur sa partition racine. Boom!

Des solutions que je lui ai données:

  • Augmentez les variables de configuration MySQL tmp_table_size et max_heap_table_size afin que MySQL puisse créer de très grandes tables temporaires en mémoire. Mais ce n’est pas une bonne idée d’autoriser MySQL à créer des tables temporaires de 1,5 Go en mémoire, car il n’y a aucun moyen de limiter le nombre de tables créées simultanément. Vous pouvez épuiser votre mémoire assez rapidement de cette façon.

  • Définissez la variable de configuration MySQL tmpdir sur un répertoire sur une autre partition de disque avec plus d’espace.

  • Déterminez laquelle de vos requêtes crée de telles tables temporaires et optimisez la requête. Par exemple, utilisez des index pour aider cette requête à réduire son parsing à une tranche plus petite de la table. Ou bien archivez certaines des données du conte pour que la requête n’ait pas autant de lignes à parsingr.

Pour moi, ce problème est survenu après une longue période d’utilisation de mysql et du serveur Web. Donc, j’étais sûr que mes parameters étaient corrects; Le simple redémarrage du service corrige ce problème. La partie étrange du problème est que l’on peut toujours se connecter à la firebase database, et même interroger / append des tables en utilisant l’outil mysql. par exemple :

 mysql -u root -p 

J’ai redémarré en utilisant:

 systemctl start mysqld.service 

ou service mysqld restart ou /etc/init.d/mysqld restart

Remarque: en fonction de la machine / de l’environnement de ces commandes, redémarrez le service.

c’est très facile, il vous suffit d’accorder au dossier / tmp la permission 777. il suffit de taper:

 chmod -R 777 /tmp