场景回顾
环境
场景
使用 root 账户连接数据库,执行如下脚本建立用户,赋权:
use mysql;select VERSION();drop user if EXISTS 'demo'@'%';create user if not EXISTS 'demo'@'%' IDENTIFIED by 'demo123';create DATABASE if not EXISTS demo_test;grant all PRIVILEGES on demo_test.* to 'demo'@'%';GRANT SELECT ON `performance_schema`.user_variables_by_thread TO 'demo'@'%';show grants for 'demo'@'%';FLUSH PRIVILEGES;
连接不上 mysql 报错 ERROR 1045 (28000): Access denied for user 'demo'@'localhost' (using password: YES)
D:\devServer\mysql-8.0.22-winx64\bin>mysql.exe -udemo -pdemo123 -h127.0.0.1mysql: [Warning] Using a password on the command line interface can be insecure.ERROR 1045 (28000): Access denied for user 'demo'@'localhost' (using password: YES)D:\devServer\mysql-8.0.22-winx64\bin>mysql.exe -udemo -pdemo123 -hlocalhostmysql: [Warning] Using a password on the command line interface can be insecure.ERROR 1045 (28000): Access denied for user 'demo'@'localhost' (using password: YES)D:\devServer\mysql-8.0.22-winx64\bin>
建立的 demo 用户,HOST 为 %,为什么就不能 127.0.0.1 (localhost)连接呢?% 不是通配符吗,通配符不匹配本机?同事的就能连接我的,自己的反而不能?
解决过程
先看官网说明
查看官网连接失败 https://dev.mysql.com/doc/refman/8.0/en/problems-connecting.html
连接说明 https://dev.mysql.com/doc/refman/8.0/en/connection-access.html
官网说了,验证账户,将 mysql.user 加载到内存中有个顺序,先走确切的(HOST 明确的,比如ip,hostname,最后走 % 通配符)。本机的 user 数据如下:
D:\devServer\mysql-8.0.22-winx64\bin>mysql.exe -uroot -p123456mysql: [Warning] Using a password on the command line interface can be insecure.Welcome to the MySQL monitor. Commands end with ; or \g.Your MySQL connection id is 30Server version: 8.0.22 MySQL Community Server - GPLCopyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.Oracle is a registered trademark of Oracle Corporation and/or itsaffiliates. Other names may be trademarks of their respectiveowners.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.mysql> use mysql;Database changedmysql> select HOST,USER from users;ERROR 1146 (42S02): Table 'mysql.users' doesn't existmysql> select HOST,USER from user;+--------------+------------------+| HOST | USER |+--------------+------------------+| % | demo || % | xiaohui || % | xiaohuihui || % | xxhh || 192.168.0.12 | || 192.168.1.59 | xh || localhost | || localhost | mysql.infoschema || localhost | mysql.session || localhost | mysql.sys || localhost | root || localhost | xiaohui |+--------------+------------------+12 rows in set (0.00 sec)mysql>
本次 mysql 的 user 中存在一个匿名的用户 ‘’@’localhost’ ,当用户从本地(127.0.0.1,localhost)尝试连接 mysql 时,先匹配 ‘’@’localhost’ ,验证没通过,就没有走 ‘demo’@’%’ 这条验证。
查看用户权限:
ALTER user if exists ''@'localhost' IDENTIFIED BY '123456';FLUSH PRIVILEGES;select CURRENT_USER(), user();show grants for CURRENT_USER();-- show grants for 后面不支持 user() 函数-- show grants for USER();show grants for ''@'localhost';
CURRENT_USER(), user() 这两个函数将显示连接的用户和host:
D:\devServer\mysql-8.0.22-winx64\bin>mysql.exe -p123456 --user=demomysql: [Warning] Using a password on the command line interface can be insecure.Welcome to the MySQL monitor. Commands end with ; or \g.Your MySQL connection id is 51Server version: 8.0.22 MySQL Community Server - GPLCopyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.Oracle is a registered trademark of Oracle Corporation and/or itsaffiliates. Other names may be trademarks of their respectiveowners.Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.mysql> select current_user(),user();+----------------+----------------+| current_user() | user() |+----------------+----------------+| @localhost | demo@localhost |+----------------+----------------+1 row in set (0.00 sec)mysql>
