在命令行输入 mysql -u root p, 输入密码, 或通过工具连接数据库时, 经常出现下面的错误信息, 详细该错误信息很多人在使用 MySQL 时都遇到过
- ERROR 1045 (28000): Access denied for user root@localhost (using password: YES)
- 1
- **
通常从网上都能找到解决方案:
**
1. 停止服务: 停止 MySQL 服务;
- # windows
- net stop mysql
- # linux
- service mysqld stop
- 1
- 2
- 3
- 4
2. 跳过验证: 修改 MySQL 安装目录下的 my.ini 配置文件, 使登录时跳过权限检查;
- # 到 mysql 根目录找到 mysql 配置文件
- vim my.ini
- #在 my.ini,[mysqld] 下添加一行, 使其登录时跳过权限检查
- skip_grant_tables
- 1
- 2
- 3
- 4
3. 修改密码: 启动 MySQL 服务, 登录 MySQL, 此时提示输入密码, 输入任意密码回车即可进入 MySQL
- # 登录 mysql
- mysql -u root -p
- 1
- 2
然后通过 SQL 语句修改 root 用户的密码;
- # 将数据库切换至 mysql 库
- mysql> USE mysql;
- # 修改密码
- mysql> UPDATE user SET password=PASSWORD(newpasswd)WHERE user=root;
- # 刷新 MySQL 权限相关的表
- mysql> flush privileges;
- mysql> exit;
- 1
- 2
- 3
- 4
- 5
- 6
- 7
4. 重启服务: 将 my.ini 文件中加入的跳过权限语句删除或加 #号注释重启服务, 使用修改后的密码登录即可
**
原因分析:
**
使用 root 用户登录 MySQL, 查看 user 表中的用户信息如下, 可以发现 host 的字段分别为 % 和 localhost
- mysql>select host,user,password from user;
- 1
在 MySQL 中 % 表示可以在任何主机上登录 MySQL 数据库, 那为什么还需要明确创建登录主机为 localhost 的用户呢?
这涉及到 MySQL 安装时的初始化用户, 匿名用户以及连接验证策略等, 下面进行深入的分析
在安装 MySQL 时, 会默认初始化一些用户, 比如 root 用户, 以及 host 字段为 localhost,user 字段为空的用户 User 字段为空的用户即为匿名用户, 该用户的密码也为空, 任何人都可以使用匿名用户登录 MySQL 数据库, 但可以做的事情却是有限的, 比如在命令行直接输入 mysql 登录, 可以查看匿名用户对哪些数据库有权限:
- mysql > select current_user;
- 1
- mysql > show databases;
- 1
通过上面的图片可以发现, 匿名用户仅对 information_schema 和 test 数据库有权限
而匿名用户又是如何影响其他用户登录, 进而出现 28000 错误的呢?
当试图连接 MySQL 数据库时, 数据库根据提供的身份和密码决定是否接受连接请求, 身份由两部分组成: 用户名和客户端主机 (即输入 mysql 命令的主机)
由于 host 字段中的 % 匹配任何主机或者 host 字段包含通配符, 就可能出现多个匹配行, 服务器必须决定匹配哪一个, 解决方案如下:
服务器将 user 表中的数据读入内存中, 按照 host 和 user 字段对行进行排序
- mysql>select host,user,password from user order by host desc,user desc;
- 1
当客户端试图连接时, 服务器查找已排序的行并使用第一个匹配客户端主机和用户名的行, user 字段为空表示可以匹配任何用户
找到匹配行后, 在验证密码是否一致, 如果一致则登录成功
此处主要关注第四行, user 为空, 即任意用户, 不使用密码登录 localhost 时, 匿名用户仅对 information_schema 和 test 数据库有权限, 使用其他数据库时, 导致失败
SO 解决办法
- mysql> select host,user,password from user order by host desc,user desc;
- mysql> update user set host = % where host = oracle and user = root;
- mysql> flush privileges;
- 1
- 2
- 3
来源: http://www.bubuko.com/infodetail-2498177.html