MySQL permission changes, when will they take effect?

This article describes how to make changes to three levels of permissions effective.

Author: Ouyang Han, DBA member of the Aikeson team, a 2.5-dimensional enthusiast who knows how to hold an umbrella when it rains~

Produced by the Aikeson open source community, original content may not be used without authorization. Please contact the editor and indicate the source for reprinting.

This article is about 1,200 words and is expected to take 4 minutes to read.

Preface

Uproxy is an efficient read-write middleware for the Cloud Tree® DMP product developed by Axon . It maintains a connection pool between itself and the back-end MySQL database to maintain a long connection to the database back-end .

background

Recent customer feedback shows that after connecting to the database through Uproxy and using a certain permission REVOKEto recycle the global library table *.*, you can still see libraries without corresponding permissions and be able to operate them, but it is FLUSH PRIVILEGESalso invalid. Is this a MySQL bug?

MySQL change permissions

In fact, this is not the case. Before the author elaborates, let me first explain the two ways to change permissions in MySQL:

1 Directly modify the authorization form

Use INSERT, UPDATEor DELETEand other statements to directly modify the authorization table (not recommended) .

update mysql.user set Select_priv='N' where user='ouyanghan' and host='%';

2 Use the GRANT/REVOKE statement

Use GRANT/REOVKEto grant and revoke permissions (recommended) .

GRANT
    priv_type [(column_list)]
      [, priv_type [(column_list)]] ...
    ON [object_type] priv_level
    TO user [auth_option] [, user [auth_option]] ...
    [REQUIRE {NONE | tls_option [[AND] tls_option] ...}]
    [WITH {GRANT OPTION | resource_option} ...]

Among them, the first one requires FLUSH PRIVILEGESreloading the permission table through . The second method is to update permissions through MySQL internal commands, which will automatically reload the permissions table. But it is worth mentioning that refreshing the permission table does not mean that you have the corresponding permissions. The specific validity needs to be divided into the following three situations. The official documents have already explained it.

  • For table level db_name.table_nameand column level, permission changes will take effect on the next client request, that is, immediately.
  • Changes to library-level permissions take effect after db_name.*the client executes USE db_namethe statement.
  • Changes to global-level permissions *.*are not affected in already connected sessions and only take effect in newly connected sessions.

The way table, column and global-level permissions take effect has no problem when I test it locally. The text above is also very easy to understand. I won’t take up your time here. But for changes to library-level permissions, the official website says that it requires talent USE db_name. It takes effect, but it actually takes effect immediately.

verify

Create ouyanghana user. At this time, the user only has usagepermissions and can only see information_schemathe library.

# root 用户登录,创建新用户
mysql> CREATE USER ouyanghan IDENTIFIED by 'oyh123';

# ouyanghan 用户登录,查看权限
mysql> SHOW GRANTS;
+---------------------------------------+
| Grants for ouyanghan@%                |
+---------------------------------------+
| GRANT USAGE ON *.* TO 'ouyanghan'@'%' |
+---------------------------------------+
1 row in set (0.00 sec)

mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
+--------------------+
1 row in set (0.00 sec)

ouyanghanGrant library-level SELECTpermissions to users and discover that changes to the library level can take effect in real time.

# root 用户授权
mysql> GRANT SELECT ON demp.* TO ouyanghan;
Query OK, 0 rows affected (0.00 sec)

# ouyanghan 用户登录查看权限(同一会话)
mysql> SHOW GRANTS;
+---------------------------------------------+
| Grants for ouyanghan@%                      |
+---------------------------------------------+
| GRANT USAGE ON *.* TO 'ouyanghan'@'%'       |
| GRANT SELECT ON `demp`.* TO 'ouyanghan'@'%' |
+---------------------------------------------+
2 rows in set (0.00 sec)

# 并且能查看到 demp 库
mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| demp               |
+--------------------+
2 rows in set (0.00 sec)

What's going on? I also found the wrong highlight moment on the official website? In fact, this is not the case. If you look closely, you will find that there is a note in the description on the official website:

Client applications may cache the database name; thus, this effect may not be visible to them without actually changing to a different database.

Client applications can cache database names; therefore, you may not see this effect without actually changing to another database.

Enable caching

Then we turn on the MySQL cache and give it a certain cache size.

# 查看此时 ouyanghan 用户的权限
mysql> SHOW GRANTS FOR demo;
+----------------------------------------+
| Grants for demo@%                      |
+----------------------------------------+
| GRANT USAGE ON *.* TO 'demo'@'%'       |
| GRANT SELECT ON `demp`.* TO 'demo'@'%' |
| GRANT SELECT ON `db1`.* TO 'demo'@'%'  |
+----------------------------------------+
3 rows in set (0.00 sec)

# 开启缓存,并赋予大小
mysql> SET GLOBAL query_cache_type = 1;
Query OK, 0 rows affected, 1 warning (0.00 sec)

mysql> SET GLOBAL query_cache_size = 1000000;
Query OK, 0 rows affected, 2 warnings (0.00 sec)

ouyanghanWhen the user logs in to MySQL, he can view db1the specific information of the table below the database.

mysql> USE db1;
Database changed

mysql> SELECT * FROM t1;
+----+------+
| id | c    |
+----+------+
|  1 | a    |
+----+------+
1 row in set (0.00 sec)

rootUser reclaims permissions.

mysql> REVOKE SELECT ON db1.* FROM ouyanghan;
Query OK, 0 rows affected (0.00 sec)

ouyanghanUser viewing permissions.

# 发现权限已经被回收
mysql> SHOW GRANTS FOR ouyanghan;
+---------------------------------------------+
| Grants for ouyanghan@%                      |
+---------------------------------------------+
| GRANT USAGE ON *.* TO 'ouyanghan'@'%'       |
| GRANT SELECT ON `demp`.* TO 'ouyanghan'@'%' |
+---------------------------------------------+
2 rows in set (0.00 sec)

# use db1 失败,报没有权限,但仍能查看到里面的内容
mysql> USE db1;
ERROR 1044 (42000): Access denied for user 'ouyanghan'@'%' to database 'db1'

mysql> SELECT * FROM db1.t1;
+----+------+
| id | c    |
+----+------+
|  1 | a    |
+----+------+

# 切换不同的库后,此时才发现权限被真正回收了,不能查看到对应的内容了
mysql> USE demp;
Reading table information for completion of table and column names
You can turn off this feature to get a quicker startup with -A

Database changed
mysql> SELECT * FROM db1.t1;
ERROR 1142 (42000): SELECT command denied to user 'ouyanghan'@'localhost' for table 't1'

Some serious readers may have doubts: "When you make changes to table and column level permissions, you don't turn on the MySQL query cache. Maybe the effective time of changes to table and column level permissions is also Need to go USE db_namethere?"

Hey, don’t tell me, it’s true, so I hurriedly tested it again and found that if I change the table-level and column-level permissions, it will take effect immediately. If you don’t believe me, just try it!

Summarize

Whether you use statements to directly modify the authorization table, or use MySQL internal commands to change permissions, you must comply with the following effective rules:

  1. For table level db_name.table_nameand column level, permission changes will take effect on the next client request, that is, immediately.
  2. Changes to library-level permissions will take effect after db_name.*the client executes USE db_namethe statement (you need to enable query_cache_typethe parameter. Of course, for the sake of MySQL performance, it is not recommended to enable this parameter, and it has been removed in MySQL 8.0 version).
  3. Changes to global-level permissions *.*are not affected in connected sessions and only take effect in newly connected sessions.

Finally, I believe that everyone here already knows how to solve the problem of permissions not taking effect that I started to encounter, right? That is to refresh the Uproxy connection pool.

For more technical articles, please visit: https://opensource.actionsky.com/

About SQLE

SQLE from the Axon open source community is a SQL audit tool for database users and managers that supports multi-scenario audits, standardized online processes, native support for MySQL audits and scalable database types.

SQLE get

type address
Repository https://github.com/actiontech/sqle
document https://actiontech.github.io/sqle-docs/
release news https://github.com/actiontech/sqle/releases
Data audit plug-in development documentation https://actiontech.github.io/sqle-docs/docs/dev-manual/plugins/howtouse

Guess you like

Origin blog.csdn.net/ActionTech/article/details/133315546