Ответ 1
Быстрая починка
Если вы просто хотите удалить базу данных независимо от того, что (но, пожалуйста, сначала прочтите весь пост: ошибка была дана по причине, и может быть важно знать, в чем причина!), Вы можете:
- найдите каталог данных командой
SHOW VARIABLES WHERE Variable_name LIKE '%datadir%';
- остановите сервер MySQL (например,
service mysql stop
илиservice mysql stop
rcmysqld stop
или аналогичная в Linux,NET STOP <name of MYSQL service, often MYSQL57 or similar>
или черезSERVICES.MSC
в Windows) - перейти к датадиру (это то, где вы должны исследовать; см. ниже)
- удалить каталог с тем же именем, что и база данных
- снова запустите MySQL сервер и подключитесь к нему
- выполнить DROP DATABASE
- это!
Причины для Errno 13
MySQL не имеет разрешения на запись в родительский каталог, в котором mydb
папка 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 и попробуйте перейти в каталог base var, затем постепенно увеличивать cd до тех пор, пока вы не окажетесь в целевом каталоге, и выполнить что-то вроде touch aardvark && rm aardvark
. Если разрешения и владение совпадают, и все же вышеприведенное приводит к ошибке доступа, есть вероятность, что это проблема инфраструктуры безопасности.
Причины для Errno 39
Этот код означает "каталог не пустой". Каталог содержит некоторые скрытые файлы, о которых MySQL ничего не знает. Для не скрытых файлов см. Errno 17. Решение то же самое.
Причины для Errno 17
Этот код означает "файл существует". Каталог содержит некоторый файл MySQL, который MySQL не думает об удалении. Такие файлы могли быть созданы с помощью SELECT... INTO OUTFILE "filename";
команда, где filename
не имеет пути. В этом случае процесс MySQL создает их в своем текущем рабочем каталоге, который (протестированный на MySQL 5.6 на OpenSuSE 12.3) является каталогом данных базы данных, например /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 как флаг эксплойта
Это произошло в системе Linux с установленным Wordpress. К сожалению, у клиента были временные ограничения, и я не мог ни создать образ диска, ни провести реальный анализ - я переустановил всю машину, и Wordpress обновился в процессе, так что я могу только сказать, что я почти уверен, что они сделали это через это плагин.
Симптомы: каталог данных mysql
содержал три файла с расширением PHP. Чего ждать?!? - и внутри файлов была большая часть кода base64, который был передан в base64_decode
, gzuncompress
и [eval()][2]
. Ага. Конечно, это были только первые попытки, неудачные. Сайт был хорошо и по-настоящему pwn3d.
Поэтому, если вы нашли файл в вашем каталоге данных mysql, который вызывает ошибку 17, проверьте его с помощью file
утилиты или отсканируйте его антивирусом. Или визуально осмотрите его содержимое. Не принимайте это там за какую-то безобидную ошибку.
Жертва в этом случае (у него был какой-то друг, "выполняющий обслуживание") никогда бы не догадалась, что его взломали, пока сценарий обслуживания/обновления/любого другого сценария не запустил DROP DATABASE
(не спрашивайте меня, почему - я не уверен, даже Я хочу знать) и получил ошибку. Судя по загрузке процессора и сообщениям системного журнала, я вполне уверен, что хост превратился в ферму спама.
Еще одна ошибка 17
Если вы выполняете rsync
или копируете между двумя установками MySQL одной и той же версии, но с разными платформами или файловыми системами, такими как Linux или Windows (что не рекомендуется и рискованно, но многие, тем не менее, делают это), и, в частности, с разными настройками чувствительности к регистру, вы можете случайно получить две версии одного и того же файла (данные, индекс или метаданные); говорят Customers.myi
и Customer.MYI
. MySQL использует один из них и ничего не знает о другом (который может быть устаревшим и привести к катастрофической синхронизации). При удалении базы данных, что также происходит во многих mysqldump... |... mysql
mysqldump... |... mysql
схемах резервного копирования mysqldump... |... mysql
DROP
будет работать, потому что этот дополнительный файл (или эти дополнительные файлы) существует. Если это произойдет, вы сможете распознать устаревшие файлы, которые нуждаются в ручном удалении из времени файла, или из того факта, что их схема обращения отличается от большинства других таблиц.
Нахождение данных-каталога
В общем, вы можете найти каталог данных, /etc/my.cnf
/etc/sysconfig/my.cnf
my.cnf
(/etc/my.cnf
, /etc/sysconfig/my.cnf
, /etc/mysql/my.cnf
в Linux; my.ini
в MySQL каталог программных файлов в Windows), под заголовком [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)