返回

Debian/树莓派重置MariaDB Root密码终极指南

Linux

Debian 上无法重置 MariaDB root 密码问题解决

在树莓派 (Raspbian GNU/Linux 10) 上,我碰到了一个麻烦事:无法重置 MariaDB (mysql Ver 15.1 Distrib 10.3.22-MariaDB) 的 root 密码。网上找了不少方法,但都卡在了某个地方。

问题现象

我按网上常见的步骤操作:

  1. sudo systemctl stop mysql.service 停止 MySQL 服务。
  2. sudo mysqld_safe --skip-grant-tables --skip-networking & 以安全模式启动,跳过权限检查和网络连接。
  3. mysql -u root 以 root 用户登录。
  4. use mysql; 选择 mysql 数据库。
  5. UPDATE user SET authentication_string = password("NEWPASSWORD") where User='root'; 修改 root 密码。这一步提示成功。
  6. flush privileges; 刷新权限。
  7. quit 退出。
  8. mysqladmin shutdown 关闭 mysql。
  9. sudo systemctl start mysql.service 重新启动服务。

最后,用新密码登录 mysql -u root -p,却提示 "ERROR 1044 (42000): Access denied for user 'root'@'localhost' to database 'defaultDB'"。 这可真是怪了!

问题根源分析

这个问题可能由多种原因引起, 主要集中在以下几方面:

  1. 密码字段名不正确: MariaDB 10.4 之前, 密码字段通常是 password。从 MariaDB 10.4 开始, 使用的是authentication_string。 老版本的教程还在使用 password, 新版本已经不用了。这算是个小坑.
  2. 'root'@'localhost' 存在多个账户: 有可能系统中存在多个名为 'root' 的用户,但关联不同的主机 (host) , 比如 'root'@'localhost', 'root'@'127.0.0.1', 'root'@'::1' 。我们修改的可能不是真正需要使用的那个 'root' 账户的密码。
  3. 插件问题 (plugin): MariaDB 使用插件处理用户认证。如果 plugin 字段不是 mysql_native_password,即使密码正确,也可能无法登录。有些老的方案没有关注过这一点。
  4. 跳过网络连接选项: --skip-networking 可能会导致某些认证方式无法使用,具体依赖于 MariaDB 配置和使用的插件。但在这个特定案例中,它一般不是主因,只是为了更安全.
  5. 旧版mysqladmin shutdown可能无法正确的结束mysqld_safe启动的进程。

解决办法

综合来看,我们需要修改密码,确保修改的是对的账户,并明确指定认证插件。 下面提供几种可靠的解决方案:

方法一: 修正密码字段并指定 Host

这种方法通过指定 Host ('localhost'),确保修改到正确的用户记录。

  1. 停止 MariaDB 服务:

    sudo systemctl stop mysql.service
    
  2. 以安全模式启动 MariaDB:

    sudo mysqld_safe --skip-grant-tables --skip-networking &
    
  3. 连接 MariaDB:

    mysql -u root
    
  4. 选择 mysql 数据库:

    use mysql;
    
  5. 更新 root 用户密码和插件: 确保把 NEWPASSWORD 换成你的新密码.

    UPDATE user SET authentication_string = PASSWORD('NEWPASSWORD'), plugin = 'mysql_native_password' WHERE User = 'root' AND Host = 'localhost';
    
  6. 刷新权限:

    FLUSH PRIVILEGES;
    
  7. 退出 MariaDB 客户端:

    quit;
    
  8. 关闭通过mysqld_safe启动的mysql:

    找到mysqld进程的pid,并用kill杀掉。千万别用 mysqladmin shutdown! 因为那个大概率会失败!

    ps aux | grep mysqld
    sudo kill <pid>
    

    <pid>mysqld 进程的 ID。

  9. 正常启动mariadb :

     sudo systemctl start mysql.service
    
  10. 测试新密码:

    mysql -u root -p
    

    输入你刚才设置的密码。如果能成功登录,那就 OK 了!

方法二: 使用 ALTER USER 语句(推荐)

如果你的 MariaDB 版本支持 ALTER USER 语句(通常都支持),这会是更规范、更简洁的方法。

  1. 停止 MariaDB 服务:

    sudo systemctl stop mysql.service
    
  2. 以安全模式启动 MariaDB:

    sudo mysqld_safe --skip-grant-tables --skip-networking &
    
  3. 连接 MariaDB:

    mysql -u root
    
  4. 修改 root 用户密码: 一定要将 NEWPASSWORD 替换成你的实际密码.

    ALTER USER 'root'@'localhost' IDENTIFIED BY 'NEWPASSWORD';
    
  5. 刷新权限(可选,ALTER USER会自动刷新):

    FLUSH PRIVILEGES;
    
  6. 退出 MariaDB 客户端:

    quit;
    
  7. 关闭通过mysqld_safe启动的mysql:

    同样,别用 mysqladmin shutdown,用 kill!

    ps aux | grep mysqld
    sudo kill <pid>  # <pid> 是 `mysqld` 进程的 ID.
    
  8. 正常启动 MariaDB:

    sudo systemctl start mysql.service
    
  9. 测试新密码:

    mysql -u root -p
    

方法三: 删除所有 root 用户再重建(极端情况)

如果以上两种方法都无效, 且你确认没有重要数据, 可以尝试这个方法。此方法会删除所有 root 用户 ,然后重建一个。这方法比较暴力, 小心使用!

  1. 停止 MariaDB 服务:

    sudo systemctl stop mysql.service
    
  2. 以安全模式启动 MariaDB:

    sudo mysqld_safe --skip-grant-tables --skip-networking &
    
  3. 连接 MariaDB:

    mysql -u root
    
  4. 删除所有名为 'root' 的用户:

    use mysql;
    DELETE FROM user WHERE User='root';
    FLUSH PRIVILEGES;
    
  5. 创建新的 root 用户并设置密码 (把 NEWPASSWORD 替换为实际密码):

    CREATE USER 'root'@'localhost' IDENTIFIED BY 'NEWPASSWORD';
    GRANT ALL PRIVILEGES ON *.* TO 'root'@'localhost' WITH GRANT OPTION;
    FLUSH PRIVILEGES;
    
  6. 退出 MariaDB 客户端:

    quit;
    
  7. 关闭通过mysqld_safe启动的mysql:
    ```bash
    ps aux | grep mysqld
    sudo kill # mysqld 进程的 ID.

  8. 正常启动 MariaDB

    sudo systemctl start mysql.service
    
  9. 测试新密码:

    mysql -u root -p
    

额外安全建议:

  • 强密码: 设置一个复杂且难以猜测的密码,包含大小写字母、数字和符号。
  • 定期修改密码: 没事定期改一下 root 密码.
  • 限制远程访问: 如果不需要从外部访问数据库,配置 MariaDB 只监听本地连接。 这可以在 MariaDB 配置文件 (通常是 /etc/mysql/mariadb.conf.d/50-server.cnf 或类似文件) 中设置 bind-address = 127.0.0.1
  • 最小权限原则: 不要随意用root账号操作.平时使用的数据库账号, 给需要的权限就行了.

进阶:理解 root 用户和 host

在 MariaDB (以及 MySQL) 中, 用户认证是基于用户名 host 的。 这意味着你可以有多个名为 'root' 的用户, 但它们关联到不同的 host.

  • 'root'@'localhost' 表示只能从本机登录的 root 用户.
  • 'root'@'127.0.0.1' 也是表示本机 (IPv4), 但通常与 localhost 稍有区别(有时受 hosts 文件影响).
  • 'root'@'::1' 同样表示本机 (IPv6).
  • 'root'@'%" 表示可以从任意主机登录的 root 用户 (这 非常 不安全!).

一般情况下, 重置密码应该针对 'root'@'localhost' , 这能覆盖最常见的本地登录场景. 如果你有特别的配置 (例如允许远程访问), 则可能需要修改对应 host 的 root 用户密码.

希望这回能彻底帮你搞定 MariaDB root 密码重置问题!