0
点赞
收藏
分享

微信扫一扫

mysqldump全备恢复到新另一个实例然后再执行flush privileges的情况分析

实验前准备

mysql 1:表示mysql的实例1
mysql 2:表是mysql的实例2

如果mysqldump全备一个库,新建了一个新的实例2,实例2上除了root用户没有其他用户,但是root密码不相同,那mysql.user能恢复成功吗,执行flush privileges会发生什么。

mysqldump全备

mysql 1:root密码123456,进行一次全备

mysqldump -uroot  -p'123456'  -S /tmp/mysql.sock  --default-character-set=utf8mb4 --single-transaction --master-data=2 --set-gtid-purged=OFF --hex-blob --triggers --routines --events  -A  > /tmp/all.sql

mysql 2:root密码234567

mysqldump -uroot  -p'234567' 

全备进行恢复

mysql 2:登录后操作
source /tmp/all.sql 能成功

mysql 2:mysql.user表也被更新

(root@localhost) [(none)] select user ,host from mysql.user;
+---------------+-----------+
| user | host |
+---------------+-----------+
| cjr | % |
| ly | % |
| lytest | % |
| mysql.session | localhost |
| mysql.sys | localhost |
| root | localhost |
+---------------+-----------+
6 rows in set (0.00 sec)

恢复异常分析

但是查看用户的权限,执行flush privileges后可以查看

(root@localhost) [(none)] show grants for cjr@'%';
ERROR 1141 (42000): There is no such grant defined for user 'cjr' on host '%'

(root@localhost) [(none)] grant all on *.* to cjr@'%';
Query OK, 0 rows affected (0.01 sec)


(root@localhost) [(none)] show grants for cjr@'%';
ERROR 1141 (42000): There is no such grant defined for user 'cjr' on host '%'


(root@localhost) [(none)] flush privileges;
Query OK, 0 rows affected (0.00 sec)

(root@localhost) [(none)] show grants for cjr@'%';
+------------------------------------------+
| Grants for cjr@% |
+------------------------------------------+
| GRANT ALL PRIVILEGES ON *.* TO 'cjr'@'%' |
+------------------------------------------+
1 row in set (0.00 sec)

退出mysql 2,再次登录,发现密码错误,使用mysql 1的root密码,登录成功

[root@VM-0-9-centos ~]# mysql -uroot -S /tmp/mysql3308.sock -p'234567'
mysql: [Warning] Using a password on the command line interface can be insecure.
ERROR 1045 (28000): Access denied for user 'root'@'localhost' (using password: YES)
[root@VM-0-9-centos ~]# mysql -uroot -S /tmp/mysql3308.sock -p'123456'
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 12
Server version: 5.7.33-log MySQL Community Server (GPL)

Copyright (c) 2000, 2021, Oracle and/or its affiliates.

Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

(root@localhost) [(none)]

分析结论

使用全备恢复到一个新的实例中,由于备份了mysql.user表
flush privileges 会覆盖掉当前数据库mysql 2密码和权限,变为mysql 1的密码和权限
flush privileges 是在什么时候使用呢,是当数据表中的权限数据跟内存中的权限数据不一致的时候,
可以用来重建内存数据,达到一致状态。

flush privileges 命令会清空 acl_users 数组,然后从 mysql.user 表中读取数据重新加载,
重新构造一个 acl_users 数组。也就是说,以数据表中的数据为准,会将全局权限内存数组重新加载一遍。

所以,mysql.user 在执行完flush privileges后是可以恢复的。

补充

mysql的权限由磁盘上 mysql.user 表和内存数组 acl_users 控制
mysql客户端登录到服务器的连接会被分配一个线程,受到内存acl_users 数组的控制,从内存中数组里查到这个用户的权限,并将权限值拷贝到这个线程对象中。所以会出现如上所示的情况,新实例导入了mysql.user表,但是新实例依然可以用自己原来的root密码登录,但是一旦flush privileges,内存数组被重新加载,那么密码权限会被覆盖。

举报

相关推荐

0 条评论