TL;DR
- partial_revokes が有効な状態だと
GRANT ALL ON 'd%'.* TO ..
みたいなデータベースワイルドカードの構文が効かない
In privilege assignments, enabling partial_revokes causes MySQL to interpret occurrences of unescaped _ and % SQL wildcard characters in schema names as literal characters, just as if they had been escaped as \_ and \%. Because this changes how MySQL interprets privileges, it may be advisable to avoid unescaped wildcard characters in privilege assignments for installations where partial_revokes may be enabled.
In addition, use of _ and % as wildcard characters in grants is deprecated as of MySQL 8.0.35, and you should expect support for them to be removed in a future version of MySQL.
https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_partial_revokes
ドキュメントに書いてある以外に地味な罠があったし、そもそもこのpartial_revokesの制限を知らずに知らずに時間を溶かしたのでメモ。。
CREATE USER yoku0825;
GRANT ALL ON `d%`.* TO yoku0825; -- シングルクォートでなくてバッククォート
mysql80 9> SHOW GRANTS;
+--------------------------------------------------+
| Grants for yoku0825@% |
+--------------------------------------------------+
| GRANT USAGE ON *.* TO `yoku0825`@`%` |
| GRANT ALL PRIVILEGES ON `d%`.* TO `yoku0825`@`%` |
+--------------------------------------------------+
2 rows in set (0.00 sec)
mysql80 9> CREATE DATABASE d11; -- d%` にマッチするから
Query OK, 1 row affected (0.00 sec)
mysql80 9> CREATE DATABASE d15; -- d% にマッチするから
Query OK, 1 row affected (0.01 sec)
mysql80 9> CREATE DATABASE newdb; -- d% にマッチしないから
ERROR 1044 (42000): Access denied for user 'yoku0825'@'%' to database 'newdb'
SET GLOBAL partial_revokes = ON;
mysql80 11> CREATE DATABASE d17; -- d% が文字列リテラルとして解釈されるから
ERROR 1044 (42000): Access denied for user 'yoku0825'@'%' to database 'd17'
mysql80 11> DROP DATABASE d11; -- !?
Query OK, 0 rows affected (0.00 sec)
mysql80 11> CREATE TABLE d15.t1 (num int); -- !?
Query OK, 0 rows affected (0.01 sec)
このデータベースのワイルドカード指定が8.0.35から非推奨だから、この一貫性のない挙動が直ってくれる気はしない…。
【2024/02/09 15:21】
他の環境(8.0.32 + partial_revokes)だと既存のスキーマに対する操作もちゃんと拒否された(一貫性がある)
違いがわからぬ。。。
【2024/02/09 17:41】
my.cnfにpartial_revokes足してmysqldを再起動したらちゃんと一貫性のある動作になった。安心。