web-dev-qa-db-ja.com

MySQL:データベースの削除エラー(errno 13; errno 17; errno 39)

データベースの削除に失敗しました:

 mysql> drop database mydb; 
エラー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 

私は何をすべきか?

53
Philippe Blayo

クイックフィックス

何があってもデータベースを削除したいだけの場合(ただし please は最初に投稿全体を読みます:エラー理由のために与えられた。理由を知ることが重要です!)、次のことができます:

  • コマンドSHOW VARIABLES WHERE Variable_name LIKE '%datadir%';でdatadirを見つけます
  • mySQLサーバーを停止します(例:Linuxではservice mysql stopまたはrcmysqld stop、またはLinuxではNET STOP <name of MYSQL service, often MYSQL57 or similar>またはWindowsではSERVICES.MSCを使用)
  • 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   

Linuxでは、MySQLとAppArmor/SELinuxパッケージを組み合わせて使用​​した場合にも発生する可能性があります。何が起こるかというと、AppArmorはmysqldが/path/to/data/dirにデータを持っていることを期待し、そこに完全なR/Wを許可しますが、MySQLdは異なるディストリビューションまたはビルドのものであり、実際にデータを保存しますelsewhere (例:/var/lib/mysql5/data/**ではなく/var/lib/mysql/**)。つまり、ディレクトリには正しいアクセス許可と所有権がありますが、apparmor/selinuxはアクセスを許可しないため、Errno 13が引き続き表示されます。

確認するには、システムログでセキュリティ違反を確認し、手動でapparmor/selinux設定を検査し、mysqlユーザーになりすましてベースvarディレクトリに移動してから、ターゲットディレクトリに移動するまで増分cdし、次のように実行しますtouch aardvark && rm aardvark。権限と所有権が一致しているにもかかわらず、上記の方法でアクセスエラーが発生する場合、セキュリティフレームワークの問題である可能性があります。

Errno 39の理由

このコードは「空でないディレクトリ」を意味します。ディレクトリには、MySQLが何も知らないhiddenファイルが含まれます。非隠しファイルについては、Errno 17を参照してください。解決策は同じです。

Errno 17の理由

このコードは「ファイルが存在する」ことを意味します。ディレクトリには、MySQLが削除について感じないMySQLファイルが含まれています。このようなファイルは、filenameにパスがないSELECT ... INTO OUTFILE "filename";コマンドによって作成された可能性があります。この場合、MySQLプロセスはそれらを現在の作業ディレクトリに作成します(OpenSuSE 12.3上のMySQL 5.6でテスト済み)は、データベースの dataディレクトリです。 /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が更新されたため、私は almost 確実に このプラグイン で実行しました。

症状mysqlデータディレクトリには、拡張子PHPの3つのファイルが含まれていました。 待って、何?!?-そして、ファイル内には、base64_decodegzuncompress[eval()][2] Aha 。もちろん、これらは最初の試みであり、失敗したものです。このサイトはよく、本当にpwn3dでした。

したがって、エラー17の原因となっているmysqlデータディレクトリ内にファイルが見つかった場合は、fileユーティリティで確認またはウイルス対策ソフトウェアでスキャンします。または、その内容を視覚的に検査します。 無害な間違いがあると想定しないでください。

(言うまでもなく、ファイルを視覚的に検査するには、ダブルクリックしないでください)。

この場合の被害者(友人に「メンテナンスを行う」という友人がいた)は、メンテナンス/更新/スクリプトがDROP DATABASE do not askなぜだか-知りたい)でもわからないし、エラーが発生した。 CPU負荷とsyslogメッセージから、ホストがスパムファームになったことはかなり肯定的です。

さらに別のエラー17

同じバージョンの2つのMySQLインストール間でrsyncをコピーするか、異なるプラットフォームまたはファイルシステム(LinuxまたはWindowsなど)それにもかかわらず)、特に異なる 大文字と小文字の区別 設定を使用すると、誤って同じファイル(データ、インデックス、メタデータのいずれか)の2つのバージョンで終わる可能性があります); Customers.myiおよびCustomer.MYIと言います。 MySQLはそのうちの1つを使用し、もう1つについては何も認識しません(これは古く、壊滅的な同期につながる可能性があります)。多くのmysqldump ... | ... mysqlバックアップスキームでも発生するデータベースを削除すると、DROPは失敗します。これは、その追加ファイル(または those 追加ファイル)が存在するためです。 。これが発生した場合、ファイル時間から、またはそれらのケーススキームが他の大部分のテーブルと異なるという事実から、手動で削除する必要がある古いファイルを認識できるはずです。

データディレクトリを見つける

一般的に、データディレクトリは、my.cnfファイル(/etc/my.cnf/etc/sysconfig/my.cnf、Linuxの/etc/mysql/my.cnf、MySQLプログラムファイルディレクトリのmy.iniを調べることで見つけることができます。 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)
107
LSerni

私の場合、「lower_case_table_names」パラメーターが原因でした。

Lower_case_table_namesパラメーターを持つ大文字のテーブル名で構成されるデータベースを削除しようとすると、エラー番号39がスローされます。

これは、小文字のパラメーターの変更を以前の状態に戻すことで修正されます。

28
Sambuvarayas

単に/opt/lampp/var/mysql

そこでdatabase名を見つけることができます。そのフォルダを開きます。ファイルがあれば削除します

phpmyadminに移動して、そのdatabaseをドロップします

5
venkat

ERRORCODE 39に関しては、ディスク上の物理テーブルファイルを完全に削除できます。場所は、OSの配布とセットアップによって異なります。 Debianでは、通常/ var/lib/mysql /database_name/の下にあります。

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

次に、選択したツールから、またはコマンドを使用してデータベースを削除します。

DROP DATABASE <database_name>
2
TomRA

私の場合、データベースに属していない追加のファイルがデータベースフォルダー内にありました。エラーを引き起こしたすべてのテーブルを削除した後、Mysqlはフォルダーが空でないことを検出しました。ファイルを削除すると、ドロップデータベースは正常に機能しました。

0
fran