达梦数据库实时主备集群的同步机制和切换机制

Posted chen丨yu

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了达梦数据库实时主备集群的同步机制和切换机制相关的知识,希望对你有一定的参考价值。

DM数据守护介绍

1. DM 数据守护(Data Watch)
是一种集成化的高可用、高性能数据库解决方案,是数据库异地容灾的首选方案。通过部署 DM 数据守护,可以在硬件故障(如磁盘损坏)、自然灾害(地震、火灾)等极端情况下,避免数据损坏、丢失,保障数据安全,并且可以快速恢复数据库服务,满足用户不间断提供数据库服务的要求。与常规的数据库备份(Backup)、还原(Restore)技术相比,数据守护可以更快地恢复数据库服务。随着数据规模不断增长,通过还原手段恢复数据,往往需要数个小时、甚至更长时间,而数据守护基本不受数据规模的影响,只需数秒时间就可以将备库切换为主库对外提供数据库服务。
3. 实时主备
由一个主库以及一个或者多个配置了实时(Realtime)归档的备库组成,其主要目的是保障数据库可用性,提高数据安全性。实时主备系统中,主库提供完整的数据库功能,备库提供只读服务。主库修改数据产生的Redo日志,通过实时归档机制,在写入联机Redo日志文件之前发送到备库,实时备库通过重演Redo日志与主库保持数据同步。当主库出现故障时,备库在将所有Redo日志重演结束后,就可以切换为主库对外提供数据库服务。

一、 实时主备集群同步机制

  1. 概念
    达梦数据库主备集群中主库与备库进行同步需要了解以下几点:
    (1)主库
    Primary 模式,提供完整数据库服务的实例,一般来说主库是用来直接支撑应用系统的生产库。

    (2)备库
    Standby 模式,提供只读数据库服务的实例。备库除了用于容灾,还可以提供备份、查询等只读功能,并且备库还支持临时表的 Insert/Delete/Update 操作。

    (3)MAL 系统
    MAL 系统是基于 TCP 协议实现的一种内部通信机制,具有可靠、灵活、高效的特性。
    DM 通过 MAL 系统实现 Redo 日志传输,以及其他一些实例间的消息通讯。

    (4)Redo 日志
    Redo 日志包含了所有物理数据页的修改内容,Insert/delete/update 等 DML 操作、Create Table 等 DDL 操作,最终都会转化为对物理数据页的修改,这些修改都会反映到 Redo 日志中。

    (5)Redo 日志包(RLOG_PKG)
    Redo 日志包(RLOG_PKG)是 DM 数据库批量保存物理事务产生的 Redo 日志的数据单元,以物理事务 PTX 为单位保存日志,一个日志包内可连续保存一个或多个 PTX。日志包具有自描述的特性,日志包大小不固定,采用固定包头和可变包头结合的方式,包头记录日志的控制信息,包括类型、长度、包序号、LSN 信息、产生日志的节点号、加密压缩信息、日志并行数等内容。

    日志包生成时按照序号连续递增,相邻日志包的 LSN 顺序是总体递增的,但是在多节点集群的 DSC 环境下不一定连续。如果未开启并行日志,RLOG_PKG 包内日志的 LSN 是递增的。如果开启并行日志,一个 RLOG_PKG 包内包含多路并行产生的日志,每一路并行日志的 LSN 是递增的,但是各路之间并不能保证 LSN 有序,因此并行日志包内 LSN 具有局部有序,整体无序的特点。

    物理事务提交时将 Redo 日志写入到日志包中,在数据库事务提交或日志包被写满时触发日志刷盘动作。日志刷盘线程负责将日志包中的 Redo 日志写入联机日志文件,如果配置了 Redo 日志归档,日志刷盘线程还将负责触发归档动作。DM 数据守护系统中,主库以RLOG_PKG 为最小单位发送 Redo 日志到备库。

    RLOG_PKG 具有自描述、自校验特征,数据的组织形式更加灵活、高效,支持 HUGE 表操作产生 Redo 日志,并且支持以 RLOG_PKG 为单位进行日志加密和压缩。

    (6)Redo 日志传输
    主备库之间的 Redo 日志传输,以日志包 RLOG_PKG 为单位,主库通过 MAL 系统发送Redo 日志到备库。各种不同数据守护类型的区别,就在于主库日志包 RLOG_PKG 的发送时机,以及备库收到 Redo 日志后的处理策略。

    (7)KEEP_PKG 介绍
    主库的RLOG_PKG日志通过实时归档机制发送到备库后,备库将最新收到的RLOG_PKG保存在内存中,不马上启动重演,这个 RLOG_PKG 我们称之为 KEEP_PKG

    (8)Redo 日志重演
    Redo 日志重演的过程,就是备库收到主库发送的 Redo 日志后,在物理数据页上,重新修改数据的过程。Redo 日志重演由专门的 Redo 日志重演服务完成,重演服务严格按照Redo 日志产生的先后顺序,解析 Redo 日志、修改相应的物理数据页,并且重演过程中备库会生成自身的 Redo 日志写入联机日志文件。

    (9)本地归档
    本地归档(Local),就是将 Redo 日志写入到本地归档日志文件的过程。本地归档在 REDO 日志写入联机日志文件后触发,由归档线程完成本地归档动作;与联机 Redo 日志文件可以被覆盖重用不同,本地归档日志文件不能被覆盖,写入其中的 Redo 日志信息会一直保留,直到用户主动删除;如果配置了归档日志空间上限,系统会自动删除最早生成的归档 Redo 日志文件,腾出空间。

    配置本地归档情况下,Normal/Primary 模式库在 Redo 日志写入联机 Redo 日志文件后,将对应的 RLOG_PKG 由专门的归档线程写入本地归档日志文件中。Standby 模式库收到主库产生的 Redo 日志后,直接进行本地归档,写入本地归档日志文件中,同时启动 Redo 日 志重演。

    Normal/Primary 模式库归档日志文件保存的是当前节点产生的 Redo 日志,归档日志文件内容与联机日志内容保持一致。Standby 模式库重演日志重新产生的 Redo 日志只写入联机日志文件,归档日志文件保存主库产生的 Redo 日志,因此备库联机日志文件内容和归档日志文件内容是不完全一致的。采用这种归档实现方式后,可以确保数据守护系统中所有节点的归档日志文件内容是完全一致的。

    (6)实时归档
    与本地归档写入保存在磁盘中的日志文件不同,实时归档(Realtime)将主库产生的Redo 日志通过 MAL 系统传递到备库,实时归档是实时主备和 MPP 主备的实现基础。实时 归档只在主库生效,一个主库可以配置 1~8 个实时备库。

  2. 主备集群同步机制归档流程如下所示

    场景说明(实时主备,A主库,B备库):

    用户登录主库 A 执行:
    CREATE TABLE TX(C1 INT); 
    INSERT INTO TX VALUES(1);
    COMMIT;
    

    (1)DDL和DML提交事务操作使主库产生Redo 信息,Redo 信息会存放在RLOG_PKG(Redo 日志包)中,在此过程中RLOG_PKG存放在内存当中,暂时不会写入联机日志中;
    (2)MAL通讯系统将主库的RLOG_PKG包通过实时归档机制发送到备库B中,备库将最新收到的RLOG_PKG保存在内存中,然后进行校验是否合法,合法后标记为 KEEP_PKG,不会马上启动重演,但会将之前的KEEP_PKG通过APPLY线程队列加入日志重演任务系统,并马上响应主库,不需要等待之前的Redo日志重演结束后再响应主库;

    为了防止备库上重演日志堆积太多、占用大量内存、备库重演无响应导致主库挂住不能提供服务等情况的发生 ,可通过适当调整 BUFFER 、REDOS_PRE_LOAD 、REDOS_BUF_SIZE、REDOS_BUF_NUM、REDOS_MAX_DELAY 这几个参数达到加快备库重演速度、达到设置的堆积上限后延迟响应主机 、 备库自动宕机等目的 。 其中REDOS_BUF_SIZE 和 REDOS_BUF_NUM 同时起作用,只要达到一个条件即延迟响应。

    (注意:备库确认收到主库发送的Redo 日志,并不保证备库已经完成重演这些 Redo 日志,因此主备库之间的数据同步存在一定的时间差。)

    备库 KEEP_PKG 日志重演的时机包括:
    1.备库收到新的 RLOG_PKG
    备库收到新的 RLOG_PKG 时,会将当前保存的 KEEP_PKG 日志重演,并将新收到的RLOG_PKG 再次放入
     KEEP_PKG 中。
    2. 收到主库的重演命令
    主库会定时将 FILE_LSN 等信息发送到备库,当主库 FILE_LSN 等于备库 SLSN 时,表明主库已经将
     KEEP_PKG 对应的 Redo 日志写入联机日志文件中,此时备库会启动KEEP_PKG 的日志重演。
    3. 备库切换为新主库
    在监视器执行 SWITCHOVER 或 TAKEOVER 命令,或者确认监视器通知备库自动接管时,备库会在切换为
     PRIMARY 模式之前,启动 KEEP_PKG 的日志重演。
    

    (3)主库收到备库的响应消息,确认备库已经收到 Redo 日志后,主库再将 Redo 日志写入联机日志文件中。

二、 实时主备集群切换机制

  1. 概念
    达梦数据库主备集群中主库与备库进行切换需要了解以下几点:
    (1)主库
    Primary 模式,提供完整数据库服务的实例,一般来说主库是用来直接支撑应用系统的生产库。

    (2)备库
    Standby 模式,提供只读数据库服务的实例。备库除了用于容灾,还可以提供备份、查询等只读功能,并且备库还支持临时表的 Insert/Delete/Update 操作。
    备库支持临时表修改主要基于两个因素:1.临时表数据的修改不会产生 Redo 日志,主库对临时表的修改无法同步到备库;2.可以提供更大灵活性,适应更多应用场景。
    根据数据同步情况,备库又可以分为可切换备库和不可切换备库。可切换备库是指,主备库之间数据完全同步,主库发生故障、备库切换为主库后,不会造成任何数据丢失的备库。

    (3)守护进程
    守护进程(dmwatcher)是 DM 数据守护系统不可或缺的核心部件,是数据库实例和监视器之间信息流转的桥梁。数据库实例向本地守护进程发送信息,接收本地守护进程的消息和命令,守护进程负责解析、处理、转发命令。守护进程提供了数据库监控、故障检测、故障处理、故障恢复等各种功能。监视器(dmmonitor)接收守护进程的消息,并向守护进程发送命令;数据库实例与监视器之间没有直接的消息交互;守护进程解析并执行监视器发起的各种命令(Switchover/Takeover/Open database 等),并在必要时通知数据库实例执行相应的操作。

    守护进程负责监控数据库运行状态,必要时重启数据库服务。守护进程和实例链路建立成功后,数据库实例定时发送信息到守护进程,发送到守护进程的内容包括:实例进程 ID、实例名、数据库模式、数据库状态、FILE_SEQ、FILE_LSN、CUR_SEQ、CUR_LSN、MAL链路状态、归档状态、公钥、MPP 控制文件等信息。
    守护进程更新本地记录的实例信息后,同时记录该时间戳。当检测到实例进程 ID 已经不存在或者超过一段时间没有收到实例消息(INST_ERROR_TIME),则会认定实例故障。如果配置了自动重启,则会将实例重新拉起。

    守护进程将监控的数据库实例信息和守护进程自身的信息(包括守护类型、守护模式、守护状态、守护日志、监视器执行序列号、执行返回码等)捆绑在一起,定时发送给其他守护进程和所有监视器。

    (4)监视器
    监视器(dmmonitor)用来监控守护系统内守护进程、数据库实例信息,执行用户输入命令、监控实例故障、实现自动切换等。监视器一般配置在数据库实例和守护进程以外的机器上。

  2. DM 数据守护的主要特性包括:
    (1)完整功能的主库
    主库提供完整的数据库服务,与普通单节点数据库相比,主要的功能限制包括:不支持修改表空间文件名、不支持修改 arch_ini 参数。

    (2)活动的备库
    基于独特的字典缓存技术和日志重演技术,备库在 Open 状态下执行数据同步,是真正意义上的热备库;在实现异地容灾的同时,用户可以只读访问备库,执行报表生成、数据备份等功能,减轻主库的系统负载,提高资源利用率。

    (3)多重数据保护
    每个备库都是一个完整的数据库备份,可以同时配置多个备库,为数据安全提供全方位的保护。 高可用性主库出现故障时,可以快速将备库切换为主库,继续提供数据库服务,确保数据库服务不中断。切换过程一般在数秒钟之内完成。

    (4)多种守护模式
    提供自动切换和手动切换两种守护模式,满足用户不同需求。其中,配置自动切换的前提是已经部署确认监视器。在提供第三方机器部署确认监视器情况下,可以配置为故障自动切换模式,主库出现故障时,系统自动将备库切换为主库对外提供数据库服务。

    (5)故障自动重连
    配置、使用连接服务名访问数据库,在发生主备库切换后,接口会自动将连接迁移到新的主库上。

    (6)故障库自动重加入
    主库故障,发生主备库切换。故障主库重启后,可以自动切换为 Standby 模式,作为备库重新加入数据守护系统。

    (7)历史数据自动同步
    故障备库恢复后,可以自动同步历史数据,无需用户干预,并在同步完成以后,自动恢复为可切换备库。

    (8)丰富的守护命令
    监视器dmmonitor提供主备库切换、强制接管等功能,通过简单的命令就可以实现主备库角色互换、故障接管等功能。

  3. 数据库模式
    (1)Normal 模式
    提供正常的数据库服务,操作没有限制。正常生成本地归档,但不发送实时归档(Realtime)、即时归档(Timely)和异步归档(Async)。

    (2)Primary 模式
    提供正常的数据库服务,操作有极少限制。该模式下部分功能受限,包括:不支持修改表空间文件名、不支持修改 arch_ini 参数。正常生成本地归档,支持实时归档(Realtime)、即时归档(Timely)和异步归档(Async)。Primary 模式下,对临时表空间以外的所有的数据库对象的修改操作都强制生成 Redo 日志。

    (3)Standby 模式
    可以执行数据库备份、查询等只读数据库操作。正常生成本地归档,正常发送异步归档Redo 日志;但实时归档(Realtime)、即时归档(Timely)均强制失效。该模式下时间触发器、事件触发器等都失效。

  4. 数据库状态
    (1)Startup 状态
    系统刚启动时设置为 Startup 状态。

    (2)After Redo 状态
    系统启动过程中联机日志重做完成后,回滚活动事务前设置为 After Redo 状态。非Standby 模式的实例在执行 alter database open 操作前,也会将系统设置为 After Redo 状态。

    (3)Open 状态
    数据库处于正常提供服务的状态,但不能进行归档配置等操作。

    (4)Mount 状态
    数据库在 Mount 状态下,不能修改数据,不能访问表、视图等数据库对象,但可以执行修改归档配置、控制文件和修改数据库模式等操作,也可以执行一些不修改数据库内容的操作,比如查询动态视图或者一些只读的系统过程。由于 Mount 状态不生成 PWR 日志,因此数据页可以正常刷盘,也正常推进检查点。系统从 Open 状态切换为 Mount 状态时,会强制回滚所有活动事务,但不会强制清理(Purge)已提交事务,不会强制断开用户连接,也不会强制 Buffer 中的脏页刷盘。

    (5)Suspend 状态
    数据库在 Suspend 状态下,可以访问数据库对象,甚至可以修改数据,但限制 Redo日志刷盘,一旦执行 COMMIT 等触发 Redo 日志刷盘的操作时,当前操作将被挂起。相比 Open 到 Mount 的状态切换,Open 到 Suspend 的状态切换更加简单、高效,不会回滚任何活动事务,在状态切换完成后,所有事务可以继续执行。一般在修改归档状态之前将系统切换为 Suspend 状态,比如备库故障恢复后,在历史
    数据(归档日志)同步完成后,需要重新启用实时归档功能时:
    ①将系统切换为 Suspend 状态,限制 Redo 日志写入联机 Redo 日志文件;
    ②修改归档状态为 Valid;
    ③重新将数据库切换为 Open 状态,恢复 Redo 日志写入功能;
    ④备库与主库重新进入实时同步状态。 另外,实时归档失败时(比如网络故障导致),Primary 实例将试图切换成 Suspend状态,防止后续的日志写入。因为一旦写入,主备切换时有可能备库没有收到最后那次的RLOG_PKG,导致主库上多一段日志,很容易造成主备数据不一致。当实例成功切换为SUSPEND 状态时,可直接退出,强制丢弃多余的日志,避免主备数据不一致。

    (6)Shutdown 状态
    实例正常退出时设置为 Shutdown 状态。

  5. 守护状态
    守护进程包括以下一些状态:
    ① Startup 守护进程启动状态,需要根据远程守护进程发送的状态信息,结合本地数据库的初始模式、状态和数据同步情况,确定本地数据库的启动模式和状态后,进入Open 状态。

    ② Open 守护进程正常工作,监控数据库,并定时发送数据库的状态信息,接收其他守护进程发送的信息,接收监视器发送的用户请求。

    ③Shutdown 守护进程停止监控数据库状态,也不提供主备库切换功能。

    ④ Switchover 主备库正常情况下,手动主备切换过程中设置为 Switchover 状态。

    ⑤Failover 远程备库故障后,本地主库执行故障处理时,守护进程设置为Failover 状态。

    ⑥ Recovery 故障恢复同步历史数据过程中设置为 Recovery 状态。

    ⑦ Confirm 通过监视器确认远程主(备)库是否活动的过程中,守护进程设置为Confirm 状态。

    ⑧Takeover 主库确认故障后,备库手工接管或监视器通知自动接管过程中,守护进程设置为 Takeover 状态。

    ⑨Open force 借助监视器命令强制 Open 主库或备库实例时,守护进程设置为Open force 状态。

    ⑩Error 超过一段时间(DW_ERROR_TIME)没有接收到远程守护进程消息,本地守护进程或监视器认定远程守护进程故障,修改远程守护进程为 Error 状态。

    ⑪Login check 监视器执行登录命令时,守护进程所处的状态。

    ⑫Mppctl update 修改主库 MPP 控制文件(dmmpp.ctl)时,守护进程所处的状态,只在 MPP 主备系统出现。

    ⑬Change arch 监视器执行 set arch invalid 命令时守护进程所处的状态。

    ⑭Standby check 主库守护进程监控到备库异常后,切换到此状态下通知主库修改此备库归档无效。

    ⑮Clear send info 清理主库上的归档发送信息时,守护进程所处的状态。

    ⑯Clear rapply stat 清理备库上的重演信息时,守护进程所处的状态。

    ⑰Unify ep 统一 DMDSC 集群各节点实例状态,或者各实例状态已经一致时,守护进程在 Startup 或 Open 状态下通知实例执行相关操作,都进入 Unify_ep 状态执行。

    ⑱Css process 监视器发起的对 DMDSC 集群的部分命令,比如启动、关闭、强杀 DMDSC 库,或者打开、关闭节点实例的自动拉起功能等命令,需要借助 dmcss 执行时,守护进程会切换到此状态下。
    守护进程所有状态变换和它监控的数据库的状态变换都会生成相应的 LOG 信息,写入到…/log 目录中以’dm_dmwatcher_实例名_当前年月.log’方式命名的日志文件中。用户可以通过查看日志文件,分析数据库和守护进程的运行状态、监控故障处理过程。
    守护进程的状态转换如下图所示:

    另外,当远程守护故障,任何状态都可转到 Error 状态。

  6. 实时主备系统主要功能
    (1)实时数据同步
    主备库通过实时归档完成数据同步,实时归档要求主库将 RLOG_PKG 发送到备库后,再将RLOG_PKG 写入本地联机 Redo 日志文件。但要注意的是,备库确认收到主库发送的Redo 日志,并不保证备库已经完成重演这些 Redo 日志,因此主备库之间的数据同步存在一定的时间差。

    (2)主备库切换,主备库正常运行过程中,可以通过监视器的 Switchover 命令,一键完成主备库角色
    转换。主备库切换功能可以确保在软、硬件升级,或系统维护时,提供不间断的数据库服务。

    (3)自动故障处理
    备库故障,不影响主库正常提供数据库服务,守护进程自动通知主库修改实时归档为Invalid 状态,将实时备库失效。

    (4)自动数据同步
    备库故障恢复后,守护进程自动通知主库发送归档 Redo 日志,重新进行主备库数据同步。并在历史数据同步后,修改主库的实时归档状态为 Valid,恢复实时备库功能。备库接管后,原主库故障恢复,守护进程自动修改原主库的模式为 Standby,并重新作为备库加入主备系统。

    (5)备库接管
    主库发生故障后,可以通过监视器的 Takeover 命令,将备库切换为主库,继续对外提供服务。如果配置为自动切换模式,确认监视器可以自动检测主库故障,并通知备库接管,这个过程不需要人工干预。

    (6)备库强制接管
    如果执行 Takeover 命令不成功,但主库可能由于硬件损坏等原因无法马上恢复,为了及时恢复数据库服务,DM 提供了 Takeover Force 命令,强制将备库切换为主库。但需要由用户确认主库故障前,主库与接管备库的数据是一致的(主库到备库的归档是 Valid状态),避免引发守护进程组分裂。

    注意:执行Takeover Force有可能引发组分裂,而Takeover命令在确保不会产生组分裂情况下才允许执行。
    
  7. 集群故障处理
    (1)备库故障处理
    故障自动切换模式下,备库故障后,如果主备库之间的归档状态仍然有效,主库的守护进程会先切换为 Confirm 状态,等待确认监视器的确认消息,如果确认为符合故障处理条件,主库守护进程再切换至 Failover 状态,将故障备库的归档失效。

    故障手动切换模式下,备库故障后,如果主备库之间的归档状态仍然有效,会直接切换到 Failover 状态,并将故障备库的归档失效,不需要备库故障确认。备库故障后,备库的守护进程如果还处于活动状态且监控功能没有被关闭,则会切换到Startup 状态下。

    备库故障重启后,如果存在活动主库,主库守护进程根据备库实例的模式、状态、备库守护进程状态、守护进程控制文件状态、备库已经同步到的 Open 记录以及备库的恢复间隔等信息判断是否可以进行故障恢复,在满足故障恢复条件的情况下,主库守护进程启动Recovery 流程,重新恢复主备库到一致状态。如果一直没有观察到主库守护进程发起 Recovery 流程,可以借助监视器的 check recover 命令查找备库不满足条件的原因,并做对应的处理。

    (2)备库异常处理
    备库异常,指备库的数据库实例正常,但响应速度出现异常,这里的响应速度可能受主备库之间的网络影响,比如网络不稳定、网速大幅下降,也可能受备库自身的软硬件影响,比如操作系统原因或磁盘读写速度异常降低等异常情况导致响应主库的速度变慢,这种情况下会极大拖慢主库性能,影响主库正常处理对外的业务请求。

    守护进程提供 RLOG_SEND_THRESHOLD 参数用于监控主备之间的日志发送速度,此参数应配置为大于 0 的值,否则守护进程不会打开监控功能。主库守护进程在 Open 状态下对日志发送速度进行检测,一旦检测到异常,主库守护进程会切换到 Standby check 状态,并通知主库将异常备库的归档失效,暂停到此备库的数据同步,避免拖慢主库性能。

    完整的备库异常处理流程如下(Standby check 状态处理):
    ① 收集所有的异常备库。
    ②将主库守护进程上记录的这些异常备库的最近一次恢复时间修改为当前时间。恢复间隔仍然为 dmwatcher.ini 中配置的 INST_RECOVER_TIME 值。这一步骤的目的是为了防止修改备库归档为 Invalid 无效状态后,主库立马启动 recovery,但是还未取到备库最新的 LSN 信息,导致 recovery 无法正确执行的情况发生。
    ③通知主库修改这些异常备库的归档为 Invalid 无效状态。
    ④守护进程切回 Open 状态。

    (3)主库故障处理
    故障自动切换模式下,主库故障后,确认监视器会捕获到故障信息,自动选出可接管的备库,并通知备库进行接管。备库接管由确认监视器自动触发,无需用户干预。

    故障手动切换模式下,主库故障后,需要人工干预,通过监视器执行接管命令,将可接管备库切换为主库。

    故障自动切换模式下,可以实时处理故障,但对网络稳定性要求更高,需要确保主备库之间,主备库与守护进程、确认监视器之间的网络稳定可靠,否则可能会误判主库故障,备库自动接管后,出现多个 Open 状态的主库,引发脑裂。故障手动切换模式下,备库不会自动接管,出现节点故障或者网络故障时,由用户根据各种故障情况,进行人工干预。

    主库故障重启后,守护进程根据本地和远程库的 Open 记录、LSN 信息以及模式和状态信息来判定重启后的恢复策略,可能继续作为主库加入守护系统,也可能修改为 Standby模式,以备库身份重新加入守护系统,如果出现分裂,则需要用户干预。

    (4)故障恢复处理
    故障恢复状态(Recovery)由守护进程自行判断是否切换,和监视器无关。如果符合以下条件,主库的守护进程可自动进入 Recovery 状态,进行数据恢复:
    ①本地主库 [Primary,Open],守护进程 Open 状态;
    ②远程备库[Standby,Open],归档状态 Invalid,守护进程 Open 状态;
    ③远程备库[Standby,Open]的ASEQ/ALSN和SSEQ/SLSN相等,没有待重做日志;
    ④根据 Open 记录等信息判断备库可加入;
    ⑥远程备库[Standby,Open]达到了设置的启动恢复的时间间隔。
    对于前 4 点,只是概括说明,详细的条件比较多,这里不再逐一列出,如果某个备库一直没有被恢复,可以借助监视器的 check recover 命令来查找备库无法进行恢复的原因。
    对于第 5 点,可通过配置主库守护进程 dmwatcher.ini 的 INST_RECOVER_TIME来控制,取值(3s~ 86400 s),该值对所有备库有效,可通过监视器的 show arch send info 命令查看当前设置的到指定备库的恢复时间间隔。也可以使用监视器的 set recover time 命令来动态设置指定备库的恢复间隔,该命令只会修改命令中指定的备库的恢复间隔,并且只保存在主库的守护进程内存中,不会写入到 dmwatcher.ini 文件。

    在主备库运行正常,不需要执行备库故障恢复的情况下,主库守护进程内存中对备库的恢复间隔值和 dmwatcher.ini 中配置的 INST_RECOVER_TIME 值是一致的,在某些场景下会被设置为不同的值,下面分别进行说明:
    ①主库守护进程主动设置恢复间隔为 3s
    在以下场景中,主库的守护进程会重置内存中的 INST_RECOVER_TIME 为 3s,对满足前述前 4 个条件的备库在 3s 后会立即启动恢复流程:

    1 数据守护系统启动完成之后;
    2 守护系统运行过程中,主库手动重启或者守护进程自动启动 Open 之后;
    3 监视器执行Switchover 主备切换/Takeover 备库接管/强制 Open 主库的操作之后。

    ②使用监视器命令动态设置恢复间隔
    监视器提供有以下命令可动态修改 INST_RECOVER_TIME 值:

    1 set database [group_name.]db_name recover time time_value
    动态修改指定备库实例的恢复间隔 ,只修改对应主库守护进程内存中的INST_RECOVER_TIME 值。
    2 set group [group_name] recover time time_value
    动态修改指定组或所有组中所有备库的恢复间隔,只修改对应主库守护进程内存中的INST_RECOVER_TIME 值。
    3 set group [group_name] para_name para_value
    动态修改指定组或所有组中所有守护进程的配置参数值,para_name 允许指定为 INST_RECOVER_TIME , 同时修改dmwatcher.ini 文件和主库内存中的INST_RECOVER_TIME 值。

    以上 3 个命令都可以用来修改 INST_RECOVER_TIME 值,修改完成后,一旦主库对指定备库执行过恢复操作,不管恢复执行成功或失败,通过监视器动态修改的内存值都不再有效,主库守护进程在恢复完成后,会根据恢复结果重置内存中的恢复间隔值(对dmwatcher.ini 中的值没有影响)。

    ③主库守护进程根据恢复结果设置恢复间隔
    如果备库恢复成功,会重置此备库的恢复间隔为主库 dmwatcher.ini 中配置的值。如果备库恢复失败,会根据失败 code 区分设置为不同的值,比如 1800s,一般是在主备库日志校验不连续的情况下设置,其他还可能设置为 3s、30s、300s 或者dmwatcher.ini 中设置的值,这里不再详细说明,具体可通过服务器和守护进程的 log日志查看详细的设置信息,也可以通过监视器的 show arch send info 命令查看相关
    code 信息。
    完整的故障恢复流程如下:

    1 通知备库丢弃 KEEP_PKG;
    2 通知主库发送归档日志,同步历史数据;
    3 通知主库切换为 Suspend 状态;
    4 再次通知主库发送归档日志;
    5 通知主库设置备库归档为 Valid 状态;
    6 通知主库切换为 Open 状态。

    整个恢复过程中最耗时的是发送归档日志,当存在多个备库需要恢复时,为了提高恢复的效率,采用多备库并行发送归档的方式进行。守护进程每次搜集一个可恢复备库到恢复列表,按照上述故障恢复流程执行单个步骤,在等待发送归档日志的过程中,继续检测是否有备库可以恢复,如果有则加入恢复列表,也对其开始进行恢复流程处理;如果没有则检查恢复列表中是否有归档日志发送完成的备库,有则对其进行后续步骤处理,直至归档变成有效状态后从恢复列表中删除。对于恢复过程中出错的备库,也从恢复列表中删除。当恢复列表为空时,恢复流程执行结束,守护进程恢复为 OPEN 状态。
    恢复过程中,守护进程会继续检测是否有恢复列表之外的备库需要恢复,如果有则可以动态加入恢复列表,实现动态并行恢复。

    注意:以下情况会导致 Recovery 过程中断: ①Recovery 过程中收到监视器的命令。 ②存在多个备库时,Recovery
    过程中发现其他正常备库故障,且符合failover 条件,则守护进程主动中断 Recovery,先做 failover 处理。
    ③存在多个备库时,Recovery 过程中发现到其他正常备库归档发送异常,则守护进程主动中断 Recovery,先做异常处理。
    ④Recovery 过程中,当前正在被恢复的备库出现异常。 ⑤正在执行 Recovery 的主库或备库是 DMDSC
    集群,Recovery 过程中 DMDSC 集群启动故障处理或者故障重加入,也会中断当前的 Recovery动作。

    在守护进程打开备库异常监控的情况下,对于异常备库的恢复处理需要注意下面两点:

    ①如果主备库的 LSN 已经相等,但是根据统计出来的时间信息判断主库的归档发送时间或备库的日志重演时间仍然大于设置的阈值,则不会再进入Recovery状态,直到主库上有新的日志产生需要同步到备库,可以对统计的历史时间信息进行更新的情况下才会再进入 Recovery 状态尝试恢复。
    ②在进入 Recovery 状态后,通知主库 Suspend之前(主备库数据已经同步一致),会对主库的归档发送时间和备库的日志重演时间进行检查,在两者都小于或等于设置的阈值的情况下,才允许继续执行Suspend,并恢复备库归档为有效状态,否则不允许再往下执行,本次 Recovery 执行失败。

  8. 集群数据守护场景
    (1)正常运行状态
    守护系统正常运行时,同一个守护进程组中,只有一个主库,其他的都是备库。主库处于 Open 状态,主库守护进程也处于 Open 状态,本地没有守护进程控制文件,其内存值是 Valid 有效状态。
    所有备库也处于 Open 状态,所有备库守护进程处于 Open 状态,本地没有守护进程控制文件,其内存值是 Valid 有效状态。
    主库到所有备库的归档也都处于 Valid 有效状态。

    (2)数据守护的启动
    Normal 模式的库默认以 Open 状态启动,也可以通过增加启动参数 Mount 将数据库启动到 Mount 状态。而 Primary/Standby 模式的库启动后,自动进入 Mount 状态,因此,数据守护系统启动时,所有数据库实例处于 Mount 状态。所有守护进程处于 Startup状态。如果实例还未启动到 Mount 状态(比如还处于 After redo 状态),守护进程不会通知实例 Open。
    Local 守护类型的守护进程,直接 Open 数据库实例,并修改守护进程状态为 Open。
    Global 守护类型的守护进程,需要相互协调信息,自动将数据库实例切换到 Open 状态,并将守护进程状态也切换为 Open 状态。
    Global 守护类型的守护进程通知本地库 Open 的总体原则:
    ①对于备库,如果可加入远程任意一个库,则允许将其 Open;
    ②对于主库,如果远程所有库都可加入自己,则允许将其 Open。
    还有一些细节条件这里不再具体列出,如果通过监视器没有观察到主库或备库 Open,可以借助监视器的 Check Open 命令查找原因,根据命令返回的原因考虑是否进行人工干预,比如需要通过监视器命令强制 Open 主库或备库。

    注意:
    手动方式启动数据守护系统时,对于守护进程,数据库实例和监视器的启动顺序没有严格要求,也可以通过监视器命令启动守护系统(前提是所有守护进程已经启动)。
    启动流程中,守护进程在通知主库 Open 之前,会先收集出和主库数据一致的备库(备库的 ALSN 信息和主库的 FLSN 信息相等),守护进程会将这些备库的归档设置为 Valid 有效状态,其他数据不一致的备库则设置为Invalid 无效状态。Primary 模式数据库实例切换为 Open 状态时,需要回滚活动事务、Purge 已提交事务,并重构回滚段,会引发数据变化、LSN增长。对归档无效的备库,在数据守护启动完成后,主备库数据肯定是处于不一致状态。
    主库守护进程 Open 主库后,会修改 INST_RECOVER_TIME 内存值为 3 秒(默认 60 秒),确保归档状态无效的备库 Open 后,尽快启动故障恢复流程,同步主库数据完成后,重新将归档设置为 Valid 状态。
    如果在故障恢复流程完成之前,主库故障,并且不存在归档状态有效的备库,则无法执行备库接管;备库强制接管会引发守护进程组分裂。
    读写分离集群,在 Timely 或 Realtime 归档变为 Valid 之前,不会在备库上创建数据库连接,只读操作也无法分流到对应的备库。

    (3)强制 Open 数据库
    正常情况下,守护进程 dmwatcher 可以自动 Open 数据库实例,但某些情况下(比如备库硬件故障无法启动),数据守护系统不满足 6.2 介绍的启动条件,我们可以通过监视器执行 Open database 命令强制 Open 数据库实例。主备库都可以强制 Open,其执行流程如下:

    1 假设需要强制 Open 数据库 A,只需要启动一个监视器,登录后输入 Open database A 即可完成强制启动。 如果数据库 A 是 Standby 模式,强制 Open 的执行流程如下:
    ①通知 A 的守护进程切换为 Open Force 状态
    ②通知 A 执行 Open 操作
    ③通知守护进程切换 Open 状态

    2 如果数据库 A 是 Primary 模式,强制 Open 的执行流程如下:
    ①通知 A 的守护进程切换为 Open Force 状态
    ②修改 A 到所有归档目标的实时归档/即时归档状态为无效
    ③通知 A 执行 Open 操作
    ④通知守护进程切换 Open 状态

    3 Primary 模式数据库实例切换为 Open 状态时,需要回滚活动事务、Purge 已提交事 务,并重构回滚段,会引发数据变化、LSN 增长。因此,这个操作可能会引发守护进程组分 裂,比如下面的场景:
    ①主库 A 故障
    ②备库 B 接管,成为主库
    ③B 故障
    ④A 重启,并强制 Open
    ⑤A 和 B 数据不一致,并且无法恢复到一致状态。此时,B 重启,就会产生守护进程 组分裂。

    注意:
    强制 Open 主库前,会设置主库到所有归档目标的实时归档/即时归档为 Invalid 状态。
    强制 Open 主库命令,会修改主库守护进程 INST_RECOVER_TIME 内存值为3 秒(默认 60 秒),确保
    主库 Open 后,尽快启动故障恢复流程,同步主库数据完成后,重新将归档设置为 Valid 状态。
    如果在故障恢复流程完成之前,主库故障,将无法执行备库接管;备库强制接管会引发守护进程组分裂。
    

    (4)关闭数据守护系统
    关闭守护系统时,必须按照一定的顺序来关闭守护进程和数据库实例。特别是自动切换模式,如果退出守护进程或主备库的顺序不正确,可能会引起主备切换,甚至造成守护进程组分裂。通过监视器执行 Stop Group 命令关闭数据守护系统,是最简单、安全的方式。命令执行成功后,数据库实例正常关闭。但守护进程并没有真正退出,而是将状态切换为Shutdown 状态。
    Stop Group 命令内部流程如下:

    ①通知守护进程切换为 Shutdown 状态
    ②通知主库退出
    ③通知其他备库退出

    如果使用手动方式关闭数据守护系统,请严格按照以下顺序执行:

    ①如果启动了确认监视器,先关闭确认监视器(防止自动接管)
    ②关闭备库守护进程(防止重启实例)
    ③关闭主库守护进程(防止重启实例)
    ④Shutdown 主库
    ⑤Shutdown 备库

    如果是只关闭主库,并且不想引发备库自动接管,有以下两种方法:

    方法一:
    1 通过 Detach database 命令将所有备库分离
    2 通过 Stop database 命令退出主库
    方法二:严格按照以下顺序执行:
    1 通过 Stop dmwatcher 命令关闭所有守护进程监控
    2 手动正常退出主库

    如果是只关闭备库,并且不想引发主库发送日志失败进入 Suspend 状态,请严格按照
    以下顺序执行:

    1 通过 Detach database 命令将备库分离出数据守护系统
    2 正常退出备库(手动退出或者通过 Stop database命令退出)

    (5)主备库切换
    主库维护,滚动升级等场景,可以执行 Switchover 命令,实现主备库切换。如果存在多个备库,需要先执行 Choose Switchover 命令,选出守护进程组中可以切换的备库。
    Choose Switchover 命令选择可切换备库的条件如下:

    1 主库守护进程是 Open 状态
    2 备库守护进程是 Open 状态
    3 主、备库的 OPEN 记录项内容相同,并且守护进程控制文件是 Valid 有效状态(内存值)
    4 主库正常运行
    5 备库正常运行
    6 主库处于 Open 状态
    7 备库处于 Open 状态
    8 主库到备库的归档是 Valid 状态
    

    假定选出的可切换备库是 B,Switchover 切换流程如下:

    1 通知主备库守护进程,切换为 Switchover 状态
    2 通知主库(A) Mount
    3 实时或 MPP 主备环境下,通知备库(B) APPLY KEEP_RLOG_PKG
    4 通知备库(B) Mount
    5 通知(A) 切换为 Standby 模式
    6 MPP 主备环境下,通知(A)修改 MPP_INI 内存值为 0
    7 通知(B) 切换为 Primary 模式
    8 通知(B) 修改所有归档目标的归档状态为无效
    9 MPP 主备需要通知各组活动主库更新 dmmpp.ctl 文件,参考后文说明
    10 通知新的备库(A) Open
    11 通知新的主库(B) Open
    12 通知主备库守护进程切换为 Open 状态
    13 清理所有守护进程上记录的监视器命令执行信息
    

    注意: 主备库切换在实现逻辑上等同于主备库正常状态 下用户主动发起的Takeover 操作。Swithover完成后,主备库之间数据是不完全同步的,要由新主库 B 的守护进程通过 Recovery 流程,重新同步数据到新备库 A。Switchover 命令会修改切换后主库守护进程 INST_RECOVER_TIME 内存值为 3 秒(默认 60 秒),确保尽快启动故障恢复流程,同步主库数据完成后,重新将归档设置为 Valid 状态。
    在故障恢复流程完成之前,再次执行Switchover 命令会报错,如果主库故障,备库接管将会报错;备库强制接管会引发守护进程组分裂。

    (6)主库故障、备库接管
    当出现硬件故障(掉电、存储损坏等)原因导致主库无法启动,或者是主库内部网卡故障导致主库短期不能恢复正常的情况下,可使用备库接管功能,将备库切换为主库继续对外服务。
    故障自动切换模式下,确认监视器会自动选择符合条件的备库进行接管。
    故障手动切换模式下,可以先在监视器上执行 Choose Takeover 命令,选出守护进程组中可以接管的备库。
    为了避免备库接管后,造成守护进程组分裂,执行 Takeover 必须满足下列条件:

    1 主库是 Primary 模式、Open 状态时,发生故障
    2 主库守护进程故障,故障前是 Startup/Open/Recovery 状态;或者主库守护
    进程正常
    3 主库故障前到接管备库的归档状态为 Valid
    4 接管备库是 Standby 模式、Open 状态
    5 接管备库的守护进程控制文件状态为 Valid(内存值)
    6 故障主库和接管备库的 Open 记录项内容相同
    

    假设主库 A 故障时,在故障自动切换模式下确认监视器自动选出待接管备库 B 并通知备库 B 自动接管,或者在故障手动切换模式下,通过监视器上的 Choose Takeover 命令,选出待接管备库 B,在监视器上输入 Takeover 命令通知备库 B 执行接管,这两种方式的接管执行流程是一样的。
    以备库 B 为例,接管的执行流程包括:

    1 监视器通知守护进程(B)切换为 Takeover 状态
    2 实时主备或 MPP 主备环境下,通知备库(B) APPLY KEEP_PKG
    3 通知备库(B) Mount
    4 通知(B) 切换为 Primary 模式
    5 通知(B) 修改到所有归档目标的归档状态为 Invalid
    6 MPP 主备需要通知活动主库更新 dmmpp.ctl 文件(步骤参考 6.5 主备库切换)
    7 通知新的主库(B) Open
    8 通知守护进程(B)切换为 Open 状态
    

    (7)备库强制接管
    有些情况下,备库接管会失败,但主库不能启动或者及时恢复对外服务的情况下,可以使用 Takeover Force 命令,进行备库强制接管。强制接管具有一定的风险,可能导致备库和故障主库数据不一致,而造成部分数据的丢失,出现数据库分裂的情况,所以应该慎重使用。
    例如主库和守护进程故障时,监视器未启动,用户启动监视器后,由于监视器并未收到故障主库任何信息,因此不满足 Takeover 条件,执行 Takeover 会报错。如果用户可确认主库故障时主备数据是一致的(如故障时主库未执行操作,主备库归档有效的,并且两者的 LSN 一致)、或者丢失小部分数据的影响可忽略、或者丢失小部分数据的影响小于主库持续宕机造成的影响,则可以考虑执行 takeover force 强制接管。
    强制接管,先通过 Choose Takeover Force 选出符合强制接管条件的备库,再执行 Takeover Force 命令。
    备库强制接管时,如果接管备库是处于 Mount 状态/Standby模式的库,则会自动 Open 备库,其他执行流程与备库接管一致。强制接管的条件包括:

    1 不存在活动主库
    2 备库守护进程处于 Open 或 Startup 状态
    3 备库实例运行正常
    4 备库是 Standby 模式
    5 备库处于 Open 或 Mount 状态
    6 备库的 KLSN 必须是所有备库中最大的
    7 备库守护进程控制文件必须有效
    

    (8)主库故障重启(备库接管前重启)
    主库故障后立即重启,此时主库的守护进程变成 Startup 状态,重新进入守护进程的启动流程,将数据一致的备库归档设置为有效状态,其余备库归档设置成无效状态,并重新Open 主库。Open 成功后继续作为主库,当检测到归档状态无效的备库正常时会启动Recovery 处理流程,重新同步主备库数据。

    (9)备库故障处理
    备库产生故障(硬件故障或者内部网卡故障)时,主库的处理流程对手动切换、自动切换模式处理上有些差异。
    ①手动切换模式
    对于手动切换模式,检测到备库故障,满足 Failover 条件时,主库的守护进程立即切换到 Failover 状态,执行对应的故障处理,如果不满足切换 Failover 条件,则保持当前状态不变。
    手动切换模式下,主库守护进程切换 Failover 条件:

    1 备库实例故障,或者主备库之间出现网络故障,或者备库重演时校验 LSN 不匹配,这三种场景下引发主库
    同步日志到备库失败挂起,主库实例处于 Suspend 状态
    2 主库到此备库的归档状态是 Valid(读写分离集群没有此限制)
    3 主库的守护进程处于 Startup、Open 或 Recovery 状态
    4 当前没有监视器命令正在执行
    

    ②自动切换模式
    对于自动切换模式,主库的守护进程会自动判断切换到 Failover 状态或者 Confirm确认状态,如果两种状态切换条件都不满足,则保持当前状态不变。
    自动切换模式下,主库守护进程不进入 Confirm 确认状态,直接切换到 Failover 条件:

    1 前四项条件,和上面列出的手动切换条件相同
    2 备库实例故障,备库守护进程正常
    

    如果只满足条件 1,不满足条件 2,则主库守护进程会先进入 Confirm 确认状态,等待确认监视器的确认消息。主库的守护进程进入 Confirm 确认状态后,会有下面几种不同的处理:
    1 主库和确认监视器之间网络连接正常
    主库的守护进程收到了确认监视器返回的确认消息,如果确认监视器认定可以执行 Failover,则主库的守护进程会切换为 Failover 状态并执行对应的处理;如果确认监视器认定不满足执行 Failover 条件,则主库的守护进程会一直保持在 Confirm 状态。确认监视器认定主库可以执行 Failover 条件:

    1)主库守护进程处于 Confirm 状态
    2)主库实例正常,处于 Suspend 状态
    3)主库没有被接管,不存在其他主库
    4)没有 takeover/switchover 命令在执行
    5)当前所有归档有效的备库均可以加入主库
    

    2 主库和确认监视器之间网络连接异常,或者没有启动确认监视器。满足下面条件后
    主库允许切换至 Failover 状态执行故障处理:

    1)主库实例正常,处于 Suspend 状态
    2)备库守护进程正常
    3)主库没有被接管,不存在其他主库
    4)没有 takeover/switchover 命令正在执行
    5)备库故障前可以加入主库
    

    3 主库和确认监视器网络恢复正常后,主库已经被接管。老主库的守护进程切换为
    Startup 状态,重新判断是否可加入新主库。
    主库守护进程进入 Failover 状态后的执行流程(自动或手动切换模式下执行流程相
    同):

    1)对实时主备或 MPP 主备,通知主库修改发送归档失败的备库归档状态无效
    2)通知主库重新 Open。
    3)将主库的守护进程切换为 Open 状态
    

    ⑩确认监视器未启动
    故障自动切换模式下,确认监视器必须一直处于启动状态,并且要确保确认监视器的配置正确(否则无法和守护进程通信,相当于确认监视器没有启动)。若确认监视器未启动或者配置错误的,在主库或备库发生故障时,无法通过确认监视器执行正常的故障处理。确认监视器的具体作用请参考状态确认和自动接管小节。
    在没有确认监视器或确认监视器配置错误的情况下:

    1 如果主库故障,则备库无法自动接管为新主库。
    2 如果备库实例和备库的守护进程都出现故障,或者主备库之间出现网络故障,则主库的守护进程无法通过确认监视器来确认备库状态,主库守护进程会处于Confirm 确认状态,实例处于 Suspend 挂起状态。

    对于第 2 种情况,当备库实例和备库守护进程重新恢复正常,或者主备库之间的网络恢复正常后,即使没有确认监视器,主库的守护进程也会切换至 Failover 状态,将主库重新 Open,后续进行正常的备库恢复处理,而不会一直处于 Confirm 确认状态。
    可以通过监视器的 show monitor 命令查看连接到指定守护进程的所有监视器信息,以此可以检查守护系统中是否启动有确认监视器以及确认监视器和守护进程的通信是否正常,也可以尝试再启动一个新的确认监视器,如果守护系统中已经启动有确认监视器,则不允许再启动第二个。

    到此文章结束,请耐心阅读~
    
    更多达梦技术资讯,请访问达梦技术社区:
    达梦数据库 - 新一代大型通用关系型数据库 | 达梦云适配中心
    https://eco.dameng.com/
    

以上是关于达梦数据库实时主备集群的同步机制和切换机制的主要内容,如果未能解决你的问题,请参考以下文章

高并发/高可用/哨兵机制/集群模式/高可用与主备切换/主从复制/断点续传

高并发/高可用/哨兵机制/集群模式/高可用与主备切换/主从复制/断点续传

Hadoop集群安装与配置

Spark系列Master主备切换机制

postgresql + pgpool 构建容灾高可用集群(数据同步流复制/主备自动切换)

spark的主备切换极致原理剖析