Fichier de clé MySQL incorrect pour la table tmp lors de plusieurs jointures

Je ne viens pas souvent ici pour demander de l’aide, mais je suis plutôt frustré et j’espère que quelqu’un l’a déjà rencontré.

Chaque fois que j’essaie d’extraire des enregistrements d’une table en utilisant plusieurs jointures, j’obtiens cette erreur:

#126 - Incorrect key file for table '/tmp/#sql_64d_0.MYI'; try to repair it 

Donc, cette requête produira l’erreur:

 SELECT * FROM `core_username` INNER JOIN `core_person` ON (`core_username`.`person_id` = `core_person`.`id`) INNER JOIN `core_site` ON (`core_username`.`site_id` = `core_site`.`id`) ORDER BY `core_username`.`name` ASC LIMIT 1 

Mais celui-ci ne va pas:

 SELECT * FROM `core_username` INNER JOIN `core_person` ON (`core_username`.`person_id` = `core_person`.`id`) ORDER BY `core_username`.`name` ASC LIMIT 1 

Et celui-ci non plus:

 SELECT * FROM `core_username` INNER JOIN `core_site` ON (`core_username`.`site_id` = `core_site`.`id`) ORDER BY `core_username`.`name` ASC LIMIT 1 

Qu’est-ce qui peut causer cela? Je ne sais pas vraiment comment réparer une table tmp mais je ne pense pas que ce soit le problème car il s’agit d’une nouvelle table tmp à chaque fois. La table de nom d’utilisateur est assez grande (233 718 enregistrements en ce moment) mais je doute que cela ait quelque chose à voir avec cela.

Toute aide serait très appréciée.

MISE À JOUR : Après quelques tests supplémentaires, il semble que l’erreur ne se produit que lorsque j’essaie de commander les résultats. C’est-à-dire que cette requête me donnera ce que j’attends:

 SELECT * FROM `core_username` INNER JOIN `core_person` ON (`core_username`.`person_id` = `core_person`.`id`) INNER JOIN `core_site` ON (`core_username`.`site_id` = `core_site`.`id`) LIMIT 1 

Mais si j’ajoute le:

 ORDER BY `core_username`.`name` ASC 

L’erreur est déclenchée. Cela ne se produit que sur le serveur Web spécifique que j’utilise actuellement. Si je télécharge la firebase database et essaye la même chose sur mon hôte local ainsi que sur d’autres serveurs, elle fonctionne correctement. La version de MySQL est la 5.0.77.

Sachant cela, je suis assez confiant que ce qui se passe, c’est que la table tmp créée est beaucoup trop volumineuse et que MySQL s’étouffe comme décrit dans cet article de blog . Je ne suis toujours pas sûr de la solution, bien que…

Parfois, lorsque cette erreur se produit avec les tables temporaires:

 #126 - Incorrect key file for table '/tmp/#sql_64d_0.MYI'; try to repair it 

Cela peut être dû au fait que le dossier /tmp est à court d’espace. Sur certaines installations Linux, /tmp trouve dans sa propre partition et n’a pas beaucoup d’espace – de grandes requêtes MySQL le rempliront.

Vous pouvez utiliser df -h pour vérifier si \tmp trouve dans sa propre partition et combien d’espace lui est alloué.

Si c’est dans sa propre partition et à court d’espace, vous pouvez soit:

(a) modifier / tmp pour que sa partition ait plus d’espace (soit en la réaffectant, soit en la déplaçant sur la partition principale – par exemple, voir ici )
(b) changer la config MySql pour qu’il utilise un dossier temp différent sur une partition différente, par exemple /var/tmp

Vérifiez votre espace disponible MySQL tmpdir (/ tmp dans votre cas) tout en exécutant les requêtes car il peut manger des centaines de Mo lorsque vous travaillez avec de grandes tables. Quelque chose comme ça a fonctionné pour moi:

 $ while true; do df -h /tmp; sleep .5; done 

lance ça

 REPAIR TABLE `core_username`,`core_site`,`core_person`; 

ou faites ceci:

 select * from ( SELECT * FROM `core_username` INNER JOIN `core_person` ON (`core_username`.`person_id` = `core_person`.`id`) INNER JOIN `core_site` ON (`core_username`.`site_id` = `core_site`.`id`) LIMIT 1) ORDER BY `name` ASC 

J’ai eu ce problème avec une requête sur une table qui avait 500K + enregistrements. Il me donnait exactement le même type d’erreur, pointant vers un fichier .MYI dans le répertoire / tmp qui était rarement présent lors de la vérification. J’avais déjà augmenté la taille des fichiers tas et temp dans le fichier /etc/my.cnf.

Le problème avec la requête était qu’il contenait bien une clause ORDER à la fin, en omettant de faire fonctionner la requête sans erreur. Il y avait aussi une limite. J’essayais de regarder les 5 enregistrements les plus récents du tableau. Avec la clause ORDER incluse, il a étouffé et a donné l’erreur.

Ce qui se passait était que mysqld créait une table temporaire interne avec TOUS les enregistrements de la table géante pour appliquer la commande.

La façon dont j’ai contourné cela est d’appliquer une condition WHERE supplémentaire, limitant les enregistrements de la table géante à un ensemble plus petit. J’avais commodément un champ datetime pour effectuer le filtrage.

J’espère que cela aide quelqu’un.

Vous pouvez trouver que courir “ANALYZE TABLE” aide.

Nous avons eu ce problème d’apparaître soudainement sur une grande table (~ 100M de lignes) et MySQL a essayé d’utiliser / tmp pour écrire une table temporaire de plus de 1Go, qui a échoué car / tmp était limité à ~ 600M.

Il s’est avéré que les statistiques pour la table InnoDB étaient plutôt obsolètes. Après avoir exécuté “ANALYZE TABLE …”, les statistiques ont été mises à jour et le problème résolu. Avec des statistiques plus précises, MySQL a pu optimiser la requête correctement et le fichier tmp volumineux n’était plus requirejs.

Nous exécutons maintenant “mysqlcheck -Aa” périodiquement pour conserver toutes les statistiques de la table.

Sous Unix, MySQL utilise la valeur de la variable d’environnement TMPDIR comme nom de chemin du répertoire dans lequel stocker les fichiers temporaires. Si TMPDIR n’est pas défini, MySQL utilise le système par défaut, à savoir / tmp, / var / tmp ou / usr / tmp.

Sous Windows, Netware et OS2, MySQL vérifie dans l’ordre les valeurs des variables d’environnement TMPDIR, TEMP et TMP. Pour le premier élément trouvé, MySQL l’utilise et ne vérifie pas ceux qui restnt. Si aucun paramètre TMPDIR, TEMP ou TMP n’est défini, MySQL utilise la valeur par défaut du système Windows, qui est généralement C: \ windows \ temp.

Si le système de fichiers contenant votre répertoire de fichiers temporaires est trop petit, vous pouvez utiliser l’option –tmpdir pour que mysqld spécifie un répertoire dans un système de fichiers contenant suffisamment d’espace .

Dans MySQL 5.0, l’option –tmpdir peut être définie sur une liste de plusieurs chemins utilisés à la manière d’un round-robin. Les chemins d’access doivent être séparés par des deux-points (“:”) sur les caractères Unix et les points-virgules (“;”) sous Windows, NetWare et OS / 2.

J’ai le même problème

Voici ma solution: 1. N’utilisez pas “select *”. Il suffit de sélectionner le champ dont vous avez besoin. 2. Divisez la requête. Si le champ que vous sélectionnez est trop important, le fractionner en une requête peut être un résultat. Vous pouvez “array_merge ()” le résultat plus tard si vous souhaitez que la variable contenant le résultat ne soit pas modifiée.

Dans mon cas, je divise la requête en 5 requêtes, puis le tableau le fusionne avec PHP.

Le problème réside sur le serveur mysql. C’est juste une chose que le développeur d’applications (tel que nous) n’a pas de privilège.

J’ai eu un problème similaire. Dans mon cas, le problème est survenu en raison d’une autorisation ou d’un propriétaire incorrect. J’ai juste dû changer le propriétaire de mon répertoire de données en utilisateur mysql et cela a résolu le problème.

N’augmentez le fichier tmp que parce que mysql n’a pas d’espace pour les requêtes …

 mount -o remount,size=[NEW MAX SIZE HERE] tmpfs /tmp 

Référence des liens:

Erreur générale: 126 Fichier de clé incorrect pour la table ‘/tmp/#sql_254c_0.MYI’; essayer de le réparer

[ERREUR] / usr / sbin / mysqld: fichier de clé incorrect pour la table ‘/mysqltmp/#sql_ca1a_0.MYI’; essayer de le réparer

Comment augmenter la taille de la partition / tmp

les clés d’index pour l’une des 3 tables peuvent être mauvaises, essayez d’exécuter une commande de réparation sur les 3 tables.

L’utilisation du mot clé EXPLAIN peut vous aider à mieux optimiser cette requête. Essentiellement, vous devez obtenir le plus rapidement possible l’ensemble de résultats le plus petit possible. Si vous avez un jeu de résultats pour chaque ligne de core_username jusqu’à la fin, lorsque vous le commandez, vous courez le risque de … this.

Si vous pouvez faire le sorting sur core_username sans problème, vous pouvez vouloir obtenir la ligne min () en tant que sous-requête.