Rychlá oprava
Pokud chcete databázi bez ohledu na to zahodit (ale prosím nejprve si přečtěte celý příspěvek:chyba byla uvedena z nějakého důvodu , a mohlo by být důležité vědět, jaký byl důvod!), můžete:
- najděte datadir pomocí příkazu
SHOW VARIABLES WHERE Variable_name LIKE '%datadir%';
- zastavte server MySQL (např.
service mysql stop
neborcmysqld stop
nebo podobné na Linuxu,NET STOP <name of MYSQL service, often MYSQL57 or similar>
nebo prostřednictvímSERVICES.MSC
v systému Windows) - přejděte do datadir (tady byste měli prozkoumat; viz níže)
- odeberte adresář se stejným názvem jako databáze
- znovu spusťte server MySQL a připojte se k němu
- spustit DROP DATABASE
- to je ono!
Důvody pro Errno 13
MySQL nemá oprávnění k zápisu do nadřazeného adresáře, ve kterém je mydb
složka sídlí.
Zkontrolujte to pomocí
ls -la /path/to/data/dir/ # see below on how to discover data dir
ls -la /path/to/data/dir/mydb
V Linuxu k tomu může dojít také v případě, že kombinujete balíčky MySQL a AppArmor/SELinux. Co se stane je, že AppArmor očekává, že mysqld bude mít svá data v /path/to/data/dir
a umožňuje tam plné R/W, ale MySQLd je z jiné distribuce nebo sestavení a ve skutečnosti ukládá svá data jinde (např.:/var/lib/mysql5/data/**
na rozdíl od /var/lib/mysql/**
). Vidíte tedy, že adresář má správná oprávnění a vlastnictví a přesto stále dává Errno 13, protože apparmor/selinux k němu neumožní přístup.
Pro ověření zkontrolujte systémový protokol, zda nedošlo k porušení zabezpečení, ručně zkontrolujte konfiguraci apparmor/selinux a/nebo zosobněte uživatele mysql a zkuste přejít do základního adresáře var, poté cd postupně, dokud se nedostanete do cílového adresáře, a spusťte něco jako touch aardvark && rm aardvark
. Pokud se oprávnění a vlastnictví shodují, a přesto výše uvedené způsobí chybu přístupu, je pravděpodobné, že se jedná o problém bezpečnostního rámce.
Důvody pro Errno 39
Tento kód znamená „adresář není prázdný“. Adresář obsahuje nějaké skryté soubory, o kterých MySQL nic neví. Pro neskryté soubory viz Errno 17. Řešení je stejné.
Důvody pro Errno 17
Tento kód znamená „soubor existuje“. Adresář obsahuje nějaký soubor MySQL, který MySQL nechce smazat. Takové soubory mohly být vytvořeny SELECT ... INTO OUTFILE "filename";
příkaz kde filename
neměl cestu. V tomto případě je proces MySQL vytvoří ve svém aktuálním pracovním adresáři, což (testováno na MySQL 5.6 na OpenSuSE 12.3) je datový adresář databáze , např. /var/lib/mysql/data/nameofdatabase
.
Reprodukovatelnost:
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)
Přesuňte soubor(y) ven (nebo odstraňte, pokud to není potřeba) a zkuste to znovu. Také určete, proč byly vůbec vytvořeny – mohlo by to ukazovat na chybu v některé aplikaci . Nebo hůř:viz níže...
AKTUALIZACE:Chyba 17 jako příznak zneužití
Stalo se to na systému Linux s nainstalovaným Wordpressem. Bohužel zákazník byl v časové tísni a nemohl jsem ani zobrazit disk, ani provést skutečné forenzní kolo - přeinstaloval jsem celý stroj a Wordpress byl během procesu aktualizován, takže mohu jen říci, že jsem téměř určitě to udělali prostřednictvím tohoto pluginu .
Příznaky :mysql
datový adresář obsahoval tři soubory s příponou PHP. Počkat, co?!? -- a uvnitř souborů byla velká část kódu base64, který byl předán base64_decode
, gzuncompress
a [eval()][2]
. Aha . Samozřejmě to byly jen první pokusy, ty neúspěšné. Stránka byla dobrá a skutečně pwn3d.
Pokud tedy v datovém adresáři mysql najdete soubor, který způsobuje chybu 17, zkontrolujte jej pomocí file
utility nebo jej naskenujte antivirem. Nebo vizuálně zkontrolujte jeho obsah. Nepředpokládejte, že je to tam kvůli nějaké neškodné chybě.
(Netřeba dodávat, že pro vizuální kontrolu souboru nikdy na něj neklikejte dvakrát ).
Oběť v tomto případě (měl nějakého přítele „provádět údržbu“) by nikdy neuhádla, že byl hacknut, dokud skript údržby/aktualizace/cokoli nespustil DROP DATABASE
(neptejte se mě proč – nejsem si jistý, ani když to chci vědět ) a došlo k chybě. Podle zatížení procesoru a zpráv syslog jsem si docela jistý, že se z hostitele stala spamová farma.
Další chyba 17
Pokud rsync
nebo kopírování mezi dvěma instalacemi MySQL stejné verze ale různé platformy nebo souborových systémů jako je Linux nebo Windows (což se nedoporučuje a je to riskantní, ale mnozí to přesto dělají) a konkrétně s různými rozlišování malých a velkých písmen
nastavení, můžete omylem skončit se dvěma verzemi stejného souboru (buď data, index nebo metadata); řekněte Customers.myi
a Customer.MYI
. MySQL používá jeden z nich a neví nic o druhém (který by mohl být zastaralý a vést ke katastrofální synchronizaci). Při shazování databáze, což se také stává v mnoha mysqldump ... | ... mysql
schémata zálohování, DROP
selže, protože tento extra soubor (nebo tyto další soubory) existuje. Pokud k tomu dojde, měli byste být schopni rozpoznat zastaralé soubory, které je třeba ručně odstranit, z času souboru nebo ze skutečnosti, že jejich schéma případu se liší od většiny ostatních tabulek.
Nalezení datového adresáře
Obecně můžete datový adresář najít prozkoumáním my.cnf
soubor (/etc/my.cnf
, /etc/sysconfig/my.cnf
, /etc/mysql/my.cnf
na Linuxu; my.ini
v adresáři programových souborů MySQL ve Windows), pod [mysqld]
nadpis, jako datadir
.
Případně jej můžete požádat o samotnou MySQL:
mysql> SHOW VARIABLES WHERE Variable_name LIKE '%datadir%';
+---------------+-----------------+
| Variable_name | Value |
+---------------+-----------------+
| datadir | /var/lib/mysql/ |
+---------------+-----------------+
1 row in set (0.00 sec)