局域网连接MySQL8.0+异常问题解决

局域网连接MySQL 8.4.4 时遇到 “Client does not support authentication protocol requested by server” 错误,通常是因为客户端与服务器的认证协议不兼容。以下是针对 Docker 环境安装的MySql8.0+连接异常的详细解决方案:


问题原因

  • MySQL 8.0+ 默认使用 caching_sha2_password 认证插件,而旧版客户端(如 Navicat、旧版 MySQL Workbench 或某些编程驱动)仅支持 mysql_native_password。
  • 即使你修改了配置文件,Docker 容器可能未正确加载配置,或用户权限未正确设置。

解决方案步骤

方法 1:修改用户认证插件(直接在容器内执行)

  1. 进入运行中的 Docker 容器:

    1
    docker exec -it <容器名或容器ID> /bin/bash

    (例如:docker exec -it mysql-container /bin/bash)

  2. 登录 MySQL:

    1
    mysql -u root -p

    输入你在启动容器时设置的 MYSQL_ROOT_PASSWORD。

  3. 修改用户认证插件:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    -- 查看当前用户插件(确认问题)
    SELECT user, host, plugin FROM mysql.user;

    -- 将 root 用户的认证插件改为 mysql_native_password
    ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY '你的密码';
    ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY '你的密码';

    -- 刷新权限
    FLUSH PRIVILEGES;
  4. 退出并重启容器:

    1
    2
    3
    exit  # 退出 MySQL
    exit # 退出容器
    docker restart <容器名或容器ID>

方法 2:通过 Docker 启动时配置环境变量

在启动容器时,通过环境变量直接修改用户认证插件:

  1. 停止并删除现有容器(如果已存在):
    1
    2
    docker stop mysql-container
    docker rm mysql-container
  2. 重新启动容器并传递 SQL 初始化命令:
    1
    2
    3
    4
    5
    6
    docker run --name mysql-container -e MYSQL_ROOT_PASSWORD=your_password \
    -e MYSQL_INITDB_MYSQL_TCP_PORT=3306 \
    -v /path/to/your/custom/my.cnf:/etc/mysql/my.cnf \ # 可选:挂载自定义配置文件
    -p 3306:3306 \
    -d mysql:8.4.4 \
    --init-file /docker-entrypoint-initdb.d/init.sql
  3. 创建初始化 SQL 文件(init.sql): 在容器启动目录下创建 init.sql,内容如下:
    1
    2
    3
    ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'your_password';
    ALTER USER 'root'@'localhost' IDENTIFIED WITH mysql_native_password BY 'your_password';
    FLUSH PRIVILEGES;

方法 3:修改 Docker 配置文件(my.cnf)

如果希望通过配置文件修改,需确保文件被正确挂载到容器中:

  1. 创建自定义 my.cnf 文件(宿主机路径):

    1
    2
    3
    4
    5
    6
    7
    8
    [mysqld]
    bind-address = 0.0.0.0 # 允许所有IP访问
    skip-name-resolve # 禁用DNS解析(可选,加速连接)
    # MySQL 8.4+ 需确保:
    mysql_native_password=ON # 启用旧客户端兼容插件(如需)
    # 旧版本配置
    #default_authentication_plugin=mysql_native_password

  2. 挂载配置文件到容器:

    1
    2
    3
    4
    5
    docker run --name mysql-container \
    -v /path/to/your/my.cnf:/etc/mysql/my.cnf \
    -e MYSQL_ROOT_PASSWORD=your_password \
    -p 3306:3306 \
    -d mysql:8.4.4

    这会强制 MySQL 使用 mysql_native_password 插件作为默认认证方式。


常见问题排查

问题 1:配置文件未生效

  • 原因:Docker 容器未正确挂载配置文件。
  • 解决:
    1. 确保 my.cnf 文件路径正确。
    2. 检查 Docker 启动命令的挂载参数是否正确:
      1
      -v /宿主机路径/my.cnf:/etc/mysql/my.cnf

问题 2:用户权限未覆盖所有 Host

  • 原因:用户可能仅配置了 localhost 而未配置 %(允许远程连接)。
  • 解决:
    1
    2
    -- 修改所有 Host 的用户权限
    ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'your_password';

问题 3:客户端驱动版本过旧

  • 原因:客户端(如 Navicat、Python 的 mysql-connector)不支持新协议。
  • 解决:
    1. 升级客户端工具(如 Navicat 到最新版)。
    2. 使用兼容驱动:
      • Python 示例:
        1
        pip install mysql-connector-python==8.0.*  # 确保版本 >=8.0
      • Java 示例:
        1
        2
        3
        4
        5
        <dependency>
        <groupId>mysql</groupId>
        <artifactId>mysql-connector-java</artifactId>
        <version>8.0.*</version>
        </dependency>

验证连接

执行以下命令测试连接:

1
2
# 在宿主机执行
mysql -h 127.0.0.1 -P 3306 -u root -p

如果成功登录,则说明问题已解决。


总结

  • 关键点:通过修改用户认证插件为 mysql_native_password 或强制 MySQL 使用旧协议。
  • Docker 特殊性:确保配置文件正确挂载,或通过环境变量/初始化脚本直接修改用户权限。

如果问题仍未解决,请提供以下信息以便进一步排查:

  1. Docker 容器的启动命令。
  2. MySQL 用户表的 plugin 列值(通过 SELECT user, host, plugin FROM mysql.user;)。
  3. 客户端连接的具体命令或代码片段。