在Ubuntu 16.04中,无法使用普通用户账户登录MySQL的root用户。

我刚刚在Ubuntu 16.04 LTS上安装了phpmariadbnginx软件包。我运行了mysql_secure_installation并更改了root密码。
现在,当我尝试使用root帐户登录Ubuntu时,作为普通用户账户登录mysql时,我收到了访问被拒绝的消息。
当我使用sudo mysql登录时,mysql甚至不要求我输入密码。如果我运行mysql_secure_installtion,我可以看到旧设置从未被永久设置。
我做错了什么?

如果您想通过unix_socket插件恢复默认的无密码root访问权限:UPDATE mysql.user SET plugin='unix_socket' WHERE user='root'; flush privileges``` - Wolfgang Fahl
1不,你应该使用alter user root@localhost identified by unix_socket。操作mysq.user表的时代已经过去了。请使用提供的SQL语句。 - danblack
11个回答

最近我把我的Ubuntu 15.04升级到了16.04,这个方法对我有效:
  1. 首先,使用sudo mysql连接

     sudo mysql -u root
    
  2. 检查您数据库中的账户

     SELECT User,Host FROM mysql.user;
     +------------------+-----------+
     | User             | Host      |
     +------------------+-----------+
     | admin            | localhost |
     | debian-sys-maint | localhost |
     | magento_user     | localhost |
     | mysql.sys        | localhost |
     | root             | localhost |
    
  3. 删除当前的root@localhost账户

     mysql> DROP USER 'root'@'localhost';
     Query OK, 0 rows affected (0,00 sec)
    
  4. 重新创建您的用户

     mysql> CREATE USER 'root'@'localhost' IDENTIFIED BY '';
     Query OK, 0 rows affected (0,00 sec)
    
  5. 为您的用户授予权限(不要忘记刷新权限)

     mysql> GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION;
     Query OK, 0 rows affected (0,00 sec)
    
     mysql> FLUSH PRIVILEGES;
     Query OK, 0 rows affected (0,01 sec)
    
  6. 退出MySQL并尝试从本地机器上重新连接而无需使用sudo。

编辑:之前的答案建议创建一个用户'root'@'%'。然而,更安全的做法是创建'root'@'localhost',这样只能从本地进行连接,而不能远程连接。对于本地开发来说,这两种解决方案都同样有效。

希望这能帮到某人:)


18这是唯一对我有效的方法,有人知道在安装16.04上的mysql-server时,root用户到底发生了什么吗? - Ruggi
43等一下,百分之百不是意味着你可以随时随地远程连接吗? - tread
从任何主机上都可以,但不建议在生产环境中使用。 - Loremhipsum
1如果您不关心远程访问安全,这是一个很好的本地开发解决方案。 - Charney Kaye
12您可以更改行为:CREATE USER 'root'@'localhost' IDENTIFIED BY ''; - vladnev
在执行第四步时,我遇到了“ERROR 1819 (HY000):您的密码不符合当前策略要求”的错误。 - Nabin
16对于关注安全的人来说:未加密的root@localhost mysql连接模式是本地开发中的基本操作,但绝对不应该出现在其他任何地方。 - Charney Kaye
@Ruggi 我猜应该是myslq_update起了神奇的作用。对我来说,在Xubuntu 16.10上正常升级软件包(同时也升级了MySQL)时就运行了这个命令。所以你最好设置好root密码,因为随时都可能发生这种情况。而且很可能发生! - benzkji
解决了一个大问题,谢谢!但是我永远也想不明白,它毫无意义。所有的命令都没有影响到任何行。。 - Laercio
5这里的新根用户的授权语句没有给予"with grant"权限,所以根用户在运行此语句之后无法进行授权。请将授权语句更改为grant all privileges on *.* to 'root'@'localhost' with grant option; - Loren
4在这里到底发生了什么?它似乎只是重新创建了与以前相同的根用户。这个新的根用户和原始的根用户有什么区别? - Jake Wilson
2@JakeWilson 以下是解释的区别: https://askubuntu.com/a/964762/110005 这个解决方案之所以有效,是因为它从头开始创建了根用户,但是实施它将导致未来授权方面的问题,正如这些评论中所指出的。与创建新用户相比,更新现有的根用户要简单得多。 - Gazzer
1工作正常!在Ubuntu 18.04 LTS上。非常感谢! - Kristoffer Berg - EcodeAS
谢谢。这很有帮助。 在我选择mysql_secure_installation时,之前我选择了“禁止删除连接”。看来,这就是原因。 - Juljan
这在Ubuntu 18.10上运行成功。 - wuppi
如果你遇到了“ERROR 1819 (HY000): Your password does not satisfy the current policy requirements”问题,请按照这里描述的步骤降低密码策略要求:https://stackoverflow.com/questions/43094726/your-password-does-not-satisfy-the-current-policy-requirements - fustaki
抱歉,我要给你一个负评,因为这种方法比不太受欢迎的答案更过头了,而且它甚至没有解决问题发生的原因。还有因为它创建了一个名为'root@anywhere'的用户。 - mwfearnley
2“IDENTIFIED BY ''”这句话的意思是任何人都可以作为root用户登录而无需输入密码。与允许任何人从任何地方登录到您的服务器的'root'@'%'非常搭配 =-D。我想知道这个回答是否是由黑客发布的,他们会删除您的数据库并要求赎金... - Klesun
我必须每隔几次更新就重置一下...这似乎很有趣。虽然我使用了密码,但我想知道这是否是原因?在更新后,我只能执行“sudo mysql -u root -p”,直到我这样做。 - BrianBlaze
我真的很爱你,你解决了我的头疼问题。 - Masoud Motallebipour
刚刚在Ubuntu 20上遇到了MySQL 5.7的问题。这是唯一有效的解决方案! - Gert-Jan

如果您安装了5.7版本,并且没有为root用户提供密码,它将使用auth_socket插件。该插件不需要密码,也不关心密码。它只是检查用户是否使用UNIX套接字连接,然后比较用户名。
引用自在MySQL 5.7中使用"plugin: auth_socket"更改用户密码 因此,要将插件更改回mysql_native_password,请执行以下操作:
1. 使用sudo登录: ``` sudo mysql -u root ```
2. 通过单个命令更改`plugin`并设置密码: ``` ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'test'; ```
当然,你也可以使用上面的命令来设置空密码。
只是为了记录一下(对于MariaDB < 10.2的用户),还有另一种方法可以只更改插件而不提供密码(将其留空):
update mysql.user set plugin = 'mysql_native_password' where User='root';
// to change the password too (credits goes to Pothi Kalimuthu)
// UPDATE mysql.user SET plugin = 'mysql_native_password', Password = PASSWORD('secret') WHERE User = 'root';
FLUSH PRIVILEGES;

2谢谢,出于某种原因,在apt-get升级后,这个设置突然自动启用了,我想... - Tominator
这终于是问题所在,经过从Ubuntu 14.04升级到16.04的更新后,我被锁在了我的数据库之外... - Reflic
我猜是myslq_update起了作用。对我来说,在xubuntu 16.10上正常升级软件包时会运行这个命令。所以你最好设置好root密码,因为它可能随时发生。 - benzkji
5另外,我更喜欢这个答案——它要温和得多;-) - benzkji
注意:您必须使用适用于MariaDB < 10.2的查询,因为这个版本中添加了alter user命令,但它仍然支持(并使用)auth_socket插件。 - Loren
1谢谢你指出这个插件:它真的很有用! - aba
5对于MariaDB < 10.2版本,要同时更改插件和密码,请使用以下查询语句:UPDATE mysql.user SET plugin = 'mysql_native_password', Password = PASSWORD('secret') WHERE User = 'root'; FLUSH PRIVILEGES; 来源:https://stackoverflow.com/a/41537019/1004587 - Pothi Kalimuthu
110x @PothiKalimuthu,刚刚更新了答案。 - Todor
在Linux Mint 18.2 Sonya中,我收到以下错误消息:MariaDB [(none)]> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'root'; ERROR 1064 (42000):在第1行附近出现了一个语法错误,请检查与您的MariaDB服务器版本相对应的手册以获取正确的语法。 - user22516
10这应该是被接受的回答。 - Geo C.
4我希望我能给这个点赞两次。 - James Smith
1每次 MySQL 更新后,我都会来这里,复制粘贴所需的代码行,但仍然无法熟记它。 - benzkji
我在这个操作中遇到了ERROR 1396 (HY000): Operation ALTER USER failed for 'root'@'localhost'的错误。 - xjcl
你是一个好人。 - reza.safiyat
1每次在Ubuntu上更新MySQL后,我都希望能给它点赞! - benzkji

简而言之,关于MariaDB
UPDATE mysql.user SET plugin = 'mysql_native_password', 
      Password = PASSWORD('NEWPASSWORD') WHERE User = 'root';

在这里,您将使用您想要的密码替换NEWPASSWORD,并且其他内容保持不变。

问题在于当安装/更新MariaDB或MySQL时(特别是如果在某个时候设置了root而没有密码),则在用户表中实际上密码为空(或被忽略),登录取决于与MySQL用户对应的系统用户。 您可以通过切换到系统根目录,然后输入以下命令来测试:

mysql -uroot -p

然后输入无密码或者错误的密码。你很可能会被放行。(甚至可以通过简单地使用# mysql作为密码并定义用户来从unix root登录)。
那么发生了什么呢?如果你以root身份登录并执行以下操作:
select User,host,plugin from mysql.user; 
+----------------+-----------+-----------------------+
| User           | host      | plugin                |
+----------------+-----------+-----------------------+
| root           | localhost | auth_socket           |
+----------------+-----------+-----------------------+

你会注意到auth_socket(在MariaDB上可能是unix_socket)。这些套接字忽略密码,并允许相应的Unix用户在没有密码检查的情况下登录。这就是为什么你可以用root登录,但不能用其他用户登录的原因。
所以解决方案是更新用户,不使用auth_socket/unix_socket,并正确设置密码。
在MariaDB(<10.2,请参见下面的评论)上,这对于Ubuntu 16版本(截至2017年)应该足够了。NEWPASSWORD是你的密码。mysql_native_password你要逐字输入。
UPDATE mysql.user SET plugin = 'mysql_native_password', Password = PASSWORD('NEWPASSWORD') WHERE User = 'root';

(将插件设置为空可能会起作用。结果因人而异。我没有尝试过这个方法,所以这是一个替代方案。)
UPDATE mysql.user SET plugin = '', Password = PASSWORD('NEWPASSWORD') WHERE User = 'root';

否则:
ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'NEWPASSWORD';

然后
FLUSH PRIVILEGES;

就记录而言,涉及删除用户并使用“%”重新创建用户的解决方案使我完全被锁定在数据库之外,并且除非您完全正确地编写grant语句,否则可能会引起其他问题 - 更容易的方法是简单地更新您已经拥有的root用户。
根据我的经验,这个问题只会发生在root用户上,因为其他用户将手动添加,而不是作为初始安装/更新的一部分。

2找到这个方法完美运行。但让我好奇的是,为什么使用 mysql_secure_installation 更改根密码没有产生相同的效果。它将新密码存储在哪里? - Mausy5043
你能编辑你的回答并在进行时更多地解释每个命令吗?我不清楚哪些适用。是两个UPDATE适用于MariaDB <10.2,而ALTER适用于其他版本吗?第二个UPDATE是第一个的替代,还是我们需要同时输入两个?最后,'mysql_native_password'是要逐字输入,还是应该用我们打算用于MySQL的root密码来替换它? - Michael Scheper
1@MichaelScheper 有一段时间了,所以我不想编辑太多,但这是我记得的内容。(1) 只执行第一个UPDATE (<10.2可能不是必需的)。(2) 是的,逐字输入“mysql_native_password”。本质上,你所做的就是告诉mariadb:“不要使用Unix权限,而要使用数据库权限”。mysql_native_password就是这个选项。 - Gazzer
我他妈把“privilege”拼错了! - Gazzer
1看起来你只差了1分半钟就错过了编辑时间限制!我有时候也会因此感到沮丧。不管怎样,谢谢! - Michael Scheper

默认情况下,root 用户通过 auth_socket 进行身份验证,而不是使用密码。
为了使用密码身份验证,请执行以下操作:
  1. 登录到MySQL的root shell:

    sudo mysql
    
  2. 检查不同用户启用的身份验证方法(可选):

    SELECT * FROM mysql.user;
    
  3. 使root使用密码进行身份验证:

    ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_password_here';
    
  4. 刷新权限以使更改生效:

    FLUSH PRIVILEGES;
    
  5. 退出并使用密码进行身份验证:

    exit
    mysql -u root -p
    

当我这样做时,我无法以root身份sudo mysql。我必须先su,然后才能以root身份登录mysql。所以我把它改回了auth_socket。 - untill
单个命令:mysql -u root -p -e "use mysql;update user set plugin='mysql_native_password' where user='root';flush privileges;" - Chris Stryczynski
如果你想失去对MySQL实例的访问权限,那么这个答案就是最简单的方法。 - Danila Vershinin
是的。这使问题变得更糟。 - Guissmo
这是在我电脑上进行全新的Ubuntu 20.04 LTS安装时唯一有效的方法。 - chx

如果您以root用户身份运行mysql命令,您将无需输入密码即可获得访问权限,因为root@localhost启用了套接字认证。
设置密码的唯一方法是切换到本机认证,如下所示: $ sudo mysql mysql> ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'test';

这实际上是唯一一个解释了真正发生情况的答案。其他人都是凭直觉乱猜的。 - Houman

尝试创建新的MySQL账户,对我来说有效(MySQL 5.7.12):
  1. 以sudo身份登录:

    sudo mysql -uroot
    
  2. 创建新用户并授予权限(无密码):

    CREATE USER 'admin'@'localhost' IDENTIFIED BY '';
    GRANT ALL PRIVILEGES ON *.* TO 'admin'@'localhost';
    
  3. 以新用户身份登录:

    mysql -uadmin
    

我一直在调整我创建的一些配置脚本,以便使用MariaDB,并遇到了这个确切的问题。通过整合大量信息,这里有一个Gazzer's answer真正聚焦于这个问题;它归结为auth_socket/unix_socket设置。
所以,在使用MariaDB 5.5(在Ubuntu 14.04下)和MariaDB 10(在Ubuntu 16.04下)时,登录MySQL并运行这个命令立即解决了问题:
UPDATE mysql.user SET plugin='' WHERE User='root';
FLUSH PRIVILEGES;

其他的回答,包括截至本帖最高票回答由Loremhipsum提供,都鼓励了不良的做法,即建议删除用户然后重新创建。对我来说,这是一个相当激进的解决方案。最好/最简单的解决方法是将plugin值设为null,刷新权限,继续生活。

我必须完成两件事(感谢@Todor和@Loremhipsum):
update mysql.user set plugin = 'mysql_native_password' where User='root';
grant all privileges on *.* to 'root'@'localhost';

然后:
FLUSH PRIVILEGES;

我不建议删除用户root

先试试这段代码,

echo "CREATE USER 'root'@'localhost' IDENTIFIED BY 'root';" > your_init_file.sql
echo "GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION;" >> your_init_file.sql 
echo "FLUSH PRIVILEGES;" >> your_init_file.sql

然后,
killall mysqld
mysqld_safe --init-file=$PWD/your_init_file.sql

然后按下Ctrl+Z,输入:bg将进程从前台切换到后台运行,然后通过以下方式验证您的访问权限:
mysql -u root -proot
mysql> show grants;

最高安全性

由于Unix身份验证是最安全的身份验证方式,最好的做法是保持默认的root账户不变(即继续使用无密码的Unix套接字身份验证),如果不使用root账户,则通过sudo来使用。如果攻击者已经获得了root/sudo访问权限,那么他们已经完全控制了您的服务器...

当您需要通过其他方法(即非CLI)访问MySQL/MariaDB时,请创建一个新的带有密码和所需权限的MySQL/MariaDB用户。