无法使用 JDBC 连接到 docker 中的本地 MySQL

Posted

技术标签:

【中文标题】无法使用 JDBC 连接到 docker 中的本地 MySQL【英文标题】:Can't connect to local MySQL in docker with JDBC 【发布时间】:2018-11-04 18:07:11 【问题描述】:

我正在开发一个 Java 应用程序,它使用在 Docker 容器中运行的 mysql。我最近从 Windows 环境切换到 Mac OS,无法使用 JDBC 连接到 Java 代码中的数据库。我可以使用 MySQL Workbench 和命令行客户端连接到数据库。

我使用 Docker for Mac(即没有默认的 docker 机器)。

我用这个启动我的 Docker 容器:

CONTAINER_NAME=hypo-mysql
PORT="3306:3306"
VOLUME_FROM="hypo-mysql-data"
CONFIG_DIR="$(pwd)/conf.d"
MYSQL_ROOT_PASSWORD="xxxxx"
MYSQL_USER="hypo"
MYSQL_PASSWORD="doktorBenArmsson"
MYSQL_DATABASE="Hypo"

docker run --name $CONTAINER_NAME \
            -p $PORT \
            --volumes-from $VOLUME_FROM \
            -v $CONFIG_DIR:/etc/mysql/conf.d \
            -e MYSQL_ROOT_PASSWORD=$MYSQL_ROOT_PASSWORD \
            -e MYSQL_USER=$MYSQL_USER \
            -e MYSQL_PASSWORD=$MYSQL_PASSWORD \
            -e MYSQL_DATABASE=$MYSQL_DATABASE \
            -d --restart=always mysql \

当我启动我的 Java 应用程序时,我一开始就出现了这个错误:

Caused by: java.sql.SQLException: Unable to load authentication plugin 'caching_sha2_password'.

由于我的 JDBC 驱动程序不支持 MySQL 使用的新身份验证方法,我将用户更改为使用旧的本地方法:

mysql> select user, host, plugin from user;
+------------------+-----------+-----------------------+
| user             | host      | plugin                |
+------------------+-----------+-----------------------+
| hypo             | %         | caching_sha2_password |
| root             | %         | caching_sha2_password |
| mysql.infoschema | localhost | mysql_native_password |
| mysql.session    | localhost | mysql_native_password |
| mysql.sys        | localhost | mysql_native_password |
| root             | localhost | caching_sha2_password |
+------------------+-----------+-----------------------+

ALTER USER 'hypo'@'%' IDENTIFIED WITH mysql_native_password BY ‘xxxxxxx’;

mysql> select user, host, plugin from user;
+------------------+-----------+-----------------------+
| user             | host      | plugin                |
+------------------+-----------+-----------------------+
| hypo             | %         | mysql_native_password |
| root             | %         | caching_sha2_password |
| mysql.infoschema | localhost | mysql_native_password |
| mysql.session    | localhost | mysql_native_password |
| mysql.sys        | localhost | mysql_native_password |
| root             | localhost | caching_sha2_password |
+------------------+-----------+-----------------------+

现在我从 Java 收到以下错误:

Caused by: java.sql.SQLException: Unknown system variable 'query_cache_size'

我在 gradle 中升级了我的 JDBC 驱动程序:

//old driver: compile 'mysql:mysql-connector-java:5.1.38'
compile 'mysql:mysql-connector-java:5.1.46'

现在我从 Java 收到此错误:

Caused by: java.io.IOException: Keystore was tampered with, or password was incorrect
    at sun.security.provider.JavaKeyStore.engineLoad(JavaKeyStore.java:780)
    at sun.security.provider.JavaKeyStore$JKS.engineLoad(JavaKeyStore.java:56)
    at sun.security.provider.KeyStoreDelegator.engineLoad(KeyStoreDelegator.java:224)
    at sun.security.provider.JavaKeyStore$DualFormatJKS.engineLoad(JavaKeyStore.java:70)
    at java.security.KeyStore.load(KeyStore.java:1445)
    at com.mysql.jdbc.ExportControlled.getSSLSocketFactoryDefaultOrConfigured(ExportControlled.java:381)
    ... 27 more
Caused by: java.security.UnrecoverableKeyException: Password verification failed
    at sun.security.provider.JavaKeyStore.engineLoad(JavaKeyStore.java:778)

但我无法弄清楚这个错误的实际含义或如何摆脱它。我知道密码是正确的,因为我在通过 Workbench 连接时使用相同的密码。但是,关于密钥库的消息让我感到困惑……我一开始没有接触密钥库,但后来我尝试重新生成密钥库文件,但我仍然从 Java 中收到相同的错误消息。

更新: 我为 mysql 重新创建了 docker 容器并明确使用了版本 5:

docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                    NAMES
8bf6b9ddd29f        mysql:5             "docker-entrypoint.s…"   15 seconds ago      Up 13 seconds       0.0.0.0:3306->3306/tcp   hypo-mysql
1a0add303fe0        mysql:5             "docker-entrypoint.s…"   4 minutes ago       Created                                      hypo-mysql-data

docker exec -it hypo-mysql bash
mysql --version
mysql  Ver 14.14 Distrib 5.7.22, for Linux (x86_64) using  EditLine wrapper

在我恢复到原来的 jdbc 驱动程序版本 5.1.38 之后,它似乎可以工作了!

非常感谢任何帮助和提示!

【问题讨论】:

java.sql.SQLException: Unknown system variable 'query_cache_size'的可能重复 【参考方案1】:

您在 docker 镜像中使用 mysql8,它有不同的身份验证实现。

请参阅以下链接中的caching_sha2_password 更改

Authentication plugin 'caching_sha2_password' cannot be loaded

https://dev.mysql.com/doc/refman/8.0/en/caching-sha2-pluggable-authentication.html

所以暂时尝试将mysql版本降级到5.7。 在旁注中,通过链接使用 mysql-8 的正确步骤。 查看 jdbc-connector 的以下链接。https://dev.mysql.com/doc/refman/8.0/en/upgrading-from-previous-series.html#upgrade-caching-sha2-password-compatible-connectors

【讨论】:

我认为你是对的,重新创建了带有标签 5 的 docker 映像并返回使用我们的旧/原始 JDBC 驱动程序,至少我没有再收到密钥库错误了!谢谢。

以上是关于无法使用 JDBC 连接到 docker 中的本地 MySQL的主要内容,如果未能解决你的问题,请参考以下文章

无法在本地环境中使用 docker 连接到 cakephp 中的 mysql 数据库

无法从本地主机连接到 Docker 中的 MySQL(Docker for Mac beta)

我无法使用 DataGrip 数据库客户端从本地主机连接到 docker 中的 mysql

docker-compose 中的“无法连接到本地 MySQL 服务器”

如何通过 Spark 中的 jdbc 连接到 docker 托管的 postgresql 数据库?

无法从本地连接到 mysql docker