sql >> Databasteknik >  >> RDS >> Mysql

MySQL:Fel när databasen släpptes (fel 13; fel 17; fel 39)

Snabbfix

Om du bara vill släppa databasen oavsett vad (men snälla läs först hela inlägget:felet angavs av en anledning , och det kan vara viktigt att veta vad orsaken var!), kan du:

  • hitta datakatalogen med kommandot SHOW VARIABLES WHERE Variable_name LIKE '%datadir%';
  • stoppa MySQL-servern (t.ex. service mysql stop eller rcmysqld stop eller liknande på Linux, NET STOP eller via SERVICES.MSC på Windows)
  • gå till datakatalogen (det är här du bör undersöka, se nedan)
  • ta bort katalogen med samma namn som databasen
  • starta MySQL-servern igen och anslut till den
  • kör en DROP DATABAS
  • det är det!

Orsaker till Errno 13

MySQL har ingen skrivbehörighet för den överordnade katalogen där mydb mappen finns.

Kontrollera 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 detta även hända om du blandar och matchar MySQL- och AppArmor/SELinux-paket. Det som händer är att AppArmor förväntar sig att mysqld ska ha sina data i /path/to/data/dir , och tillåter fullständig R/W där, men MySQLd är från en annan distribution eller build, och den lagrar faktiskt sina data annanstans (t.ex.:/var/lib/mysql5/data/** i motsats till /var/lib/mysql/** ). Så det du ser är att katalogen har korrekt behörighet och ägande och ändå ger det fortfarande Errno 13 eftersom apparmor/selinux inte tillåter åtkomst till det.

För att verifiera, kontrollera systemloggen för säkerhetsöverträdelser, inspektera apparmor/selinux-konfigurationen manuellt och/eller imitera mysql-användaren och försök gå till basen var-katalogen, cd sedan stegvis tills du är i målkatalogen, och kör något i stil med touch aardvark &&rm jordvark . Om behörigheter och ägande stämmer överens, och ändå ger ovanstående ett åtkomstfel, är chansen stor att det är ett säkerhetsramverk.

Orsaker till Errno 39

Denna kod betyder "katalogen är inte tom". Katalogen innehåller några dolda filer MySQL vet ingenting om. För icke-dolda filer, se Errnr 17. Lösningen är densamma.

Orsaker till Errno 17

Denna kod betyder "filen existerar". Katalogen innehåller någon MySQL-fil som MySQL inte känner för att ta bort. Sådana filer kan ha skapats av en SELECT ... INTO OUTFILE "filnamn"; kommando där filnamn hade ingen väg. I det här fallet skapar MySQL-processen dem i sin nuvarande arbetskatalog, som (testad på MySQL 5.6 på OpenSuSE 12.3) är datakatalogen för databasen , t.ex. /var/lib/mysql/data/databasens namn .

Reproducerbarhet:

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)

Flytta filen/filerna utanför (eller ta bort om det inte behövs) och försök igen. Ta även reda på varför de skapades från början – det kan peka på en bugg i något program . Eller ännu värre:se nedan...

UPPDATERING:Fel 17 som exploateringsflagga

Detta hände på ett Linux-system med Wordpress installerat. Tyvärr var kunden under tidspress och jag kunde varken avbilda disken eller göra en riktig forensisk runda - jag installerade om hela maskinen och Wordpress uppdaterades under processen, så jag kan bara säga att jag är nästan> säker på att de gjorde det genom denna plugin .

Symtom :mysql datakatalogen innehöll tre filer med filtillägget PHP. Vänta, vad?!? -- och inuti filerna fanns det en stor del av base64-koden som skickades till base64_decode , gzuncompress och [eval()][2] . Aha . Naturligtvis var detta bara de första försöken, de misslyckade. Webbplatsen hade varit pwn3d.

Så om du hittar en fil i din mysql-datakatalog som orsakar ett fel 17, kontrollera den med fil verktyg eller skanna den med ett antivirusprogram. Eller visuellt inspektera dess innehåll. Anta inte att det är där för något ofarligt misstag.

(Det behöver inte sägas att för att visuellt inspektera filen, dubbelklicka aldrig på den ).

Offret i det här fallet (han hade en vän som "gör underhållet") skulle aldrig ha gissat att han hade blivit hackad förrän ett underhåll/uppdatering/vilket skript körde en DROP DATABASE (fråga mig inte varför – jag är inte säker på att ens jag vill veta det ) och fick ett fel. Från CPU-belastningen och syslog-meddelandena är jag ganska säker på att värden hade blivit en spamfarm.

Ännu ett fel 17

Om du rsync eller kopiera mellan två MySQL-installationer av samma version men olika plattform eller filsystem som Linux eller Windows (vilket är avskräckt och riskabelt, men många gör det ändå), och specifikt med olika skiftlägeskänslighet inställningar kan du av misstag sluta med två versioner av samma fil (antingen data, index eller metadata); säg Customers.myi och Customer.MYI . MySQL använder en av dem och vet ingenting om den andra (vilket kan vara inaktuellt och leda till en katastrofal synkronisering). När du släpper databasen, vilket också händer i många mysqldump ... | ... mysql backup-scheman, DROP kommer att misslyckas eftersom den extra filen (eller de). extra filer) finns. Om detta händer bör du kunna känna igen de föråldrade filerna som behöver raderas manuellt från filtiden eller från det faktum att deras ärendeschema skiljer sig från majoriteten av de andra tabellerna.

Hitta data-dir

I allmänhet kan du hitta datakatalogen genom att inspektera my.cnf fil (/etc/my.cnf , /etc/sysconfig/my.cnf , /etc/mysql/my.cnf på Linux; my.ini i MySQL-programfilkatalogen i Windows), under [mysqld] rubrik, som datadir .

Alternativt kan du be det till MySQL själv:

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


  1. Hur man använder DISTINCT i SQL

  2. Hur ändrar jag en MySQL-tabell till UTF-8?

  3. Generera klass från databastabell

  4. Vad är primär nyckelbegränsning i SQL Server Database - SQL Server / T-SQL självstudie del 54