MySQLダンプからDEFINER句を削除


114

データベースの1つのMySQLダンプがあります。その中には、次のようなDEFINER句があります。

"DEFINER=`root`@`localhost`" 

つまり、これらのDEFINER句はCREATE VIEWおよびCREATE PROCEDUREステートメントにあります。これらのDEFINER句をダンプファイルから削除する方法はありますか?


バグは数年前に報告されましたが、見捨てられたようです:bugs.mysql.com/bug.php
id=

回答:


109

DEFINERダンプへのの追加を無視する方法はないと思います。ただし、ダンプファイルの作成後にそれらを削除する方法があります。

  1. テキストエディターでダンプファイルを開き、すべての出現箇所をDEFINER=root@localhost空の文字列 ""に置き換えます

  2. 以下を使用して、ダンプを編集(または出力をパイプ)しperlます。

    perl -p -i.bak -e "s/DEFINER=\`\w.*\`@\`\d[0-3].*[0-3]\`//g" mydatabase.sql
  3. 出力をパイプしますsed

    mysqldump ... | sed -e 's/DEFINER[ ]*=[ ]*[^*]*\*/\*/' > triggers_backup.sql

1
@FastTrack、文字列全体を削除してください。
Abhay

3
DEFINERを削除する代わりに、次のようにCURRENT_USERに設定できることをお勧めします:sed -E 's/DEFINER=[^ ]+@ [^] + /DEFINER=CURRENT_USER/g' dump.sql > new_dump.sql制限/アクセス制御を維持するという利点があります。
4thfloorstudios 2016年

27
このsedコマンドは、プロシージャと関数からDEFINER句を削除しません。ここで強化されたバージョンは、そのハンドルのビュー、トリガ、プロシージャと関数: sed -e 's/DEFINER[ ]*=[ ]*[^*]*\*/\*/' | sed -e 's/DEFINER[ ]*=[ ]*[^*]*PROCEDURE/PROCEDURE/' | sed -e 's/DEFINER[ ]*=[ ]*[^*]*FUNCTION/FUNCTION/'
ウラジミールStrugatsky

4
FYI ---この回答の時点ではそうではありませんでしたが、MySQL> 5.6には、オプションとして「--skip- definer
Kevin_Kinsey

4
いいえ、それはmysqldumpではありませんが、--skip-definerを持つmysql p umpです。
-Xdg

70

SEDを使用して削除できます

sed -i 's/DEFINER=[^*]*\*/\*/g' mydump.sql

MacOSの場合:

sed -i '' 's/DEFINER=[^*]*\*/\*/g' mydump.sql

ここMacOSで何が違うのですか?
Alex

1
Macでのsedのマンページには次のように書か -i extensionれています。ディスクスペースが使い果たされた場合などに破損または部分的なコンテンツのリスクがあるため、インプレース編集ファイル。」
チャド

それを知ってうれしい、@チャド。Macでこのようなsedを5年以上使用しています。スペースや破損したファイルの問題は一度もありませんでした。しかし、もちろん、考慮すべきことです。明確にしていただきありがとうございます。
Ricardo Martins

Macでもこれらの問題に遭遇したことはありません。@アレックスが尋ねたので私が明確にするだろうと思っただけです:)
チャド

57

mysqlバージョン5.7.8以降--skip-definer、mysqlpumpでオプションを使用できます。例:

mysqlpump --skip-definer -h localhost -u user -p yourdatabase

http://dev.mysql.com/doc/refman/5.7/en/mysqlpump.html#option_mysqlpump_skip-definerで更新されたmysqlマニュアルを参照してください


8
mysqldumpとの違いは何だろうと思う人のためにmysqlpump-ここに関連する質問があります:dba.stackexchange.com/questions/118846/mysqldump-vs-mysqlpump
Scadge

phpMyAdminとMySQL Workbenchがインストールされています。Windowsでこのコマンドを実行するにはどうすればよいですか?
posfan12

(いくつかのテストの後:-1)を使用しますinformation_schema.userが、これはすべてのユーザーにとって常に読み取り可能とは限りません
bato3

17

これらのアイデアを使用して、自分のmysqldump出力からDEFINER句を取り除きましたが、より簡単な方法を採用しました。

削除するだけ !コード前とDEFINERをで、コメントの残りは通常のコメントになります。

例:

/*!50017 DEFINER=`user`@`111.22.33.44`*/

これを行うだけで無力にレンダリングされます。

/* 50017 DEFINER=`user`@`111.22.33.44`*/

ただし、最も簡単な正規表現は、!と数字

mysqldump | /usr/bin/perl -pe 's/\!\d+ DEFINER/DEFINER/' > dumpfile.sql

それは!#### DEFINERDEFINERを削除して置き換えます... DEFINERも削除することができます。なくなっている


16

相手の推奨事項に従って、ダンプが完了した後、DEFINERをダンプから削除する方法の例を次に示します。

mysqldump -u user --password='password' -h localhost database | grep -v "50013 DEFINER" > dump.sql

4
トリガーの場合、行は/ *!50003 CREATE * / / *!50017 DEFINER = user@ localhost* / / *!50003 trigger my_triggername BEFORE INSERT ON my_table FOR EACH ROW .... * / ;;のようになります。そしてgrep -vそれらの行を完全に削除します。(ただし50017!= 50013)
ケニー

13

他の人が述べたように、あらゆる種類の正規表現で定義者を取り除くことはあまり複雑ではありません。しかし、他の例では、ビューの定義が取り除かれました。

これは私のために働いた正規表現です:

sed -e 's/DEFINER=[^ ]* / /'

そしてより速く^^ありがとう
KevinLabécot15年

1
トリガーでは機能しません-も削除します*/。MySQL 5.6.31。
FrancDrobnič16年

10

自動化されたソリューションについては、をご覧くださいmysqlmigrate。これは、mysqldumpデータベースを移行してDEFINERステートメントを無視できるようにするBashラッパーです。例:

$ mysqlmigrate -u root -p pass --ignore-definer from_db to_db

http://thesimplesynthesis.com/post/mysqlmigrate(またはGitHub

それ以外の場合は、はい、Abhayが指摘するようなコマンドが必要です。

$ mysqldump -u root -ppass the_db | sed -e 's/DEFINER[ ]*=[ ]*[^*]*\*/\*/' > the_db.sql

6

ファイル内の定義者を削除するOSXの別のオプション:

sed -i '' 's/DEFINER=`[^`][^`]*`@`[^`][^`]*`//g' file.sql

5

あなたはここで答えを見る必要があります:https : //dba.stackexchange.com/questions/9249/how-do-i-change-the-definer-of-a-view-in-mysql/29079#29079

私の意見では、この問題に対処する最善の方法は、sedやgrepなどの文字列の余分な解析を追加することではなく、mysqldumpが--single-transactionを追加することで適切なダンプを生成できることです


なぜ反対票を投じたのですか?なぜこの回答は役に立たないと考えられているのですか?
Jose Nobile 2017

1
あなたの返答は、それにふさわしいポジションを得るために約90票を必要とします。あなたは私のものを持っています:)
Patrick van Bergen

4

これを行う簡単な方法は、mysqldumpの出力をsedにパイプしてDEFINER、条件付きコメントで囲まれたステートメントを削除することです。これDEFINERCREATE TRIGGERステートメントから削除するために使用しますが、目的に合わせて正規表現で条件コメントのバージョン番号を調整できます。

mysqldump -u user --password='password' -h localhost database | \
  sed 's/\/\*!50017 DEFINER=`.*`@`.*`\*\///' 

1
もう少し読みやすいsedステートメント:sed "s / DEFINER(。*?)FUNCTION / FUNCTION /"
reustmd

4

それが役立つかどうかはわかりませんが、私はSQLyog Community Editionを使用しています。

https://code.google.com/p/sqlyog/wiki/Downloads

SQLをダンプしたり、別のデータベースにコピーしたりすると、「DEFINERを無視する」ことができます

無料で、多くの人が必要とする基本的な機能を提供します

から利用できる有料版もあります:-

https://www.webyog.com/product/sqlyog

乾杯


単に「役に立たない」とフラグを立てるのではなく、なぜ役に立たないと感じたのかを返信した方が便利でしょう。
2014

3

私にとって、これは機能しますperl -p -i.bak -e "s/DEFINER=[^ |\s]*//g" yourdump.dmp。これにより、作成プロシージャの各ステートメントで、ダンプからDEFINER = root @ localhostが削除されました


2

MySQL 5.6.xとLinuxのDEFINER情報を削除するための完全に機能するソリューションを次に示します。(テスト済みCentOS 6.5

通常、Mysqlダンプの次のエントリを置き換える必要があります(データおよびトリガー/ルーチン/関数と一緒に取得した場合)。

/*!50013 DEFINER=`MYSQLUSER`@`localhost` SQL SECURITY DEFINER */
/*!50013 DEFINER=`MYSQLUSER`@`%` SQL SECURITY DEFINER */
CREATE DEFINER=`MYSQLUSER`@`%` PROCEDURE `PROCEDURENAME`(
CREATE DEFINER=`MYSQLUSER`@`localhost` PROCEDURE `PROCEDURENAME`(
CREATE DEFINER=`MYSQLUSER`@`%` FUNCTION `FUNCTIONNAME`(
CREATE DEFINER=`MYSQLUSER`@`localhost` FUNCTION `FUNCTIONNAME`(
/*!50003 CREATE*/ /*!50017 DEFINER=`MYSQLUSER`@`%`*/ /*!50003 TRIGGER `TRIGGERNAME`
/*!50003 CREATE*/ /*!50017 DEFINER=`MYSQLUSER`@`localhost`*/ /*!50003 TRIGGER `TRIGGERNAME`

ダンプは、以下のmysqldumpコマンドで取得されました。

mysqldump -uMYSQLUSER -pPASSWORD DATABASENAME -R > dbdump.sql

DEFINER情報のない必須のダンプファイルは、以下の3つのコマンドで取得できます。

Command-1    
sed -i 's|DEFINER=[^*]*\*|\*|g' [PATH/]dbdump.sql

Command-2
find -name [PATH/]dbdump.sql | xargs perl -pi -e "s/ DEFINER=\`MYSQLUSER\`@\`localhost\`//"

Command-3
find -name [PATH/]dbdump.sql | xargs perl -pi -e "s/ DEFINER=\`MYSQLUSER\`@\`%\`//"

ダンプファイルが現在のフォルダーにある場合は、[PATH /]を無視してください。

テーブルのデータが非常に大きい場合は、2つのファイルでダンプを取得し、1つのダンプファイルでデータ付きのダンプを取得し、他のダンプファイルでスクリプトのみのダンプ(トリガー/関数/手順)を取得して、上記の3つを実行します。 2番目のダンプ(スクリプト)ファイルのコマンド。


1

すべての定義者ユーザーをCURRENT_USERに置き換えます。バックアップを作成する私のgradleスクリプトでは、私の置換スクリプトは次のようになります。

ant.replaceregexp(file: "$buildDir/sql/setupDB.sql", match: "`${project.ext.prod_db_username}`@`%`", replace: "CURRENT_USER", byline: true);

これは本当にANTを呼び出しているだけです。そうすれば、心配する必要はありません。


1

Linuxマシンでは、次のワンライナーを使用できます。

mysql -uuser -ppwd -A --skip-column-names -e"SELECT CONCAT('SHOW CREATE VIEW ',table_schema,'.',table_name,';') FROM information_schema.tables WHERE engine IS NULL and table_schema like 'mydb%'" | mysql -uuser -ppwd -A --skip-column-names | sed -rn 's/.*?VIEW ([^\s]+?) (AS .*?)\s([^\s]+?)\s([^\s]+?)/DROP VIEW \1;\nCREATE VIEW \1 \2;/p' | mysql -uuser -ppwd -A --skip-column-names

太字の文字列を、DBユーザーの資格情報とデータベース名/ likeパターンで置き換えるだけです。

詳細はこちら:http : //blog.novoj.net/2014/05/16/recreate-mysql-views-without-definer-one-liner-solution-linux/


1

Windowsで動作させる唯一の方法:

http://gnuwin32.sourceforge.net/をインストールして、コマンドラインでsedを実行し、WindowsのPATHに追加します。D:\ programs \ GetGnuWin32 \ bin;

sed -i "s|DEFINER=`mydbuser`@`%%` SQL SECURITY DEFINER||g" "D:/prod_structure.sql"

sed -i "s|DEFINER=`mydbuser`@`%%`||g" "D:/prod_structure.sql"

mysqldump -P{port} -h{host} -u{user} -p{password} --routines --no-data --lock-tables=false database_prod > D:\prod_structure.sql

1

ヒントをありがとうございます。怠惰なので、「MYsqldump」という名前のスクリプトを書きました。

DB=$1
HOST=$2
USER=$3
MYSQLDUMP='/usr/bin/mysqldump'
PARAMS="--complete-insert --disable-keys=0 --extended-insert=0 --routines=0 --skip-comments"
DAY=`date +%d`
MONTH=`date +%m`
YEAR=`date +%Y`
FILE=$DB.$DAY-$MONTH-$YEAR.sql

    if (( $# < 3 )) ; then
        echo ""
        echo "usage: MYsqldump <db> <host> <user>"
        echo ""
        exit 1
    fi

    $MYSQLDUMP -h $HOST -u $USER -p  $PARAMS $DB | grep -v '/*!50013 DEFINER' > $FILE

1

次のような場合:

区切り文字;;
CREATE DEFINER = `mydb` @` localhost` FUNCTION `myfunction`()はint(11)を返します
ベギン
(...)
終わり ;;

これを試して:

mysqldump --force --routines --opt --user = myuser --databases mydb | sed -e 's / DEFINER = `。*` @ `。*` \ // g'

1
  1. 任意のエディターでデータベースを開きます。メモ帳++で使用しました。

  2. すべてのテストを見つけDEFINER=root@localhost 、それをnone("")IEに置き換えます。消して。

次に、それを任意のホストにインポートできます。


0

私にとってすべてのオブジェクトで機能する最も単純な正規表現は次のとおりです。

sed 's/DEFINER=[^ ]*`//' ...

quote-namesする必要があることに注意してくださいTRUE(デフォルトである)。

新しいバージョンでは--skip-definer、バージョン5.7のmysqlpumpで導入されたスイッチもmysqldumpに含まれることを願っています。


0

PowerShellスクリプトを使用して、次の行をすべて削除しましたDEFINER

get-content $ file_in_full_path | 選択文字列-パターン$ line_string_delete -notmatch | Out-File -width 1000000000 -Encoding Default $ file_out_full_path


0

何もうまくいかなかったので、自分で正規表現を書く必要がありました。

  1. データベースをファイル、catファイル全体、およびgrep定義者ステートメントのみにダンプして、それらを確認してください。

    cat file.sql | grep -o -E '。{、60} DEFINER。{、60}'

  2. 正規表現を書く

  3. ダンプをこの正規表現でsedにパイプします。たとえば、私の声明は次のとおりです。

    mysqldump | sed -E 's // *!500 [0-9] [0-9] DEFINER =。+?* ///' | sed -E 's / DEFINER = ?[^ ]+??@ ?[^ ]+??//'

  4. 利益!


0

remove_definers.bat:

@echo off
(for /f "tokens=1,2*" %%a in (dumpfile.sql) do (
 if "%%b"=="" (echo %%a) else (
  echo %%b | find "DEFINER" > null && echo %%a %%c || echo %%a %%b %%c
 )
)) > dumpfile_nodefiners.sql
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.