2011-01-09 5 views
3

ユーザのグループがDBD::mysqlを使用してPerlのDBI経由でmysqlにサブミットすることを許可した場合、データベースを変更したり、重要ではない情報を漏洩したり、データベースの負荷?もしそうなら、どうですか?mysqlでは、「説明しています...」は常に安全ですか?

私は"explain $whatever"を介して、テーブル/列は(あなたがに持っているが、しかし、名を推測)と、表のおおよそどのように多くのレコードまたはインデックス付きフィールドの特定の値を持つレコードの数が存在するかを把握することができます知っています。インデックス化されていないフィールドの内容に関する情報を得ることはできません。

DBD::mysqlは複数のステートメントを許可してはいけません。したがって、どのクエリも実行することはできません(ただ1つのクエリを説明する)。サブクエリを実行するべきではなく、単に説明してください。

しかし、私はMySQLのエキスパートではなく、確かに私が気づいていないmysqlの機能もあります。

クエリプランを考え出す際に、オプティマイザは実際に式を実行して、インデックス付きフィールドが比較される値を思い付くことがありますか? atable.classがインデックスではなく、ユニークでclass='unused'にレコードを見つけていないだろうが、class='common' 100万レコードを見つけるだろうさ

explain select * from atable where class = somefunction(...) 

。評価するかもしれないsomefunction(...)?そして、somefunction(...)はそれがデータを変更するように書くことができますか?

+3

おそらくそれは安全ですが、私はとにかくそれをやりません;) 'explain'でだまされる理由がある人は、DBとmysql CLIのテストコピーを渡すべきです。テストDBを必要としない人は、クエリーを書くことから保存しなければならないので、 'explain'は必要ありません;) – hobbs

答えて

6

「Explain」は実行に時間がかかり、いくつかのリソースが使い果たされた場合にクラッシュするなど、任意の量のサーバーリソースを使用することがあります(たとえば、あまりにも多くのネストされたサブクエリによるスタックオーバーフロー)。

"Explain"は、一時的なディスクスペース、サーバーアドレススペース(32ビットシステムでは64ビットシステムでは仮想メモリ)またはスレッドスタック(故意に悪意を持って構築されたクエリの場合)を簡単に使い果たします。

一般に、完全に信頼されていないユーザーがSQLの一部を送信することを許可することはできません。 1つのテーブルにアクセスしなくても、サーバを十分に試してもクラッシュする可能性があります。


EDIT:さらに詳細

匿名ビューを使用するクエリ/副問合せをマテリアライズド、多くの場合、一時テーブルに、EXPLAIN時に全体の内側のクエリを実行します。フォーム

SELECT * FROM (
    SELECT h1.*, h2.* FROM huge_table h1, huge_table h2) AS rediculous 

だから、クエリが説明し、TMPDIRにディスクスペースを消費するために永遠にかかります。

+1

詳しい情報を提供できますか?どのような説明が任意の時間を要したり、一時的なディスクスペースやメモリを使い果たしたりする可能性がありますか? – ysth

+0

ありがとうございます。それは良い洞察です。これは、「説明する」の後にテキストの合計サイズを制限するだけの理由で、いくらかキャップされる可能性のあるもののように聞こえる。少なくとも、**私は、O(n!)またはO(n ** 2)として説明する複雑さが増していくSQLクエリを、クエリテキストの長さと比較することはできません。 – tye

+0

私は例を挙げました。 – MarkR

1

ユーザーがデータベースに接続できるようにするが、変更しないようにするには、ユーザー権限を使用する必要があります。SELECT権限しかない場合は、何も変更できません。

+0

ありがとう。それは素晴らしいアドバイスです。読解専用ユーザーを追加し、「説明する」ときにそれを使用すると、主要なリスク(「説明」によって更新を行う方法を理解している人)が完全になくなります。 – tye

+0

パーミッションシステムはデータの変更を止めますが、サーバをクラッシュさせたり、サービス拒否を引き起こしたりすることはありません。 – MarkR

3

私は正確なクエリに一致する行の正確な数を得るために '説明'を使用することができました。だから、1はすぐに何でも「秘密」の文字を決定した後、最終的には「秘密」の値を明らかにし、文字の順序を決定するに移動する

explain select * from user where name='tye' and secret like '%a%' 

を使用することができます。

関連する問題