既存のMySQLインスタンス(テスト)があり、2つのデータベースと、各データベースへのアクセス権限がそれぞれ異なる少数のユーザーが含まれています。
ここで、データベースの1つ(本番環境)とそれに関連付けられたユーザーを複製する必要があります。
データベースの複製は 簡単 :
書き出す:
mysqldump --no-data --tables -u root -p secondb >> secondb_schema.sql
インポート:
mysql -u root -p -h localhost secondb < secondb_schema.sql
ただし、usersをコマンドライン(内部または外部)からエクスポートおよびインポートする簡単な方法は見つかりませんでしたmysql)。
コマンドラインから ser をエクスポートおよびインポートするにはどうすればよいですか?
Update:これまでのところ、これを達成するための手動の(したがってエラーが発生しやすい)ステップを見つけました。
-- lists all users
select user,Host from mysql.user;
次に、助成金を見つけます。
-- find privilege granted to a particular user
show grants for 'root'@'localhost';
次に、手動で上記の「show grants」コマンドの結果にリストされた許可でユーザーを作成します。
より安全で自動化された方法を好みます。あるの?
ユーザーをエクスポートする最も簡単な方法の1つは、Perconaのツールpt-show-grantsを使用することです。 Perconaツールキットは無料で、インストールが簡単で、使いやすく、多くのドキュメントがあります。これは、すべてのユーザーまたは特定のユーザーを表示する簡単な方法です。すべての付与と出力をSQL形式でリストします。 test_userのすべての許可を表示する方法の例を示します。
Shell> pt-show-grants --only test_user
そのコマンドの出力例:
GRANT USAGE ON *.* TO 'test_user'@'%' IDENTIFIED BY PASSWORD '*06406C868B12689643D7E55E8EB2FE82B4A6F5F4';
GRANT ALTER, INSERT, LOCK TABLES, SELECT, UPDATE ON `test`.* TO 'test_user'@'%';
通常、出力をファイルに再編集して、必要なものを編集するか、mysqlにロードします。
あるいは、Perconaツールを使用せず、すべてのユーザーのダンプを行いたい場合は、次のようにmysqldumpを使用できます。
Shell> mysqldump mysql --tables user db > users.sql
注:--flush-privilegesは、db全体がダンプされないため、これでは機能しません。つまり、手動で実行する必要があります。
Shell> mysql -e "FLUSH PRIVILEGES"
mysql -u<user> -p<password> -h<Host> -e"select concat('show grants for ','\'',user,'\'@\'',Host,'\'') from mysql.user" > user_list_with_header.txt
sed '1d' user_list_with_header.txt > ./user.txt
while read user; do mysql -u<user> -p<password> -h<Host> -e"$user" > user_grant.txt; sed '1d' user_grant.txt >> user_privileges.txt; echo "flush privileges" >> user_privileges.txt; done < user.txt
awk '{print $0";"}' user_privileges.txt >user_privileges_final.sql
rm user.txt user_list_with_header.txt user_grant.txt user_privileges.txt
上記のスクリプトはLinux環境で実行され、出力はuser_privileges_final.sqlになります。これは、ユーザー権限をコピーする新しいmysqlサーバーにインポートできます。
更新:欠落していた-
2番目のmysqlステートメントのユーザー用。
PHPユーザーをループしてgrantコマンドを取得するスクリプトは次のようになります。
// Set up database root credentials
$Host = 'localhost';
$user = 'root';
$pass = 'YOUR PASSWORD';
// ---- Do not edit below this ----
// Misc settings
header('Content-type: text/plain; Charset=UTF-8');
// Final import queries goes here
$export = array();
// Connect to database
try {
$link = new PDO("mysql:Host=$Host;dbname=mysql", $user, $pass);
} catch (PDOException $e) {
printf('Connect failed: %s', $e->getMessage());
die();
}
// Get users from database
$statement = $link->prepare("select `user`, `Host`, `password` FROM `user`");
$statement->execute();
while ($row = $statement->fetch())
{
$user = $row[0];
$Host = $row[1];
$pass = $row[2];
$export[] = 'CREATE USER \''. $user .'\'@\''. $Host .'\' IDENTIFIED BY \''. $pass .'\'';
// Fetch any permissions found in database
$statement2 = $link->prepare('SHOW GRANTS FOR \''. $user .'\'@\''. $Host .'\'');
$statement2->execute();
if ($row2 = $statement2->fetch())
{
$export[] = $row2[0];
}
}
$link = null;
echo implode(";\n", $export);
要点: https://Gist.github.com/zaiddabaeen/e88a2d10528e31cd6692
PhpMyAdmin phpMyAdminを使用できます。
ログインして、ユーザーがアクセスできるデータベースまたはテーブルに移動します。
特権を選択
アクセスできるすべてのユーザーがそこにいます。
エクスポートを選択します。そして、すべてのGRANTSが表示された小さなウィンドウが、コピーして貼り付ける準備ができています。
Perconaツールの代わりに使用するLinux用のもう1つのbashワンライナー:
mysql -u<user> -p<password> -h<Host> -N mysql -e "select concat(\"'\", user, \"'@'\", Host, \"'\"), authentication_string from user where not user like 'mysql.%'" | while read usr pw ; do echo "GRANT USAGE ON *.* TO $usr IDENTIFIED BY PASSWORD '$pw';" ; mysql -u<user> -p<password> -h<Host> -N -e "SHOW GRANTS FOR $usr" | grep -v 'GRANT USAGE' | sed 's/\(\S\)$/\1;/' ; done
同じ問題がありました。解決策は、バックアップのインポート後に「フラッシュ権限」を実行する必要があることです。その後、元のデータベースと同様に、ユーザーの権限がアクティブになります。
SO
mysql -u root -p -h localhost secondb <secondb_schema.sql
mysql -u root;次に、mysqlで:「flush privilege;」
@ Sergey-Podushkinの答えを補完するものとして、このシェルスクリプトコードは私のために働いています:
mysql -u<user> -p<password> -N mysql -e "select concat(\"'\", user, \"'@'\", Host, \"'\"), authentication_string from user where not user like 'root'" | while read usr pw ; do mysql -u<user> -p<password> -N -e "SHOW GRANTS FOR $usr" | sed 's/\(\S\)$/\1;/'; done
これが、日々のバックアップスクリプトの一部として最近使用しているものです(ルートシェルとMySQLアクセス、Linuxシェルが必要で、mysql組み込みスキーマを使用します:
最初に、rootパスワードを含むファイル/var/backup/mysqlroot.cnfを作成して、スクリプトを自動化し、パスワードをハードコーディングしないようにします。
[client]
password=(put your password here)
次に、ダンプを作成するエクスポートスクリプトを作成し、ユーザーコマンドを作成し、次のように許可します。
touch /var/backup/backup_sql.sh
chmod 700 /var/backup/backup_sql.sh
vi /var/backup/backup_sql.sh
そして、次の内容を書きます。
#!/bin/bash
mysql --defaults-extra-file=/var/backup/mysqlroot.cnf -sNe " \
SELECT \
CONCAT( 'CREATE USER \'', User, '\'@\'', Host, '\' IDENTIFIED BY ', authentication_string, '\;' ) AS User \
FROM mysql.user \
WHERE \
User NOT LIKE 'mysql.%' AND CONCAT( User, Host ) <> 'rootlocalhost' AND User <> 'debian-sys-maint' \
"
mysql --defaults-extra-file=/var/backup/mysqlroot.cnf -sNe " \
SELECT \
CONCAT( '\'', User, '\'@\'', Host, '\'' ) as User FROM mysql.user \
WHERE \
User NOT LIKE 'mysql.%' \
AND CONCAT( User, Host ) <> 'rootlocalhost' \
AND User <> 'debian-sys-maint' \
" | sort | while read u ;
do echo "-- $u"; mysql --defaults-extra-file=/var/backup/mysqlroot.cnf -sNe "show grants for $u" | sed 's/$/;/'
done
次に、次のように実行するだけです:/var/backup/backup_sql.sh> /tmp/exportusers.sql
私は小さなC#プログラムでこれに取り組みました。スクリプトを生成するか、ソースから宛先に直接付与を適用するコードがここにあります。 Windows-> * nix環境から移植する場合、大文字と小文字の区別の問題を考慮する必要があります。
using System;
using MySql.Data.MySqlClient;
using System.Configuration;
using System.IO;
using System.Collections.Generic;
namespace GenerateUsersScript
{
class Program
{
static void Main(string[] args)
{
List<string> grantsQueries = new List<string>();
// Get A Show Grants query for each user
using (MySqlConnection sourceConn = OpenConnection("sourceDatabase"))
{
using (MySqlDataReader usersReader = GetUsersReader(sourceConn))
{
while (usersReader.Read())
{
grantsQueries.Add(String.Format("SHOW GRANTS FOR '{0}'@'{1}'", usersReader[0], usersReader[1]));
}
}
Console.WriteLine("Exporting Grants For {0} Users", grantsQueries.Count);
using (StreamWriter writer = File.CreateText(@".\UserPermissions.Sql"))
{
// Then Execute each in turn
foreach (string grantsSql in grantsQueries)
{
WritePermissionsScript(sourceConn, grantsSql, writer);
}
//using (MySqlConnection destConn = OpenConnection("targetDatabase"))
//{
// MySqlCommand command = destConn.CreateCommand();
// foreach (string grantsSql in grantsQueries)
// {
// WritePermissionsDirect(sourceConn, grantsSql, command);
// }
//}
}
}
Console.WriteLine("Done - Press A Key to Continue");
Console.ReadKey();
}
private static void WritePermissionsDirect(MySqlConnection sourceConn, string grantsSql, MySqlCommand writeCommand)
{
MySqlCommand cmd = new MySqlCommand(grantsSql, sourceConn);
using (MySqlDataReader grantsReader = cmd.ExecuteReader())
{
while (grantsReader.Read())
{
try
{
writeCommand.CommandText = grantsReader[0].ToString();
writeCommand.ExecuteNonQuery();
}
catch (Exception ex)
{
Console.WriteLine(grantsReader[0].ToString());
Console.WriteLine(ex.Message);
}
}
}
}
private static void WritePermissionsScript(MySqlConnection conn, string grantsSql, StreamWriter writer)
{
MySqlCommand command = new MySqlCommand(grantsSql, conn);
using (MySqlDataReader grantsReader = command.ExecuteReader())
{
while (grantsReader.Read())
{
writer.WriteLine(grantsReader[0] + ";");
}
}
writer.WriteLine();
}
private static MySqlDataReader GetUsersReader(MySqlConnection conn)
{
string queryString = String.Format("SELECT User, Host FROM USER");
MySqlCommand command = new MySqlCommand(queryString, conn);
MySqlDataReader reader = command.ExecuteReader();
return reader;
}
private static MySqlConnection OpenConnection(string connName)
{
string connectionString = ConfigurationManager.ConnectionStrings[connName].ConnectionString;
MySqlConnection connection = new MySqlConnection(connectionString);
connection.Open();
return connection;
}
}
}
を含むapp.configで...
<connectionStrings>
<add name="sourceDatabase" connectionString="server=localhost;user id=hugh;password=xxxxxxxx;persistsecurityinfo=True;database=MySql" />
<add name="targetDatabase" connectionString="server=queeg;user id=hugh;password=xxxxxxxx;persistsecurityinfo=True;database=MySql" />
</connectionStrings>