簡體   English   中英

mysql主/從復制問題:無法創建PoolableConnectionFactory

[英]mysql master/slave replication issue: Cannot create PoolableConnectionFactory

我花了很多時間,但無法弄清楚。 我知道,如果我使用BasicDataSource則需要在openjpa.ConnectionProperties屬性中傳遞配置。 openjpa.ConnectionProperties是用逗號(,)分隔的屬性,這些屬性映射到DataSource實例。 現在, MySQL還期望主機以逗號(,)分隔格式。 因此無法弄清楚,如何使用MySQL replication創建DataSource ?*

我正在嘗試使用openjpa設置master / slave數據庫,但從EntityManagerFactory創建createEntityManager()時,它失敗並出現以下異常。

這是代碼:

String driver ="com.mysql.jdbc.ReplicationDriver";
String url = "jdbc:mysql:replication://master:3306,slave:3306/db";
String user = "abc";
String password = "123";
String connProps = "DriverClassName={0},Url={1},Username={2},Password={3}";

public void method() {
    connProps = MessageFormat.format(connProps, driver, url, user, password);
    Properties props = new Properties();
    props.setProperty("openjpa.ConnectionProperties", connProps);
    props.setProperty("openjpa.ConnectionDriverName", "org.apache.commons.dbcp.BasicDataSource");
    EntityManagerFactory factory = Persistence.createEntityManagerFactory("mysql", props);
    EntityManager manager = factory.createEntityManager();
}

我收到以下異常:

Exception in thread "main" <openjpa-2.4.1-r422266:1730418 fatal general error> org.apache.openjpa.persistence.PersistenceException: Cannot create PoolableConnectionFactory (Must specify at least one slave host to connect to for master/slave replication load-balancing functionality)
    at org.apache.openjpa.jdbc.sql.DBDictionaryFactory.newDBDictionary(DBDictionaryFactory.java:106)
    at org.apache.openjpa.jdbc.conf.JDBCConfigurationImpl.getDBDictionaryInstance(JDBCConfigurationImpl.java:603)
    at org.apache.openjpa.jdbc.meta.MappingRepository.endConfiguration(MappingRepository.java:1520)
    at org.apache.openjpa.lib.conf.Configurations.configureInstance(Configurations.java:533)
    at org.apache.openjpa.lib.conf.Configurations.configureInstance(Configurations.java:458)
    at org.apache.openjpa.lib.conf.PluginValue.instantiate(PluginValue.java:121)
    at org.apache.openjpa.conf.MetaDataRepositoryValue.instantiate(MetaDataRepositoryValue.java:68)
    at org.apache.openjpa.lib.conf.ObjectValue.instantiate(ObjectValue.java:83)
    at org.apache.openjpa.conf.OpenJPAConfigurationImpl.newMetaDataRepositoryInstance(OpenJPAConfigurationImpl.java:967)
    at org.apache.openjpa.conf.OpenJPAConfigurationImpl.getMetaDataRepositoryInstance(OpenJPAConfigurationImpl.java:958)
    at org.apache.openjpa.kernel.AbstractBrokerFactory.makeReadOnly(AbstractBrokerFactory.java:642)
    at org.apache.openjpa.kernel.AbstractBrokerFactory.newBroker(AbstractBrokerFactory.java:202)
    at org.apache.openjpa.kernel.DelegatingBrokerFactory.newBroker(DelegatingBrokerFactory.java:154)
    at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:226)
    at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:153)
    at org.apache.openjpa.persistence.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:59)
    at ExampleJPA.method(ExampleJPA.java:22)
    at ExampleJPA.main(ExampleJPA.java:27)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:606)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:144)
Caused by: org.apache.commons.dbcp.SQLNestedException: Cannot create PoolableConnectionFactory (Must specify at least one slave host to connect to for master/slave replication load-balancing functionality)
    at org.apache.commons.dbcp.BasicDataSource.createPoolableConnectionFactory(BasicDataSource.java:1549)
    at org.apache.commons.dbcp.BasicDataSource.createDataSource(BasicDataSource.java:1388)
    at org.apache.commons.dbcp.BasicDataSource.getConnection(BasicDataSource.java:1044)
    at org.apache.openjpa.lib.jdbc.DelegatingDataSource.getConnection(DelegatingDataSource.java:110)
    at org.apache.openjpa.lib.jdbc.DecoratingDataSource.getConnection(DecoratingDataSource.java:86)
    at org.apache.openjpa.jdbc.sql.DBDictionaryFactory.newDBDictionary(DBDictionaryFactory.java:90)
    ... 22 more
Caused by: java.sql.SQLException: Must specify at least one slave host to connect to for master/slave replication load-balancing functionality
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:957)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:896)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:885)
    at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:860)
    at com.mysql.jdbc.NonRegisteringDriver.connectReplicationConnection(NonRegisteringDriver.java:414)
    at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:313)
    at org.apache.commons.dbcp.DriverConnectionFactory.createConnection(DriverConnectionFactory.java:38)
    at org.apache.commons.dbcp.PoolableConnectionFactory.makeObject(PoolableConnectionFactory.java:582)
    at org.apache.commons.dbcp.BasicDataSource.validateConnectionFactory(BasicDataSource.java:1556)
    at org.apache.commons.dbcp.BasicDataSource.createPoolableConnectionFactory(BasicDataSource.java:1545)
    ... 27 more

數據庫的主從設置似乎工作正常。 我已經檢查了從站通過telnet從站的連通性。

在花費大量時間后,此解決方案似乎很愚蠢。 我工作了。 我需要將雙引號( "jdbc:mysql:replication://master:3306,slave:3306/db" )傳遞給jdbc url,然后才能正常工作。

我將盡快提供更多信息。

傳遞給MySQL驅動程序的JDBC URL不是您所想的。 MySQL驅動程序正在嘗試解析URL並使用","令牌對其進行拆分

    if ((hostStuff != null) && (hostStuff.trim().length() > 0)) {
        List<String> hosts = StringUtils.split(hostStuff, ",", ALLOWED_QUOTES, ALLOWED_QUOTES, false);

但是找不到一個以上的對象,因此會產生錯誤:

    int numHosts = Integer.parseInt(parsedProps.getProperty(NUM_HOSTS_PROPERTY_KEY));

    if (numHosts < 2) {
        throw SQLError.createSQLException("Must specify at least one slave host to connect to for master/slave replication load-balancing functionality",
                SQLError.SQL_STATE_INVALID_CONNECTION_ATTRIBUTE, null);
    }

JDBC URL很可能被DBCP或OpenJPA修改/破壞了。

鏈接到

我認為錯誤的原因是使用openjpa.ConnectionProperties在一個字符串中設置屬性,用逗號作為分隔符,而屬性URL的值也用逗號分隔

按照@rkosegi的答案,有些東西與逗號“,”有關,以解決我認為您必須使用分隔的屬性而不是1個字符串的問題。 或至少考慮刪除Url={1},然后使用openjpa.ConnectionURL設置

這是我認為您需要在method()

props.setProperty("openjpa.ConnectionDriverName", "org.apache.commons.dbcp.BasicDataSource");
props.setProperty("openjpa.ConnectionUserName", user);
props.setProperty("openjpa.ConnectionPassword", password);
props.setProperty("openjpa.ConnectionURL", url);

刪除行:

props.setProperty("openjpa.ConnectionProperties", connProps);

不要使用String connProps = "DriverClassName={0},Url={1},Username={2},Password={3}"; 了。

PS:請注意,您正在使用"org.apache.commons.dbcp.BasicDataSource"而不是driver參數。 只要確保這就是您想要的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM