技术分享 | 何时需要手动刷新授权表

作者:杨涛涛

资深数据库专家,专研 MySQL 十余年。擅长 MySQL、PostgreSQL、MongoDB 等开源数据库相关的备份恢复、SQL 调优、监控运维、高可用架构设计等。目前任职于爱可生,为各大运营商及银行金融企业提供 MySQL 相关技术支持、MySQL 相关课程培训等工作。

本文来源:原创投稿

*爱可生开源社区出品,原创内容未经授权不得随意使用,转载请联系小编并注明来源。


本篇来源于客户咨询的问题。

问题概要为:记忆中在 MySQL 里对用户进行授权操作后都需要执行 flush privileges 才能生效,怎么我在你写的涉及到用户授权相关的文章里都没有看到执行 flush privileges 语句?

对于这个问题的解答,首先得明白语句 flush privileges 的作用是什么?flush privileges 是 flush 语句集合里的一条子项,执行它的作用是来同步 MySQL 磁盘和内存中的授权数据,让其保持一致。说详细点就是全量读取授权表的磁盘数据并且完全覆盖内存中的授权数据,又或者反着同步磁盘上的授权数据。
具体可以参考官网手册链接:https://dev.mysql.com/doc/refman/8.0/en/privilege-changes.html

接下来用两个简单示例说明执行 flush privileges 语句的时机。
第一,何时使用?
当授权数据在磁盘和内存中不一致时,存在两种时机:一是内存数据较新;另一个则是磁盘数据较新。当这两点中的任意一点存在时都需要执行 flush privileges 语句。
比如直接对表 mysql.user 执行 DML 语句,那么此时磁盘数据较新,需要手动执行 flush privileges 语句来覆盖内存中的授权数据。

举个例子,用户 ytt_u1 拥有的权限数据如下:

mysql:(none)>show grants for ytt_u1;
+-------------------------------------+
| Grants for ytt_u1@%                 |
+-------------------------------------+
| GRANT SELECT ON *.* TO `ytt_u1`@`%` |
+-------------------------------------+
1 row in set (0.00 sec)

管理员来直接更新底层用户表数据: 取消 select 权限。

mysql:(none)>update mysql.user set select_priv='N' where user ='ytt_u1';
Query OK, 1 row affected (0.07 sec)
Rows matched: 1  Changed: 1  Warnings: 0

复查用户 ytt_u1 拥有的权限数据:结果没有同步。

mysql:(none)>show grants for ytt_u1;
+-------------------------------------+
| Grants for ytt_u1@%                 |
+-------------------------------------+
| GRANT SELECT ON *.* TO `ytt_u1`@`%` |
+-------------------------------------+
1 row in set (0.00 sec)

手动执行 flush privileges 语句:再次查看用户 ytt_u1 的权限数据,数据已经同步为最新。

mysql:(none)>flush privileges;
Query OK, 0 rows affected (0.12 sec)

mysql:(none)>show grants for ytt_u1;
+------------------------------------+
| Grants for ytt_u1@%                |
+------------------------------------+
| GRANT USAGE ON *.* TO `ytt_u1`@`%` |
+------------------------------------+
1 row in set (0.00 sec)
第二,何时不需要使用?
MySQL 内部命令自动更新或者删除用户授权数据。

比如 create user 、grant 、revoke 等语句执行后会自动同步授权数据,如无异常,则不需要手动执行 flush privileges 语句。举个例子:还是用户ytt_u1,查看最新权限数据,结果显示没有任何权限。

mysql:(none)>show grants for ytt_u1;
+------------------------------------+
| Grants for ytt_u1@%                |
+------------------------------------+
| GRANT USAGE ON *.* TO `ytt_u1`@`%` |
+------------------------------------+
1 row in set (0.00 sec)

用 grant 语句来给用户 ytt_u1 赋予数据库 ytt 的只读权限:

mysql:(none)>grant select on ytt.* to ytt_u1;
Query OK, 0 rows affected (0.20 sec)

查看用户 ytt_u1 的权限数据:数据已经同步为最新。

mysql:(none)>show grants for ytt_u1;
+-----------------------------------------+
| Grants for ytt_u1@%                     |
+-----------------------------------------+
| GRANT USAGE ON *.* TO `ytt_u1`@`%`      |
| GRANT SELECT ON `ytt`.* TO `ytt_u1`@`%` |
+-----------------------------------------+
2 rows in set (0.00 sec)

再来看下取消授权操作是否也会同步最新授权数据:

mysql:(none)>revoke select on ytt.* from ytt_u1;
Query OK, 0 rows affected (0.09 sec)

查看用户 ytt_u1 的权限数据:数据也是及时同步的。

mysql:(none)>show grants for ytt_u1;
+------------------------------------+
| Grants for ytt_u1@%                |
+------------------------------------+
| GRANT USAGE ON *.* TO `ytt_u1`@`%` |
+------------------------------------+
1 row in set (0.00 sec)
所以只要按照 MySQL 内置的用户管理语句来操作用户授权信息,则不需要手动执行 flush privileges 语句,反之则需要。
上一篇:MySQL数据库与表基础总结


下一篇:Windows10通过WSL编译jdk12