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 stop
或 rcmysqld 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 问题 --
您冒着几个安全意识程序的风险拒绝再运行(例如,如果您对 SSH 密钥这样做,再见 SSH 连接;等)因为他们意识到他们现在处于不安全的环境中。 实际上,无论 MySQL 是否允许或 不是,MySQL 本身不知道 - 即有可能 默默地破坏整个数据库。 上述可能有时会由绝望且知识渊博的人在极度悲惨中完成,以再次获得进入其他地方的机会 无法访问的拧紧 MySQL 安装(即即使chown 777
。 请不要这样做 那个。对于那些还不知道的人来说,777(或 775,或 666)不是 不知何故 MySQL 程序员忘记应用的幻数 他们自己,或者不想让你知道。每个数字都有一个 含义,777 的意思是“我在此同意每个人用我的 东西,直到并包括执行它,就好像它是二进制文件或外壳一样 脚本”。通过这样做(你可能不会被允许这样做 这在一个配置良好的系统上),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_decode
、gzuncompress
和 [eval()][2]
。 啊哈。当然,这些只是第一次尝试,没有成功。该网站运行良好且真正 pwn3d。
因此,如果您在 mysql 数据目录中发现导致错误 17 的文件,请使用 file
实用程序检查它 或使用防病毒软件对其进行扫描。或目视检查其内容。 不要以为这是因为一些无害的错误。
(不用说,要直观地检查文件,永远不要双击它)。
在这种情况下,受害者(他有一些朋友“进行维护”)永远不会猜到他被黑客入侵了,直到维护/更新/任何脚本运行 DROP DATABASE
(不要问我为什么- 我什至不确定我是否想知道)并且出错了。从 CPU 负载和系统日志消息来看,我相当肯定主机已成为垃圾邮件场。
又一个错误 17
如果您rsync
或在相同版本但不同平台或文件系统(例如 Linux 或 Windows)的两个 MySQL 安装之间进行复制(不鼓励这样做,并且有风险,但许多人仍然这样做) ,特别是使用不同的case sensitivity 设置,您可能会意外地得到同一文件(数据、索引或元数据)的两个版本;说Customers.myi
和Customer.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