60

我未能删除数据库:

mysql> 删除数据库 mydb;
ERROR 1010 (HY000): 删除数据库时出错(不能 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

我该怎么办?

4

7 回答 7

131

快速解决

如果您无论如何都只想删除数据库(但请先阅读整篇文章:错误是有原因的,知道原因可能很重要!),您可以:

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

Errno 13 的原因

mydbMySQL 对文件夹所在的父目录没有写权限。

检查它

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

在 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. 如果权限和所有权匹配,但上述情况会产生访问错误,则很可能是安全框架问题。

“EASY FIX”被认为是有害的

我在“专家论坛”(不是Stack Overflow,谢天谢地)上遇到了一个“简单修复”建议,我有时会为 Web 和 FTP 问题找到相同的“修复”—— chown 777请不要那样做。对于那些还不知道的人来说,777(或 775,或 666)并不是 MySQL 程序员以某种方式忘记应用不想让你知道的神奇数字。每个数字都有一个含义,777 的意思是“我在此同意每个人对我的东西做任何他们想做的事情,直到并包括执行它,就好像它是一个二进制或 shell 脚本一样”。通过这样做(很可能你不会被允许在配置合理的系统上这样做),

  • 你冒着几个安全意识程序拒绝运行的风险(例如,如果你对你的 SSH 密钥这样做,再见 SSH 连接等),因为他们意识到他们现在处于不安全的环境中。
  • 您实际上允许对系统具有任何级别访问权限的每个人都可以读取和写入您的数据,无论 MySQL 是否允许,MySQL 本身都不知道- 即,可以默默地破坏整个数据库。
  • 有时可能会在极度困难的情况下,由绝望和知识渊博的人完成上述操作,以再次获得对原本无法访问的拧紧 MySQL 安装的访问权限(即甚至mysqladmin不再授予本地访问权限),并且一旦事情恢复就会立即撤消正常-这不是永久性的变化,即使那样也不是。这不是解决“一个能够删除我的数据库的奇怪技巧”的方法。

(不用说,它几乎也不是任何 Web 或 FTP 问题的真正解决方案。“最近,妻子的钥匙无法打开前门,她无法进入我们家”的解决方案是“检查钥匙或把锁修好或更换了';公认的更快chown 777的是“只要把前门敞开!轻松!可能发生的最坏情况是什么?”)

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)

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

更新:错误 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将失败,因为那个额外的文件(或那些额外文件)存在。如果发生这种情况,您应该能够从文件时间中识别出需要手动删除的过时文件,或者从它们的案例方案与大多数其他表不同的事实中识别出来。

查找数据目录

通常,您可以通过检查my.cnf文件(在 Linux 上为 , ;/etc/my.cnf/etc/sysconfig/my.cnfWindows中的 MySQL 程序文件目录中)在标题下找到数据目录,如./etc/mysql/my.cnfmy.ini[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)
于 2012-08-30T13:06:29.530 回答
34

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

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

这可以通过将小写参数更改恢复到以前的状态来解决。

于 2014-03-10T12:59:13.513 回答
10

只需前往/opt/lampp/var/mysql

在那里你可以找到你的database名字。打开那个文件夹。如果其中有任何文件,请删除

现在来phpmyadmin扔掉那个database

于 2017-11-09T17:21:53.990 回答
5

至于ERRORCODE 39,您绝对可以只删除磁盘上的物理表文件。该位置取决于您的操作系统分布和设置。在 Debian 上,它通常在 /var/lib/mysql/ database_name / 下,所以这样做:

rm -f /var/lib/mysql/<database_name>/

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

DROP DATABASE <database_name>
于 2018-05-03T07:50:22.180 回答
0

这就是我解决它的方法:

mysql> DROP DATABASE mydatabase;
ERROR 1010 (HY000): Error dropping database (can't rmdir '.\mydatabase', errno: 13)
mysql> 

我去删除了这个目录:C:\...\UniServerZ\core\mysql\data\mydatabase.

mysql> DROP DATABASE mydatabase;
ERROR 1008 (HY000): Can't drop database 'mydatabase'; database doesn't exist
于 2020-04-20T14:54:32.910 回答
-1

在我的情况下,一个不属于数据库的附加文件位于数据库文件夹中。删除所有触发错误的表后,Mysql 发现文件夹不为空。我删除了文件,drop 数据库工作正常。

于 2018-11-01T15:16:19.763 回答
-2

在linux中,只需转到“/var/lib/mysql”右键单击并(以管理员身份打开),在mysql文件夹中找到与您的数据库名称对应的文件夹并将其删除。就是这样。数据库被删除。

于 2018-07-13T08:00:52.463 回答