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 REVOKE
to recycle the global library table *.*
, you can still see libraries without corresponding permissions and be able to operate them, but it is FLUSH PRIVILEGES
also 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
, UPDATE
or DELETE
and 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/REOVKE
to 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 PRIVILEGES
reloading 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_name
and 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 executesUSE db_name
the 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 ouyanghan
a user. At this time, the user only has usage
permissions and can only see information_schema
the 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)
ouyanghan
Grant library-level SELECT
permissions 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)
ouyanghan
When the user logs in to MySQL, he can view db1
the 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)
root
User reclaims permissions.
mysql> REVOKE SELECT ON db1.* FROM ouyanghan;
Query OK, 0 rows affected (0.00 sec)
ouyanghan
User 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_name
there?"
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:
- For table level
db_name.table_name
and column level, permission changes will take effect on the next client request, that is, immediately. - Changes to library-level permissions will take effect after
db_name.*
the client executesUSE db_name
the statement (you need to enablequery_cache_type
the 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). - 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 |