DM数据守护(DM Data Watch)的实现原理非常简单:将主库(生产库)产生的Redo日志传输到备库,备库接收并重新应用Redo日志,从而实现备库与主库的数据同步。DM数据守护的核心思想是监控数据库状态,获取主、备库数据同步情况,为Redo日志传输与重演过程中出现的各种异常情况提供一系列的解决方案。
其他守护进程或者监视器通过MAL_HOST:MAL_DW_PORT(52141)来和dmwatcher创建TCP连接的方式进行通信;
dmwatcher通过MAL_HOST:MAL_INST_DW_PORT(33141)和自己的dmserver创建TCP连接的方式进行通信。
主库产生的redo日志通过MAL系统传递到备库(其他一些实例间的消息通讯也是通过mal系统完成),使用MAL_HOST:MAL_PORT(61141)创建MAL链路。
Redo 日志记录物理数据页内容变动情况,是数据库十分重要的一个功能,在数据库系 统故障(比如服务器掉电)重启时,利用 Redo 日志可以把数据恢复到故障前的状态。 Redo 日志也是数据守护的实现基础,数据库中 Insert、Delete、Update 等 DML 操作以及 Create TABLE 等 DDL 操作最终都会体现为对某一个或者多个物理数据页的修 改,因此备库通过重做 Redo 日志可以与主库数据保持一致。
主备库之间的 Redo 日志传输,以日志包 RLOG_PKG 为单位,主库通过 MAL 系统发送 Redo 日志到备库。各种不同数据守护类型的区别,就在于主库日志包 RLOG_PKG 的发送时机,以及备库收到 Redo 日志后的处理策略。
主备库同步数据以RLOG_PKG(日志包)为单位。
日志包大小不固定,采用固定包头和可变包头结合的方式,包头记录日志的控制信息,包括类型、长度、包序号、LSN信息、产生日志的节点号、加密压缩信息、日志并行数等内容。
Redo日志包(RLOG_PKG)是DM数据库批量保存物理事务产生的Redo日志的数据单元日志包以物理事务PTX为单位保存日志,一个日志包内可连续保存一个或多个PTX,日志包大小不固定。
物理事务(Physical Transaction,简称ptx)是数据库内部一系列修改物理数据页操作的集合。
一般说来一条修改数据的SQL语句(比如Insert),在系统内部会转化为多个相互独立的物理事务来完成,物理事务提交时会将产生的Redo日志写入日志包RLOG_PKG中。
一个物理事务包含一个或者多个Redo记录(Redo Record)
每条Redo记录(RREC)都对应一个修改物理数据页的动作。
物理RREC记录的是数据页的变化情况,内容包括:操作类型、修改数据页地址、页内偏移、数据页上的修改内容,如果是变长类型的Redo记录,在RREC记录头之后还会有一个两字节的长度信息。
逻辑RREC记录的是一些数据库逻辑操作步骤,主要包括:事务启动、事务提交、事务回滚、字典封锁、事务封锁、B树封锁、字典淘汰等。逻辑RREC记录是专门为数据守护增加的记录类型。
主库:Primary模式,提供完整数据库服务的实例,一般来说主库是用来直接支撑应用系统的生产库。不支持修改表空间文件名,不支持修改arch_ini参数。对临时表空间以外的所有的数据库对象的修改操作都强制生成Redo日志。支持本地,实时,即时,异步归档。
备库:Standby模式,提供只读数据库服务的实例。备库除了用于容灾,还可以提供备份、查询等只读功能,并且备库还支持临时表的Insert/Delete/Update操作。备库支持临时表修改主要基于两个因素:1.临时表数据的修改不会产生Redo日志,主库对临时表的修改无法同步到备库;2.可以提供更大灵活性,适应更多应用场景。
可以执行数据库备份、查询等只读数据库操作。正常生成本地归档,正常发送异步归档Redo日志;但实时归档(Realtime)、即时归档(Timely)均强制失效。该模式下时间触发器、事件触发器等都失效。
LSN(Log Sequence Number)是由系统自动维护的Bigint类型数值,具有自动递增、全局唯一特性,每一个LSN值代表着DM系统内部产生的一个物理事务。DM中每条REDO日志记录都对应一个唯一的LSN值,每一个LSN值代表着DM系统内部产生的一个物理事务
DM数据库中与LSN相关的信息,可以通过查询V$RLOG表来获取。类似于oracle的SCN,SYSTEM CHANGE NUMBER。
CUR_LSN(CLSN)是系统已经分配的最大LSN值。物理事务提交时,系统会为其分配一个唯一的LSN值,大小等于CUR_LSN+1,然后再修改CUR_LSN=CUR_LSN+1。n
FILE_LSN(FLSN)是已经写入联机Redo日志文件的最大LSN值。每次将Redo日志包RLOG_PKG写入联机Redo日志文件后,都要修改FILE_LSN值。
FLUSH_LSN是已经发起日志刷盘请求,但还没有真正写入联机Redo日志文件的最大LSN值。
CKPT_LSN是检查点LSN,所有LSN<=CKPT_LSN的物理事务修改的数据页,都已经从Buffer缓冲区写入磁盘,CKPT_LSN由检查点线程负责调整。
nAPPLY_LSN(ALSN)是备库已写入联机Redo日志文件的日志包的原始最大LSN值,此LSN取自主库对应的原始日志包中的最大LSN值。如果主库是DMDSC集群,备库分别为主库每一个节点维护一个APPLY_LSN。
RPKG_LSN(RLSN)是备库重演LSN,表示备库已经重演完成的最大LSN。如果主库是DMDSC集群,备库分别为主库每一个节点维护一个RPKG_LSN。
与上述LSN对应,DM数据守护也定义了一批LSN:
CLSN与CUR_LSN保持一致,数据库已经分配的最大LSN值。
FLSN与FILE_LSN保持一致,已写入联机日志文件的LSN值。
ALSN与APPLY_LSN保持一致,备库已写入联机日志文件的原始LSN值。
RLSN与RPKG_LSN保持一致,备库已经重演完成的最大LSN值.
SLSN是StandbyLSN的缩写,表示备库明确可重演的最大LSN值。
KLSN是KeepLSN的缩写,表示备库已经收到、但未明确是否可以重演的RLOG_PKG的最大LSN值。在即时读写分离集群中KLSN==SLSN(即时备库没有KLSN)
备库的ALSN=主库的FLSN,说明备库和主库数据一致。
执行检查点:
为了达到循环利用日志系统空间的目的,必须在所有日志文件空间将被占满时,系统能够自动清空一部分日志,以便重用日志文件的空间。
为了保证被清空的日志所“保护”的数据在磁盘上是安全的,需要引入一个关键的数据库概念——检查点。
当系统产生检查点时,将系统缓冲区中被修改过的数据页写入磁盘,以保证当前日志所“保护”的数据页都已安全写入磁盘,这样日志文件即可被安全重用。
DM的检查点分为两种:完全检查点和部分检查点:
完全检查点:会将内存缓冲区中的所有脏页写入磁盘,并调整CKPT_LSN,在数据库正常关闭时会产生一个完全检查点。
部分检查点:根据dm.ini配置文件中的参数CKPT_FLUSH_RATE和CKPT_FLUSH_PAGES,确定每次检查点刷脏页的数量。执行部分检查点的过程中,DDL/DML操作都可以正常执行,DM 系统中绝大多数情况下触发的都是部分检查点。
1. 当服务器启动和关闭时,系统都会产生检查点。
2. 服务器运行过程中,系统会自动判断是否需要执行检查点;
3. 当空闲日志空间不足时,系统自动产生一个检查点;
4. 系统调度线程也会定时产生检查点;
5. 还可以通过调用系统函数CHECKPOINT(rate int)主动生成检查点。
rate为刷脏页百分比,取值范围:0~100
--非法的参数数据
CHECKPOINT(-1);
--执行成功
CHECKPOINT(0);
--执行成功
CHECKPOINT(80.5);
--执行成功
CHECKPOINT(100);
--非法的参数数据
CHECKPOINT(101);
所谓脏读就是对脏数据的读取,而脏数据所指的就是未提交的已修改数据
每个RLOG_PKG 都有对应的序号属性,称之为包序号(PKG SEQNO),日志包生成时按照序号连续递增。
包序号包括本地包序号(LSEQ)和全局包序号(GSEQ)
本地包序号是节点内唯一、连续递增的值,用于校验联机日志连续性;
全局包序号由数据守护集群的主备库共同维护,具有全局唯一、连续、递增的特性,用于校验归档日志的连续性。
DM数据库中与全局包序号相关的信息可以通过查询V$RLOG表来获取,主要包括以下几种类型的全局包序号:
CUR_SEQ是系统已经分配的最大全局包序号。RLOG_PKG写入联机日志文件前,系统会为其分配一个唯一的全局包序号。
FILE_SEQ是已经写入联机Redo日志文件的日志包的最大全局包序号。每次将Redo日志包RLOG_PKG写入联机Redo日志文件后,都要修改FILE_SEQ值。
APPLY_SEQ是备库已写入联机Redo日志文件的日志包的原始最大全局包序号,此序号取自主库对应的原始日志包的包序号。如果主库是DSC集群,备库分别为主库每一个节点维护一个APPLY_SEQ。
(新版手册里的)RPKG_SEQ 是备库重演全局包序号,表示备库已经重演完成的最大全局包序号。
DM数据守护中也相应地定义了一批全局包序号:
CSEQ全局已分配包序号,标识系统已经分配的最大GSEQ值。
FSEQ全局文件包序号,标识已写入联机日志文件的最大GSEQ值。
ASEQ原始全局文件包序号,标识备库已写入联机日志文件的原始GSEQ值。
RSEQ全局重演包序号,标识备库已经重演的最大GSEQ值。
SSEQ全局备库包序号,标识备库明确可重演的最大GSEQ值。
KSEQ全局保留包序号,表示备库已经收到、未明确是否可以重演的最大GSEQ值。在读写分离集群中SSEQ==KSEQ。
实时:在某事发生、发展的实际时间同步。
即时:立即,当下;立刻。
可以参考实时通信和即时通信的区别,理解成实时响应快即时响应慢就行了。
设置归档保留时间ARCH_RESERVE_TIME为43200(一个月),数据库每隔五分钟检查归档是否存在超过保留时间的归档并删除
实时归档的执行流程是:
1.主库在Redo日志(RLOG_PKG)写入联机日志文件前,将Redo日志发送到备库
2.备库收到Redo日志(RLOG_PKG)后标记为KEEP_PKG,将原KEEP_PKG加入日志重演任务系统,并马上响应主库,不需要等待Redo日志重演结束后再响应主库。
3.主库收到备库的响应消息,确认备库已经收到Redo日志后,再将Redo日志写入联机日志文件中。
主库生成联机Redo日志,当触发日志写文件操作后(当事务提交或Redo日志包满或执行检查点时会进行日志刷盘),日志线程先将RLOG_PKG发送到备库,备库接收后进行合法性校验(包括日志是否连续、备库状态是否Open等),不合法则返回错误信息,合法则作为KEEP_PKG保留在内存中,原有KEEP_PKG的Redo日志加入Apply任务队列进行Redo日志重演,并响应主库日志接收成功。
备库KEEP_PKG日志重演时机包括:
1.备库收到新的RLOG_PKG
备库收到新的RLOG_PKG时,会将当前保存的KEEP_PKG日志重演,并将新收到的RLOG_PKG再次放入KEEP_PKG中。
2.收到主库的重演命令
主库会定时将FILE_LSN等信息发送到备库,当主库FILE_LSN(已经写入Redo)等于备库SLSN(明确可以重演)时,表明主库已经将KEEP_PKG对应的Redo日志写入联机日志文件中,此时备库会启动KEEP_PKG的日志重演。
3.备库切换为新主库
在监视器执行SWITCHOVER或TAKEOVER命令,或者确认监视器通知备库自动接管时,备库会在切换为PRIMARY模式之前,启动KEEP_PKG的日志重演。
备库收到新的RLOG_PKG后,重演的是原来的KEEP_PKG,也就是说,主库的联机日志文件在某个时间点会比备库的联机日志文件更多一点,估计这个时间很短,因为主库会定时将FILE_LSN等信息发送到备库,备库SLSN=主库FLSN的时候,就会将KEEP_PKG重演,此时主备库的联机日志文件就是一致的。
即时归档(Timely)在主库将Redo日志写入联机日志文件后,通过MAL系统将Redo日志发送到备库。
即时归档在RLOG_PKG写入主库联机Redo日志文件后,再发送RLOG_PKG到备库,因此即时备库没有KEEP_PKG。
导致发送RLOG_PKG失败后,主库马上修改即时归档为Invalid状态,并切换数据库为Suspend状态。
即时归档修改为Invalid状态后,会强制断开对应此备库上存在影子会话的用户会话,避免只读操作继续分发到该备库,导致查询数据不一致。
实时归档和即时归档有两种模式:
根据配置文件dmarch.ini中的ARCH_WAIT_APPLY配置项来确定,1表示事务一致模式,0表示高性能模式。
事务一致模式:
1.主库事务提交触发Redo日志刷盘和归档
2.备库收到主库发送的Redo日志(此时直接将RLOG_PKG写入本地的归档日志文件),并重演完成后再响应主库。
3.主库收到备库响应消息后,再响应用户的提交请求。
事务一致模式下,同一个事务的SELECT语句无论是在主库执行,还是在备库执行,查询结果都满足READ COMMIT隔离级要求。
高性能模式:
与实时归档一样,备库收到主库发送的Redo日志后,马上响应主库,再启动日志重演。高性能模式下,备库与主库的数据同步存在一定延时(一般情况下延迟时间非常短暂,用户几乎感觉不到),不能严格保证事务一致性。
read commit(备库只支持读提交事务隔离级别):
DM数据库的读提交隔离可以确保只访问到已提交事务修改的数据,保证数据处于一致性状态,能够满足大多数应用的要求,并最大限度的保证系统并发性能,但可能会出现不可重复读取和幻像读。
用户可以在事务开始时使用以下语句设定事务为读提交隔离级:
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;
根据是否满足读提交事务隔离级特性,读写分离集群可以配置为事务一致模式和高性能两种模式。简单的说,事务一致模式下,不论一个 Select 语句是在备库执行、还是在主库执行,其查询结果集都是一样的。高性能模式则不能保证查询是一致的,备库的数据与主库的数据同步存在一定的延迟,当 Select 语句发送到备库执行时,返回的有可能是主库上一个时间点的数据。
实时读写分离下,默认值为0,即采用高性能模式。这个参数在实时归档中的用法和在即时归档中是相同的,只是默认值不同。
对实时读写分离的事务一致模式仅在数据守护配置为自动切换模式下才会生效。
REDOS_PARALLEL_NUM 默认1 静态
指定故障重启、还原恢复、备库重演场景下,并行日志重演的线程数,有效值范围(1~64)。1 表示不进行并行日志重演
请大家注意主备和读写分离开启并行重演的的情况下,备机上的隔离级是读未提交的,所以读写分离集群是不能开启并行重演的。主备情况下开启并行重演只能用于高可用的需求,备机查到的数据是未提交的
Redo日志本地归档(Local),就是将Redo日志写入到本地归档日志文件的过程。
Normal/Primary模式库在Redo日志写入联机Redo日志文件后,将对应的RLOG_PKG由专门的归档线程写入本地归档日志文件中。
Standby模式库收到主库产生的Redo日志后,直接进行本地归档,写入本地归档日志文件中,同时启动Redo日志重演。
远程归档专门用于DMDSC环境中。
所谓远程归档(REMOTE ARCHIVE),顾名思义就是将归档目录配置在远程节点上。远程归档采用双向配置的方式,双向配置远程归档就是两个节点将自己的远程归档相互配置在对方机器上。集群中所有的节点,都拥有一套包括所有节点的,完整的归档日志文件。
具体有两种配置方式:
一是共享本地归档的远程归档,即将远程归档目录配置为另一节点的本地归档目录,以此来共享它的本地归档日志文件;
二是通过MAL发送的远程归档,即将写入本地归档的REDO日志信息,通过MAL发送到远程节点,并写入远程节点的指定归档目录中,形成远程归档日志文件。
远程归档的使用场景:
1.执行数据库恢复时,恢复工具(如DMRMAN)所在节点需要访问其他各节点归档日志。
2.DMDSC守护系统中进行主、备库异步归档日志的同步或备库恢复时,DMDSC控制节点作为发送端,需要访问其他从节点的归档日志。
本地归档写入失败(比如磁盘空间不足),系统将会挂起;而远程归档失败则会直接将远程归档失效,不再发送REDO日志到指定数据库实例。当节点间网络恢复、或者远程节点重启成功后,系统会自动检测并恢复远程归档,继续发送新写入的REDO日志,但不会主动补齐故障期间的REDO日志。
异步归档(Async)由主、备库上配置的定时器触发,根据异步备库的KEEPLSN信息,扫描本地归档目录获取Redo日志,并通过MAL系统将Redo日志发送到异步备库。异步备库的Redo日志重演过程与实时归档等其他类型的归档完全一致。
异步备库可以级联配置,异步备库本身也可以作为源库配置异步备库。
异步备库可以不配置本地归档。
本地归档、实时归档和即时归档均包含两种状态:Valid和Invalid。
异步归档只有一种归档状态:Valid。
Valid:归档有效,正常执行各种数据库归档操作。
Invalid:归档无效,主数据库不发送联机Redo日志到备数据库。
在不同的归档类型中,归档状态转换时机不同。具体转换时机描述如下:
1.主备库启动后,主库到所有备库的归档默认为Valid状态,
守护进程Open主库前,根据主备库日志同步情况,将数据不一致备库的归档修改为Invalid状态。(所以刚搭建完打开监视器查看的时候如果显示备库的归档为invalid状态,说明该备库的数据可能和主库不一致。)
2.备库故障恢复,从主库同步历史数据后,守护进程将主库修改为Suspend状态,并将主库到备库的归档状态从Invalid修改为Valid。当守护进程再次Open主库后,主备库数据重新恢复为一致状态。
3.主库发送日志到实时备库失败挂起,守护进程处理Failover过程中,将主库到备库的归档状态修改为Invalid。
4.主库发送即时归档失败后,直接将主库到备库的归档改为Invalid状态。
5.异步归档始终保持Valid状态,一旦归档失败马上返回,等待下一次触发再继续发送。
实时归档、即时归档只对Primary模式的主库有效,备库上配置的实时归档、即时归档状态没有实际意义,始终保持Valid状态。
RSTAT :此字段对备库有效,表示主库到备库的归档状态,可能为Valid/Invalid/Unknown,对于本地守护类型的备库,此字段为NULL,对于主库本身,此字段值为Valid。
备库归档日志文件写入的并不是自己重演生成的Redo日志,而是直接将主库产生的Redo日志写入到本地归档日志文件中。为了区分生成Redo日志和写入Redo日志的库,归档日志文件头增加了几个MAGIC字段:
PMNT_MAGIC
永久魔数,用来唯一标识数据库,初始化数据库时生成并保持不变(DDL_CLONE还原库除外),数据守护集群中所有主备库的PMNT_MAGIC是相同的。
DB_MAGIC
数据库魔数,数据库初始化时生成,数据库还原后重新生成新的DB_MAGIC,数据守护集群中所有主备库的DB_MAGIC是不同的。归档日志文件使用DB_MAGIC标识写入Redo日志的库。
SRC_DB_MAGIC
源库魔数,产生Redo日志数据库的DB_MAGIC值;主库归档日志文件中SRC_DB_MAGIC与DB_MAGIC相同;备库归档日志文件中SRC_DB_MAGIC与主库的DB_MAGCI值相同。
Primary/Normal模式库本地归档日志文件的命名方式调整为:
ARCH_NAME_DB_MAGIC[SEQNO]_日期时间.log
Standby模式库(备库)生成的归档日志文件的命名方式调整为:
STANDBY_ARCHIVE_DB_MAGIC[SEQNO]_日期时间.log
守护进程根据主备库Open记录的包含关系、主库各节点LSN信息和备库日志重演信息,判断是否出现主备库分裂。在未出现分裂情况下,综合考虑各数据库模式、状态要素,选择正确的主库并进行自动Open数据库。
组分裂:
同一守护进程组中,不同数据库实例的数据出现不一致,并且无法通过重演Redo日志重新同步数据的情况,我们称为组分裂。
引发组分裂的主要原因包括:
1.即时归档中,主库在将Redo日志写入本地联机Redo日志文件之后,发送Redo日志到备库之前出现故障,导致主备库数据不一致,为了继续提供服务,执行备库强制接管。此时,当故障主库重启后,就会引发组分裂。
2.故障备库重新完成数据同步之前,主库硬件故障,并且长时间无法恢复;在用户接受丢失部分数据情况下,为了尽快恢复数据库服务,执行备库强制接管,将备库切换为主库。此时,如果故障主库重启,也会造成组分裂。
检测到组分裂后,守护进程会修改控制文件(SYSTEM_PATH 路径下自动创建dmwatcer.ctl,文件中记录状态为分裂状态)为分裂状态,被分裂出去的数据库需要通过备份还原等技术手段重新恢复。
借助监视器的show命令、或者tip命令可以查看守护系统中是否发生数据库的分裂,对于已发生的分裂,可以借助以下方法找出分裂产生的原因:
1. 查看分裂库的服务器和守护进程log日志,查找带有“[!!!”和“!!!]”标签的log信息,log信息格式形如“[!!!LOG_INFO!!!]”,记录有数据库分裂的详细原因。
cat dm_dmwatcher_DM1_202212.log | grep -i split
cat dm_dmwatcher_DM1_202212.log | grep "\[\!\!\!" 特殊字符要转义
2.如果分裂库的守护进程控制文件状态不是Valid,可借助监视器的showopeninfo命令,根据DESC字段找出原因。
3.根据服务器、守护进程和监视器的log日志,找出历史操作信息,分析产生分裂的原因。发生分裂后,用户需要选择适当的主库作为最新主库,备库采用重建的方法加入系统。
脑裂:
脑裂是同一个守护进程组中同时出现两个或者多个活动主库,并且这些主库都接收用户请求,提供完整数据库服务。一旦发生脑裂,将无法保证数据一致性,对数据安全造成严重后果。
确认监视器启动故障切换之前,会进行严格的条件检查,避免脑裂发生。守护进程一旦检测到脑裂发生,会马上强制退出主库,等待用户干预,避免数据差异进一步扩大。
故障自动切换模式下,可以实时处理故障,但对网络稳定性要求更高,需要确保主备库之间,主备库与守护进程、确认监视器之间的网络稳定可靠,否则可能会误判主库故障,备库自动接管后,出现多个 Open 状态的主库,引发脑裂。
造成脑裂的主要原因有两个:网络不稳定或错误的人工干预。为了避免出现脑裂,我们建议:
1.设置dm.ini参数ALTER_MODE_STATUS=0,限制用户进行直接通过SQL修改数据库模式、状态以及OGUID。
2.提供稳定、可靠的网络环境。
3.配置自动切换数据守护时,将确认监视器部署在独立的第三方机器上,不要与某一个数据库实例部署在一起,避免由于网络问题触发自动故障切换,导致脑裂发生。
4.通过人工干预,将备库切换为主库之前,一定要确认主库已经发生故障,避免主库活动情况下,备库强制接管,人为造成脑裂。
守护进程是管理数据守护系统的核心部件,监视器(dmmonitor)负责发起命令,守护进程负责解析、处理、转发命令。守护进程提供了数据库监控、故障检测、故障处理、故障恢复等各种功能。
dmwatcher通过MAL_HOST:MAL_INST_DW_PORT和自己的dmserver创建TCP连接的方式进行通信。
守护进程和实例链路建立成功后,数据库实例定时发送信息到守护进程,发送到守护进程的内容包括:实例进程ID、实例名、数据库模式、数据库状态、FILE_SEQ、FILE_LSN、CUR_SEQ、CUR_LSN、MAL链路状态、归档状态、公钥、MPP控制文件等信息。
守护进程更新本地记录的实例信息后,同时记录该时间戳。当检测到实例进程ID已经不存在或者超过一段时间没有收到实例消息(INST_ERROR_TIME),则会认定实例故障。 如果配置了自动重启,则会将实例重新拉起。
守护进程采用超时机制判断实例是否故障,即当前时间和上次收到消息的时间差是否超过故障认定时间(INST_ERROR_TIME,手册里的例子是给10s),因此不建议在数据守护系统运行过程中调整操作系统时间,避免导致这个差值很大,误判实例故障。
守护进程将监控的数据库实例信息和守护进程自身的信息(包括守护类型、守护模式、守护状态、守护日志、监视器执行序列号、执行返回码等)捆绑在一起,定时发送给其他守护进程和所有监视器。
其他守护进程或者监视器通过MAL_HOST:MAL_DW_PORT来和dmwatcher创建TCP连接的方式进行通信;
接收并解析其他守护进程发送的消息,如果超过一段时间(DW_ERROR_TIME 手册里的例子是给10s)没有收到远程守护进程消息,会将远程守护进程状态认定为ERROR状态。
监视器和守护进程之间也是采用超时机制判断对方是否故障,即当前时间和上次收到消息的时间差是否超过故障认定时间(守护进程配置的DW_ERROR_TIME 手册里的例子是给10s)。
主备切换、备库接管等操作都是通过监视器命令进行,监视器将操作命令分解成多个步骤顺序执行。守护进程接收这些消息并通知实例进行相应操作,例如执行 SQL 语句修改实例模式、状态、INI 参数、设置归档状态等一系列动作,这些步骤依次执行完成后,即可完成主备库的切换或备库的接管等操作。
例如,主备切换操作,监视器首先通知待切换主备库的守护进程修改为 Switchover 状态,设置成功以后,其他监视器将不能再进行命令操作。守护进程收到监视器将实例 Mount 的命令,转发到本地实例执行,实例执行完成后返回执行结果。执行结果包含在实例向守护进程发送的消息中,守护进程根据消息中的执行码判断是否执行成功,并响应监视器。
注意
监视器和守护进程之间也是采用超时机制判断对方是否故障,即当前时间和上次收到消息的时间差是否超过故障认定时间(守护进程配置的DW_ERROR_TIME),因此不建议在数据守护系统运行过程中调整操作系统时间,避免导致这个差值很大,误判监视器故障。
数据守护系统启动时,所有数据库实例处于Mount状态。所有守护进程处于Startup状态。
Local守护类型的守护进程,直接Open数据库实例,并修改守护进程状态为Open。
Global守护类型的守护进程,需要相互协调信息,自动将数据库实例切换到Open状态,并将守护进程状态也切换为Open状态。
Global守护类型的守护进程通知本地库Open的总体原则:
对于备库,如果可加入远程任意一个库,则允许将其Open;
对于主库,如果远程所有库都可加入自己,则允许将其Open。
如果通过监视器没有观察到主库或备库Open,可以借助监视器的Check Open命令查找原因,根据命令返回的原因考虑是否进行人工干预,比如需要通过监视器命令强制Open主库或备库。
本地守护:
提供最基本的守护进程功能,监控本地数据库服务。
如果实例使用 Mount 方式启动,守护进程会通知实例自动 Open,
如果连续一段时间没有收到来自其监控数据库的消息,即认定数据库出现故障,根据配置(INST_AUTO_RESTART)确定是否使用配置的启动命令重启数据库服务。
异步备库采用这种方式。
全局守护:
实时主备、MPP 主备和读写分离集群系统中,需要将守护进程配置为全局守护类型;
DMDSC 数据守护除了仅配置异步备库,也需要将守护进程配置为全局守护类型。
守护进程根据数据库服务器配置的归档类型以及MPP_INI参数情况,自动识别具体的集群类型(实时主备、MPP主备、读写分离集群或DMDSC数据守护)。
全局守护类型在本地守护类型的基础上,通过和远程守护进程的交互,增加了主备库切换、主备库故障检测、备库接管、数据库故障重加入等功能。
配置全局守护类型后,守护进程守护的数据库实例,必须配置实时或即时归档,否则dmwatcher会启动失败。
守护进程支持两种故障切换模式:
故障自动切换:
主库发生故障时,确认监视器自动选择一个备库,切换为主库对外提供服务。故障自动切换模式,要求必须且只能配置一个确认监视器。
故障手动切换:
主库发生故障时,由用户根据实际情况,通过监视器命令将备库切换为主库。在用户干预之前,备库可以继续提供只读服务和临时表的操作。
实时主备/MPP 主备/读写分离集群都可以配置为故障自动切换或故障手动切换模式,这两种模式下守护系统的启动流程、数据同步和故障处理机制存在一定的差异,主要差异参下表。
注意
一个数据守护集群,只能配置一个确认监视器。如果同时启动多个确认监视器,后启动的确认监视器将报错并自动退出。
守护进程包括以下一些状态:
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’方式命名的日志文件中。用户可以通过查看日志文件,分析数据库和守护进程的运行状态、监控故障处理过程。
守护进程的状态转换如下图所示:
从图中可以看出,守护进程主要工作在 Startup 和 Open 状态,几乎任何状态都可以转到这两种状态,并且这两种状态之间也可以相互转换。
另外,当远程守护故障,任何状态都可转到 Error 状态。
监视器(dmmonitor)是基于监视器接口(详见 9.2 监视器接口)实现的一个命令行工具,是 DM 数据守护系统的重要组成部分。
通过监视器,可以监控数据守护系统的运行情况,获取主备库状态、守护进程状态以及主备库数据同步情况等信息。同时,监视器(dmmonitor)还提供了一系列命令来管理数据守护系统。
监视器的基本作用如下:
1、监控数据守护系统
接收守护进程发送的消息,显示主、备数据库状态变化,以及故障切换过程中,数据库模式、状态变化的完整过程。
2、管理数据守护系统
用户可以在监视器上输入命令,启动、停止守护进程的监控功能,执行主备库切换、备库故障接管等操作。
3、确认状态信息
用于故障自动切换的数据守护系统中,主、备库进行故障处理之前,需要通过监视器进行信息确认,确保对应的备库或者主库是真的产生异常了,避免主备库之间网络故障引发脑裂。
4、发起故障自动接管命令
用于故障自动切换的数据守护系统中,主库发生故障时,挑选符合接管条件的备库,并通知备库执行接管操作。
注意
对于实时主备和读写分离集群,监视器只允许配置一个守护进程组;MPP主备允许配置多组,并且要求这些组的主库必须是同一套MPP系统;
所有普通监视器都可以接收守护进程消息,获取守护系统状态,也可以执行各种监控命令。所有监视器都可以发起Switchover等命令,但守护进程一次只能接收一个监视器的命令,在一个监视器命令执行完成之前,守护进程收到其他监视器发起的请求,会直接报错返回。
确认监视器和普通监视器的区别在于,除了具备普通监视器所有功能之外,确认监视器还具有状态确认和自动接管两个功能。故障自动切换模式的数据守护系统,必须部署一个确认监视器,否则在出现数据库故障时,会导致数据库服务中断。
注意,状态确认和自动接管两个功能必须是故障自动切换模式数据守护系统。
监视器分为两种类型:普通监视器和确认监视器。监视器类型由配置文件(dmmonitor.ini)的 MON_DW_CONFIRM 参数来确定。MON_DW_CONFIRM 参数的默认值是 0,表示普通监视器;MON_DW_CONFIRM 参数值为 1 时,表示确认监视器。
用户可根据实际需要,选择是否配置监视器或配置多少个监视器。普通监视器和确认监视器可以在系统中同时存在,也可以只配置其中一种。故障自动切换模式下,必须配置确认监视器。
为了防止单实例确认监视器出现故障,建议用户将确认监视器配置多实例形式。
一个数据守护系统中,最多允许同时启动 10 个普通监视器。多个普通监视器之间的关系为相互独立,互不干扰。
所有普通监视器都可以接收守护进程消息,获取守护系统状态,也可以执行各种监控命令。所有监视器都可以发起 Switchover 等命令,但守护进程一次只能接收一个监视器的命令,在一个监视器命令执行完成之前,守护进程收到其他监视器发起的请求,会直接报错返回。
确认监视器和普通监视器的区别在于,除了具备普通监视器所有功能之外,确认监视器还具有状态确认和自动接管两个功能。在数据守护系统的故障自动切换模式下,必须部署一个确认监视器,否则在出现数据库故障时,会导致数据库服务中断。DM 提供了两种确认监视器的配置形式,分别为单实例和多实例。
一个数据守护集群中,最多只能配置一个确认监视器。
当单实例确认监视器故障时,无法继续进行集群的故障自动接管和备库故障确认,影响正常使用,故 DM 提供了多实例确认监控器来进一步提高集群的高可用性。
除了具备普通监视器的所有功能之外,单实例确认监视器具有状态确认和自动接管两个功能。相比于多实例确认监视器,单实例确认监视器出现故障就无法正常提供服务。
在使用主备多实例监视器的情况下,确认监视器可以配置多个,但是同时进行工作的确认监视器的mid必须配置为相同值,代表这些确认监视器属于同一个数据守护系统。
故障自动切换模式下,必须配置确认监视器,且确认监视器最多只能配置一个。
多实例确认监控器提供的功能与单实例确认监控器相同。
多实例确认监视器采用 RAFT 协议实现。在多实例确认监视器中,只有一个实例作为确认监视器提供服务,其它实例作为备库存在而不提供服务。当确认监视器出现故障时,系统会从它的备库中选举一位作为新的确认监视器继续提供服务。
多实例确认监视器系统中,每个实例配置一个dmmonitor.ini。多个dmmonitor.ini中,除MON_ID参数不同以外,其他参数应完全一致(实际上日志路径可以不一致)。
与配置单实例确认监视器相比,配置多实例监视器时组的配置信息不做更改,监视器实例的配置信息需要新增确认监视器特有的配置参数,通过组和实例的配置信息内容的不同来区分组和实例。
多实例监视器的话,只有leader身份的监视器才能执行监视器命令。
下文将从 RAFT 协议、多实例确认监视器中的各角色状态的作用和特点、多实例确认监视器中选举主监视器三个角度对多实例确认监视器进行详细的
更多相关资料请参考达梦云适配技术社区
达梦数据库 - 新一代大型通用关系型数据库 | 达梦在线服务平台