达梦数据库守护集群(主备)是应用场景非常广的数据库解决方案。如果能系统地了解其概念、原理,那么对更好维护达梦守护集群有所助益。
本文依次对达梦数据库守护集群(主备)主备架构、日志归档流程、守护进程、监视器类型、守护状态五个子主题进行相关总结、梳理和介绍,以便系统的了解达梦守护集群(主备)原理。
DM 数据守护(DM Data Watch)的实现原理非常简单:将主库(生产库)产生的 Redo 日志传输到备库,备库接收并重新应用 Redo 日志,从而实现备库与主库的数据同步。DM 数据守护的核心思想是监控数据库状态,获取主、备库数据同步情况,为 Redo 日志传输与重演过程中出现的各种异常情况提供一系列的解决方案。
DM 数据守护系统结构参考下图。主要由主库、备库、Redo 日志、Redo 日志传输、Redo 日志重演、MAL系统、守护进程(dmwatcher)、监视器(dmmonitor)组成。
主备架构图
Primary 模式,提供完整数据库服务的实例,一般来说主库是用来直接支撑应用系统的生产库。
Standby 模式,提供只读数据库服务的实例。备库除了用于容灾,还可以提供备份、查询等只读功能,并且备库还支持临时表的 Insert/Delete/Update 操作。
备库支持临时表修改主要基于两个因素:1.临时表数据的修改不会产生 Redo 日志,主库对临时表的修改无法同步到备库;2.可以提供更大灵活性,适应更多应用场景。
根据数据同步情况,备库又可以分为可切换备库和不可切换备库。可切换备库是指,主备库之间数据完全同步,主库发生故障、备库切换为主库后,不会造成任何数据丢失的备库。
Redo 日志记录物理数据页内容变动情况,是数据库十分重要的一个功能,在数据库系统故障(比如服务器掉电)重启时,利用 Redo 日志可以把数据恢复到故障前的状态。
Redo 日志也是数据守护的实现基础,数据库中 Insert、Delete、Update 等 DML 操作以及 Create TABLE 等 DDL 操作最终都会体现为对某一个或者多个物理数据页的修改,因此备库通过重做 Redo 日志可以与主库数据保持一致。
主备库之间的 Redo 日志传输,以日志包 RLOG_PKG 为单位,主库通过 MAL 系统发送 Redo 日志到备库。各种不同数据守护类型的区别,就在于主库日志包 RLOG_PKG 的发送时机,以及备库收到 Redo 日志后的处理策略。
Redo 日志重演的过程,就是备库收到主库发送的 Redo 日志后,在物理数据页上,重新修改数据的过程。Redo 日志重演由专门的 Redo 日志重演服务完成,重演服务严格按照 Redo 日志产生的先后顺序,解析 Redo 日志、修改相应的物理数据页,并且重演过程中备库会生成自身的 Redo 日志写入联机日志文件。
MAL 系统是基于 TCP 协议实现的一种内部通信机制,具有可靠、灵活、高效的特性。DM 通过 MAL 系统实现 Redo 日志传输,以及其他一些实例间的消息通讯。
守护进程(dmwatcher)是数据守护系统的核心工具:
1.监控数据库实例的运行状态和主备库数据同步情况,在出现故障时启动各种处理预案。
2.守护进程是各种消息的中转站,接收数据库实例、其他守护进程、以及监视器发送的各种消息;
3.同时,守护进程也会将收到的数据库实例消息转发给其他守护进程和监视器。守护进程必须和被守护的数据库实例部署在同一台机器上。
监视器的基本作用如下:
1.监控数据守护系统
接收守护进程发送的消息,显示主、备数据库状态变化,以及故障切换过程中,数据库模式、状态变化的完整过程。
2.管理数据守护系统
用户可以在监视器上输入命令,启动、停止守护进程的监控功能,执行主备库切换、备库故障接管等操作。
3.确认状态信息
用于故障自动切换的数据守护系统中,主、备库进行故障处理之前,需要通过监视器进行信息确认,确保对应的备库或者主库是真的产生异常了,避免主备库之间网络故障引发脑裂。
4.发起故障自动接管命令
用于故障自动切换的数据守护系统中,主库发生故障时,挑选符合接管条件的备库,并通知备库执行接管操作。
DM 支持 3 种数据库模式:Normal 模式、Primary 模式和 Standby 模式。
Normal 模式
提供正常的数据库服务,操作没有限制。正常生成本地归档,但不发送实时归档(Realtime)、即时归档(Timely)和异步归档(Async)。
Primary 模式
提供正常的数据库服务,操作有极少限制。该模式下部分功能受限,包括:不支持修改表空间文件名、不支持修改 arch_ini 参数。正常生成本地归档,支持实时归档(Realtime)、即时归档(Timely)和异步归档(Async)。Primary 模式下,对临时表空间以外的所有的数据库对象的修改操作都强制生成 Redo 日志。
Standby 模式
可以执行数据库备份、查询等只读数据库操作。正常生成本地归档,正常发送异步归档 Redo 日志;但实时归档(Realtime)、即时归档(Timely)均强制失效。该模式下时间触发器、事件触发器等都失效。
可以通过 SQL 语句切换数据库模式,模式切换必须在 Mount 状态下执行。切换模式 SQL 语句如下:
将数据库切换为 Primary 模式: ALTER DATABASE PRIMARY; 将数据库切换为 Standby 模式: ALTER DATABASE STANDBY; 将数据库切换为 Normal 模式: ALTER DATABASE NORMAL;
DM 的数据库状态包括:
Startup 状态
系统刚启动时设置为 Startup 状态。
After Redo 状态
系统启动过程中联机日志重做完成后,回滚活动事务前设置为 After Redo 状态。非 Standby 模式的实例在执行 alter database open 操作前,也会将系统设置为 After Redo 状态。
Open 状态
数据库处于正常提供服务的状态,但不能进行归档配置等操作。
Mount 状态
数据库在 Mount 状态下,不能修改数据,不能访问表、视图等数据库对象,但可以执行修改归档配置、控制文件和修改数据库模式等操作,也可以执行一些不修改数据库内容的操作,比如查询动态视图或者一些只读的系统过程。由于 Mount 状态不生成 PWR 日志,因此数据页可以正常刷盘,也正常推进检查点。
系统从 Open 状态切换为 Mount 状态时,会强制回滚所有活动事务,但不会强制清理(Purge)已提交事务,不会强制断开用户连接,也不会强制 Buffer 中的脏页刷盘。
Suspend 状态
数据库在 Suspend 状态下,可以访问数据库对象,甚至可以修改数据,但限制 Redo 日志刷盘,一旦执行 COMMIT 等触发 Redo 日志刷盘的操作时,当前操作将被挂起。
相比 Open 到 Mount 的状态切换,Open 到 Suspend 的状态切换更加简单、高效,不会回滚任何活动事务,在状态切换完成后,所有事务可以继续执行。
一般在修改归档状态之前将系统切换为 Suspend 状态,比如备库故障恢复后,在历史数据(归档日志)同步完成后,需要重新启用实时归档功能时:
- 将系统切换为 Suspend 状态,限制 Redo 日志写入联机 Redo 日志文件;
- 修改归档状态为 Valid;
- 重新将数据库切换为 Open 状态,恢复 Redo 日志写入功能;
- 备库与主库重新进入实时同步状态。
另外,实时归档失败时(比如网络故障导致),Primary 实例将试图切换成 Suspend 状态,防止后续的日志写入。因为一旦写入,主备切换时有可能备库没有收到最后那次的 RLOG_PKG,导致主库上多一段日志,很容易造成主备数据不一致。当实例成功切换为 SUSPEND 状态时,可直接退出,强制丢弃多余的日志,避免主备数据不一致。
Shutdown 状态
实例正常退出时设置为 Shutdown 状态。
不同的数据库转换如下图:
不同数据库状态之间的转换规则如图 2.2 所示。用户可以通过 SQL 语句进行数据库状态切换:1. Open 状态与 Mount 状态可以相互切换;2. Open 状态与 Suspend 状态可以相互切换;3. Mount 和 Suspend 状态不能直接转换;4. 其他状态为系统内部状态,用户不能主动干预。
将数据库修改为 Open 状态。当系统处于 Primary/Standby 模式时,必须强制加上 FORCE 子句。 ALTER DATABASE OPEN [FORCE]; 将数据库修改为 Mount 状态。 ALTER DATABASE MOUNT; 将数据库修改为 Suspend 状态。 ALTER DATABASE SUSPEND;
实时归档是实时主备数据同步的基础,其流程如下图所示:
1.主库生成联机 Redo 日志。
2.当触发日志写文件操作后,日志线程先将 RLOG_PKG 发送到备库。
3.备库接收后进行合法性校验(包括日志是否连续、备库状态是否 Open 等),不合
法则返回错误信息。
4.合法则作为 KEEP_RLOG_PKG 保留在内存中。
5.原有 KEEP_RLOG_PKG的 Redo 日志加入 Apply 任务队列进行 Redo 日志重演,并响应主库日志接收成功。当有多个备库时,主库需要收到所有备库的响应消息才继续后续操作。
实时主备系统由主库、实时备库、守护进程和监视器组成。通过部署实时主备系统,可以及时检测并处理各种硬件故障、数据库实例异常,确保持续提供数据库服务。
实时主备系统主要功能包括:
主备库通过实时归档完成数据同步,实时归档要求主库将 RLOG_PKG 发送到备库后,再将 RLOG_PKG 写入本地联机 Redo 日志文件。但要注意的是,备库确认收到主库发送的 Redo 日志,并不保证备库已经完成重演这些 Redo 日志,因此主备库之间的数据同步存在一定的时间差。
主备库正常运行过程中,可以通过监视器的 Switchover 命令,一键完成主备库角色转换。主备库切换功能可以确保在软、硬件升级,或系统维护时,提供不间断的数据库服务。
备库故障,不影响主库正常提供数据库服务,守护进程自动通知主库修改实时归档为 Invalid 状态,将实时备库失效。
备库故障恢复后,守护进程自动通知主库发送归档 Redo 日志,重新进行主备库数据同步。并在历史数据同步后,修改主库的实时归档状态为 Valid,恢复实时备库功能。
备库接管后,原主库故障恢复,守护进程自动修改原主库的模式为 Standby,并重新作为备库加入主备系统。
主库发生故障后,可以通过监视器的 Takeover 命令,将备库切换为主库,继续对外提供服务。如果配置为自动切换模式,确认监视器可以自动检测主库故障,并通知备库接管,这个过程不需要人工干预。
如果执行 Takeover 命令不成功,但主库可能由于硬件损坏等原因无法马上恢复,为了及时恢复数据库服务,DM 提供了 Takeover Force 命令,强制将备库切换为主库。但需要由用户确认主库故障前,主库与接管备库的数据是一致的(主库到备库的归档是 Valid 状态),避免引发守护进程组分裂。
在备库查询的实时性要求不高的条件下,实时主备也可以配置接口的读写分离属性访问,实现读写分离功能特性。
读写分离集群可以配置为即时归档,也可以配置为实时归档,这两种配置方式仅仅是归档流程上有差别,读写分离集群的特性仍然是一致的。即时归档流程与实时归档流程存在一定差异:
1. 主库先将日志写入本地联机 Redo 日志文件中,再发送 RLOG_PKG 到备库。
2. 备库日志重演时机有两种选择:
事务一致模式 要求备库在重演 Redo 日志完成后再响应主库。
高性能模式 与实时归档一样,收到 Redo 日志后,马上响应主库。
3. 即时归档的同步机制可以保证备库的 Redo 日志不会比主库的 Redo 日志多,因此
即时备库不需要 KEEP_RLOG_PKG,收到 RLOG_PKG 直接加入到 Apply 任务系统,启动
Redo 日志重演。
4. 备库故障或主备库之间网络故障,导致发送 RLOG_PKG 失败后,主库马上修改即
时归档为 Invalid 状态,并切换数据库为 Suspend 状态。
5. 即时归档修改为 Invalid 状态后,会强制断开对应此备库上存在影子会话的用户
会话,避免只读操作继续分发到该备库,导致查询数据不一致。
下面表格是各种归档类型比较,特别要注意红色框标注的【实时归档】和【即时归档】的归档时机、失败处理、备机响应时机,对这些原理要加深理解和认识,对守护集群日常维护极为重要。
本地归档、实时归档和即时归档均包含两种状态:Valid 和 Invalid。异步归档只有一种归档状态:Valid。而同步备库有三种归档状态,分别是 Valid,Invalid 和 Async_send。
在不同的归档类型中,归档状态转换时机不同。具体转换时机描述如下:
- 主备库启动后,主库到所有备库的归档默认为 Valid 状态,守护进程 Open 主库前,根据主备库日志同步情况,将数据不一致备库的归档修改为 Invalid 状态。
- 实时备库和即时备库故障恢复,从主库同步历史数据后,守护进程将主库修改为 Suspend 状态,并将主库到备库的归档状态从 Invalid 修改为 Valid。当守护进程再次 Open 主库后,主备库数据重新恢复为一致状态。
- 同步备库故障恢复,主库开始同步历史数据时,将备库归档状态从 Invalid 修改为 Async_send,中间会将日志刷盘线程挂起确保备库能够追到和主库数据完全一致,并将主库到备库的归档状态从 Async_send 修改为 Valid,然后唤醒日志刷盘线程,主备库数据重新恢复为一致状态。
- 主库发送日志到实时备库失败挂起,守护进程处理 Failover 过程中,将主库到备库的归档状态修改为 Invalid。
- 主库发送即时归档失败后,直接将主库到备库的归档改为 Invalid 状态。
- 主库发送同步归档失败后,直接将主库到备库的归档改为 Invalid 状态,并且不会有主库切换到 Suspend 状态的过程。
- 异步归档始终保持 Valid 状态,一旦归档失败马上返回,等待下一次触发再继续发送。
- 主库发现同步备库归档状态为 Invalid,且满足同步备库故障恢复的条件时,将主库到备库的归档状态从 Invalid 改为 Async_send,并开始同步历史数据到备库,同步完成后会将备库归档状态从 Async_send 修改为 Valid 有效状态。
守护进程是管理数据守护系统的核心部件,监视器(dmmonitor)负责发起命令,守护进程负责解析、处理、转发命令。守护进程提供了数据库监控、故障检测、故障处理、故障恢复等各种功能。
守护进程负责监控数据库运行状态,必要时重启数据库服务。守护进程和实例链路建立成功后,数据库实例定时发送信息到守护进程,发送到守护进程的内容包括:实例进程 ID、实例名、数据库模式、数据库状态、FILE_SEQ、FILE_LSN、CUR_SEQ、CUR_LSN、MAL 链路状态、归档状态、公钥、MPP 控制文件等信息。
守护进程更新本地记录的实例信息后,同时记录该时间戳。当检测到实例进程 ID 已经不存在或者超过一段时间没有收到实例消息(INST_ERROR_TIME),则会认定实例故障。如果配置了自动重启,则会将实例重新拉起。
守护进程将监控的数据库实例信息和守护进程自身的信息(包括守护类型、守护模式、守护状态、守护日志、监视器执行序列号、执行返回码等)捆绑在一起,定时发送给其他守护进程和所有监视器。
接收并解析其他守护进程发送的消息,如果超过一段时间(DW_ERROR_TIME)没有收到远程守护进程消息,会将远程守护进程状态认定为 ERROR 状态。另外还会结合本地数据库信息和守护进程自身状态,切换数据库的运行模式和系统状态。
注意
守护进程采用超时机制判断远程守护进程是否故障,即当前时间和上次收到消息的时间差是否超过故障认定时间(DW_ERROR_TIME),因此不建议在数据守护系统运行过程中调整操作系统时间,避免导致这个差值很大,误判远程守护进程故障。
监视器分为两种类型:普通监视器和确认监视器。监视器类型由配置文件(dmmonitor.ini)的 MON_DW_CONFIRM 参数来确定。MON_DW_CONFIRM 参数的默认值是 0,表示普通监视器;MON_DW_CONFIRM 参数值为 1 时,表示确认监视器。
用户可根据实际需要,选择是否配置监视器或配置多少个监视器。普通监视器和确认监视器可以在系统中同时存在,也可以只配置其中一种。故障自动切换模式下,必须配置确认监视器。
为了防止单实例确认监视器出现故障,建议用户将确认监视器配置多实例形式。
一个数据守护系统中,最多允许同时启动 10 个普通监视器。多个普通监视器之间的关系为相互独立,互不干扰。
所有普通监视器都可以接收守护进程消息,获取守护系统状态,也可以执行各种监控命令。所有监视器都可以发起 Switchover 等命令,但守护进程一次只能接收一个监视器的命令,在一个监视器命令执行完成之前,守护进程收到其他监视器发起的请求,会直接报错返回。
确认监视器和普通监视器的区别在于,除了具备普通监视器所有功能之外,确认监视器还具有状态确认和自动接管两个功能。在数据守护系统的故障自动切换模式下,必须部署一个确认监视器,否则在出现数据库故障时,会导致数据库服务中断。DM 提供了两种确认监视器的配置形式,分别为单实例和多实例。
一个数据守护集群中,最多只能配置一个确认监视器。
当单实例确认监视器故障时,无法继续进行集群的故障自动接管和备库故障确认,影响正常使用,故 DM 提供了多实例确认监控器来进一步提高集群的高可用性。
故障自动切换模式数据守护系统中,主库守护进程监测到备库故障时,需要向确认监视器求证,确认备库是真的故障了,再启动故障处理流程将归档失效,避免引发脑裂。比如,主库网络故障,主库直接将归档失效继续以 Primary 模式提供服务;同时,确认监视器认为主库故障,将备库切换为 Primary 模式,守护进程组中同时出现多个主库,引发脑裂。
状态确认只对故障自动切换数据守护系统有效,主库守护进程在满足一定条件时,会切换到 Confirm 状态,向确认监视器进行求证。
主库守护进程切换到 Confirm 之后,根据不同的场景决定是否切换为 Failover 状态并启动故障处理流程,这里列举出几种常见的场景处理(注意前提是主库的守护进程已经处于 Confirm 状态):
1.主库网络故障,主库到备库、主库到确认监视器的连接异常。这种情况下主库守护进程一直保持 Confirm 状态,不会启动故障处理流程。
2.备库故障或者备库网络故障,主库守护进程会切换为 Failover 状态,启动故障处理流程。
3.主备库之间网络故障,但与确认监视器之间的网络正常,确认监视器确认主库满足 Failover 执行条件,主库守护进程会切换为 Failover 状态,启动故障处理流程,否则主库守护进程一直保持在 Confirm 状态。
故障自动切换模式下,确认监视器检测到主库故障后,根据收到的主备库 LSN、归档状态、MAL 链路状态等信息,确定一个接管备库,并将其切换为主库。确认监视器启动自动接管流程的主要场景有三种,任何一种都会导致备库自动接管。场景如下:
1.主库数据库实例异常终止,主库守护进程正常。
2.主库硬件故障、或者数据库实例和守护进程同时故障。
3.主库网络故障,主备库之间、主库与监视器之间连接异常。
若想实现备库自动接管,主库、归档状态、备库都必须符合一定条件才行。条件如下:
- 主库
- 主库是 Primary 模式、Open 状态时,产生故障。(如图 4.2 左、中)
- 主库守护进程故障,故障前是 Open/Recovery 状态。(如图 4.2 中)
- 故障主库与接管备库和确认监视器之间的 MAL 链路断开。(如图 4.2 右)
- 归档状态
故障主库到接管备库的归档状态为 Valid。
- 备库
接管备库是 Standby 模式、Open 状态。
1. Help
显示帮助信息。
2. exit
退出监视器。
3. show version
显示监视器自身版本信息。
同一套数据守护系统中,服务器、守护进程和监视器要求中括号内的数据守护版本号必须一致,否则不能建立连接,各自的控制台工具上会打印版本不匹配信息。
4. show global info
数据守护系统中如果包含有多个 DMDSC 集群,通过监视器查看所有库的详细信息时,信息会过于庞杂,需要再逐个分割查找每个库的重点信息,比如状态是否 OK、是否发生分裂等信息。为了帮助用户更快捷地掌握整个守护系统的运行状态,此命令只打印出每个库的全局状态信息,不再详细打印每个节点实例信息,用户可借助 show database 命令查看指定库的详细状态信息。
此命令的显示结果中各字段含义说明如下:
1) 组全局字段信息
GROUP:守护进程组名。
OGUID:守护进程组配置的唯一 OGUID 值。
MON_CONFIRM:监视器是否配置为确认模式,值为 TRUE 或 FALSE。
MODE:当前配置的切换模式,AUTO 表示故障自动切换模式,MANUAL 表示故障手动切换模式。
MPP_FLAG:当前是否为 MPP 主备环境,值为 TRUE 或 FALSE。
2) 库全局字段信息
守护进程和监视器是以库为单位进行管理的,对有多个节点的 DMDSC 集群,看作是一个完整的库,以下信息属于库的全局信息,部分守护进程相关的信息直接取自控制守护进程。
IP:守护进程的 IP 地址,取自控制守护进程。
MAL_DW_PORT:守护进程的监听端口,取自控制守护进程。
WTIME:守护进程本地的当前时间,取自控制守护进程。
WTYPE:守护进程配置的守护类型,包括 LOCAL/GLOBAL 两种类型,取自控制守护进程。
WCTLSTAT:守护进程控制文件状态,包括 Valid/Split/Invalid 三种状态,对于配置为本地守护类型的实例,由于不需要有守护进程控制文件,该字段值为 NULL。
WSTATUS:守护进程状态,取自控制守护进程。
INAME:库名称,取自控制节点实例名。
N_EP:库的节点个数。
N_OK:此字段对 DMDSC 集群内的节点有效,表示 DMDSC 集群内 OK 节点个数。
ISTATUS:数据库状态,包括 Startup/After Redo/Mount/Open/Suspend/
Shutdown 这几种状态,由控制守护进程综合当前所有节点实例的状态得出。
IMODE:数据库模式,包括 Unknown/Normal/Primary/Standby 这四种模式,由控制守护进程综合当前所有节点实例的模式得出。
RTYPE:数据库配置的归档类型,只统计 REALTIME/TIMELY/SYNC 这三种归档类型,如果这三种归档都没有配置,则显示为 NONE。
RSTAT:此字段对备库有效,表示主库到备库的归档状态,可能为 Valid/Invalid/Async_send/Unknown,其中 Async_send 为同步备库特有的归档状态。对于除同步备库之外的本地守护类型备库,此字段为 NULL,对于主库本身,此字段值为 Valid。该字段值要从备库对应的主库实例上取,如果当前没有活动主库或者备库无法确认对应的主库,则该字段显示为 Unknown。
5. show database [group_name.]db_name
此命令用于详细显示指定库的相关状态信息。
各字段含义说明如下:
1) 库全局字段信息
和 show global info 命令中的库全局字段含义相同。
2) 各节点实例字段信息
INST_PORT:节点实例的监听端口。
INST_OK:控制守护进程认定的节点实例状态,OK 或 ERROR。
INAME:节点实例名称。
ISTATUS:节点实例状态,包括 Startup/After Redo/Mount/Open/Suspend/Shutdown 这几种状态。
IMODE:节点实例模式,包括 Normal/Primary/Standby 这三种模式。
DSC_STATUS:此字段对单节点可忽略,只对 DMDSC 集群内的节点有意义,表示节点当前的 DMDSC 集群状态。
DSC_SEQNO:此字段对单节点可忽略,只对 DMDSC 集群内的节点有意义,表示节点在 DMDSC 集群内的序号。
DSC_CONTROL_NODE:此字段对单节点可忽略,只对 DMDSC 集群内的节点有意义,表示 DMDSC 集群内控制节点的序号。
RTYPE:节点实例配置的归档类型,只统计 REALTIME/TIMELY/SYNC 这三种归档类型,如果这三种归档都没有配置,则显示为 NONE。
RSTAT:此字段对备库控制节点有效,表示主库到备库控制节点的归档状态,可能为 Valid/Invalid/Async_send/Unknown,其中 Async_send 为同步备库特有的归档状态。对于除同步备库之外的本地守护类型备库,此字段为 NULL,对于主库本身,此字段值为 Valid。该字段值要从备库对应的主库实例上取,如果当前没有活动主库或者备库无法确认对应的主库,则该字段显示为 Unknown。
FSEQ:节点实例已经写入联机日志的 RLOG_PKG 包序号。
FLSN:节点实例的文件 LSN,指已经写入联机日志文件的最大 LSN 值。
CSEQ:节点实例的系统当前 PKG_SEQNO,指当前数据库最新产生的 RLOG_PKG 包的序号。
CLSN:节点实例的系统当前 LSN,指当前数据库最新产生的 LSN 值。
DW_STAT_FLAG:节点当前的执行标记。
如果是备库模式,show 命令还会显示备库控制节点当前的重演信息,重演信息的行数和产生日志的主库节点个数一致,可以查看备库对主库不同节点日志的重演情况。
EDOS_PARALLEL_NUM: 备库并行重演线程数。
DSC_SEQNO:主库节点序号。
SSEQ:备库可重演到的最大日志包序号。
SLSN:备库可重演到的最大 LSN,对应日志包序号为 STDBY_PKG_SEQNO。
KSEQ:非自动切换模式下,备库保持不重演的日志包序号。
KLSN:非自动切换模式下,备库保持不重演最大 LSN,对应的日志包序号为 KSEQ。
RSEQ:备库针对主库此节点已经重演到的日志包序号。
RLSN:备库针对主库此节点已经重演到的 LSN 值,对应的日志包序号为 RSEQ。
N_TSK:备库针对主库此节点的待重演任务个数。
TSK_MEM_USE:备库当前针对主库此节点的日志重演已经占用的内存大小(单位:字节)。
REDO_LSN_ARR: 备库各路并行重演线程已重演到的 LSN 值,数组中每个元素对应一路重演 LSN。
ARCH_SEND_UNTIL_TIME:备库针对主库此节点重演到的截止时间。
6. show [group_name]
如果指定 group_name,则显示指定组中所有库的详细状态信息,如果没有指定,则显示所有组中所有库的详细状态信息。
show 命令由下面几种信息组成:
- 组全局字段信息
- 库全局字段信息
- 各节点实例字段信息
也就是 show global info 和 show database 命令的整合,各字段含义可参考这两个命令中的含义说明。
7. show i[nterval] n
在 dmmonitor 工具界面上定时每隔 n 秒自动显示所有组中所有库的详细状态信息,相当于每隔 n 秒自动执行一次 show 命令,n 取值范围为 5~3600(s),相关字段含义可参考 show [group_name] 命令说明。
如果在工具界面上手动执行其他命令,则会自动取消定时显示功能。
8. q
取消 show i[nterval] n 命令设置的自动显示功能。
9. list [[group_name.]db_name]
此命令列出指定组中指定实例的守护进程配置信息,只有一组时允许不指定 group_name,如果组名和库名都没有指定,则显示所有守护进程的配置信息。
list 命令显示的字段和 dmwatcher.ini 的配置内容完全一致,可参考 5.4dmwatcher.ini 配置表格的各个字段说明。
如果守护进程守护的是 DMDSC 集群,list 命令会额外显示 dmdcr.ini 中配置的 DMDCR_ASM_RESTART_INTERVAL 和 DMDCR_DB_RESTART_INTERVAL 参数值,在监视器中对应显示为 CSS_ASM_RESTART_INTERVAL 和 CSS_DB_RESTART_INTERVAL,方便用户查看 dmcss 的自动拉起配置情况。
10. show open info [group_name.]db_name
此命令显示指定库的 INST_NAME、N_ITEM、CTL_STATUS 以及 DESC。只有一组时,此命令允许不指定 group_name。
INST_NAME:守护的数据库名称。
N_ITEM:Open 历史信息记录数。Open 历史信息记录最多只记录 128 项,写满 128 项后从第一项记录覆盖起,循环写入。Open 历史信息只有 Primary 和 Normal 模式的库 Open 时才主动写入。
CTL_STATUS:控制文件状态,包括 Valid/Split/Invalid 三种状态。
DESC:本地分裂库的描述信息,如果是有效状态,描述信息为空。
Open 历史信息包括 TGUID、ROWID、OPEN_TIME、SYS_MODE、PRI_INST_NAME、CUR_INST_NAME、PRI_DB_MAGIC、CUR_DB_MAGIC、N_EP、RSEQ_ARR 以及 RLSN_ARR,具体含义如下:
TGUID:Open 记录唯一标识。
ROWID:对应 SYSOPENHISTORY 中记录的 rowid。
OPEN_TIME:Open 的时间。
SYS_MODE:系统 Open 时所处的模式。
PRI_INST_NAME:对应主库的实例名。
CUR_INST_NAME:当前主库的实例名。
N_EP:数据库节点实例个数。非 DSC 环境,实例个数为 1。
RSEQ_ARR:已经写入联机日志的日志包序号,数组长度为 N_EP。
RLSN_ARR:已经重演的日志包序号,数组长度为 N_EP。
11. show monitor [group_name[.]] [db_name]
列出连接到指定库控制守护进程的所有监视器信息。
对于 group_name,在配置有多组时需要指定,否则可以不指定。对于 db_name,如果指定,则显示指定实例守护进程上的连接信息,如果没有指定,则根据 dmmonitor.ini 对应组中的配置顺序,显示第一个活动的守护进程上的监视器连接信息。如果 group_name 和 db_name 同时指定,则需要用“.”符号分隔。
同一个守护系统中允许最多 10 个监视器同时连接,可通过此命令获取指定守护进程上监视器连接信息,包括连接时间、确认监视器配置、监视器 ID、监视器 IP 和版本信息。显示的第一行结果为本地监视器的连接信息。
命令显示结果的字段说明如下:
DW_CONN_TIME:守护进程和监视器建立连接的时间。
MON_CONFIRM:监视器是否配置为确认模式。
MID:唯一标识监视器的 ID 值。监视器从启动到退出,MID 值保持不变。每次执行操作,监视器会把 MID 设置到所有的守护进程上,操作执行完,会清理掉所有守护进程上的 MID 值。守护进程每隔 5s 会检查一次,如果监视器已经退出,会自行清理掉自己保存的 MID 值。
MON_IP:监视器所在机器的 IP 地址。
MON_VERSION:监视器版本信息,如果监视器和守护进程版本不一致,则不允许建立连接。
12. tip
打印当前守护系统的运行状态。
检查库状态、库的守护进程状态、库的分裂信息、库的可加入信息、是否存在多个主库以及 MPP 环境下 dmmpp.ctl 是否处于一致状态等系统信息,并打印检查结果。
13. login[/@service_name]
监视器优先选择主库校验登录口令,如果没有活动主库,则选择一个活动备库校验登录口令,部分监视器命令需要先登录才允许执行。
login 命令有如下两种登录方式:
1)交互式登录
直接输入 login。不指定/@service_name,并且 login 命令之后不能有除空格外的其它字符。按照此方式输入命令后,监视器会逐步提示用户输入用户名和口令。登录口令和服务器的用户登录口令一致,且该用户必须有 SYSDBA 权限,默认使用 SYSDBA/SYSDBA。
2)wallet 方式登录
输入 login/@service_name,其中”/@”为固定用法,service_name 为服务名。监视器会到 dmmonitor.ini 中配置的 MON_WALLET_LOCATION 路径下读取 wallet 文件,并根据 service_name 到 wallet 文件中寻找对应的用户名和口令登录监视器。 服务名最长为 128 字节,若输入长度超过限定长度,则登录失败并显示错误信息。
使用 wallet 方式登录之前,用户需要先使用 dmmkstore 工具创建好 wallet 文件,并完成配置对应的服务名、用户名和口令,然后将该文件拷贝到 MON_WALLET_LOCATION 路径下,才能使用该功能。service_name 指定的服务对应的用户需要有 SYSDBA 权限,并且登录口令也要与该用户在服务器上配置的口令一致,才能成功登录监视器。
14. logout
退出登录。
15. get takeover time [group_name]
如果在主库正常退出时,配置了备库自动接管需要等待的时间(MON_TAKEOVER_SHUTDOWN),则可通过该命令打印备库自动接管仍需等待的剩余时间,若主备库状态正常,则打印无自动接管实例。
16. show state
显示当前监视器所在监视器配置组的所有监视器的状态(监视器角色)等信息。
相关字段含义如下:
MON_BRO_INTERVAL:监视器实际广播超时。
MON_VOTE_INTERVAL: 监视器实际选举超时。
MON_NAME: 监视器名。
MON_STATE: 监视器状态(相对于当前监视器)。
ID: 监视器在系统中的 ID。
MON_ROLE: 监视器当前角色(显示当前监视器所知的内容)。
MON_IP: 监视器 IP。
MON_PORT: 监视器 PORT。
17. startup dmwatcher database [group_name.]db_name
打开指定库的守护进程监控功能,只有一个组的情况下,可以不指定 group_name。
此命令是指在指定库的守护进程处于 Shutdown 状态时,将其切换至 Startup 状态,恢复守护进程的监控功能,而不是启动守护程序。如果守护进程不是处于 Shutdown 状态,则跳过不执行。
另外切换至 Startup 状态后,守护进程可能会根据本地或远程库状态信息自动做一些状态切换处理,不一定会一直保持在 Startup 状态。
18. startup dmwatcher [group_name]
启动指定组的所有守护进程监控功能,只有一组的情况下,可以不指定 group_name。
此命令是指在守护进程处于 Shutdown 状态时,将其切换至 Startup 状态,恢复守护进程的监控功能,而不是启动守护程序。如果守护进程不是处于 Shutdown 状态,则跳过不执行。
另外切换至 Startup 状态后,守护进程可能会根据本地或远程库状态信息自动做一些状态切换处理,不一定会一直保持在 Startup 状态。
19. stop dmwatcher database[group_name.]db_name
关闭指定库的守护进程监控功能,只有一组的情况下,可以不指定 group_name。执行此命令需要先登录监视器。
此命令只是将指定库的守护进程切换为 Shutdown 状态,并不会退出守护进程,守护进程切换至 Shutdown 状态后,不会再自动处理故障,也不会自动启动实例,但仍然能够正常接收、发送消息,监视器仍然能够监控到最新的实例状态。
如果本地守护的是 DMDSC 集群,此命令只会将控制守护进程切换为 Shutdown 状态,不会修改普通守护进程状态。
20. stop dmwatcher [group_name]
关闭指定组的所有守护进程监控功能,只有一组的情况下,可以不指定 group_name。执行此命令需要先登录监视器。
此命令只是将守护进程切换为 Shutdown 状态,并不会退出守护进程,守护进程切换至 Shutdown 状态后,不会再自动处理故障,也不会自动启动实例,但仍然能够正常接收、发送消息,监视器仍然能够监控到最新的实例状态。
如果本地守护的是 DMDSC 集群,此命令只会将控制守护进程切换为 Shutdown 状态,不会修改普通守护进程状态。
21. startup group [group_name]
启动指定组中的所有节点实例,只有一组的情况下,可以不指定 group_name。
如果守护进程的监控功能被关闭,处于 Shutdown 状态,在通知实例启动之前,会先打开守护进程的监控功能,再通知守护进程启动实例。对 DMDSC 集群,如果组内 dmcss 的自动拉起功能是关闭的,在各节点实例拉起成功后,会将其打开。
守护系统正常运行时,同一个守护进程组中,只有一个主库,其他的都是备库。
主库处于 Open 状态,主库守护进程也处于 Open 状态,本地没有守护进程控制文件,其内存值是 Valid 有效状态。
所有备库也处于 Open 状态,所有备库守护进程处于 Open 状态,本地没有守护进程控制文件,其内存值是 Valid 有效状态。
主库到所有备库的归档也都处于 Valid 有效状态。
MPP 主备系统中,所有主库的 dmmpp.ctl 都处于一致状态。
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之前,不会在备库上创建数据库连接,只读操作也无法分流到对应的备库。
正常情况下,守护进程 dmwatcher 可以自动 Open 数据库实例,但某些情况下(比如备库硬件故障无法启动),数据守护系统不满足 6.2 介绍的启动条件,我们可以通过监视器执行 Open database 命令强制 Open 数据库实例。主备库都可以强制 Open,其执行流程如下:
假设需要强制 Open 数据库 A,只需要启动一个监视器,登录后输入 Open database A 即可完成强制启动。
如果数据库 A 是 Standby 模式,强制 Open 的执行流程如下:
- 通知 A 的守护进程切换为 Open Force 状态
- 通知 A 执行 Open 操作
- 通知守护进程切换 Open 状态
如果数据库 A 是 Primary 模式,强制 Open 的执行流程如下:
- 通知 A 的守护进程切换为 Open Force 状态
- 修改 A 到所有归档目标的实时归档/即时归档状态为无效
- 通知 A 执行 Open 操作
- 通知守护进程切换 Open 状态
Primary 模式数据库实例切换为 Open 状态时,需要回滚活动事务、Purge 已提交事务,并重构回滚段,会引发数据变化、LSN 增长。因此,这个操作可能会引发守护进程组分裂,比如下面的场景:
- 主库 A 故障
- 备库 B 接管,成为主库
- B 故障
- A 重启,并强制 Open
- A 和 B 数据不一致,并且无法恢复到一致状态。此时,B 重启,就会产生守护进程组分裂。
注意
强制Open主库前,会设置主库到所有归档目标的实时归档/即时归档为Invalid状态。
强制 Open 主库命令,会修改主库守护进程 INST_RECOVER_TIME 内存值为 3 秒(默认 60 秒),确保主库 Open 后,尽快启动故障恢复流程,同步主库数据完成后,重新将归档设置为 Valid 状态。
如果在故障恢复流程完成之前,主库故障,将无法执行备库接管;备库强制接管会引发守护进程组分裂。
关闭守护系统时,必须按照一定的顺序来关闭守护进程和数据库实例。特别是自动切换模式,如果退出守护进程或主备库的顺序不正确,可能会引起主备切换,甚至造成守护进程组分裂。
通过监视器执行 Stop Group 命令关闭数据守护系统,是最简单、安全的方式。命令执行成功后,数据库实例正常关闭。但守护进程并没有真正退出,而是将状态切换为 Shutdown 状态。
Stop Group 命令内部流程如下:
- 通知守护进程切换为 Shutdown 状态
- 通知主库退出
- 通知其他备库退出
如果使用手动方式关闭数据守护系统,请严格按照以下顺序执行:
- 如果启动了确认监视器,先关闭确认监视器(防止自动接管)
- 关闭备库守护进程(防止重启实例)
- 关闭主库守护进程(防止重启实例)
- Shutdown 主库
- Shutdown 备库
如果是只关闭主库,并且不想引发备库自动接管,有以下两种方法:
方法一:
1.通过 Detach database 命令将所有备库分离
2.通过 Stop database 命令退出主库
方法二:严格按照以下顺序执行:
- 通过 Stop dmwatcher 命令关闭所有守护进程监控
- 手动正常退出主库
如果是只关闭备库,并且不想引发主库发送日志失败进入 Suspend 状态,请严格按照以下顺序执行:
- 通过 Detach database 命令将备库分离出数据守护系统
- 正常退出备库(手动退出或者通过 Stop database 命令退出)
注意
关闭整个数据守护系统时,先关闭主库再关闭备库,顺序一定不能错。对于本地守护类型的库,在关闭数据守护系统时,不受此顺序限制。
因为主库 Shutdown 过程中,需要 Purge 所有已提交事务,会修改数据,并产生 Redo 日志。如果先 Shutdown 备库,会导致主库发送归档日志失败,并且由于主库已经处于 Shutdown 状态,会导致主库异常关闭。
当正常关闭数据守护系统后,可以将守护系统主备库都升级到新版本然后正常启动数据守护系统以达到升级整个数据守护系统版本的目的。如果需要不中断数据库服务升级数据守护系统,可使用滚动升级功能。
升级版本后重新启动数据守护系统时,由于升级过程中可能涉及系统表、动态视图等的修改,需要在主库版本升级后将升级过程中的 Redo 日志发送到备库,备库通过重做这段 Redo 日志进行版本升级。在此过程中,不允许对备库进行访问,否则会报“备库版本升级时不允许访问”的错误。Redo 日志重做完成后,备库允许正常访问。
主库维护,滚动升级等场景,可以执行 Switchover 命令,实现主备库切换。如果存在多个备库,需要先执行 Choose
Switchover 命令,选出守护进程组中可以切换的备库。
Choose Switchover 命令选择可切换备库的条件如下:
- 主库守护进程是 Open 状态
- 备库守护进程是 Open 状态
- 主、备库的 OPEN 记录项内容相同,并且守护进程控制文件是 Valid 有效状态(内存值)
- 主库正常运行
- 备库正常运行
- 主库处于 Open 状态
- 备库处于 Open 状态
- 主库到备库的归档是 Valid 状态
假定选出的可切换备库是 B,Switchover 切换流程如下:
- 通知主备库守护进程,切换为 Switchover 状态
- 通知主库(A) Mount
- 实时或 MPP 主备环境下,通知备库(B) APPLY KEEP_RLOG_PKG
- 通知备库(B) Mount
- 通知(A) 切换为 Standby 模式
- MPP 主备环境下,通知(A)修改 MPP_INI 内存值为 0
- 通知(B) 切换为 Primary 模式
- 通知(B) 修改所有归档目标的归档状态为无效
- MPP 主备需要通知各组活动主库更新 dmmpp.ctl 文件,参考后文说明
- 通知新的备库(A) Open
- 通知新的主库(B) Open
- 通知主备库守护进程切换为 Open 状态
- 清理所有守护进程上记录的监视器命令执行信息
其 cmmpp.ctl 步骤说明如下:
主库收集条件:
1)组中只有一个活动主库,不存在多个 OPEN 主库
2)主库守护进程不是 Error 状态,且控制文件是有效状态
3)主库实例不是 Error 状态
首先通知执行 Switchover 命令的守护进程组的主库执行更新操作,再通知其他组的主库执行更新操作。通知其他组执行更新操作时,会先将其主库的守护进程切换为 Mppctl update 状态,更新完成后,再切换回 Open 状态。
对步骤 1 中不符合收集条件的组,在步骤 2 中跳过不再处理,后续待其主库恢复正常后,可借助 recover mppctl 命令恢复 dmmpp.ctl 文件到一致状态。
更新 MPP 控制文件时,服务器自动断开当前所有的会话连接,回滚未提交事务,挂起所有工作线程,该过程可能会持续一段时间。
步骤 2 中如果某个活动主库更新失败,则终止切换,执行失败。
注意
主备库切换在实现逻辑上等同于主备库正常状态下用户主动发起的Takeover 操作。Swithover完成后,主备库之间数据是不完全同步的,要由新主库B的守护进程通过Recovery流程,重新同步数据到新备库A。
Switchover命令会修改切换后主库守护进程INST_RECOVER_TIME内存值为3秒(默认60秒),确保尽快启动故障恢复流程,同步主库数据完成后,重新将归档设置为Valid状态。在故障恢复流程完成之前,再次执行Switchover命令会报错,如果主库故障,备库接管将会报错;备库强制接管会引发守护进程组分裂。
主库在切换时会先被设置为Mount状态和Standby模式,此时若主库上的已有连接执行操作,可能会触发-510(系统处于MOUNT状态)或-710(试图在STANDBY模式下,修改用户库)报错。
当出现硬件故障(掉电、存储损坏等)原因导致主库无法启动,或者是主库内部网卡故障导致主库短期不能恢复正常的情况下,可使用备库接管功能,将备库切换为主库继续对外服务。
故障自动切换模式下,确认监视器会自动选择符合条件的备库进行接管。
故障手动切换模式下,可以先在监视器上执行 Choose Takeover 命令,选出守护进程组中可以接管的备库。
为了避免备库接管后,造成守护进程组分裂,执行 Takeover 必须满足下列条件:
- 主库是 Primary 模式、Open 状态时,发生故障
- 主库守护进程故障,故障前是 Open/Recovery 状态;或者主库守护进程正常
- 主库故障前到接管备库的归档状态为 Valid
- 接管备库是 Standby 模式、Open 状态
- 接管备库的守护进程控制文件状态为 Valid(内存值)
- 故障主库和接管备库的 Open 记录项内容相同
假设主库 A 故障时,在故障自动切换模式下确认监视器自动选出待接管备库 B 并通知备库 B 自动接管,或者在故障手动切换模式下,通过监视器上的 Choose
Takeover 命令,选出待接管备库 B,在监视器上输入 Takeover 命令通知备库 B 执行接管,这两种方式的接管执行流程是一样的。
以备库 B 为例,接管的执行流程包括:
- 监视器通知守护进程(B)切换为 Takeover 状态
- 实时主备或 MPP 主备环境下,通知备库(B) APPLY KEEP_RLOG_PKG
- 通知备库(B) Mount
- 通知(B) 切换为 Primary 模式
- 通知(B) 修改到所有归档目标的归档状态为 Invalid
- MPP 主备需要通知活动主库更新 dmmpp.ctl 文件(步骤参考[6.5 主备库切换](#6.5 主备库切换))
- 通知新的主库(B) Open
- 通知守护进程(B)切换为 Open 状态
注意
例如,主库C故障,备库B接管。执行Takeover命令后,会修改守护进程(B)的INST_RECOVER_TIME内存值为3秒(默认60秒),确保尽快启动B->C的故障恢复流程,同步主库数据完成后,重新将B->C的归档设置为Valid状态。在故障恢复流程完成之前,主库(B)故障,备库(C)无法接管;强制备库(C)接管会引发守护进程组分裂。
有些情况下,备库接管会失败,但主库不能启动或者及时恢复对外服务的情况下,可以使用 Takeover Force 命令,进行备库强制接管。强制接管具有一定的风险,可能导致备库和故障主库数据不一致,而造成部分数据的丢失,出现数据库分裂的情况,所以应该慎重使用。
例如主库和守护进程故障时,监视器未启动,用户启动监视器后,由于监视器并未收到故障主库任何信息,因此不满足 Takeover 条件,执行 Takeover 会报错。如果用户可确认主库故障时主备数据是一致的(如故障时主库未执行操作,主备库归档有效的,并且两者的 LSN 一致)、或者丢失小部分数据的影响可忽略、或者丢失小部分数据的影响小于主库持续宕机造成的影响,则可以考虑执行 takeover force 强制接管。
强制接管,先通过 Choose Takeover Force 选出符合强制接管条件的备库,再执行 Takeover Force 命令。备库强制接管时,如果接管备库是处于 Mount 状态/Standby 模式的库,则会自动 Open 备库,其他执行流程与备库接管一致。强制接管的条件包括:
- 不存在活动主库
- 备库守护进程处于 Open 或 Startup 状态
- 备库实例运行正常
- 备库是 Standby 模式
- 备库处于 Open 或 Mount 状态
- 备库的 KLSN 必须是所有备库中最大的
- 备库守护进程控制文件必须有效
注意
与Takeover命令一样,Takeover Force命令会修改主库守护进程的INST_RECOVER_TIME内存值为3秒(默认60秒),确保尽快启动故障恢复流程。
强制接管具有一定的风险,可能导致备库和故障主库数据不一致,从而造成部分数据的丢失、数据库分裂,所以应该综合考虑当时情况,慎重使用。 对于强制接管并且引发分裂的场景,故障主库重启恢复后,只有当新接管的主库处于 Primary & Open,并且实例是活动情况下,才会主动设置原来的主库为 Split 分裂状态。如果新接管主库也被重启到 Mount 状态,由于两个主库互相不可加入,守护进程无法在两个 Mount 主库之间选出有效主库,需要用户干预。
主库故障后立即重启,此时主库的守护进程变成 Startup 状态,重新进入守护进程的启动流程,将数据一致的备库归档设置为有效状态,其余备库归档设置成无效状态,并重新 Open 主库。Open 成功后继续作为主库,当检测到归档状态无效的备库正常时会启动 Recovery 处理流程,重新同步主备库数据。
备库产生故障(硬件故障或者内部网卡故障)时,主库的处理流程对手动切换、自动切换模式处理上有些差异。
对于手动切换模式,检测到备库故障,满足 Failover 条件时,主库的守护进程立即切换到 Failover 状态,执行对应的故障处理,如果不满足切换 Failover 条件,则保持当前状态不变。
手动切换模式下,主库守护进程切换 Failover 条件:
- 备库实例故障,或者主备库之间出现网络故障,或者备库重演时校验 LSN 不匹配,这三种场景下引发主库同步日志到备库失败挂起,主库实例处于 Suspend 状态
- 主库到此备库的归档状态是 Valid(读写分离集群没有此限制)
- 主库的守护进程处于 Startup、Open 或 Recovery 状态
- 当前没有监视器命令正在执行
对于自动切换模式,主库的守护进程会自动判断切换到 Failover 状态或者 Confirm 确认状态,如果两种状态切换条件都不满足,则保持当前状态不变。
自动切换模式下,主库守护进程不进入 Confirm 确认状态,直接切换到 Failover 条件:
- 前四项条件,和上面列出的手动切换条件相同
- 备库实例故障,备库守护进程正常
如果只满足条件 1,不满足条件 2,则主库守护进程会先进入 Confirm 确认状态,等待确认监视器的确认消息。主库的守护进程进入 Confirm 确认状态后,会有下面几种不同的处理:
主库的守护进程收到了确认监视器返回的确认消息,如果确认监视器认定可以执行 Failover,则主库的守护进程会切换为 Failover 状态并执行对应的处理;如果确认监视器认定不满足执行 Failover 条件,则主库的守护进程会一直保持在 Confirm 状态。确认监视器认定主库可以执行 Failover 条件:
- 主库守护进程处于 Confirm 状态
- 主库实例正常,处于 Suspend 状态
- 主库没有被接管,不存在其他主库
- 没有 takeover/switchover 命令在执行
- 当前所有归档有效的备库均可以加入主库
- 主库和确认监视器之间网络连接异常,或者没有启动确认监视器。满足下面条件后主库允许切换至 Failover 状态执行故障处理:
- 主库实例正常,处于 Suspend 状态
- 备库守护进程正常
- 主库没有被接管,不存在其他主库
- 没有 takeover/switchover 命令正在执行
- 备库故障前可以加入主库
- 主库和确认监视器网络恢复正常后,主库已经被接管。老主库的守护进程切换为 Startup 状态,重新判断是否可加入新主库。
主库守护进程进入 Failover 状态后的执行流程(自动或手动切换模式下执行流程相同):
- 对实时主备或 MPP 主备,通知主库修改发送归档失败的备库归档状态无效
- 通知主库重新 Open。
- 将主库的守护进程切换为 Open 状态。
通过上面相对系统的介绍,希望大家对达梦守护集群(主备)架构、相关概念、归档日志流程、相关组件功能和作用,尤其是守护状态涉及的多个场景的工作逻辑认识。这样才能更深入理解该架构其背后设计逻辑的严谨思考,由此带来更好数据库解决方案及更好用户体验。
关于达梦数据库更多学习内容,欢迎访问达梦社区:
https://eco.dameng.com