如何从 MySQL 导出权限,然后导入到新服务器?

Gar*_*eth 94 mysql linux debian mysql-replication database-administration

我知道如何使用 mysqldump 导出/导入数据库,这很好,但我如何将权限授予新服务器。

额外的一点是,新数据库上已经有几个现有数据库,如何导入旧服务器权限而不破坏现有的几个数据库。

旧服务器:5.0.67-社区

新服务器:5.0.51a-24+lenny1

编辑:我从旧服务器上获得了 db 'mysql' 的转储,现在想知道与新服务器上的 'mysql' db 合并的正确方法。

我尝试使用 phpMyAdmin 直接“导入”,结果出现了关于重复的错误(我已经手动迁移过)。

任何人都有合并两个“mysql”数据库的优雅方式?

Bru*_*sky 177

不要弄乱 mysql 数据库。除了用户表之外,还有很多事情要做。最好的选择是“ 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;}'
}
Run Code Online (Sandbox Code Playgroud)

第一个 mysql 命令使用 SQL 生成有效的 SQL,该 SQL 将通过管道传输到第二个 mysql 命令。然后输出通过 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
Run Code Online (Sandbox Code Playgroud)

这是移动用户的正确方式。您的 MySQL ACL 是用纯 SQL 修改的。

  • 这很好,但它有一个很大的缺陷。一个额外的“\”被添加到数据库名称中的下划线,因此,如果您有一个对名为 foo_bar 的数据库具有特定权限的用户,它将被呈现为 foo\\_bar 而不是 foo\_bar,这样就不会正确导入。至少,如果您将脚本的输出保存到 SQL 文件中,然后将其导入新服务器,就会发生这种情况。我还没有尝试在一行中直接导出和导入。 (3认同)

Rol*_*DBA 55

从 MySQL 实例中提取 SQL 授权有两种方法

方法#1

您可以使用Percona Toolkit 中的pt-show-grants

MYSQL_CONN="-uroot -ppassword"
pt-show-grants ${MYSQL_CONN} > MySQLUserGrants.sql
Run Code Online (Sandbox Code Playgroud)

方法#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
Run Code Online (Sandbox Code Playgroud)

这两种方法都将生成 MySQL 授权的纯 SQL 转储。剩下要做的就是在新服务器上执行脚本:

mysql -uroot -p -A < MySQLUserGrants.sql
Run Code Online (Sandbox Code Playgroud)

试一试 !!!

  • 但答案 #2 也一样好,无需额外软件即可工作! (7认同)
  • pt-show-grants 正是您想要的,它效果很好。 (3认同)

小智 15

理查德布罗诺斯基的回答对我非常有用。非常感谢!!!

这是一个对我有用的小变化。它有助于在两个运行 phpmyadmin 的 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;}'
}
Run Code Online (Sandbox Code Playgroud)

  • 如果您查看我的示例,其中我使用 `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 ` (3认同)

小智 7

或者,为此目的使用 percona-toolkit(以前的 maatkit)并使用pt-show-grants(或mk-show-grants)。无需繁琐的脚本和/或存储过程。


ned*_*edm 6

您可以 mysqldump 'mysql' 数据库并导入到新数据库;需要刷新权限或重新启动,并且您肯定要先备份现有的 mysq 数据库。

为避免删除现有权限,请确保在权限表(db、columns_priv、host、func 等)中附加而不是替换行。


小智 5

您也可以将其作为存储过程执行:

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
Run Code Online (Sandbox Code Playgroud)

并调用它

$ mysql -p -e "CALL spShowGrants" mysql
Run Code Online (Sandbox Code Playgroud)

然后通过 Richards sed 命令将输出通过管道传输以获取权限的备份。


Ibr*_*wal 5

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";
    }
}
Run Code Online (Sandbox Code Playgroud)