BLOGTIMES
2013/11/21

MySQL の View や Stored Procedure がダンプできない

  mysql 
このエントリーをはてなブックマークに追加

MySQL でリモート接続で定義したストアドがローカルから接続するとダンプできないという不思議な問題にどっぷりとハマってしまったのでメモ。

ユーザーが root だったりすると強制的にダンプできるので気づかないことも多いですが、MySQL の View や Stored Procedure には DEFINER という特性がついていて、誰がそれを定義したのかというのを覚えておくようになっています。これによって他のユーザーから View やストアドの内容を勝手に書き換えられるのを防ぐことができるので、この機能自体はセキュリティ的に有用です。

ちなみに DEFINER のデフォルト値は CURRENT_USER です。

これだけだと、ユーザーが同じであれば接続元をリモートからローカルに変えても問題なさそうという感じがしますが、ここにちょっとした落とし穴があります。というのも MySQL の CURRENT_USER はuser_name の値とhost_name がセットになったものだからです

MySQL :: MySQL 5.1 リファレンスマニュアル :: 17.2.1 CREATE PROCEDUREおよびCREATE FUNCTION 構文

user 値を附与する場合、それを ' user_name'@' host_name ' フォーマット(GRANT ステートメントに使用したと同じフォーマット)の中にあるMySQLアカウントにすべきです。user_name の値とhost_name の値が両方共必要です。CURRENT_USERをCURRENT_USER()として附与することもできます。DEFINER の初期値はCREATE PROCEDUREもしくはCREATE FUNCTIONもしくはステートメントを実行するユーザです。(これはDEFINER = CURRENT_USERと同じです。)

実際にローカル接続とリモート接続の時の CURRENT_USER を SELECT してみると分かりますが、こんな感じになります。
つまり、ローカル接続のときとリモート接続の時で違う DEFINER になっているわけです。

【ローカル接続: 】 mysql> select CURRENT_USER; +-------------------+ | CURRENT_USER | +-------------------+ | hogeuser@locahost | +-------------------+ 【リモート接続】 mysql> select CURRENT_USER; +--------------+ | CURRENT_USER | +--------------+ | hogeuser@% | +--------------+

つまり、このホスト名の部分は MySQL の認証機構の根幹に関わっているため省略することができません
また、DEFINER の値は View の呼出に時に SQL の実行ユーザーとして使われることもあります*1

とりあえず、ストアドについては下記の SQL で DEFINER を一括してアップデートすることができることが分かりました。

UPDATE `mysql`.`proc` SET definer = 'hogeuser@%' WHERE definer='hogeuser@localhost' AND db='fugadb';
  • *1: SQL SECURITY { DEFINER | INVOKER } が DEFINER と指定されている場合(INVOKER の場合は呼び出したユーザーの権限で実行となる)。

トラックバックについて
Trackback URL:
お気軽にどうぞ。トラックバック前にポリシーをお読みください。[policy]
このエントリへのTrackbackにはこのURLが必要です→https://blog.cles.jp/item/6287
Trackbacks
このエントリにトラックバックはありません
Comments
愛のあるツッコミをお気軽にどうぞ。[policy]
古いエントリについてはコメント制御しているため、即時に反映されないことがあります。
コメントはありません
Comments Form

コメントは承認後の表示となります。
OpenIDでログインすると、即時に公開されます。

OpenID を使ってログインすることができます。

Identity URL: Yahoo! JAPAN IDでログイン