web-dev-qa-db-fra.com

MySQL: Impossible de créer / écrire dans le fichier '/tmp/#sql_3c6_0.MYI' (Errcode: 2) - Qu'est-ce que cela signifie même?

Pour une raison quelconque, ma base de production a décidé de diffuser ce message. Tous les appels d'application échouent vers la base de données avec l'erreur suivante:

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 même. 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. Quelqu'un en at-il entendu parler ou a-t-il vu cette erreur? Quel pourrait être le problème et certaines choses possibles à regarder?

La base de données MySQL semble être opérationnelle et peut être interrogée via la console, mais l'application ne semble pas pouvoir y accéder. Aucune modification n'a été apportée au code/aux fichiers de l'application. C'est arrivé tout seul. Donc, je ne sais même pas par où commencer ni quelles tactiques de résolution appliquer. Des idées?

41
PhD

Cela signifie souvent que votre partition /tmp Est saturée d'espace disque et que le fichier ne peut pas être créé. Pour une raison quelconque, le processus mysqld ne peut pas écrire dans ce répertoire en raison de problèmes d'autorisations. C'est parfois le cas lorsque selinux pleut sur votre défilé.

Toute opération nécessitant un "fichier temporaire" sera placée par défaut dans le répertoire /tmp. Le nom que vous voyez est juste un nom interne aléatoire.

19
tadman

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

Je l'ai googlé, et trouver un moyen de résoudre ce problème.

Peut-être que cela vous aidera aussi.

  1. vérifiez la configuration de mysql: my.cnf

     cat /etc/my.cnf | grep tmpdir
    

    Je ne vois rien dans mon my.cnf

  2. ajouter tmpdir=/tmp à my.cnf en dessous de [mysqld]

  3. redémarrez web/app et le serveur mysql

    /etc/init.d/mysqld restart

36
Rivsen

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

156 129 8: 1/tmp/systemd-espace-noms-AN7vo9/privé/tmp RW, relatime - ext4/dev/sda1 RW, seclabel, data = en ordre

Cela signifie qu'un dossier temporaire/tmp/systemd-namespace-AN7vo9/private est monté en tant que/tmp dans l'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 motif d'exclusion -X '/tmp/systemd-namespace*' comme ça:

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

16
ArturZ

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.

Cependant, 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 avec MySQL et j’ai aidé un client qui avait des erreurs de disque saturées par intermittence sur sa partition racine, même si chaque fois qu’il regardait, il avait environ 6 Go disponibles. Après avoir examiné ses journaux de requêtes, nous avons découvert qu'il exécutait parfois plusieurs requêtes simultanément, chacune créant une table temporaire de 1,5 Go dans/tmp, qui se trouvait sur sa partition racine. Boom!

Les solutions que je lui ai données:

  • Augmenter 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 de permettre à MySQL de créer des tables temporaires de 1,5 Go en mémoire, car il n’ya 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 dans un répertoire situé sur une autre partition de disque disposant de plus d’espace.

  • Déterminez laquelle de vos requêtes crée de telles tables temporaires et optimisez-la. Par exemple, utilisez des index pour aider cette requête à réduire son analyse à une plus petite tranche de la table. Ou bien archivez certaines des données du récit pour que la requête ne contienne plus autant de lignes à analyser.

13
Bill Karwin

Grand merci à ArturZ de m'avoir orienté dans la bonne direction à ce sujet. 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 qu'il appelle 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. CLONE_NEWNS ayant été défini dans le n ° 1, ce point de montage est invisible pour tous les processus.

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

  4. Certaines opérations de base de données spécifiques (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. D'autres opérations de base de données s'exécutent sans utiliser/tmp.

  5. Au bout de 10 jours, même si la base de données elle-même reste 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, rendant effectivement le fichier privé/tmp inutilisable pour mysqld alors que le fichier public/tmp reste disponible pour tout le reste du système.

Redémarrer mysqld fonctionne parce que tout recommence à l’étape 1 avec un tout nouveau répertoire privé/tmp. Cependant, le problème finit par revenir. Et encore.

La solution simple consiste à configurer/bin/systemd-tmpfiles de manière à préserver tout élément de/tmp portant 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.

13
Thomas Dwyer III

Pour moi, ce problème est survenu après une longue période de non utilisation de mysql ni du serveur web. Donc j'étais sûr que mes réglages étaient corrects; Le simple redémarrage du service résout ce problème. La partie étrange sur le problème est que l'on peut toujours se connecter à la base de données, et même interroger/ajouter 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, l’une de ces commandes doit redémarrer le service.

6
SvennD
5
Ranjith Siji

c'est très simple, vous accordez simplement le dossier/tmp avec l'autorisation 777. il suffit de taper:

chmod -R 777 /tmp
3
Ken Yang

Sur Debian 7.5, j'ai la même erreur. J'ai réalisé le /tmp propriétaire du dossier et les autorisations étaient désactivées. Comme une autre réponse suggérée j'ai fait comme suit (doit être la racine):

chown root:root /tmp && chmod 1777 /tmp

Je n'ai même pas eu à redémarrer le démon mysql.

2
Abner

Sur une boîte Ubuntu, j'ai commencé à avoir cette erreur après avoir déplacé/tmp vers un autre volume (lien symbolique). Même après avoir défini l'autorisation requise 1777, le problème n'a pas été résolu.

MySQL est protégé par AppArmor, qui interdisait les écritures dans le nouvel emplacement tmp/mnt/tmp. J'ai dû ajouter les lignes suivantes à /etc/apparmor.d/abstractions/user-tmp pour résoudre ce problème.

propriétaire/mnt/tmp/** rwkl,

/ mnt/tmp/rw,

2
krishnakumarp

En raison des politiques de sécurité du contrôle d'accès, en particulier lorsque SELinux est activé, il ne permet pas aux exécutables externes de créer des fichiers temporaires dans les emplacements système.

Désactivez SELinux en lançant la commande ci-dessous:

echo 0>/selinux/enforce

Vous pouvez maintenant lancer mysql, il ne donnera aucune erreur liée à la permission lors de la lecture/écriture dans/tmp ou dans les répertoires système.

Si vous souhaitez activer la sécurité SELinux, changez la commande 0 à 1 dans la commande ci-dessus.

1
Shoaib Khan

Vérifiez les problèmes de permission, mysql config.

Vérifiez également si vous n'avez pas atteint l'espace disque, les limites de quota.

Remarque: Certains systèmes limitent le nombre de fichiers (pas seulement l'espace), la suppression d'anciens fichiers de session a permis de résoudre le problème dans mon cas.

0
takeshin

J'utilise mariadb. Quand j'essaie de mettre cette ligne à /etc/my.cnf:

[mysqld]
tmpdir=/tmp 

Il a résolu l'erreur générée par l'interface Web liée à/tmp. Mais, il a un problème d’arrière-plan avec/tmp. Exemple, lorsque je tente de reconstruire mariadb à partir du backend, il ne peut pas lire le répertoire/tmp et génère ensuite une erreur similaire.

mysqldump: Couldn't execute 'show fields from `wp_autoupdate`': Can't create/write to file '/tmp/#sql_1680_0.MAI' (Errcode: 2 "No such file or directory") (1)

Donc, celui-ci fonctionne pour les deux front-end et back-end:

1. Mkdir/var/lib/mysql/tmp

2. Chmod mysql: mysql/var/lib/mysql/tmp

. Ajoutez la ligne suivante dans la section [mysqld]:

    tmpdir = /var/lib/mysql/tmp

4. Redémarrez mysqld (par exemple, Centos7: systemctl redémarrer mysqld)

0
MaXi32