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

Posted

技术标签:

【中文标题】MySQL:删除数据库时出错(errno 13;errno 17;errno 39)【英文标题】:MySQL: Error dropping database (errno 13; errno 17; errno 39) 【发布时间】:2012-08-25 04:31:27 【问题描述】:

我未能删除数据库:

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

我该怎么办?

【问题讨论】:

听起来像是权限问题。你能发布完整的ls -l 输出吗? @Chris Henry:我已经用# ls -l mydb 的结果更新了问题 【参考方案1】:

快速修复

如果您无论如何都想删除数据库(但首先阅读整篇文章:错误是出于某种原因给出的,这可能很重要要知道原因是什么!),您可以:

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

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   

在 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 的意思是“我在此同意每个人用我的 东西,直到并包括执行它,就好像它是二进制文件或外壳一样 脚本”。通过这样做(你可能不会被允许这样做 这在一个配置良好的系统上),

您冒着几个安全意识程序的风险拒绝再运行(例如,如果您对 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 在此过程中得到了更新,所以我只能说我几乎 确定他们是通过this plugin 做到的。

症状mysql 数据目录包含三个扩展名为 php 的文件。 等等,什么?!? -- 在文件中,有大量 base64 代码被传递给 base64_decodegzuncompress[eval()][2]啊哈。当然,这些只是第一次尝试,没有成功。该网站运行良好且真正 pwn3d。

因此,如果您在 mysql 数据目录中发现导致错误 17 的文件,请使用 file 实用程序检查它 或使用防病毒软件对其进行扫描。或目视检查其内容。 不要以为这是因为一些无害的错误。

(不用说,要直观地检查文件,永远不要双击它)。

在这种情况下,受害者(他有一些朋友“进行维护”)永远不会猜到他被黑客入侵了,直到维护/更新/任何脚本运行 DROP DATABASE不要问我为什么- 我什至不确定我是否想知道)并且出错了。从 CPU 负载和系统日志消息来看,我相当肯定主机已成为垃圾邮件场。

又一个错误 17

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

查找数据目录

一般情况下,您可以通过检查my.cnf 文件(在Linux 上为/etc/my.cnf/etc/sysconfig/my.cnf/etc/mysql/my.cnf;在Windows 中的MySQL 程序文件目录中my.ini)找到数据目录,在@ 下987654357@ 标题,如datadir

您也可以向 MySQL 本身询问:

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

【讨论】:

感谢@xk0der 的提醒(但我相信这实际上应该是一个评论)。关于my.cnf 的建议已添加到答案中。 errno 13 的东西可能对来这里进行故障排除的人很有用,所以我决定保留它。 就我而言,我试图使用 OUTFILE 转储表,并且该文件保存在数据库名称下的数据目录中。通过删除该文件解决了它。【参考方案2】:

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

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

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

【讨论】:

是的。这可能是由于该设置。但是,恢复该设置不是正确的解决方案,而是妥协恕我直言。 这解决了我的问题。您可以还原它,删除您的数据库并将其还原... 是的,这也是我的原因【参考方案3】:

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

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

现在来phpmyadmin 并放弃database

【讨论】:

【参考方案4】:

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

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

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

DROP DATABASE <database_name>

【讨论】:

这对我有用。在删除文件之前,先停止mysql服务器(service mysql stop),然后删除文件并重新启动。最后登录mysql和DROP db。 非常感谢,很有用,救救我,简单直接。【参考方案5】:

我就是这样解决的:

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

【讨论】:

【参考方案6】:

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

【讨论】:

【参考方案7】:

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

【讨论】:

以上是关于MySQL:删除数据库时出错(errno 13;errno 17;errno 39)的主要内容,如果未能解决你的问题,请参考以下文章

删除数据库时出错(不能 rmdir './someDB/', errno: 17)

在 SQL 中删除数据库时出错(不能 rmdir './tract',errno: 66)

在 Mac OS 上的 MySQL Workbench 上删除数据库时出现错误 1010

解决MySQL复制出错 Last_SQL_Errno:1146

MySQL删除数据库时的错误(errno: 39)

linux c 打开文件 errno 13