sql >> Database teknologi >  >> RDS >> Mysql

MySQL:Fejl under sletning af database (fejl 13; fejl 17; fejl 39)

Hurtig løsning

Hvis du bare vil droppe databasen uanset hvad (men venligst læs først hele indlægget:fejlen blev givet af en grund , og det kan være vigtigt at vide, hvad årsagen var!), kan du:

  • find datakataloget med kommandoen SHOW VARIABLES WHERE Variable_name LIKE '%datadir%';
  • stop MySQL-serveren (f.eks. service mysql stop eller rcmysqld stop eller lignende på Linux, NET STOP eller gennem SERVICES.MSC på Windows)
  • gå til datakataloget (det er her, du skal undersøge det; se nedenfor)
  • fjern mappen med samme navn som databasen
  • start MySQL-serveren igen, og opret forbindelse til den
  • udfør en DROP DATABASE
  • det er det!

Årsager til Errno 13

MySQL har ingen skrivetilladelse på det overordnede bibliotek, hvori mydb mappen ligger.

Tjek det med

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

På Linux kan dette også ske, hvis du blander og matcher MySQL- og AppArmor/SELinux-pakker. Det, der sker, er, at AppArmor forventer, at mysqld har sine data i /path/to/data/dir , og tillader fuld R/W der, men MySQLd er fra en anden distribution eller build, og den gemmer faktisk sine data andre steder (f.eks.:/var/lib/mysql5/data/** i modsætning til /var/lib/mysql/** ). Så det, du ser, er, at mappen har korrekte tilladelser og ejerskab og alligevel giver det stadig Errno 13, fordi apparmor/selinux ikke giver adgang til det.

For at verificere, tjek systemloggen for sikkerhedsovertrædelser, inspicer apparmor/selinux-konfigurationen manuelt og/eller efterlign mysql-brugeren og prøv at gå til base var-biblioteket, derefter cd trinvist, indtil du er i målbiblioteket, og kør noget som f.eks. touch aardvark &&rm aardvark . Hvis tilladelser og ejerskab matcher, og alligevel giver ovenstående en adgangsfejl, er chancerne for, at det er et sikkerhedsrammeproblem.

Årsager til Errno 39

Denne kode betyder "bibliotek ikke tomt". Mappen indeholder nogle skjulte filer MySQL ved intet om. For ikke-skjulte filer, se Errno 17. Løsningen er den samme.

Årsager til Errno 17

Denne kode betyder "fil eksisterer". Mappen indeholder en eller anden MySQL-fil, som MySQL ikke har lyst til at slette. Sådanne filer kunne være blevet oprettet af en SELECT ... INTO OUTFILE "filnavn"; kommando hvor filnavn havde ingen vej. I dette tilfælde opretter MySQL-processen dem i dens nuværende arbejdsmappe, som (testet på MySQL 5.6 på OpenSuSE 12.3) er databasens datamappe , for eksempel. /var/lib/mysql/data/databasenavn .

Reproducerbarhed:

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)

Flyt filen(erne) udenfor (eller slet, hvis det ikke er nødvendigt), og prøv igen. Afgør også, hvorfor de blev oprettet i første omgang - det kan pege på en fejl i et program . Eller endnu værre:se nedenfor...

OPDATERING:Fejl 17 som udnyttelsesflag

Dette skete på et Linux-system med Wordpress installeret. Desværre var kunden under tidspres, og jeg kunne hverken afbilde disken eller lave en rigtig retsmedicinsk runde - jeg geninstallerede hele maskinen, og Wordpress blev opdateret i processen, så jeg kan kun sige, at jeg næsten sikker på, at de gjorde det gennem dette plugin .

Symptomer :mysql databiblioteket indeholdt tre filer med filtypenavnet PHP. Vent, hvad?!? -- og inde i filerne var der en masse af base64-kode, som blev sendt til base64_decode , gzuncompress og [eval()][2] . Aha . Det var selvfølgelig kun de første forsøg, de mislykkede. Siden havde været pwn3d.

Så hvis du finder en fil i din mysql data dir, der forårsager en fejl 17, tjek den med fil nytte eller scan den med et antivirusprogram. Eller inspicere indholdet visuelt. Antag ikke, at det er der for en eller anden uskadelig fejl.

(Det er overflødigt at sige, for visuelt at inspicere filen, du må aldrig dobbeltklikke på den ).

Offeret i denne sag (han fik en ven til at "gøre vedligeholdelsen") ville aldrig have gættet, at han var blevet hacket, før en vedligeholdelse/opdatering/hvad som helst script kørte en DROP DATABASE (spørg mig ikke hvorfor – jeg er ikke sikker på, om jeg vil vide det ) og fik en fejl. Ud fra CPU-belastningen og syslog-meddelelserne er jeg ret sikker på, at værten var blevet en spamfarm.

Endnu en fejl 17

Hvis du rsync eller kopier mellem to MySQL-installationer af den samme version men anden platform eller filsystemer såsom Linux eller Windows (hvilket er frarådigt og risikabelt, men mange gør det ikke desto mindre), og specifikt med forskellige store og små bogstaver indstillinger, kan du ved et uheld ende med to versioner af den samme fil (enten data, indeks eller metadata); sig Customers.myi og Customer.MYI . MySQL bruger den ene af dem og ved intet om den anden (hvilket kan være forældet og føre til en katastrofal synkronisering). Når du dropper databasen, hvilket også sker i mange en mysqldump ... | ... mysql backup-skemaer, DROP vil mislykkes, fordi den ekstra fil (eller dem). ekstra filer) findes. Hvis dette sker, bør du være i stand til at genkende de forældede filer, der skal slettes manuelt, fra filtidspunktet eller fra det faktum, at deres sagsskema er forskelligt fra størstedelen af ​​de andre tabeller.

Find data-dir

Generelt kan du finde databiblioteket ved at inspicere my.cnf fil (/etc/my.cnf , /etc/sysconfig/my.cnf , /etc/mysql/my.cnf på Linux; my.ini i mappen MySQL-programfiler i Windows), under [mysqld] overskrift, som datadir .

Alternativt kan du bede det til MySQL selv:

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


  1. 19 Onlineressourcer til at lære om databasedesignfejl

  2. MySQL få rækkeposition i BESTIL EFTER

  3. En potentiel forbedring af statistikopdateringer:MAXDOP

  4. PHP-kode til indsæt afkrydsningsfeltværdi i specifik kolonne på mysql med vælg formular