問題があります データベースのバックアップ 更新後。私はなぜかわからないようにするために私のシステムをぶらついています。私が実行した1つのクエリがこの結果を返しました。
Got error: 1449: The user specified as a definer ('cittool'@'%') does not exist when using LOCK TABLES
調査の結果、これらのビューの定義者は、システムから削除された古い開発者アカウントであるようです。この問題のあるデータベースとビューはほとんど使用されず、ほとんどがアーカイブ目的で保持されています。
存在しない定義機能を持つビューが約40あります。すべてを同時に定義者を別のアカウントに変更する簡単な方法はありますか? mysqldumpですべてのビューをファイルにダンプして、そのファイルを編集してビューを再作成できるようにする方法はありますか?
すべてのビュー定義を含むテキストファイルを作成します。
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
試してみる !!!
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コマンドを挿入する必要があります。
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'
ビュー内の無効な定義者について文句を言うべきではありません。
データベースのすべてのビューをエクスポート<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
スイッチを指定します。
簡単なpythonスクリプトを作成して、本番データベースの定義者をローカルのデータベース定義者に置き換えました。このスクリプトは、ダンプファイルを変更し、指定したデータベースを自動的にインポートします。
GITリポジトリ: https://github.com/mjakal/db-auto-import