下面介绍其使用场景,主要包括计划内主备切换、计划外主备切换、容灾切换三个方面。
计划内主备切换
计划内主备切换一般都是数据库在进行例行的维护和升级中用到的,由运维管理员主动发起。在做计划内主备切换时,GaussDB会自动判断和等待达到一个安全的事务边界后,在驱动层缓存会话数据和事务数据,把数据缓存完之后数据库再进行主备切换。
安全的事务边界是指当前会话上的事务执行到某一个一致性点,可以分为两种情况,一是执行完事务后进行主备切换,即事务级排空,二是执行完一个SQL语句即可进行主备切换,即语句级排空,这个时候事务属于未提交状态,可以说语句级排空对业务影响更小一点。
在整个数据库主备切换期间,GaussDB驱动进行连接保持,当数据库服务恢复之后,先重建连接,再去恢复事务,事务恢复之后从事务一致性点继续执行。我们可以看到在正常的计划内主备切换场景下,使用应用无损透明特性,对数据库来说是无感知的,而且这种主备切换会使用语句级排空。OLTP场景下,SQL语句执行时长都是毫秒级的,使用应用无损透明功能下的主备切换只是增加了一个SQL语句执行时间的等待,也就是多等待一个毫秒级的时间,相对于原来几秒甚至几十秒的主备切换时间来说,多出来的毫秒级等待时间几乎可以忽略不计。
计划外主备切换
下面我们看一下计划外的场景。计划外可以说是灾难性的、突发的,它和计划内的主备切换场景的部分处理机制有所不同。针对计划外的主备切换,GaussDB数据库通过基于事务粒度来缓存整个事务里的语句和重放整个事务来实现。GaussDB自动以事务作为一致性边界,在事务执行过程中,驱动自动缓存执行过的事务SQL语句。数据库服务恢复后,GaussDB重新执行缓存的事务SQL语句,为了避免重复执行和提交事务,驱动重放时会首先根据逻辑事务ID来查询事务执行状态,如果事务已经提交了就不需要再执行。
之所以采用事务粒度重放,而不是以语句粒度重放,是因为数据库的主库和备库之间的数据同步,是以事务为单位的,当事务在主库上被提交了,为了保证数据不丢失,一定会把事务的WAL日志实时同步到备库上。这是数据库的主备数据复制的一个通用的基本机制,已经完全能满足事务粒度重放的要求。而如果要使用语句粒度的重放,必然需要采用一些额外的手段,例如使用savepoint作为主备实时同步边界,用来阶段性保存进度等。和事务粒度重放相比,语句粒度重放使方案更复杂,覆盖的场景更少,性能更差。
容灾切换
我们看一下容灾场景。异地容灾是两个城市相距几千公里,时延在几十毫秒,这么大的时延很难要求跨地区访问数据库,所以异地场景的容灾切换是数据库的容灾和业务程序容灾相互配合,同时切换的过程。目前容灾切换面临一个困境,因为这两个切换是互相独立的,数据库集群切换完了,而应用程序却没有切换完,端到端看数据库恢复了,但是业务没有恢复。
为了解决端到端的问题,GaussDB提供了一个消息通知服务功能(即GNS)。当数据库发生容灾切换时,比如说生产集群降为灾备集群时,会立即把消息发送到应用,应用程序收到数据库集群降备的事件通知后,就可以立即进行主备切换;当数据库容灾集群升为主集群时,GNS会及时通知应用程序,应用程序收到消息之后,就可以立即切流以恢复业务。这样一个相互配合的机制,可以解决端到端的RTO时长问题,不需要多余的等待,也不需要人为判断。
除了异地容灾外,还有一种同城容灾部署场景,因为是同城,所以时延比较低,网络环境比较好。同城容灾这种场景下,可能只是数据库集群发生切换,而应用程序保持不变。这种场景如果我们使用GaussDB提供的应用无损透明机制,也就是通过连接保持和事务断点继续技术,在同城容灾切换时,不仅能确保RPO=0不丢数据,还能保证数据库的容灾切换对应用程序也是透明的。




