Mysql
 sql >> Base de Dados >  >> RDS >> Mysql

MySQL:Erro ao descartar banco de dados (errno 13; errno 17; errno 39)

Correção rápida


Se você quiser apenas descartar o banco de dados, não importa o que aconteça (mas por favor primeiro leia o post inteiro:o erro foi dado por um motivo , e pode ser importante saber qual foi o motivo!), você pode:
  • encontre o datadir com o comando SHOW VARIABLES WHERE Variable_name LIKE '%datadir%';
  • parar o servidor MySQL (por exemplo, service mysql stop ou rcmysqld stop ou similar no Linux, NET STOP <name of MYSQL service, often MYSQL57 or similar> ou através de SERVICES.MSC no Windows)
  • vá para o datadir (é aqui que você deve investigar; veja abaixo)
  • remova o diretório com o mesmo nome do banco de dados
  • inicie o servidor MySQL novamente e conecte-se a ele
  • executar um DROP DATABASE
  • é isso!

Razões para o erro 13


O MySQL não tem permissão de gravação no diretório pai no qual o mydb pasta reside.

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

No Linux, isso também pode acontecer se você misturar e combinar os pacotes MySQL e AppArmor/SELinux. O que acontece é que o AppArmor espera que o mysqld tenha seus dados em /path/to/data/dir , e permite R/W completo lá, mas o MySQLd é de uma distribuição ou compilação diferente e, na verdade, armazena seus dados em outro lugar (por exemplo:/var/lib/mysql5/data/** ao contrário de /var/lib/mysql/** ). Então, o que você vê é que o diretório tem permissões e propriedade corretas e ainda dá Errno 13 porque apparmor/selinux não permite acesso a ele.

Para verificar, verifique o log do sistema em busca de violações de segurança, inspecione manualmente a configuração do apparmor/selinux e/ou personifique o usuário mysql e tente ir para o diretório base var, depois cd incrementalmente até estar no diretório de destino e execute algo como touch aardvark && rm aardvark . Se as permissões e a propriedade corresponderem, e ainda assim o resultado acima gerar um erro de acesso, é provável que seja um problema de estrutura de segurança.


Razões para o erro 39


Este código significa "diretório não vazio". O diretório contém alguns arquivos ocultos arquivos sobre os quais o MySQL não sabe nada. Para arquivos não ocultos, consulte o Errno 17. A solução é a mesma.

Razões para o Errno 17


Este código significa "arquivo existe". O diretório contém algum arquivo MySQL que o MySQL não sente sobre a exclusão. Esses arquivos podem ter sido criados por um SELECT ... INTO OUTFILE "filename"; comando onde filename não tinha caminho. Neste caso, o processo MySQL os cria em seu diretório de trabalho atual, que (testado no MySQL 5.6 no OpenSuSE 12.3) é o diretório de dados do banco de dados , por exemplo. /var/lib/mysql/data/nameofdatabase .

Reprodutibilidade:
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)

Mova o(s) arquivo(s) para fora (ou exclua se não for necessário) e tente novamente. Além disso, determine por que eles foram criados em primeiro lugar - isso pode apontar para um bug em algum aplicativo . Ou pior:veja abaixo...

ATUALIZAÇÃO:Erro 17 como sinalizador de exploração


Isso aconteceu em um sistema Linux com o Wordpress instalado. Infelizmente, o cliente estava com restrições de tempo e eu não pude criar imagens do disco ou fazer uma rodada forense real - reinstalei a máquina inteira e o Wordpress foi atualizado no processo, então só posso dizer que estou quase com certeza eles fizeram isso através deste plugin .

Sintomas :o mysql data diretório continha três arquivos com extensão PHP. Espere, o que?!? -- e dentro dos arquivos havia uma grande quantidade de código base64 que foi passado para base64_decode , gzuncompress e [eval()][2] . Ah . Claro que essas foram apenas as primeiras tentativas, as malsucedidas. O site tinha sido bem e verdadeiramente pwn3d.

Portanto, se você encontrar um arquivo no diretório de dados do mysql que está causando um erro 17, verifique-o com file utilitário ou escaneá-lo com um antivírus. Ou inspecione visualmente seu conteúdo. Não presuma que está lá por algum erro inócuo.

(Não é preciso dizer que, para inspecionar visualmente o arquivo, nunca clique duas vezes nele ).

A vítima neste caso (ele tinha um amigo "fazendo a manutenção") nunca teria adivinhado que ele havia sido hackeado até que um script de manutenção/atualização/qualquer que seja executasse um DROP DATABASE (não me pergunte por que - não tenho certeza nem se quero saber ) e deu um erro. Pela carga da CPU e pelas mensagens do syslog, tenho certeza de que o host se tornou um farm de spam.

Mais um erro 17


Se você rsync ou copie entre duas instalações MySQL da mesma versão mas diferentes plataformas ou sistemas de arquivos como Linux ou Windows (que é desencorajado e arriscado, mas muitos fazem isso mesmo assim), e especificamente com diferentes diferenciação de maiúsculas e minúsculas configurações, você pode acabar acidentalmente com duas versões do mesmo arquivo (seja dados, índice ou metadados); diga Customers.myi e Customer.MYI . O MySQL usa um deles e não sabe nada sobre o outro (o que pode estar desatualizado e levar a uma sincronização desastrosa). Ao descartar o banco de dados, o que também acontece em muitos mysqldump ... | ... mysql esquemas de backup, o DROP falhará porque esse arquivo extra (ou aqueles arquivos extras) existe. Se isso acontecer, você deve ser capaz de reconhecer o(s) arquivo(s) obsoleto(s) que precisam de exclusão manual do tempo do arquivo, ou do fato de que seu esquema de maiúsculas e minúsculas é diferente da maioria das outras tabelas.

Encontrando o diretório de dados


Em geral, você pode encontrar o diretório de dados inspecionando o my.cnf arquivo (/etc/my.cnf , /etc/sysconfig/my.cnf , /etc/mysql/my.cnf em Linux; my.ini no diretório de arquivos de programa MySQL no Windows), sob o [mysqld] título, como datadir .

Alternativamente, você pode perguntar ao próprio MySQL:
mysql> SHOW VARIABLES WHERE Variable_name LIKE '%datadir%';
+---------------+-----------------+
| Variable_name | Value           |
+---------------+-----------------+
| datadir       | /var/lib/mysql/ |
+---------------+-----------------+
1 row in set (0.00 sec)