对于数据库系统来说,高可用和业务连续性是用户最为关注的问题。在我参与的几次用户调研中,业务连续性问题都是排名第一的关注点,而且热度是排名第二的问题的2倍以上。对于企业级应用或者关键系统来说,业务连续性是永恒的话题。券商的数据库出问题了,那么能否在数秒内恢复业务?银行的数据库出问题了,能否RPO=0,RTO接近于0?对于绝大多数中小金融机构的大多数系统,运营商的大多数系统,政府、医疗、制造业的绝大多数关键系统而言,单机集中式数据库的处理能力是足够的,用户最需要担心的其实只是高可用的问题。
Oracle 在1998年推出Oracle 8i的时候,推出了一个叫做透明应用故障切换TAF(Transparent Application Failover)的技术组件。从而让OPS节点故障时实现连接的自动切换。20年后,Oracle 18C中的高可用从透明估值切换演变成了透明应用连续性TAC(Transparent Application Continuity),这个功能将会成为Oracle 23C首推的高可用切换方案。今天我们就来简单地了解一下Oracle的数据库高可用技术的发展历程。国产数据库厂商也应该能够从这个发展历程中受到一定的启发,从而优化国产数据库的高可用能力。
个人认为Oracle的数据库高可用大体可以分为TAF/FCF/TAC(AC)三大阶段。可能有些朋友会有其他的一些分段方法。TAF主打的是OPS/RAC的透明故障切换。这是一种客户端故障切换技术,当客户端发现数据库实例无法正常工作的时候,经过数次RETRY无效,则自动发起连接切换。这种切换有两种模式,一种是SESSION模式,重新创建一个新的会话,抛弃以前做的所有任务,重新开始新的工作。还有一种是SELECT模式,如果发生切换的会话正在做一个只读事务,则正在做的SELECT可以继续进行。这是因为与SELECT相关的所有数据与控制信息在PGA中是完整的,不需要依赖服务器的SGA和服务器的状态。
TAF功能够强,只不过切换的时间会长了一点,因为客户端感知故障,多次RETRY,都会浪费一定的时间。而一些关键应用需要更快地切换时间。因此快速连接故障切换(FCF)在Oracle中应运而生了,这个技术在Oracle 11G随着UCP连接池的推出,变得更加完善了。FCF技术依赖于Fast Application Notification (FAN)。传统上,数据库实例产生某些变化(服务、实例、节点的DOWN 或 UP)时,应用程序会挂起,直到超时,此时应用程序会收到相关的SQL异常。随 Oracle Database 11g 引入FAN,事件以快速可靠的方式通知给订阅者。借助Oracle 10g开始引入的 Oracle 通知服务 (ONS),数据库实例宕机时,服务或者节点50毫秒或更短的时间内启动故障转移。
FCF解决了快速切换的问题,如果应用程序里捕获了ONS中的事件产生的客户端错误,并且自动放弃当前的业务逻辑,重新完成业务逻辑,那么在客户端几乎可以对RAC某个节点的故障无感知。不过FCF有一点是对TAF的一个倒退,那就是FCF要放弃所有的故障前的操作。哪怕有一条SELECT已经查了2小时,还有1秒钟就可以完成。
为了解决这个问题,让系统的高可用更加完备,Oracle在12C中对整个数据库高可用框架进行了重构。引入了全局数据服务(GDS)、事务守护者Transaction Guard (TG)等机制。基于这些新的机制,实现了应用连续性(AC)和透明应用连续性(TAC)。并且将高可用框架扩展到了RAC以外。ADG/OGG复制环境中,也可以使用这些高可用解决方案。
Oracle要实现的目标是,当系统故障切换的时候,能不能做到应用无感。也就是说,如果切换是无损切换(比如RAC节点故障,同步ADG的故障切换,ADG的SWITCHOVER等场景)的时候,是不是可以实现快速的无损切换,让业务连续性得到最大的保护呢?为了实现这个目标,Oracle引入了TG和故障事务重播。基于此,DML/DDL等写操作都可以实现透明切换。
从Oracle Database 12c开始,每个事务都与一个逻辑事务 ID (LTXID) 相关联。其目的是帮助可靠地确定运行中 COMMIT 语句的结果。已分配 LTXID由 RDBMS 在每个事务开始时更改(即递增),仅在以下情况下由 RDBMS 更改:相应的事务要么被提交,要么被回滚。为了更好的实现TG,Oracle 12c 引入了“数据库请求”的概念。UCP 在连接检出时透明地划分数据库请求的开始和连接的结束。同时“可恢复的错误”的概念引入也相当关键。Oracle 12c 将所有 SQL 异常分为两大类:可恢复错误和 不可恢复(即违反约束)。所有错误消息都有一个附加的名为 OracleException.IsRecoverable 的属性。
有了这些基础技术以后,TAC的实现就能牛逼了。当RAC的节点故障时,如果你配置了TAC,那么故障的SESSION能自动切换到接管实例上,未完成的 读写操作继续完成,应用端无需捕获错误,也不会捕获到错误。应用端的感受仅仅是好像当前事务比以往略微慢了一点点。
TAC不仅可以在RAC中实现,对于ADG环境中依然可以实现。如果ADG采用了同步复制模式,那么数据肯定是无损的,因此ADG可以在FAILOVER的时候通过TAC来实现切换。如果ADG不是同步模式的 ,那么为了确保故障回放的一致性,此切换仅仅能在SWITCHOVER这种无损切换中使用。在ADG上的TAC实现效果与RAC上并无太大区别,只是切换的时间长了不少而已。
从上面我对Oracle高可用技术发展的描述上,大家应该可以看出Oracle为了提高数据库的可用性而做的努力。目前国产数据库也在推出类似Oracle RAC的技术,在这些国产的“RAC”里,无一例外地支持了类似TAF的技术。我觉得在Oracle已经演进到了TAC的今天,我们的国产数据库厂商哪怕不做个弯道超车,追上Oracle,实现真正的平替也是很必要的吧。
另外对于我们亲爱的用户和应用开发商,我也想说两句,二十多年过去了,你还只会用TAF做故障切换吗?TAC难道不是你们更好的选择吗?