最近在本地开发环境用Docker部署MySQL 8时遇到了连接问题,无论是用DBeaver还是Navicat都报错。经过一番折腾终于解决了,这里把完整过程和原理分享给大家。
MySQL 8默认使用了新的身份验证插件caching_sha2_password,而很多客户端工具还没有完全适配这个新机制。这会导致出现"Client does not support authentication protocol"这类错误。下面我会从安装到连接一步步说明如何解决。
首先是最基本的Docker安装命令:
bash复制docker run --name mysql8 -e MYSQL_ROOT_PASSWORD=yourpassword -p 3306:3306 -d mysql:8.0
这个命令会:
注意:生产环境请使用更复杂的密码,不要用示例中的yourpassword
对于需要长期使用的环境,我建议这样启动:
bash复制docker run --name mysql8 \
-e MYSQL_ROOT_PASSWORD=your_strong_password \
-e MYSQL_DATABASE=myapp \
-e MYSQL_USER=appuser \
-e MYSQL_PASSWORD=apppassword \
-v /path/to/mysql/data:/var/lib/mysql \
-p 3306:3306 \
--restart unless-stopped \
-d mysql:8.0 \
--character-set-server=utf8mb4 \
--collation-server=utf8mb4_unicode_ci
这个配置做了以下优化:
使用DBeaver连接时常见的错误是:
code复制Public Key Retrieval is not allowed
或者
code复制Client does not support authentication protocol requested by server
这是因为MySQL 8默认使用了caching_sha2_password插件,而部分客户端还不支持。
在DBeaver的连接设置中,需要添加两个参数:
allowPublicKeyRetrieval=trueuseSSL=false
更彻底的解决方案是修改MySQL的认证方式:
sql复制ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'your_password';
FLUSH PRIVILEGES;
这条命令将root用户的认证方式改回了旧的mysql_native_password。
Navicat可能会报类似的错误:
code复制Authentication plugin 'caching_sha2_password' cannot be loaded
解决方法同样是修改认证方式:
sql复制ALTER USER 'root'@'%' IDENTIFIED WITH mysql_native_password BY 'your_password';
FLUSH PRIVILEGES;
MySQL 8默认使用caching_sha2_password插件,它:
许多客户端工具如DBeaver、Navicat等还没有完全实现对新插件的支持,主要是因为:
虽然mysql_native_password能解决兼容性问题,但从安全角度考虑:
在首次启动容器时就可以指定使用旧插件:
bash复制docker run --name mysql8 \
-e MYSQL_ROOT_PASSWORD=yourpassword \
-e MYSQL_ROOT_HOST=% \
-p 3306:3306 \
-d mysql:8.0 \
--default-authentication-plugin=mysql_native_password
不建议直接修改root的认证方式,更好的做法是:
sql复制CREATE USER 'appuser'@'%' IDENTIFIED WITH mysql_native_password BY 'password';
GRANT ALL PRIVILEGES ON *.* TO 'appuser'@'%';
FLUSH PRIVILEGES;
对于必须使用caching_sha2_password的情况,完整的JDBC连接串应该是:
code复制jdbc:mysql://host:3306/db?useSSL=true&allowPublicKeyRetrieval=true&serverTimezone=UTC
docker psdocker port mysql8docker logs mysql8docker exec -it mysql8 mysql -uroot -p如果出现权限错误,可以:
sql复制-- 查看用户权限
SELECT host, user, plugin FROM mysql.user;
-- 修改用户权限
UPDATE mysql.user SET host='%' WHERE user='root';
FLUSH PRIVILEGES;
telnet localhost 3306建议为MySQL容器分配足够的资源:
bash复制docker run --name mysql8 \
--memory="2g" \
--cpus="2" \
-e MYSQL_ROOT_PASSWORD=yourpassword \
-p 3306:3306 \
-d mysql:8.0
重要的my.cnf配置项:
ini复制[mysqld]
innodb_buffer_pool_size = 1G
innodb_log_file_size = 256M
max_connections = 200
推荐使用以下工具监控MySQL容器:
docker stats mysql8一定要配置数据卷避免数据丢失:
bash复制docker run --name mysql8 \
-v /path/to/mysql/data:/var/lib/mysql \
-e MYSQL_ROOT_PASSWORD=yourpassword \
-p 3306:3306 \
-d mysql:8.0
常用的备份方法:
bash复制# 使用mysqldump备份
docker exec mysql8 sh -c 'exec mysqldump --all-databases -uroot -p"$MYSQL_ROOT_PASSWORD"' > backup.sql
# 直接备份数据卷
tar -czvf mysql_backup.tar.gz /path/to/mysql/data
从备份恢复:
bash复制# 使用mysqldump恢复
cat backup.sql | docker exec -i mysql8 sh -c 'exec mysql -uroot -p"$MYSQL_ROOT_PASSWORD"'
# 使用数据卷恢复
tar -xzvf mysql_backup.tar.gz -C /path/to/mysql/data
在实际项目中,MySQL 8的认证机制变更确实带来了一些兼容性问题,但理解其背后的原理后,解决起来并不复杂。我个人更推荐升级客户端工具来支持新认证方式,而不是降级服务端配置。对于关键生产环境,一定要做好充分的测试和备份方案。