我有一个现有的MySQL实例(测试),包含2个数据库和一些用户,每个用户对每个数据库都有不同的访问权限。
我现在需要复制其中一个数据库(进入生产阶段)和与之关联的用户。
复制数据库是easy:
导出:
mysqldump --no-data --tables -u root -p secondb >> secondb_schema.sql
导入:
mysql -u root -p -h localhost secondb < secondb_schema.sql
但是,我没有找到一种直接从命令行(在mysql内部或外部)导出和导入用户的方法。
如何从命令行导出和导入user?
更新:到目前为止,我已找到完成此操作的手动(因此容易出错)步骤:
-- lists all users
select user,host from mysql.user;
然后找到它的补助金:
-- find privilege granted to a particular user
show grants for 'root'@'localhost';
然后手动使用上面'show grants'命令的结果中列出的授权创建用户。
我更喜欢更安全,更自动化的方式。有吗?
答案 0 :(得分:31)
我发现出口用户的最简单方法之一就是使用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不能使用它,因为整个数据库都没有被转储。这意味着您需要手动运行它。
shell> mysql -e "FLUSH PRIVILEGES"
答案 1 :(得分:18)
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 :(得分:1)
另一个bash one-liner for linux使用而不是Percona工具:
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
答案 3 :(得分:0)
我用一个小的C#程序解决了这个问题。这里有代码生成脚本或直接从源到目标应用授权。如果从Windows移植 - &gt; * nix环境您可能需要考虑区分大小写问题。
int main() {
Derived * d;
d = new Derived();
d->thisMustBeDefined();
}
使用包含...
的app.configusing 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;
}
}
}
答案 4 :(得分:0)
用于循环用户以获取授权命令的PHP脚本将如下:
// 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);
答案 5 :(得分:0)
答案 6 :(得分:0)
我有同样的问题。解决方案是,导入备份后,您需要执行“刷新特权;”。然后,用户权限将与原始数据库中一样处于活动状态。
SO
mysql -u root -p -h localhost secondb
mysql -u root; 然后在mysql中:“刷新权限;”
答案 7 :(得分:0)
作为@ Sergey-Podushkin答案的补充,此shell脚本代码对我有用:
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
答案 8 :(得分:0)
这是我最近日常备份脚本的一部分(需要root shell和MySQL访问权限,linux shell,并使用mysql内置模式:
首先,我创建一个包含根密码的文件/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
答案 9 :(得分:0)
pass=your_password_here; \ MYSQL_PWD=$pass mysql -B -N -uroot -e "SELECT CONCAT('\'', user,'\' ','\'', host,'\' ','\'', authentication_string,'\' ','\'', plugin,'\'') FROM mysql.user WHERE user != 'debian-sys-maint' AND user != 'root' AND user != 'mysql.sys' AND user != 'mysql.session' AND user != ''" > mysql_all_users.txt; \ while read line; do linearray=(${line}); \ MYSQL_PWD=$pass mysql -B -N -uroot -e "SELECT CONCAT('CREATE USER \'',${linearray[0]},'\'@\'',${linearray[1]},'\' IDENTIFIED WITH \'',${linearray[3]},'\' AS \'',${linearray[2]},'\'')"; \ done < mysql_all_users.txt > mysql_all_users_sql.sql; \ while read line; do linearray=(${line}); \ MYSQL_PWD=$pass mysql -B -N -uroot -e "SHOW GRANTS FOR ${linearray[0]}@${linearray[1]}"; \ done < mysql_all_users.txt >> mysql_all_users_sql.sql; \ sed -e 's/$/;/' -i mysql_all_users_sql.sql; \ echo 'FLUSH PRIVILEGES;' >> mysql_all_users_sql.sql; \ unset pass
第一个 mysql 命令:将所有用户导出到文件并排除一些。
第二个 mysql 命令:从文件循环用户以将 sql 命令“创建用户”写入导出的文件(使用身份验证凭据)。
第三个 mysql 命令:从文件循环用户以将他们的权限附加到导出的文件中。
sed 命令附加一个“;”到行尾并刷新权限以完成。
导入: MYSQL_PWD=$pass mysql -u root < mysql_all_users_sql.sql