csyperski
csyperski

Reputation: 1032

Mysql ReplicationDriver - failure handling

I have a MySql Master/Slave replication question that google couldn't seem to answer. When using com.mysql.jdbc.ReplicationDriver, how does the driver handle failures on read replicas? Does it blacklist them, does it try just continue to try them and throw an exception each time (after whatever timeouts are configured)? From my testing it seems that my application is just hanging when I kill a read replica. I'm using tomcat and here is my context.xml....

<Resource auth="Container" 
        driverClassName="com.mysql.jdbc.ReplicationDriver" 
        defaultAutoCommit="false"
        initialSize="10" 
        minIdle="5"
        logAbandoned="false"
        maxIdle="10" 
        maxWait="10000" 
        name="jdbc/db" 
        removeAbandoned="true" 
        testOnBorrow="true"  
        removeAbandonedTimeout="86400"
        testWhileIdle="true" 
        type="javax.sql.DataSource" 
        factory="org.apache.tomcat.jdbc.pool.DataSourceFactory" 
        username="powerptc" 
        password="password"   
        url="jdbc:mysql:replication://localhost:3306,host1,host2:3306/db?allowSlavesDownConnections=true&amp;readFromMasterWhenNoSlaves=true" 
        validationQuery="/* ping */ SELECT 1"
        validationQueryTimeout="5" />

Is there a way to have the driver blacklist a failed read replica ( for x minutes ) instead of just retrying it over and over again?

Upvotes: 0

Views: 578

Answers (1)

Eugeniy Chemezov
Eugeniy Chemezov

Reputation: 31

In this case MySQL driver uses LoadBalanced driver for slaves and switch to master only if picking connection from LoadBalanced cluster of slaves fails. Application hanging because default value for retriesAllDown = 120. If you set retriesAllDown = 4, then Load Balancer will sleep 4 times for 250 milliseconds before switching to master.

By default loadBalanceBlacklistTimeout = 0, it means that load balancer for slaves does not use blacklist. Even if you set loadBalanceBlacklistTimeout > 0, it does not help, because strange implementation of blacklist, which is empty if all hosts are added to blacklist. But you can use next trick: Use ServerAffinityStrategy and put master hostname to slaves list, but set only slaves as affinity servers.

My working url is:

jdbc:mysql:replication://master:3306,slave1,slave2:3306/db?allowSlaveDownConnections=true&readFromMasterWhenNoSlaves=true&loadBalanceBlacklistTimeout=30000&retriesAllDown=4&loadBalanceStrategy=serverAffinity&serverAffinityOrder=slave1,slave2

In result, master will be used only if there is no available slave

Upvotes: 3

Related Questions