web-dev-qa-db-ja.com

多くのビューでDEFINERを変更する

問題があります データベースのバックアップ 更新後。私はなぜかわからないようにするために私のシステムをぶらついています。私が実行した1つのクエリがこの結果を返しました。

Got error: 1449: The user specified as a definer ('cittool'@'%') does not exist when using LOCK TABLES

調査の結果、これらのビューの定義者は、システムから削除された古い開発者アカウントであるようです。この問題のあるデータベースとビューはほとんど使用されず、ほとんどがアーカイブ目的で保持されています。

存在しない定義機能を持つビューが約40あります。すべてを同時に定義者を別のアカウントに変更する簡単な方法はありますか? mysqldumpですべてのビューをファイルにダンプして、そのファイルを編集してビューを再作成できるようにする方法はありますか?

27
Zoredache

すべてのビュー定義を含むテキストファイルを作成します。

mysql -uusername -ppassword -A --skip-column-names -e"SELECT CONCAT('SHOW CREATE VIEW ',table_schema,'.',table_name,'\\G') FROM information_schema.tables WHERE engine IS NULL" | mysql -uusername -ppassword -A --skip-column-names > AllMyViews.sql

そこからAllMyViews.sqlを編集します。次に、ビューをドロップします

mysql -uusername -ppassword -A --skip-column-names -e"SELECT CONCAT('DROP VIEW ',table_schema,'.',table_name,';') FROM information_schema.tables WHERE engine IS NULL" | mysql -uusername -ppassword -A

AllMyViews.sqlを編集した後、リロードします

mysql -uusername -ppassword -A < AllMyViews.sql

試してみる !!!

14
RolandoMySQLDBA

ALTER VIEW情報スキーマ と組み合わせて使用​​できます。あなたはそれをテキストファイルにダンプすることを言ったので、おそらく次のようなもの:

SELECT CONCAT("ALTER DEFINER=`youruser`@`Host` VIEW `",table_name,"` AS ", view_definition,";") 
FROM information_schema.views WHERE table_schema='databasename'

これをmysqlコマンドラインと混合します(* nixはWindowsに慣れていないと想定)。

> echo "*abovequery*" | mysql -uuser -p > alterView.sql
> mysql -uuser -p databasename < alterView.sql

補足: information_schemaエントリを直接変更することはできません 。注2:これは一度に1つのデータベースでのみ機能します。WHEREtable_schemaを省略すると、それぞれの間にUSEコマンドを挿入する必要があります。

26
Derek Downey

Derekのソリューションを自動化すると、DEFINERがroot@localhostに変更され、すべてのデータベースのすべてのビューでSQL SECURITY INVOKERが設定されます(最初にそれが必要であることを確認してください)。

mysql -BNe 'show databases' | \
egrep -v '^(information_schema|performance_schema)$' | \
while read DB
do 
    mysql -BNe "SELECT CONCAT(\"ALTER DEFINER=\`root\`@\`localhost\` SQL SECURITY INVOKER VIEW \",table_name,\" AS \", view_definition,\";\") FROM information_schema.views WHERE table_schema=\"$DB\"" | \
    mysql $DB
done

警告:mysqlを完全にバックアップしたことを確認してください(たとえば、mysqldを停止し、/ var/lib/mysql内のすべてのファイルをバックアップします)。実行する前に-念のため...私ですが、YMMVです。

また、次のコマンドを使用してすべてのテーブル/ビューを確認する必要があります。

mysql -BNe 'show databases' | \
egrep -v '^(information_schema|performance_schema)$' | \
while read DB
do 
   mysql -BNe 'show tables' $DB | \
   while read t
   do
      echo "check table $t;"
   done | mysql -BN $DB
done | \
egrep -v 'status\s*OK'

ビュー内の無効な定義者について文句を言うべきではありません。

3
Matija Nalis

データベースのすべてのビューをエクスポート<DB>

mysql -BNe "SELECT TABLE_NAME FROM TABLES WHERE TABLE_SCHEMA = '<DB>' AND TABLE_TYPE = 'VIEW'" \
    information_schema | xargs mysqldump --single-transaction --no-data <DB> >views.sql

または:

mysql -BNe "SELECT TABLE_NAME FROM VIEWS WHERE TABLE_SCHEMA = '<DB>'" \
    information_schema | xargs mysqldump --single-transaction --no-data <DB> >views.sql

views.sql(定義者を変更)を編集して再作成します。

cat views.sql | mysql <DB>

必要に応じて、-uおよび-pスイッチを指定します。

3
x-yuri

簡単なpythonスクリプトを作成して、本番データベースの定義者をローカルのデータベース定義者に置き換えました。このスクリプトは、ダンプファイルを変更し、指定したデータベースを自動的にインポートします。

GITリポジトリ: https://github.com/mjakal/db-auto-import

0
Martin