MySQL 使用 Hibernate 的结构故障转移和连接池

MySQL Fabric failover and Connection Pooling with Hibernate

我正在尝试通过 MySQL Fabric 服务器组使用 JNDI 资源、Hibernate 和连接池实现自动故障转移。我们的数据库场已使用 MySQL Fabric 正确设置,我正在尝试实施 client/connector.

我在我的 server.xml 文件中声明了一个 JNDI 资源,它有一个 MySQL 基于 Fabric 的 URL 和驱动程序,并使用休眠连接池。

<Resource
name="jdbc/myApp"
type="javax.sql.DataSource"
driverClassName="com.mysql.fabric.jdbc.FabricMySQLDriver"
maxWait="1000"
url="proper.fabric.url/fabricServerGroup=myFabricGroup"
maxActive="45"
validationQuery="select 1 from dual"
/>

我遇到的问题是连接池和 Fabric 不能很好地协同工作。取下主数据库后,Fabric 会按预期自动提升一个从数据库。但是,当我尝试与数据库建立新连接时,我正在恢复旧的现已失效的连接,最值得注意的是,当我请求读写时,我正在恢复只读连接。作为附加信息,如果我重新启动 Tomcat 服务器并请求新连接,我会得到正确的结果。由于连接池,我遇到的问题特别出现。

我需要知道的是,如果我遗漏了 key/value 对,这将使我的 FabricDriver 足够聪明,知道在发生自动故障转移时擦除连接池。

我发现最好的方法是使用 testOnBorrow,不幸的是它只能使用 SELECT 查询(通过 validationQuery),尽管 请求读写。

以前有人解决过这个问题吗?

注意:如果我尝试使用 com.mysql.fabric.jdbc.FabricMySQLDataSource,我什至无法成功建立任何连接。常规 javax.sql.DataSource 似乎是这里的正确值。

第二个注意事项:我使用的是 mysql-connector-java 版本 5.1.35

刚收到 Oracle 的回复,这显然是一个已知错误,将在即将发布的版本中修复:5.1.36

我对 Oracle MySQL Connector/J 5.1.39 也有同样的问题。 我能够遵循请求与 Fabric 的新连接的故障转移,仅在我的代码中捕获异常:

...
} catch(java.sql.SQLException e) {
        int errorCode = e.getErrorCode();
        /*
         * java.sql.SQLException: The MySQL server is running with the --read-only option so it cannot execute this statement
         * java.sql.SQLException: Cannot execute statement in a READ ONLY transaction.
         *
         */
        if(errorCode == 1290 || errorCode == 1792) {
            System.out.println("Failover");
            System.out.println(e.toString());
            connection.close();

            rawConnection = DriverManager.getConnection(baseUrl, mysql_user, mysql_password);
            connection = (FabricMySQLConnection) rawConnection;
}

从连接器端询问 Oracle 支持有关自动故障转移的问题,他们回答 "Connector/J doesn't have desired feature"。

有人能够将那个捕获集成到连接池中吗?