使用 Unix Socket 的 JDBC MySQL 连接
Posted
技术标签:
【中文标题】使用 Unix Socket 的 JDBC MySQL 连接【英文标题】:JDBC MySQL connection using Unix Socket 【发布时间】:2014-09-18 17:01:35 【问题描述】:我在 Linux 上通过 --skip-networking 选项使用 mysql。
尝试使用 JDBC 将我的基于 J2EE 的应用程序(使用 servlet)连接到 MySQL 数据库。
当使用带有 --skip-networking 选项禁用的 MySQL 时,我连接到数据库的方式是:
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://localhost:3306/mydatabase","myuser","mypassword");
启用 --skip-networking 选项后,我尝试将其连接为:
Class.forName("com.mysql.jdbc.Driver");
Connection con = DriverManager.getConnection("jdbc:mysql://localhost/mydatabase","myuser","mypassword");
但这似乎不起作用,当我尝试在我的应用程序中连接到数据库时,我得到 java.lang.NullPointerException。
注释掉--skip-networking选项后,使用旧的JDBC语句,就可以连接数据库了。
注意 - 我可以通过命令行 mysql 客户端在启用 --skip-networking 选项的情况下连接到数据库。
谁能告诉我如何从 JDBC 连接到数据库?我尝试搜索它,但找不到任何令人满意的答案。提前致谢。
【问题讨论】:
你在使用 Java >= 7 是 java 7.u65_2.5.2-1 你能发布完整的堆栈跟踪吗?因为我在 linux 上并尝试使用 JDBC 连接到 mysql,它工作正常 你能给一个关于如何发布堆栈跟踪的链接 复制堆栈跟踪并编辑您的问题并将其粘贴为代码 【参考方案1】:如果您想通过 Mysql JDBC Connector/J 使用 UNIX 套接字,您需要提供 socketFactory。
jdbc:mysql:///?user=test&password=test&socketFactory=<classname>&<socket>=/tmp/mysql.sock
因此,这将因您使用的实现而异。默认情况下,Mysql 没有提供任何实现,只是在它的源代码中提供了这样一个工厂的示例。
有一个名为junixsocket 的现有UNIX 套接字Java 库,它也有这样一个socketFactory 类实现。 Connecting to a MySQL database via Unix Domain Sockets 中概述了一个示例,这是他们文档的一部分。
您可以在相关问答材料中找到更多 Java UNIX 套接字库替代方案:
UNIX socket implementation for Java?【讨论】:
【参考方案2】:您根本无法做到这一点:MySQL JDBC 驱动程序仅支持 TCP/IP 和 - 在 Windows 上 - 命名管道连接到数据库。因此,指定--skip-networking
将根本不允许您使用 JDBC MySQL Connector/J。
另见http://lists.mysql.com/java/8749:
Java 本身不支持 unix 域套接字,但由于您在 Windows 上,因此可以使用命名管道,[..]
上面帖子中的死链接现在是http://dev.mysql.com/doc/connector-j/en/connector-j-reference-configuration-properties.html
【讨论】:
谢谢。你知道命名管道是否可以在 Unix 上使用吗?您引用的帖子中的链接似乎已死。您还可以推荐任何其他支持 Unix 管道的连接器吗?作为我在某处读到的替代方案.. @AadityaBagga 我在答案中添加了等效链接。 Namedpipes - afaik - 专门用于 Windows,所以你不能在 Unix 中使用它。仅在 localhost 上绑定或使用防火墙确实是保护服务器的好选择。 谢谢,我去看看。我还找到了一个链接dev.mysql.com/doc/refman/5.0/en/connecting.html,其中列出了一些连接选项。标记为已解决。【参考方案3】:MariaDB 项目的 JDBC 驱动程序支持 Unix 域套接字,同时与 MySQL Connector/J JDBC 驱动程序保持兼容。 MariaDB 驱动程序的示例 jdbc url 是:
jdbc:mariadb://localhost:3306/revmgt?localSocket=/var/run/mysqld/mysqld.sock
值得注意的是,这需要包含 JNA 库,因为 MariaDB 驱动程序在内部通过 JNA 使用域套接字。在使用 unix 域套接字时,我看到了 CPU 绑定 java 进程的速度改进。我相信这主要是因为将工作从 java 进程卸载到本机代码,从而为已经出现 CPU 瓶颈的 java 进程释放 CPU 周期。
【讨论】:
在您的连接字符串中,您提到了 IP:port 作为 localhost:3306。通过 Unix Socket 连接时是否需要提及主机属性?? 似乎在类路径中包含 JNA 库(在我的情况下为 jna-5.6.0.jar)是绝对关键的。我花了将近一天的时间努力使 mariadb 连接器与一致的“套接字无法连接到主机:本地主机,端口:3306”一起工作。连接被拒绝(连接被拒绝)'。同时,基于控制台的 mysql 以及 Python 中的 MySQLdb 运行良好。只需在类路径中包含 JNA 即可使一切正常。不过,您不必在 url 上指定“3306”。果然,ConnectorJ 的文档确实告诉您如果要使用套接字,请安装 JNA。【参考方案4】:正如another answer 指出的那样,可以(至少在 Intellij IDE 中)为Mysql JDBC Connector/J 使用套接字连接(我使用的是 5.1 版)无需提供 socketFactory, p>
jdbc:mysql://localhost:3306/database_name?socket=/tmp/mysql.sock
【讨论】:
这看起来真的很有用,但是我无法让它工作,不得不使用 junixsocket 代替 @MatteoTassinari Intellij IDE 可能提供了一些额外的库来支持socket
参数方法。
Flyway 也是如此。但是,documentation still claims that they do not support it。所以可能还有其他一些库在后台添加了对这个选项的支持。
经过一些测试,我认为实际上可能发生的是我们正在使用 MariaDB 连接器,因为它也在监听 jdbc:mysql:
并且它也在类路径上。如果我按照here 的文档使用&disableMariaDbDriver
,我会遇到问题。以上是关于使用 Unix Socket 的 JDBC MySQL 连接的主要内容,如果未能解决你的问题,请参考以下文章
长久不用的mysql报错ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/tmp/mys
【socket】关于Unix域套接字(Unix Domain Socket)
mysql连接:ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mys
连接数据库报错:ERROR 2002 (HY000): Can't connect to local MySQL server through socket '/var/lib/mys