场景回顾
环境
场景
使用 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.1
mysql: [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 -hlocalhost
mysql: [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 -p123456
mysql: [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 30
Server version: 8.0.22 MySQL Community Server - GPL
Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> use mysql;
Database changed
mysql> select HOST,USER from users;
ERROR 1146 (42S02): Table 'mysql.users' doesn't exist
mysql> 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=demo
mysql: [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 51
Server version: 8.0.22 MySQL Community Server - GPL
Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
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>