MySQL杂记--select 权限范围变更史
前言:
在5.7版本中无意间发现,只有 select 权限的用户,是可以执行 select ... for update / select ... lock in share mode 命令的,一时想不出在什么场景下,会存在只有 select 权限的用户,需要对记录加锁操作,
复现:
---session1: mysql> create database test_privilege; Query OK, 1 row affected (0.01 sec) mysql> use test_privilege Database changed mysql> create table t1(id int primary key); Query OK, 0 rows affected (0.02 sec) mysql> insert into t1 values(1),(2),(3); Query OK, 3 rows affected (0.01 sec) Records: 3 Duplicates: 0 Warnings: 0 mysql> create user test identified by '123456'; Query OK, 0 rows affected (0.00 sec) mysql> grant select on test_privilege.* to test; Query OK, 0 rows affected (0.01 sec) ---session2: mysql> begin; select * from t1 where id=2 lock in share mode; +----+ | id | +----+ | 2 | +----+ 1 row in set (0.00 sec)
排查过程:
怀疑是MySQL数据库的一个bug,在google一翻之后,有Oracle的DBA反馈Oracle也存在这个问题。
于是咨询了一位OCM,也没解释出所以然,不过查看Oracle bug之后,有人已经反馈在 Oracle 8.1-11.2 版本存在这个问题(DocID 1357623.1),关联增强型bug需求(BUG:6823286)
认为只有 select 权限的用户,在执行 select ... for update/ locak in share mode 时应该报错,
再google翻之后,发现Oracle 12版本中已经解决了这个问题,解决方法是添加了一个read权限,这个read 权限只有select 查询权限,没有 select ... for update/lock in share mode 权限。
官方文档:
https://docs.oracle.com/database/121/DBSEG/release_changes.htm#GUID-00745268-6964-4EE7-92FE-6B4B72931043
于是想给MySQL官方一个bug,可以参考Oracle的解决方案,
我想用8.0版本去复现bug,写测试用例时,发现只有select 权限的用户执行 select ... for update 时报错了,但 select ... lock in share mode没有问题,似乎官方已经改正了,但只改了 for update 这个命令。
报错内容:
mysql> select * from t1 where id=2 for update; ERROR 1142 (42000): SELECT with locking clause command denied to user 'test'@'127.0.0.1' for table 't1'
根据报错内容继续查找,
找到了一个官方bug ,
https://bugs.mysql.com/bug.php?id=99101
有用户在5.7版本的时候,创建只有select权限的用户,并且会有这个用户去执行 select ... lock mode in share命令。但是8.0执行会报错权限问题,所以建议官方修正和5.7一样,以便兼容5.7
看到这里,想起来oracle为何会新建一个read权限,没有在原有的select权限上进行修改,估计也是为了兼容之前版本,怕出问题。
这个修复问题在提出5个多月后,官方在8.022版本中进行了修复,select 权限用户可以执行 select ... lock in share mode.
同时也修改了一些帮助文档,
在文档结尾处,有这样一个连接,8.0.1的特性被修改了
8.0.1 changelog entry update for WL3597: https://dev.mysql.com/doc/relnotes/mysql/8.0/en/news-8-0-1.html
跳转到这个8.0.1 特性,看到这样一段话
SELECT ... FOR SHARE and SELECT ... FOR UPDATE statements now require the SELECT privilege and at least one of the DELETE, LOCK TABLES, or UPDATE privileges. Previously, only the SELECT privilege was required.
在8.0.1发布时,select 权限就发生了变化,不能执行select ... for update/ select ... lock in share mode
因为有人所提bug,,所以官方在8.0.22版本中修复为select 权限可以执行 select ... lock in share mode 命令,但执行 select ... for update 会报错。
个有感觉Oracle的做法更友好一些。