Snelle oplossing
Als je de database gewoon wilt laten vallen, wat er ook gebeurt (maar alsjeblieft lees eerst het hele bericht:de fout werd gegeven met een reden , en het kan belangrijk zijn om te weten wat de reden was!), kunt u:
- vind de datadir met het commando
SHOW VARIABLES WHERE Variable_name LIKE '%datadir%';
- stop de MySQL-server (bijv.
service mysql stop
ofrcmysqld stop
of vergelijkbaar op Linux,NET STOP <name of MYSQL service, often MYSQL57 or similar>
of viaSERVICES.MSC
op Windows) - ga naar de datadir (dit is waar je het moet onderzoeken; zie hieronder)
- verwijder de map met dezelfde naam als de database
- start MySQL-server opnieuw en maak er verbinding mee
- voer een DROP DATABASE uit
- dat is het!
Redenen voor Errno 13
MySQL heeft geen schrijfrechten voor de bovenliggende map waarin de mydb
map staat.
Controleer het met
ls -la /path/to/data/dir/ # see below on how to discover data dir
ls -la /path/to/data/dir/mydb
Op Linux kan dit ook gebeuren als u MySQL- en AppArmor/SELinux-pakketten mixt en matcht. Wat er gebeurt, is dat AppArmor verwacht dat mysqld zijn gegevens heeft in /path/to/data/dir
, en staat daar volledige R/W toe, maar MySQLd is van een andere distributie of build en slaat zijn gegevens feitelijk elders op (bijv.:/var/lib/mysql5/data/**
in tegenstelling tot /var/lib/mysql/**
). Dus wat je ziet is dat de directory juiste rechten en eigendom heeft en toch geeft het nog steeds Errno 13 omdat apparmor/selinux er geen toegang toe zal toestaan.
Om dit te verifiëren, controleert u het systeemlogboek op beveiligingsschendingen, inspecteert u handmatig de apparmor/selinux-configuratie en/of imiteert u de mysql-gebruiker en probeert u naar de basis var-map te gaan, dan cd incrementeel totdat u in de doelmap bent, en voer iets uit als touch aardvark && rm aardvark
. Als machtigingen en eigendom overeenkomen en het bovenstaande toch een toegangsfout oplevert, is de kans groot dat het een probleem met het beveiligingsframework is.
Redenen voor Errno 39
Deze code betekent "map niet leeg". De map bevat enkele verborgen bestanden waar MySQL niets van weet. Voor niet-verborgen bestanden, zie Errno 17. De oplossing is hetzelfde.
Redenen voor Errno 17
Deze code betekent "bestand bestaat". De map bevat een MySQL-bestand dat MySQL niet wil verwijderen. Dergelijke bestanden kunnen zijn gemaakt door een SELECT ... INTO OUTFILE "filename";
commando waar filename
geen pad gehad. In dit geval maakt het MySQL-proces ze aan in de huidige werkmap, die (getest op MySQL 5.6 op OpenSuSE 12.3) de gegevensmap van de database is , bijv. /var/lib/mysql/data/nameofdatabase
.
Reproduceerbaarheid:
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)
Verplaats de bestanden naar buiten (of verwijder ze indien niet nodig) en probeer het opnieuw. Bepaal ook waarom ze in de eerste plaats zijn gemaakt - het kan wijzen op een bug in een toepassing . Of erger:zie hieronder...
UPDATE:Fout 17 als exploit-vlag
Dit gebeurde op een Linux-systeem waarop Wordpress was geïnstalleerd. Helaas had de klant tijdgebrek en kon ik geen image van de schijf maken of een echte forensische ronde doen - ik installeerde de hele machine opnieuw en Wordpress werd tijdens het proces bijgewerkt, dus ik kan alleen maar zeggen dat ik bijna zeker dat ze het deden via deze plug-in .
Symptomen :de mysql
data directory bevatte drie bestanden met de extensie PHP. Wacht, wat?!? -- en in de bestanden bevond zich een groot deel van de base64-code die werd doorgegeven aan base64_decode
, gzuncompress
en [eval()][2]
. Aha . Natuurlijk waren dit slechts de eerste pogingen, de mislukte. De site was echt pwn3d.
Dus als u een bestand in uw mysql-gegevensmap vindt dat een fout 17 veroorzaakt, controleer het dan met file
hulpprogramma of scan het met een antivirusprogramma. Of de inhoud visueel inspecteren. Ga er niet vanuit dat het er is voor een onschuldige fout.
(Onnodig te zeggen dat om het bestand visueel te inspecteren, nooit dubbelklikt ).
Het slachtoffer in dit geval (hij had een vriend die "het onderhoud deed") zou nooit hebben vermoed dat hij gehackt was totdat een onderhoud/update/wat dan ook script een DROP DATABASE
uitvoerde (vraag me niet waarom - ik weet niet zeker of ik het wel wil weten ) en kreeg een foutmelding. Gezien de CPU-belasting en de syslog-berichten ben ik er vrij zeker van dat de host een spamfarm is geworden.
Nog een fout 17
Als u rsync
of kopieer tussen twee MySQL-installaties van dezelfde versie maar verschillende platform- of bestandssystemen zoals Linux of Windows (wat wordt afgeraden en riskant, maar velen doen het toch), en specifiek met verschillende hoofdlettergevoeligheid
instellingen, kunt u per ongeluk eindigen met twee versies van hetzelfde bestand (data, index of metadata); zeg Customers.myi
en Customer.MYI
. MySQL gebruikt een van hen en weet niets over de andere (die verouderd zou kunnen zijn en tot een rampzalige synchronisatie zou kunnen leiden). Bij het laten vallen van de database, wat ook gebeurt in menig mysqldump ... | ... mysql
back-upschema's, de DROP
zal mislukken omdat dat extra bestand (of die extra bestanden) bestaat. Als dit gebeurt, zou u in staat moeten zijn om de verouderde bestanden die handmatig moeten worden verwijderd te herkennen aan de bestandstijd, of aan het feit dat hun casusschema verschilt van de meeste andere tabellen.
De data-dir vinden
Over het algemeen kunt u de gegevensmap vinden door de my.cnf
. te inspecteren bestand (/etc/my.cnf
, /etc/sysconfig/my.cnf
, /etc/mysql/my.cnf
op Linux; my.ini
in de map MySQL-programmabestanden in Windows), onder de [mysqld]
kop, als datadir
.
Je kunt het ook aan MySQL zelf vragen:
mysql> SHOW VARIABLES WHERE Variable_name LIKE '%datadir%';
+---------------+-----------------+
| Variable_name | Value |
+---------------+-----------------+
| datadir | /var/lib/mysql/ |
+---------------+-----------------+
1 row in set (0.00 sec)