MySQLから特権をエクスポートして、新しいサーバーにインポートするにはどうすればよいですか?


88

私はmysqldumpを使用してデータベースをエクスポート/インポートする方法を知っていますが、それは問題ありませんが、新しいサーバーに特権を取得するにはどうすればよいですか?

余分な点については、新しいデータベースにいくつかの既存のデータベースが既にあります。既存のデータベースを削除せずに古いサーバーの権限をインポートするにはどうすればよいですか。

古いサーバー:5.0.67-community

新しいサーバー:5.0.51a-24 + lenny1

編集:古いサーバーからデータベース「mysql」のダンプを取得しましたが、新しいサーバーの「mysql」dbとマージする適切な方法を知りたいと思います。

phpMyAdminを使用してまっすぐな「インポート」を試みましたが、重複(既に手動で移行したもの)に関するエラーが発生しました。

誰かが2つの「mysql」データベースをマージするエレガントな方法を手に入れましたか?


1. PHPMyAdminを使用する必要がありますか?もしそうなら、PHPMyAdmin固有の指示をいくつか書きます。2.「mysql.user limit 1から*を選択」しようとすると、PHPMyAdminから。結果またはエラーが表示されますか?
ブルーノブロノスキー2009年

1
以下で述べたように、リチャードの移民スクリプトは助成金情報を取得する良い方法だと思います。ただし、ダンプファイルを編集して、既存のユーザーのユーザーテーブルへのINSERTをコメント化することもできます。その後、古いサーバーから復元されたdbsの特権がコピーされます。新しいボックスに復元したdbの一部に既に手動で特権を割り当てている場合は、特権ファイルでこれらのテーブル名を探し、これらもコメントアウトします。後でflush_privilegesを忘れないでください。mysqlデータベースの説明:grahamwideman.com/gw/tech/mysql/perms/index.htm
nedm

回答:


169

mysql dbを台無しにしないでください。そこでは、ユーザーテーブル以外にも多くのことが行われています。最善の方法は、「SHOW GRANTS FOR」コマンドです。.bashrcには、多くのCLIメンテナンスエイリアスと関数があります(実際には、.bashrcでソースする.bash_aliases)。この関数:

mygrants()
{
  mysql -B -N $@ -e "SELECT DISTINCT CONCAT(
    'SHOW GRANTS FOR \'', user, '\'@\'', host, '\';'
    ) AS query FROM mysql.user" | \
  mysql $@ | \
  sed 's/\(GRANT .*\)/\1;/;s/^\(Grants for .*\)/## \1 ##/;/##/{x;p;x;}'
}

最初のmysqlコマンドはSQLを使用して、2番目のmysqlコマンドにパイプされる有効なSQLを生成します。次に、出力はsedを介してパイプ処理され、きれいなコメントが追加されます。

コマンドの$ @を使用すると、次のように呼び出すことができます。mygrants --host = prod-db1 --user = admin --password = secret

次のように、この上で完全なUNIXツールキットを使用できます。

mygrants --host=prod-db1 --user=admin --password=secret | grep rails_admin | mysql --host=staging-db1 --user=admin --password=secret

これがユーザーを移動する正しい方法です。MySQL ACLが純粋なSQLで変更されます。


これは実際に素晴らしいbashヘルパー関数であり、うまく機能します。それから出力を取得し、新しいサーバーで実行できるようになると、権限が適切かつ正確に入力されます。
ジェレミーボーズ2009年

1
私はあなたの機能が大好きです。今日は多くの仕事を節約しました。ありがとう、ありがとう、ありがとう
ファビオ

2
これはすばらしいことですが、大きな欠点が1つあります。追加の「\」がデータベース名の下線に追加されるため、たとえば、foo_barというデータベースに対する特定の権限を持つユーザーがいる場合、foo_barではなくfoo \ _barとしてレンダリングされるため、正しくインポートされません。 。少なくとも、スクリプトからの出力をSQLファイルに保存し、それを新しいサーバーにインポートすると、これが起こります。エクスポートとインポートの直接的なパイピングを1行で試したことはありません。
マッテオ

1
このコマンドには注意してください。あなたが持っている場合はuser、テーブルのホストを持つユーザーを%、その後にdbどこのテーブルあなたがエントリを持っているhost明示的な値である、でこれらのエントリdbの表は、このメソッドを使用して取得されていません。
ミタール

1
@matteo -r関数の2番目のmysqlコマンドに追加すると、ダブルエスケープはによって出力されませんmysql。例:mysql -r $@
lifo

45

MySQLインスタンスからSQL Grantsを抽出するには2つの方法があります

方法#1

Percona Toolkitのpt-show-grantsを使用できます

MYSQL_CONN="-uroot -ppassword"
pt-show-grants ${MYSQL_CONN} > MySQLUserGrants.sql

方法#2

pt-show-grants以下でエミュレートできます

MYSQL_CONN="-uroot -ppassword"
mysql ${MYSQL_CONN} --skip-column-names -A -e"SELECT CONCAT('SHOW GRANTS FOR ''',user,'''@''',host,''';') FROM mysql.user WHERE user<>''" | mysql ${MYSQL_CONN} --skip-column-names -A | sed 's/$/;/g' > MySQLUserGrants.sql

どちらの方法でも、MySQL許可の純粋なSQLダンプが生成されます。あとは、新しいサーバーでスクリプトを実行するだけです。

mysql -uroot -p -A < MySQLUserGrants.sql

試してみる !!!


1
pt-show-grantsはまさにこれに必要なものであり、うまく機能します。
グレンプラス

パーコナは純粋な素晴らしいものです。
sjas

7
しかし、答え#2は同様に優れており、追加のソフトウェアなしで機能します!
sjas

14

リチャード・ブロノスキーの答えは私にとって非常に役に立ちました。どうもありがとう!!!

これは私にとって便利な小さなバリエーションです。たとえば、phpmyadminを実行している2つのUbuntuインストール間でユーザーを転送するのに役立ちます。root、phpmyadmin、debian-sys-maintを除くすべてのユーザーの特権をダンプするだけです。そのコードは

mygrants()
{
mysql -B -N $@ -e "SELECT DISTINCT CONCAT(
'SHOW GRANTS FOR ''', user, '''@''', host, ''';'
) AS query FROM mysql.user WHERE user NOT IN ('root','phpmyadmin','debian-sys-maint')"  | \
mysql $@ | \
sed 's/\(GRANT .*\)/\1;/;s/^\(Grants for .*\)/## \1 ##/;/##/{x;p;x;}'
}

2
私の例を見ると、grep rails_adminすべてのエッジケースに特別な関数を作成せずにこれを行う方法を推測できます。:そのようにはgrepの「反転一致」オプションを使用しますmygrants --host=prod-db1 --user=admin --password=secret | grep -Ev 'root|phpmyadmin|debian-sys-maint' | mysql --host=staging-db1 --user=admin --password=secret
ブルーノBronosky

7

または、percona-toolkit(以前のmaatkit)を利用し、その目的に使用pt-show-grants(またはmk-show-grants)します。面倒なスクリプトやストアドプロシージャは必要ありません。


5

「mysql」データベースをmysqldumpして、新しいデータベースにインポートできます。flush_privilegesまたは再起動が必要になるため、必ず既存のmysq dbを最初にバックアップしてください。

既存の特権が削除されないようにするには、特権テーブル(db、columns_priv、host、funcなど)の行を置き換えるのではなく、必ず追加してください。


@nedmに感謝します。私がデータベースを取得しようとしている迷惑なcPanelサーバーのように、データベース「mysql」が表示されないようです。それ以外の場合は、あなたの答えをテストして確認します。それがわかったら、もう一度確認します。ありがとう。
ガレス

残念ながら理解できることですが、おそらく共有データベース上のユーザーが直接所有しているデータベース以外のデータベースにはアクセスできません。
デイブチェイニー

「はい」、「mysql」へのアクセスなしでは、ユーザーまたは許可に関連することを行うのは困難です。コマンドラインにアクセスできますか?端末またはコマンドラインからmysqldumpを実行できますか(mysqlシェルからではありません)?mysqldump -uユーザー名-ppassword mysql> mysqldump.sql
nedm

「root」としてログインした場合、Cpanel WHMからデータベース「mysql」にアクセスできました。そこから私は「mysqlの」含むデータベース権限を持っているのphpMyAdminのバージョンにアクセスすることができます
ギャレス

既存のmysqlスキーマにマージすると、mysqldumpを介してmysqlスキーマから抽出されたデータに問題があることはほぼ確実です。強制的な関係などを使用して複雑なスキーマを操作しています。実際、このスキーマは非常に複雑であるため、それを処理する専用のSQL構文(GRANT、REVOKE、DROP USERなど)を作成しました。ただし、抽出はINSERTステートメントのみで構成されます。ここでキャラクターが不足しています。続行する必要がありますか?
ブルーノブロノスキー2009年

4

ストアドプロシージャとして実行することもできます。

CREATE PROCEDURE spShowGrants()
    READS SQL DATA
    COMMENT 'Show GRANT statements for users'
BEGIN
    DECLARE v VARCHAR(64) CHARACTER SET utf8;
    DECLARE c CURSOR FOR
    SELECT DISTINCT CONCAT(
        'SHOW GRANTS FOR ', user, '@', host, ';'
    ) AS query FROM mysql.user;
    DECLARE EXIT HANDLER FOR NOT FOUND BEGIN END;  
    OPEN c;
    WHILE TRUE DO
        FETCH c INTO v;
        SET @v = v;
        PREPARE stmt FROM @v;
        EXECUTE stmt;
    END WHILE;
    CLOSE c;
END

そしてそれを呼び出す

$ mysql -p -e "CALL spShowGrants" mysql

次に、出力をRichards sedコマンドにパイプして、特権のバックアップを取得します。


3

@Richard Bronoskyの答えは正しいもののようですが、データベースのセットをあるサーバーから別のサーバーに移行しようとしたところ、この質問に出くわしました。

server1$ mysqldump -u root -p --all-databases > dbdump.sql

server2$ mysql -u root -p < dbdump.sql

この時点で、としてログインした場合、すべてのデータは表示されましたrootが、mysql.userテーブルにはすべてが含まれていましたが、他のユーザーとしてログインできず、再質問する必要があると仮定してこの質問が見つかりましたGRANTステートメントを発行します。

しかし、mysql.*テーブルの更新された特権を有効にするには、mysqlサーバーを再起動するだけでよいことがわかりました。

server2$ sudo restart mysql

うまくいけば、他の誰かが簡単なタスクを達成するのに役立つでしょう!


ああ、私の状況はOPとは少し異なりました。既存のデータベース/ユーザーを持つサーバーにダンプをマージしようとしていなかったからです。
トム

2
「特権を更新する」ためにMySQLdを再起動する必要はありません。MySQLコマンド「flush privilege;」で実行できます。
CloudWeavers

このアプローチの問題は、ソースMySQLと宛先MySQLの両方のバージョンが同じ場合にのみ機能することです。そうしないと、たとえば、ソースmysql.userテーブルに宛先mysql.userテーブルとは異なる列があるため、問題が発生する可能性があります。
ミタール

3

PHPスクリプトはどうですか?:)

このスクリプトのソースを表示すると、すべての特権がリストされます。

//connect
mysql_select_db("mysql", mysql_connect("localhost","root",""));

//create grants select statements
$rs = mysql_query("SELECT DISTINCT CONCAT('SHOW GRANTS FOR ''', user, '''@''', host, ''';') AS query FROM user");

//iterate through grants
while ($row=mysql_fetch_array($rs)) {
    //run grant query
    $rs2 = mysql_query($row['query']);
    //iterate through results
    while($row2 = mysql_fetch_array($rs2)){
        //print results
        echo $row2[0] . ";\n\n";
    }
}

2

次のコードを使用してシェルスクリプトファイルを作成します。

############################################## 3
echo "SELECT DISTINCT CONCAT (\"show grants for '\", user, \"'@'\", host, \"';\") AS query FROM mysql.user; " >   script.sql    
echo "*** You will be asked to enter the root password twice ******"    
mysql -u root -p  < script.sql > output.sql ;    
cat output.sql | grep show > output1.sql  ; rm output.sql -f ; 
mysql -u root -p  < output1.sql > output.sql ;
clear
echo "-----Exported Grants-----"    
cat  output.sql ; rm  output.sql   output1.sql -f    
echo "-------------------------"
rm  script.sql -f

****シェルで次のように実行します。rootパスワードを2回入力するよう求められ、その後GRANTS SQLが画面に表示されます。****


0

ワンライナーは素晴らしいものとほぼ同じことをしていpt-show-grantsます:

mysql --skip-column-names -A -e"SELECT CONCAT('SHOW GRANTS FOR ''',user,'''@''',host,''';') FROM mysql.user WHERE user<>''" | mysql --skip-column-names -A | sed 's/$/;/g'

UNIXツールのみに基づいており、追加のソフトウェアは必要ありません。

bashシェル内から実行します。ユーザー.my.cnfのパスワードをmysql root読み取ることができる作業があると仮定します。


@rolandomysqldbaの投稿の半分を、半年後に戻ってから複製しました。
sjas
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.