MySQL 8 vs MySQL 5:为什么通配符在 GRANT 命令中行为不当?

MySQL 8 vs MySQL 5: Why wildcards misbehave in GRANTs command?

我遇到了我的一个旧项目(使用 MySQL 5 和 PHP 5.5)。我只想使用 MySQL 8 和 PHP7.0 测试该项目。 要安装数据库,我通常会这样做:

...
mysql -u root -p < DBinstall/webAppDBinstall.sql
...

在我的网络应用程序的 "install" 脚本中。 sql 命令包含:

...
-- # ######################## SET PHP_SCRIPT & GRANTS FOR ############################
CREATE USER 'php_script'@'localhost' IDENTIFIED BY 'php_script';
GRANT INSERT,SELECT ON webApp.* TO 'php_script'@'localhost';
GRANT UPDATE ON webApp.Orders TO 'php_script'@'localhost';
GRANT UPDATE ON webApp.OrderItems TO 'php_script'@'localhost';
GRANT UPDATE ON webApp.UserStatus TO 'php_script'@'localhost';
GRANT INSERT ON webApp.History TO 'php_script'@'localhost';
...

当 运行 webApp 时,我从 PHP 得到以下错误:

$ cat /var/log/apache2/error.log

...
[Thu May 28 06:01:26.317867 2020] [:error] [pid 8906] [client 127.0.0.1:32960] PHP Warning:  mysqli::query(): Couldn't fetch mysqli in /var/www/webApp/src_php/mylib.php on line 68, referer: http://webApp/index.php?error=0 
...

Note: that this project was running flawlessly using MySQL 5 and PHP 5.

然后我觉得"it smells"就像是一个特权问题。所以我做了以下事情:

mysql> select User,Table_name,Table_priv from mysql.tables_priv where User='php_script';
+------------+------------+------------+
| User       | Table_name | Table_priv |
+------------+------------+------------+
| php_script | History    | Insert     |
| php_script | OrderItems | Update     |
| php_script | Orders     | Update     |
| php_script | UserStatus | Update     |
+------------+------------+------------+
4 rows in set (0.00 sec)

mysql>

是的,就是这样。

证明如下:

我更改了我的 DBinstall/webAppDBinstall.sql 脚本 FROM:

...
-- # ######################## SET PHP_SCRIPT & GRANTS FOR ############################
CREATE USER 'php_script'@'localhost' IDENTIFIED BY 'php_script';
GRANT INSERT,SELECT ON webApp.* TO 'php_script'@'localhost';
GRANT UPDATE ON webApp.Orders TO 'php_script'@'localhost';
GRANT UPDATE ON webApp.OrderItems TO 'php_script'@'localhost';
GRANT UPDATE ON webApp.UserStatus TO 'php_script'@'localhost';
GRANT INSERT ON webApp.History TO 'php_script'@'localhost';
...

TO:

-- # ######################## SET PHP_SCRIPT & GRANTS FOR ############################
CREATE USER 'php_script'@'localhost' IDENTIFIED BY 'php_script';
GRANT INSERT,SELECT ON  webApp.Users TO 'php_script'@'localhost';
GRANT INSERT,SELECT ON  webApp.UserStatus TO 'php_script'@'localhost';
GRANT INSERT,SELECT ON  webApp.Categories TO 'php_script'@'localhost';
GRANT INSERT,SELECT ON  webApp.ProductGroups TO 'php_script'@'localhost';
GRANT INSERT,SELECT ON  webApp.CategoriesGroups TO 'php_script'@'localhost';
GRANT INSERT,SELECT ON  webApp.Products TO 'php_script'@'localhost';
GRANT INSERT,SELECT ON  webApp.Orders TO 'php_script'@'localhost';
GRANT INSERT,SELECT ON  webApp.OrderItems TO 'php_script'@'localhost';
GRANT INSERT,SELECT ON  webApp.Messages TO 'php_script'@'localhost';
GRANT INSERT,SELECT ON  webApp.History TO 'php_script'@'localhost';
GRANT UPDATE ON webApp.Orders TO 'php_script'@'localhost';
GRANT UPDATE ON webApp.OrderItems TO 'php_script'@'localhost';
GRANT UPDATE ON webApp.UserStatus TO 'php_script'@'localhost';
GRANT INSERT ON webApp.History TO 'php_script'@'localhost';

结果是:

mysql> select User,Table_name,Table_priv from mysql.tables_priv where User='php_script';
+------------+------------------+----------------------+
| User       | Table_name       | Table_priv           |
+------------+------------------+----------------------+
| php_script | History          | Select,Insert        |
| php_script | Categories       | Select,Insert        |
| php_script | CategoriesGroups | Select,Insert        |
| php_script | Messages         | Select,Insert        |
| php_script | OrderItems       | Select,Insert,Update |
| php_script | Orders           | Select,Insert,Update |
| php_script | ProductGroups    | Select,Insert        |
| php_script | Products         | Select,Insert        |
| php_script | UserStatus       | Select,Insert,Update |
| php_script | Users            | Select,Insert        |
+------------+------------------+----------------------+
10 rows in set (0.00 sec)

mysql>

关于 'why this happens with wildcards in GRANTs' 还有其他更好的想法吗???

(很抱歉重复了我的问题,但 Whosebug 禁止我回答我自己的问题)

我的问题是: 为什么 GRANT <PRIVS> ON <DB>.* TO <USER>; 通配符语法停止 "working"

Note: This problem is different from mysqli::query(): Couldn't fetch mysqli . My webApp application is a system that runs flawlessly with MySQL 5.x deployments. ITS HAS nothing to do with PHP (although the mysqli error seems to, IT DOES NOT).

我刚刚在 MySQL 8 服务器上进行了测试,我成功地 运行 以下内容:

CREATE DATABASE webApp;
CREATE USER 'php_script'@'localhost' IDENTIFIED BY 'php_script';
GRANT INSERT,SELECT ON webApp.* TO 'php_script'@'localhost';

如我所料,通配符 g运行t 没有任何问题。 所以,恐怕您需要在其他地方搜索问题。

例如,您的一个示例中的目标数据库名为 webApp,下一个示例中的目标数据库为 webAppDB。所以,最好检查名称的一致性。

否则,您的代码语法对于 MySQL 8.

看起来没问题

[编辑] - 其他建议

  1. 确保 skip-name-resolve 设置为关闭。

看起来它在 MySQL 8 上默认是关闭的,但在某些情况下它可能会设置为打开。

在我的例子中,我 运行 MySQL 8 在 docker 容器中并且该变量设置为 ON。

如果变量设置为 ON,mysql 将不会将 localhost 解析为 localhost 的实际 IP,在您的情况下,这可能是问题所在。

此处有更多关于 skip-name-resolve 的详细信息:https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_skip_name_resolve

  1. 确保使用 FLUSH PRIVILEGES;

  2. 完成 GRANT 命令
  3. 尝试将default-authentication-plugin切换为mysql_native_password

默认情况下 MySQL 8 default-authentication-plugin 设置为 caching_sha2_password。但是看起来 mysqli 不支持这种身份验证方法(根据 2018 年的这篇文章:https://mysqlserverteam.com/upgrading-to-mysql-8-0-default-authentication-plugin-considerations/