MySQL Connector/J 支持故障转移,故障转移在潜在的风险要发生的时候使用,通常情况下,数据库连接发生错误,需要客户端的异常处理(重新创建Statement、ResultSet、重启进程),而使用Mysql Replication-Driver能够实现自动故障转移,当一个库发生宕机,将连接连到其他存活的库上,来实现主从高可用。
使用者只需像使用普通jdbc连接一样,就可以在故障发生时,无感知的实现故障转移,配置故障转移的jdbc URL如下:
jdbc:mysql://[primary host][:port],[secondary host 1][:port][,[secondary host 2][:port]]...[/[database]]»
[?propertyName1=propertyValue1[&propertyName2=propertyValue2]...]
在这个URL中包含两种主机,主库Master和从库Slave。
- 主库宕机,从库可读
- 从库宕机,主库可写,另一台从库可读
- readFromMaster=true,情况下,主库也可读
故障转移由以下连接属性支持:
- failOverReadOnly
- secondsBeforeRetryMaster
- queriesBeforeRetryMaster
- retriesAllDown
- autoReconnect
- autoReconnectForPools
配置连接模式
在一些标准连接里,主节点的初始化连接是可读可写的。然而,如果驱动确定到主节点的连接失败,将会自动切换到列表中的下一个节点,连接模式依赖于failOverReadOnly这个属性,默认是true,相似的,从节点的连接失败,主节点也会变成可读,可写的,不管主节点之前是否被连接过,连接的模式都可以通过调用connection.setReadOnly()方法进行改变(实际重写了failOverReadOnly),
-
情况A:FailOverReadOnly=true
a.到主节点的连接是可读、可写
b.设置主节点readOnly属性是true,主节点是只读模式
c.FailOver事件发生;连接到从节点是只读模式
d.设置readOnly=false,到第二个节点的连接是只读
e.主节点恢复后,主节点是可读、可写的
-
情况B:FailOverReadOnly=false
a.连接到主节点是可读、可写的
b.设置主节点readOnly属性是true,主节点是只读模式
c.FailOver事件发生;连接到从节点是只读模式
d.设置readOnly=false,到第二个节点的连接是可读、可写
e.主节点恢复后,主节点是可读、可写的
区别在于第四部,FailOver发生时,情况A第二个节点的读写模式不变,主节点不可用,直到主节点恢复前,整个集群只读;情况B立刻切换成第二个节点,可读、可写
配置恢复主节点
像之前提到过的,主节点在FailOver机制中是特别的,驱动默认希望尽快的恢复主节点,即便没有连接异常发生,两个属性,secondsBeforeRetryMaster和queriesBeforeRetryMaster决定了什么时候重试到主节点的连接
- secondsBeforeRetryMaster 决定了尝试连接到主节点前等多长时间
- queriesBeforeRetryMaster 决定了驱动尝试连接到主节点前,执行查询的数量。每次执行Statement.execute*(),查询计数器+1,因此,当Statement.executeBatch() 或 allowMultiQueries 或 rewriteBatchStatements 可用时,查询计数器是不准确的,这意味着,queriesBeforeRetryMaster只是一个粗略计算的参数。
通常情况下,尝试到主节点的连接检查,只有在上述两个条件满足下才会进行,并且尝试总是发生在事务的界限内,如果将autoCommit关闭了,这个检查只会发生在Connection.commit() 或 Connection.rollback()调用时。如果同时设置secondsBeforeRetryMaster 和 queriesBeforeRetryMaster 为 “0”,自动恢复主节点将会被关闭,设置其中一个为0,只会禁用部分检查。
配置重连
当确定一个新的连接,或者FailOver发生的时候,驱动尝试连续的连接候选主机(Slaves几点),最后一个节点尝试完,再从第一个节点开始尝试。当 a)并非所有的次节点至少尝试一个重试连接 b)通过secondsBeforeRetryMaster 和queriesBeforeRetryMaster条件定义的连接重试不满足条件时,主节点的重试连接将会被跳过。整个主机列表(不一定在主机列表的末尾完成)的连接重试,计为一次重试连接,一共尝试retriesAllDown次(默认120)
无缝重连
尽管不建议,你可以使驱动在执行failover时,不作废通过设置 autoReconnect 或 autoReconnectForPools 为 true所产生的Statement和ResultSet ,这要求客户端在failover后继续使用相同的实例,不采取任何异常措施,这将会造成意想不到的后果,例如:如果驱动通过读/写模式连接到主节点,并且他failover到一个只读的从节点,这时候写请求将会报错,而且客户端没法感知,这种限制在使用数据流时特别相关,在failover后,resultSet看起来很正常,但潜在的连接可能已经改变了,并且再也没有回退方案了。