MySQL Connector/J支持服务器故障转移。当底层活动连接发生与连接相关的错误时,就会发生故障转移。默认情况下,连接错误会传播到客户端,客户端必须通过例如重新创建工作对象(声明
,结果集
等等)并重新启动进程。有时,在客户端应用程序继续运行之前,驱动程序可能最终会自动回到原始主机,在这种情况下,主机切换是透明的,客户端应用程序甚至不会注意到它。
使用故障转移支持的连接就像标准连接一样工作:客户端在故障转移过程中不会遇到任何中断。这意味着客户端可以依赖于相同的连接实例,即使两个连续的语句可能在两个不同的物理主机上执行。然而,这并不意味着客户端不需要处理触发服务器切换的异常。
故障转移在服务器连接的初始设置阶段通过连接URL进行配置(请参阅有关其格式的说明)在这里):
jdbc: mysql: / /主要的主机] [:港口]、[二次主机1] [:港口] [[二次主机2] [:港口]]……[/数据库]]»[?propertyName1=propertyValue1[&propertyName2=propertyValue2]…]
连接URL中的主机列表由两种类型的主机组成:主主机和备用主机。当启动一个新的连接时,驱动程序总是尝试首先连接到主主机,如果需要,当遇到通信问题时,会依次故障转移到列表中的辅助主机。即使到主主机的初始连接失败,而驱动程序连接到辅助主机,主主机也永远不会失去它的特殊状态:例如,可以将它配置为与辅助主机不同的访问模式,并且在故障转移过程中选择主机时,可以将它置于更高的优先级上。
故障转移支持由以下连接属性配置(它们的功能将在下面的段落中解释):
failOverReadOnly
secondsBeforeRetryMaster
queriesBeforeRetryMaster
retriesAllDown
autoReconnect
autoReconnectForPools
配置连接接入方式
与任何标准连接一样,到主主机的初始连接是读/写模式。但是,如果驱动程序无法建立到主主机的初始连接,它会自动切换到列表中的下一个主机,那么访问模式现在取决于属性的值failOverReadOnly
,这是”真正的”默认情况下。如果驱动程序最初连接到主主机,由于某种连接失败,它将故障转移到辅助主机,那么也会发生同样的情况。每次连接回到主主机时,它的访问模式将是读/写,而不管之前是否连接了主主机。通过调用该方法,可以在运行时的任何时候更改连接访问模式Connection.setReadOnly(布尔)
,这在一定程度上覆盖了房产failOverReadOnly
.当failOverReadOnly = false
访问模式被显式设置为true或false,它成为主机交换机后的每个连接的模式,无论我们连接的是什么类型的主机;但是,如果failOverReadOnly = true
,只有当驱动程序连接到主主机时,才可以将访问模式更改为读写;然而,即使不能更改当前连接的访问模式,驱动程序也会记住客户机的最后意图,当返回到主主机时,将使用这种模式。有关说明,请参阅以下双主机连接的事件序列。
序列,
failOverReadOnly = true
:以读写方式连接到主主机
集
Connection.setReadOnly(真正的)
;主主机现在处于只读模式故障转移事件;以只读方式连接到备用主机
集
Connection.setReadOnly(假)
;备用主机保持只读模式返回到主主机;连接现在处于读/写模式
序列B,
failOverReadOnly = false
以读写方式连接到主主机
集
Connection.setReadOnly(真正的)
;主主机现在处于只读模式故障转移事件;以只读方式连接到备用主机
集
Connection.setReadOnly(假)
;连接到备用主机切换为读/写模式返回到主主机;连接现在处于读/写模式
两种场景的区别在于第4步:序列A中的辅助主机的访问模式在这一步不会改变,但驱动程序记得并在返回到主主机时使用set模式,否则主主机将是只读的;但在序列B中,备用主机的访问模式立即改变。
配置回退到主主机
如前所述,当涉及到主机的访问模式时,主主机在故障转移安排中是特殊的。此外,在默认情况下,驱动程序会尝试尽快返回到主主机,即使没有通信异常发生。两个属性,secondsBeforeRetryMaster
而且queriesBeforeRetryMaster
,确定驱动程序何时准备好重试到主主机的重新连接主
在属性名称中代表连接URL的主主机,它在复制设置中不一定是源主机;维护命名是为了与5.1.35之前的Connector/J版本向后兼容):
secondsBeforeRetryMaster
确定驱动程序在尝试返回到主主机之前等待的时间queriesBeforeRetryMaster
确定在驱动程序试图回落到主主机之前执行的查询数量。注意,对于驱动程序,每次调用aStatement.execute * ()
方法增加查询执行计数器;因此,当呼叫Statement.executeBatch ()
或者,如果allowMultiQueries
或rewriteBatchStatements
,则驱动程序可能无法对服务器上执行的实际查询数量进行准确计数。此外,司机呼叫Statement.execute * ()
方法内部在几个场合。所有这些都意味着你只能使用queriesBeforeRetryMaster
只是作为何时返回到主主机的粗略规范。
通常,当满足两个属性指定的至少一个条件时,就会尝试回退到主主机,并且尝试总是在事务边界处进行。但是,如果自动提交被关闭,检查只在方法Connection.commit ()
或Connection.rollback ()
被称为。自动回退到主主机可以通过同时设置关闭secondsBeforeRetryMaster
而且queriesBeforeRetryMaster
来”0”.只将其中一个属性设置为”0”只禁用检查的一部分。
配置重新连接尝试
在建立新连接或发生故障转移事件时,驱动程序尝试依次连接到主机列表上的下一个候选主机。当到达列表的末尾时,它从列表的开始重新开始;但是,如果(a)不是所有的辅助主机都已经至少测试过一次,并且(b)由定义的回退条件,则会跳过主主机secondsBeforeRetryMaster
而且queriesBeforeRetryMaster
还没有实现。整个主机列表的每次遍历(不一定在主机列表的末尾完成)都算作一次连接尝试。驱动程序尝试由属性值指定的连接尝试的次数retriesAllDown
.
无缝的重新连接
尽管不推荐,但您可以让驱动程序执行故障转移而不使活动失效声明
或结果集
实例,通过设置任一参数autoReconnect
或autoReconnectForPools
来真正的
.这允许客户端在故障转移事件后继续使用相同的对象实例,而不需要采取任何异常措施。然而,这可能会导致意想不到的结果:例如,如果驱动程序以读/写访问模式连接到主主机,并且它以实数模式故障转移到辅助主机,发出数据更改查询的进一步尝试将导致错误,而客户机不会意识到这一点。在使用数据流时,这个限制尤其相关:在故障转移之后,结果集
看起来没有问题,但是底层连接可能已经更改了,并且不再有支持游标可用。