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

MySQL:errore durante l'eliminazione del database (errno 13; errno 17; errno 39)

Risoluzione rapida

Se vuoi semplicemente eliminare il database qualunque cosa accada (ma per favore prima leggi tutto il post:l'errore è stato dato per un motivo , e potrebbe essere importante sapere qual era il motivo!), puoi:

  • trova la datadir con il comando SHOW VARIABLES WHERE Variable_name LIKE '%datadir%';
  • arrestare il server MySQL (ad es. service mysql stop o rcmysqld stop o simili su Linux, NET STOP <name of MYSQL service, often MYSQL57 or similar> o tramite SERVICES.MSC su Windows)
  • vai alla datadir (qui è dove dovresti indagare; vedi sotto)
  • rimuovere la directory con lo stesso nome del database
  • riavvia il server MySQL e connettiti ad esso
  • esegui un DATABASE DROP
  • Ecco fatto!

Motivi di Errno 13

MySQL non ha permessi di scrittura sulla directory padre in cui si trova mydb risiede la cartella.

Verificalo con

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

Su Linux, questo può succedere anche combinando e abbinando i pacchetti MySQL e AppArmor/SELinux. Quello che succede è che AppArmor si aspetta che mysqld abbia i suoi dati in /path/to/data/dir e consente R/W completo lì, ma MySQLd proviene da una distribuzione o build diversa e in realtà memorizza i suoi dati altrove (es.:/var/lib/mysql5/data/** al contrario di /var/lib/mysql/** ). Quindi quello che vedi è che la directory ha autorizzazioni e proprietà corrette eppure dà ancora Errno 13 perché apparmor/selinux non consentirà l'accesso ad esso.

Per verificare, controlla il registro di sistema per le violazioni della sicurezza, ispeziona manualmente la configurazione di apparmor/selinux e/o impersona l'utente mysql e prova ad andare alla directory var di base, quindi cd in modo incrementale finché non sei nella directory di destinazione ed esegui qualcosa di simile touch aardvark && rm aardvark . Se le autorizzazioni e la proprietà corrispondono, eppure quanto sopra produce un errore di accesso, è probabile che si tratti di un problema del framework di sicurezza.

Motivi di Errno 39

Questo codice significa "directory non vuota". La directory contiene alcuni nascosti file di cui MySQL non sa nulla. Per i file non nascosti, vedere Errno 17. La soluzione è la stessa.

Motivi di Errno 17

Questo codice significa "il file esiste". La directory contiene alcuni file MySQL che MySQL non si sente di eliminare. Tali file potrebbero essere stati creati da un SELECT ... INTO OUTFILE "filename"; comando dove filename non aveva percorso. In questo caso, il processo MySQL li crea nella sua directory di lavoro corrente, che (testata su MySQL 5.6 su OpenSuSE 12.3) è la directory dei dati del database , per esempio. /var/lib/mysql/data/nameofdatabase .

Riproducibilità:

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)

Sposta i file all'esterno (o eliminali se non necessario) e riprova. Inoltre, determina innanzitutto perché sono stati creati:potrebbe indicare un bug in alcune applicazioni . O peggio:vedi sotto...

AGGIORNAMENTO:errore 17 come flag di exploit

Questo è successo su un sistema Linux con Wordpress installato. Sfortunatamente il cliente aveva dei limiti di tempo e non potevo né eseguire l'immagine del disco né fare un vero giro di analisi forense - ho reinstallato l'intera macchina e Wordpress è stato aggiornato nel processo, quindi posso solo dire che sono quasi certo di averlo fatto tramite questo plugin .

Sintomi :il mysql la directory dei dati conteneva tre file con estensione PHP. Aspetta, cosa?!? -- e all'interno dei file c'era un grosso codice base64 che è stato passato a base64_decode , gzuncompress e [eval()][2] . Ah . Naturalmente questi erano solo i primi tentativi, quelli infruttuosi. Il sito era stato veramente bene e veramente pwn3d.

Quindi, se trovi un file nella tua directory di dati mysql che sta causando un errore 17, controllalo con file utilità o scansionalo con un antivirus. O ispezionare visivamente il suo contenuto. Non dare per scontato che sia lì per qualche errore innocuo.

(Inutile dire che per ispezionare visivamente il file, non fare mai doppio clic su di esso ).

La vittima in questo caso (aveva un amico che "faceva la manutenzione") non avrebbe mai immaginato che fosse stato violato fino a quando uno script di manutenzione/aggiornamento/qualunque altro non avesse eseguito un DROP DATABASE (non chiedermi perché - non ne sono sicuro nemmeno io lo voglio sapere ) e ha ricevuto un errore. Dal carico della CPU e dai messaggi di syslog, sono abbastanza sicuro che l'host sia diventato una spam farm.

Ancora un altro errore 17

Se rsync oppure copia tra due installazioni MySQL della stessa versione ma con piattaforma o file system diversi come Linux o Windows (che è scoraggiato e rischioso, ma molti lo fanno comunque), e in particolare con diversi maiuscole/minuscole impostazioni, potresti ritrovarti accidentalmente con due versioni dello stesso file (dati, indice o metadati); dì Customers.myi e Customer.MYI . MySQL ne usa uno e non sa nulla dell'altro (che potrebbe non essere aggiornato e portare a una sincronizzazione disastrosa). Quando si elimina il database, cosa che accade anche in molti mysqldump ... | ... mysql schemi di backup, il DROP fallirà perché quel file extra (o quelli file extra) esiste. Se ciò accade, dovresti essere in grado di riconoscere i file obsoleti che richiedono l'eliminazione manuale dall'ora del file o dal fatto che il loro schema di casi è diverso dalla maggior parte delle altre tabelle.

Trovare la directory dei dati

In generale, puoi trovare la directory dei dati controllando il my.cnf file (/etc/my.cnf , /etc/sysconfig/my.cnf , /etc/mysql/my.cnf su Linux; my.ini nella directory dei file di programma MySQL in Windows), sotto [mysqld] intestazione, come datadir .

In alternativa puoi chiederlo a MySQL stesso:

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