MySQL:删除数据库时出错(错误13;错误号17;错误号39)

Phi*_*ayo 54 mysql errno

我没有删除数据库:

mysql> drop database mydb;
ERROR 1010 (HY000): Error dropping database (can't rmdir './mydb', errno: 39)

目录db/mydb存在于mysql树中,但没有表:

# ls -l db/mydb
-rw-rw---- mysql mysql HIS_STAT.MYD
-rw-rw---- mysql mysql HIS_STAT.MYI

我该怎么办?

LSe*_*rni 110

快速解决

如果你只是想放弃数据库而不管是什么(但请先阅读整篇文章:错误是出于某种原因,并且了解原因可能很重要!),你可以:

  • 使用命令查找datadir SHOW VARIABLES WHERE Variable_name LIKE '%datadir%';
  • 停止MySQL服务器(例如service mysql stop,rcmysqld stop在Linux上,NET STOP <name of MYSQL service, often MYSQL57 or similar>SERVICES.MSC在Windows 上,或通过Windows)
  • 转到datadir(这是你应该调查的地方;见下文)
  • 删除与数据库同名的目录
  • 再次启动MySQL服务器并连接到它
  • 执行DROP DATABASE
  • 而已!

Errno的原因13

MySQL对mydb文件夹所在的父目录没有写权限.

检查一下

ls -la /path/to/data/dir/         # see below on how to discover data dir
ls -la /path/to/data/dir/mydb   
Run Code Online (Sandbox Code Playgroud)

在Linux上,如果混合使用MySQL和AppArmor/SELinux软件包,也会发生这种情况.发生的事情是AppArmor希望mysqld拥有其数据/path/to/data/dir,并允许完整的R/W,但MySQLd来自不同的分发或构建,它实际上将其数据存储在其他地方(例如:/var/lib/mysql5/data/**相反/var/lib/mysql/**).所以你看到的是该目录具有正确的权限和所有权,但它仍然给Errno 13,因为apparmor/selinux将不允许访问它.

要验证,请检查系统日志中是否存在安全违规,手动检查apparmor/selinux配置,和/或模拟mysql用户并尝试转到基本var目录,然后逐步cd,直到您进入目标目录,然后运行类似touch aardvark && rm aardvark.如果权限和所有权匹配,但上述产生访问错误,则可能是安全框架问题.

Errno的原因39

此代码表示"目录不为空".该目录包含MySQL一无所知的一些隐藏文件.对于非隐藏文件,请参阅Errno 17.解决方案是相同的.

Errno的原因17

此代码表示"文件存在".该目录包含MySQL不感兴趣删除的MySQL文件.这些文件可能是由没有路径的SELECT ... INTO OUTFILE "filename";命令创建的filename.在这种情况下,MySQL进程在其当前工作目录中创建它们(在OpenSuSE 12.3上的MySQL 5.6上测试)是数据库数据目录,例如/var/lib/mysql/data/nameofdatabase.

重现:

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)
Run Code Online (Sandbox Code Playgroud)

将文件移到外面(如果不需要则删除),然后重试.此外,首先确定它们的创建原因 - 它可能指向某些应用程序中的错误.或者更糟:见下文......

更新:错误17作为漏洞利用标志

这发生在安装了Wordpress的Linux系统上.不幸的是,客户受到时间限制,我无法对磁盘进行映像或进行真正的取证 - 我重新安装了整台机器并且Wordpress在此过程中得到了更新,所以我只能说我几乎可以肯定他们是通过这个来完成的插件.

症状:mysql数据目录包含三个扩展名为PHP的文件.等等,什么?!?- 在文件中有大量的base64代码传递给base64_decode,gzuncompress[eval()][2].啊哈.当然这些只是第一次尝试,不成功的尝试.该网站已经很好,真正的pwn3d.

因此,如果您在mysql数据目录中找到导致错误17的文件,请使用file实用程序检查它或使用防病毒软件扫描它.或目测检查其内容.不要以为它存在一些无害的错误.

(不用说,要目视检查文件,不要双击它).

在这种情况下受害者(他有一些朋友"做维护")永远不会猜到他被黑客攻击,直到维护/更新/任何脚本运行DROP DATABASE(不要问我为什么 - 我甚至不确定我想要知道)并得到一个错误.从CPU负载和系统日志消息中,我非常肯定主机已成为垃圾邮件服务器场.

又一个错误17

如果您rsync在相同版本但不同平台或文件系统(如Linux或Windows)的两个MySQL安装之间进行复制(不鼓励,冒险,但许多人仍然这样做),特别是使用不同的区分大小写设置,您可能会意外地结束了两个版本相同的文件的(或者数据,索引或元数据); 说Customers.myiCustomer.MYI.MySQL使用其中一个并且对另一个一无所知(可能过时并导致灾难性的同步).在删除数据库时(许多mysqldump ... | ... mysql备份方案中也会发生这种情况),DROP将会失败,因为存在额外的文件(或那些额外的文件).如果发生这种情况,您应该能够识别需要从文件时间手动删除的过时文件,或者它们的案例方案与大多数其他表不同的事实.

找到data-dir

在一般情况下,你可以通过检查发现数据目录my.cnf文件(/etc/my.cnf,/etc/sysconfig/my.cnf,/etc/mysql/my.cnf在Linux上,my.ini在Windows MySQL的程序文件目录),下[mysqld]标题,如datadir.

或者你也可以问MySQL本身:

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

  • 就我而言,我尝试使用 OUTFILE 转储表,并且该文件保存在数据库名称下的数据目录中。通过删除该文件解决了它。 (2认同)

小智 29

在我的情况下,这是由于'lower_case_table_names'参数.

启用了当我尝试删除包含带有lower_case_table_names参数的大写表名的数据库时抛出的错误号39.

通过将小写参数更改恢复为先前状态来解决此问题.

  • 这解决了我的问题.您可以还原它,删除您的数据库并将其还原... (4认同)

ven*_*kat 5

只需转到 /opt/lampp/var/mysql

在那里您可以找到您的database名字。打开该文件夹。删除其中是否有文件

现在phpmyadmin来看一下database


Tom*_*mRA 5

至于ERRORCODE 39,你肯定可以删除磁盘上的物理表文件。位置取决于您的操作系统分发和设置。在 Debian 上,它通常在 /var/lib/mysql/ database_name / 下,所以请执行以下操作:

rm -f /var/lib/mysql/<database_name>/
Run Code Online (Sandbox Code Playgroud)

然后从您选择的工具中删除数据库或使用以下命令:

DROP DATABASE <database_name>
Run Code Online (Sandbox Code Playgroud)