sql >> Base de Datos >  >> RDS >> Mysql

MySQL:error al eliminar la base de datos (errno 13; errno 17; errno 39)

Solución rápida

Si solo desea eliminar la base de datos sin importar qué (pero por favor primero lea la publicación completa:el error se dio por una razón , y puede ser importante saber cuál fue el motivo), puede:

  • busque el directorio de datos con el comando SHOW VARIABLES WHERE Variable_name LIKE '%datadir%';
  • detenga el servidor MySQL (por ejemplo, service mysql stop o rcmysqld stop o similar en Linux, NET STOP <name of MYSQL service, often MYSQL57 or similar> o a través de SERVICES.MSC en Windows)
  • vaya al directorio de datos (aquí es donde debe investigar; vea a continuación)
  • eliminar el directorio con el mismo nombre que la base de datos
  • inicie el servidor MySQL de nuevo y conéctese a él
  • ejecutar DROP DATABASE
  • ¡Eso es todo!

Razones del error 13

MySQL no tiene permiso de escritura en el directorio principal en el que mydb reside la carpeta.

Compruébalo con

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

En Linux, esto también puede suceder si combina los paquetes de MySQL y AppArmor/SELinux. Lo que sucede es que AppArmor espera que mysqld tenga sus datos en /path/to/data/dir , y permite R/W completo allí, pero MySQLd es de una distribución o compilación diferente, y en realidad almacena sus datos en otro lugar (por ejemplo:/var/lib/mysql5/data/** a diferencia de /var/lib/mysql/** ). Entonces, lo que ve es que el directorio tiene permisos y propiedad correctos y aún así da Errno 13 porque apparmor/selinux no permitirá el acceso a él.

Para verificar, verifique el registro del sistema en busca de violaciones de seguridad, inspeccione manualmente la configuración de apparmor/selinux y/o suplante al usuario de mysql e intente ir al directorio var base, luego cd incrementalmente hasta que esté en el directorio de destino y ejecute algo como touch aardvark && rm aardvark . Si los permisos y la propiedad coinciden y, sin embargo, lo anterior genera un error de acceso, es probable que se trate de un problema del marco de seguridad.

Razones del error 39

Este código significa "directorio no vacío". El directorio contiene algunos ocultos archivos de los que MySQL no sabe nada. Para archivos no ocultos, consulte Errno 17. La solución es la misma.

Razones del error 17

Este código significa que "el archivo existe". El directorio contiene algún archivo MySQL que MySQL no siente acerca de eliminar. Dichos archivos podrían haber sido creados por SELECT ... INTO OUTFILE "filename"; comando donde filename no tenía camino. En este caso, el proceso MySQL los crea en su directorio de trabajo actual, que (probado en MySQL 5.6 en OpenSuSE 12.3) es el directorio de datos de la base de datos , p.ej. /var/lib/mysql/data/nameofdatabase .

Reproducibilidad:

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)

Mueva los archivos al exterior (o elimínelos si no es necesario) y vuelva a intentarlo. Además, determina por qué se crearon en primer lugar; podría indicar un error en alguna aplicación . O peor:ver más abajo...

ACTUALIZACIÓN:Error 17 como bandera de explotación

Esto sucedió en un sistema Linux con Wordpress instalado. Desafortunadamente, el cliente tenía limitaciones de tiempo y no pude crear una imagen del disco ni hacer una ronda forense real:reinstalé toda la máquina y Wordpress se actualizó en el proceso, así que solo puedo decir que estoy casi seguro que lo hicieron a través de este plugin .

Síntomas :el mysql El directorio de datos contenía tres archivos con extensión PHP. Espera, ¿qué?!? -- y dentro de los archivos había una gran cantidad de código base64 que se pasó a base64_decode , gzuncompress y [eval()][2] . Ajá . Por supuesto, estos fueron solo los primeros intentos, los fallidos. El sitio había sido realmente pwn3d.

Entonces, si encuentra un archivo en su directorio de datos mysql que está causando un error 17, verifíquelo con file utilidad o escanearlo con un antivirus. O inspeccionar visualmente su contenido. No asuma que está ahí por algún error inocuo.

(No hace falta decir que, para inspeccionar visualmente el archivo, nunca haga doble clic en él ).

La víctima en este caso (tenía un amigo que "hacía el mantenimiento") nunca habría adivinado que había sido pirateado hasta que un script de mantenimiento/actualización/lo que sea ejecutó un DROP DATABASE (no me preguntes por qué - no estoy seguro ni siquiera quiero saber ) y obtuve un error. Por la carga de la CPU y los mensajes de syslog, estoy bastante seguro de que el host se ha convertido en una granja de spam.

Otro error 17

Si rsync o copie entre dos instalaciones de MySQL de la misma versión pero diferente plataforma o sistema de archivos como Linux o Windows (lo cual es desaconsejado y arriesgado, pero muchos lo hacen de todos modos), y específicamente con diferentes distinción de mayúsculas y minúsculas configuración, puede terminar accidentalmente con dos versiones del mismo archivo (ya sea de datos, índice o metadatos); diga Customers.myi y Customer.MYI . MySQL usa uno de ellos y no sabe nada sobre el otro (que podría estar desactualizado y provocar una sincronización desastrosa). Al soltar la base de datos, lo que también ocurre en muchos mysqldump ... | ... mysql esquemas de copia de seguridad, el DROP fallará porque ese archivo adicional (o esos archivos adicionales) existe. Si esto sucede, debería poder reconocer los archivos obsoletos que necesitan eliminación manual desde el momento del archivo, o por el hecho de que su esquema de caso es diferente al de la mayoría de las otras tablas.

Encontrar el directorio de datos

En general, puede encontrar el directorio de datos inspeccionando my.cnf archivo (/etc/my.cnf , /etc/sysconfig/my.cnf , /etc/mysql/my.cnf en Linux; my.ini en el directorio de archivos de programa de MySQL en Windows), bajo [mysqld] encabezado, como datadir .

Alternativamente, puede preguntarle al mismo MySQL:

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