web-dev-qa-db-fra.com

MySQL: erreur lors de la suppression de la base de données (errno 13; errno 17; errno 39)

J'ai échoué à déposer une base de données:

 mysql> drop database mydb; 
 ERROR 1010 (HY000): Erreur lors de la suppression de la base de données (impossible pour rmdir './mydb', errno: 39) 

Le répertoire db/mydb existe dans l'arborescence mysql mais n'a pas de table:

 # ls -l db/mydb 
- rw-rw ---- mysql mysql HIS_STAT.MYD 
- rw-rw ---- mysql mysql HIS_STAT.MYI 

Que devrais-je faire?

48
Philippe Blayo

Solution rapide

Si vous voulez simplement supprimer la base de données peu importe ce que vous voulez (mais s'il vous plaît lisez d'abord le message en entier: l'erreur a été donnée pour une raison, et il peut être important de savoir ce que la raison était!), vous pouvez:

  • trouvez le datadir avec la commande SHOW VARIABLES WHERE Variable_name LIKE '%datadir%';
  • arrêtez le serveur MySQL (par exemple, service mysql stop ou rcmysqld stop ou similaire sous Linux, NET STOP <name of MYSQL service, often MYSQL57 or similar> ou via SERVICES.MSC sous Windows)
  • allez au datadir (c'est là que vous devriez enquêter; voir ci-dessous)
  • supprimer le répertoire portant le même nom que la base de données
  • redémarrez le serveur MySQL et connectez-vous à celui-ci
  • exécuter une base de données DROP
  • c'est tout!

Raisons pour Errno 13

MySQL n'a pas de permission d'écriture sur le répertoire parent dans lequel réside le dossier mydb.

Vérifiez avec

ls -la /path/to/data/dir/         # see below on how to discover data dir
ls -la /path/to/data/dir/mydb   

Sous Linux, cela peut aussi arriver si vous mélangez et faites correspondre les packages MySQL et AppArmor/SELinux. Ce qui se passe, c’est que AppArmor s’attend à ce que mysqld ait ses données dans /path/to/data/dir, et autorise une lecture/sortie complète, mais MySQLd provient d’une distribution ou d’une construction différente et stocke ses données ailleurs (par exemple: /var/lib/mysql5/data/** par opposition à /var/lib/mysql/**). Donc, ce que vous voyez, c'est que le répertoire a permissions et propriété correctes et pourtant, il donne toujours Errno 13 car apparmor/selinux n'autorisera pas l'accès à celui-ci.

Pour vérifier, vérifiez que le journal système ne contient pas de violation de la sécurité, inspectez manuellement la configuration apparmor/selinux et/ou empruntez l'identité de l'utilisateur mysql et essayez d'accéder au répertoire var de base, puis effectuez un cd incrémentiel jusqu'à ce que vous soyez dans le répertoire cible, puis exécutez la commande suivante: touch aardvark && rm aardvark. Si les autorisations et la propriété correspondent, et que, toutefois, ce qui précède génère une erreur d'accès, il est probable qu'il s'agisse d'un problème de sécurité.

Raisons pour Errno 39

Ce code signifie "répertoire non vide". Le répertoire contient des fichiers cachés dont MySQL ne connaît rien. Pour les fichiers non cachés, voir Errno 17. La solution est la même.

Raisons pour Errno 17

Ce code signifie "le fichier existe". Le répertoire contient des fichiers MySQL que MySQL ne pense pas à supprimer. Ces fichiers auraient pu être créés par une commande SELECT ... INTO OUTFILE "filename";filename n'avait pas de chemin. Dans ce cas, le processus MySQL les crée dans son répertoire de travail actuel, qui (testé sur MySQL 5.6 sur OpenSuSE 12.3) est le répertoire de données de la base de données, par exemple. /var/lib/mysql/data/nameofdatabase.

Reproductibilité:

Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1676
Server version: 5.6.12-log openSUSE package
[ snip ]    

mysql> CREATE DATABASE pippo;
Query OK, 1 row affected (0.00 sec)

mysql> USE pippo;
Database changed
mysql> SELECT version() INTO OUTFILE 'test';
Query OK, 1 row affected (0.00 sec)

mysql> DROP DATABASE pippo;
ERROR 1010 (HY000): Error dropping database (can't rmdir './pippo/', errno: 17)

-- now from another console I delete the "test" file, without closing this connection
-- and just retry. Now it works.

mysql> DROP DATABASE pippo;
Query OK, 0 rows affected (0.00 sec)

Déplacez le ou les fichiers à l'extérieur (ou supprimez-les si nécessaire) et réessayez. Aussi, déterminez pourquoi ils ont été créés en premier lieu - cela pourrait indiquer un bogue dans certaines applications. Ou pire: voir ci-dessous ...

UPDATE: erreur 17 en tant qu'indicateur d'exploitation

Cela s'est produit sur un système Linux avec Wordpress installé. Malheureusement, le client était soumis à des contraintes de temps et je ne pouvais ni imaginer le disque, ni faire une analyse judiciaire - j'ai réinstallé la machine entière et Wordpress a été mis à jour au cours du processus. Je ne peux donc que dire que je presque certain qu'ils l'ont fait à travers ce plugin .

Symptômes: le répertoire de données mysql contient trois fichiers avec l'extension PHP. Attendez, quoi?!?} - et dans les fichiers, il y avait une grande partie du code base64 qui a été transmis à base64_decode, gzuncompress et [eval()][2]. Aha. Bien sûr, il ne s'agissait que des premières tentatives, des tentatives infructueuses. Le site avait été bel et bien pwn3d.

Donc, si vous trouvez un fichier dans votre répertoire de données mysql qui cause une erreur 17, vérifiez-le avec file utility ou analysez-le avec un antivirus. Ou inspectez visuellement son contenu. Ne présumez pas que c'est là pour une erreur anodine.

(Inutile de dire que pour inspecter visuellement le fichier, ne double-cliquez jamais dessus).

La victime dans cette affaire (il avait un ami "fait la maintenance") n'aurait jamais deviné qu'il avait été piraté jusqu'à ce qu'un script d'entretien/mise à jour/quel que soit le script exécute un DROP DATABASE (ne me demandez pas pourquoi - Je ne suis même pas sûr de vouloir savoir}) et j'ai une erreur. En ce qui concerne la charge du processeur et les messages syslog, je suis assez convaincu que l'hôte est devenu une batterie de spam.

Encore une autre erreur 17

Si vous rsync ou copiez entre deux installations MySQL de la même version mais sur une plate-forme ou des systèmes de fichiers différents tels que Linux ou Windows (ce qui est déconseillé et risqué, mais beaucoup le font néanmoins), et spécifiquement avec différents réglages sensibilité à la casse , vous pouvez vous retrouver accidentellement avec deux versions du même fichier (données, index ou métadonnées); dites Customers.myi et Customer.MYI. MySQL utilise l’un d’eux et ne connaît rien de l’autre (ce qui pourrait être obsolète et entraîner une synchronisation désastreuse). Lors de la suppression de la base de données, ce qui se produit également dans de nombreux schémas de sauvegarde mysqldump ... | ... mysql, la DROP échouera, car ce fichier supplémentaire (ou ses ceux} fichiers supplémentaires) existe. Si cela se produit, vous devriez être en mesure de reconnaître le ou les fichiers obsolètes qui nécessitent une suppression manuelle à partir du fichier ou du fait que leur cas est différent de la majorité des autres tables.

Trouver le répertoire de données

En général, vous pouvez trouver le répertoire de données en inspectant le fichier my.cnf (/etc/my.cnf, /etc/sysconfig/my.cnf, /etc/mysql/my.cnf sous Linux; my.ini dans le répertoire des fichiers du programme MySQL. sous Windows), sous le titre [mysqld], sous la forme datadir.

Sinon, vous pouvez le demander à MySQL lui-même:

mysql> SHOW VARIABLES WHERE Variable_name LIKE '%datadir%';
+---------------+-----------------+
| Variable_name | Value           |
+---------------+-----------------+
| datadir       | /var/lib/mysql/ |
+---------------+-----------------+
1 row in set (0.00 sec)
100
LSerni

Dans mon cas, cela était dû au paramètre "lower_case_table_names".

Le numéro d'erreur 39 émis lorsque j'ai tenté de supprimer les bases de données composées de noms de table en majuscule avec le paramètre lower_case_table_names est activé.

Ceci est corrigé en rétablissant que les paramètres de casse minuscule reviennent à l'état précédent.

25
Mathi - MySQL DBA

Il suffit d'aller à /opt/lampp/var/mysql

Vous pouvez y trouver votre nom database. Ouvrez ce dossier. Supprimer s'il y a des fichiers dedans

Maintenant, venez à phpmyadmin et abandonnez cette database

4
venkat

En ce qui concerne ERRORCODE 39 , vous pouvez simplement supprimer les fichiers de la table physique sur le disque. l'emplacement dépend de la distribution et de la configuration de votre système d'exploitation. Sur Debian, cela se trouve généralement sous/var/lib/mysql/nom_base_données/So do a:

rm -f /var/lib/mysql/<database_name>/

Et ensuite, supprimez la base de données de l'outil de votre choix ou de la commande suivante:

DROP DATABASE <database_name>
2
TomRA

Dans mon cas, un fichier supplémentaire n'appartenant pas à la base de données se trouvait dans le dossier de la base de données. Mysql a trouvé le dossier non vide après avoir supprimé toutes les tables qui ont déclenché l'erreur. Je supprime le fichier et la base de données de suppression a bien fonctionné.

0
fran