DM 数据守护与读写分离集群

更多细节详见官方文档

一、引言

  • DM 数据守护(Data Watch)是一种集成化的高可用、高性能数据库解决方案,是数据库异地容灾的首选方案。
  • 通过部署 DM 数据守护,可以在硬件故障(如磁盘损坏)、自然灾害(地震、火灾)等极端情况下,避免数据损坏、丢失,保障数据安全,并且可以快速恢复数据库服务,满足用户不间断提供数据库服务的要求。
  • 与常规的数据库备份(Backup)、还原(Restore)技术相比,数据守护可以更快地恢复数据库服务
  • 随着数据规模不断增长,通过还原手段恢复数据,往往需要数个小时、甚至更长时间,而数据守护基本不受数据规模的影响,只需数秒时间就可以将备库切换为主库对外提供数据库服务。
  • DM数据守护提供多种解决方案,可以配置成实时主备、MPP主备、DMDSC主备或读写分离集群,满足用户关于系统可用性、数据安全性、性能等方面的综合需求,有效降低总体投入,获得超值的投资回报。
  • 实时主备由一个主库以及一个或者多个配置了实时(Realtime)归档的备库组成,其主要目的是保障数据库可用性,提高数据安全性。实时主备系统中,主库提供完整的数据库功能,备库提供只读服务。主库修改数据产生的Redo日志,通过实时归档机制,在写入联机Redo日志文件之前发送到备库,实时备库通过重演Redo日志与主库保持数据同步。当主库出现故障时,备库在将所有Redo日志重演结束后,就可以切换为主库对外提供数据库服务。
  • MPP主备就是在MPP集群的基础上,为每一个MPP节点配置一套实时主备系统,这些实时主备系统一起构成了MPP主备系统。我们将一个MPP节点对应的主备系统称为一个数据守护组(Group),MPP主备系统中各个数据守护组保持相对独立,当某个MPP主节点出现故障时,在其对应的数据守护组内挑选一个备库切换为主库后,就可以确保整个MPP集群的正常使用。
  • DMDSC主备与单节点主备功能一致,DMDSC主备支持DMDSC集群和单节点之间互为主备库,一般建议将DMDSC集群部署为主库,将单节点部署为备库。当DMDSC集群为主库时,DMDSC集群控制节点收集所有节点的Redo日志发送到备库,备库严格按照各节点修改数据页的先后顺序重演Redo日志保持数据同步;当DMDSC集群为备库时,主库将Redo日志发送至DMDSC集群控制节点,DMDSC集群控制节点重演Redo日志保持数据同步。
  • 读写分离集群由一个主库以及一个或者多个配置了即时(Timely)归档或实时(Realtime)归档的备库组成,其主要目标是在保障数据库可用性基础上,实现读、写操作的自动分离,进一步提升数据库的业务支撑能力。读写分离集群通过配置事务一致模式保证主、备库数据一致性,并配合达梦数据库管理系统的各种接口(JDBC、DPI等),将只读操作自动分流到备库,有效降低主库的负载,提升系统吞吐量。

二、概述

  • DM 数据守护(DM Data Watch)的实现原理非常简单:将主库(生产库)产生的 Redo日志传输到备库,备库接收并重新应用 Redo 日志,从而实现备库与主库的数据同步。

  • DM数据守护的核心思想是:监控数据库状态,获取主、备库数据同步情况,为 Redo 日志传输与重演过程中出现的各种异常情况提供一系列的解决方案。
    在这里插入图片描述

  • DM 数据守护系统结构图 ,主要由主库、备库、Redo 日志、Redo 日志传输、Redo 日志重演、守护进程(dmwatcher)、监视器(dmmonitor)组成。
    数据库与数据库实例
    数据库(Database)是一个文件集合(包括数据文件、临时文件、重做日志文件和控制文件),保存在物理磁盘或文件系统中。
    数据库实例(Instance)就是一组操作系统进程(或者是一个多线程的进程)以及一些内存。通过数据库实例,可以操作数据库,一般情况下,我们访问、修改数据库都是通过数据库实例来完成的。
    主库
    Primary 模式,提供完整数据库服务的实例,一般来说主库是用来直接支撑应用系统的生产库。
    备库
    Standby 模式,提供只读数据库服务的实例。备库除了用于容灾,还可以提供备份、查询等只读功能,并且备库还支持临时表的 Insert/Delete/Update 操作。
    备库支持临时表修改主要基于两个因素:1.临时表数据的修改不会产生 Redo 日志,主库对临时表的修改无法同步到备库;2.可以提供更大灵活性,适应更多应用场景。
    根据数据同步情况,备库又可以分为可切换备库不可切换备库。可切换备库是指,主备库之间数据完全同步,主库发生故障、备库切换为主库后,不会造成任何数据丢失的备库。
    Redo日志
    Redo 日志记录物理数据页内容变动情况,是数据库十分重要的一个功能,在数据库系统故障(比如服务器掉电)重启时,利用 Redo 日志可以把数据恢复到故障前的状态。
    Redo 日志也是数据守护的实现基础,数据库中 Insert、Delete、Update 等 DML 操作以及 Create TABLE 等 DDL 操作最终都会体现为对某一个或者多个物理数据页的修改,因此备库通过重做 Redo 日志可以与主库数据保持一致。
    Redo日志重演
    主备库之间的 Redo 日志传输,以日志包 RLOG_PKG 为单位,主库通过 MAL 系统发送 Redo 日志到备库。各种不同数据守护类型的区别,就在于主库日志包 RLOG_PKG 的发送时机,以及备库收到 Redo 日志后的处理策略。
    守护进程
    守护进程(dmwatcher)是数据守护系统的核心工具,监控数据库实例的运行状态和主备库数据同步情况,在出现故障时启动各种处理预案。守护进程是各种消息的中转站,接收数据库实例、其他守护进程、以及监视器发送的各种消息;同时,守护进程也会将收到的数据库实例消息转发给其他守护进程和监视器。守护进程必须和被守护的数据库实例部署在同一台机器上。
    监视器
    用来监控守护系统内守护进程、数据库实例信息,执行用户输入命令、监控实例故障、实现自动切换等。监视器一般配置在数据库实例和守护进程以外的机器上。

2.1 系统特性

2.1.1 主要特性

完整功能的主库
主库提供完整的数据库服务,与普通单节点数据库相比,主要的功能限制包括:不支持修改表空间文件名、不支持修改 arch_ini 参数。
活动的备库
基于独特的字典缓存技术和日志重演技术,备库在 Open 状态下执行数据同步,是真正意义上的热备库;在实现异地容灾的同时,用户可以只读访问备库,执行报表生成、数据备份等功能,减轻主库的系统负载,提高资源利用率。
多重数据保护
每个备库都是一个完整的数据库备份,可以同时配置多个备库,为数据安全提供全方位的保护。
高可用性
主库出现故障时,可以快速将备库切换为主库,继续提供数据库服务,确保数据库服务不中断。切换过程一般在数秒钟之内完成。
多种守护模式
提供自动切换和手动切换两种守护模式,满足用户不同需求。其中,配置自动切换的前提是已经部署确认监视器。在提供第三方机器部署确认监视器情况下,可以配置为故障自动切换模式,主库出现故障时,系统自动将备库切换为主库对外提供数据库服务。
多种守护类型
守护进程可以配置为全局守护(提供实时主备、MPP 主备、读写分离集群功能)或者本地守护,适应各种应用需求。
故障自动重连
配置、使用连接服务名访问数据库,在发生主备库切换后,接口会自动将连接迁移到新的主库上。
故障库自动重加入
主库故障,发生主备库切换。故障主库重启后,可以自动切换为 Standby 模式,作为备库重新加入数据守护系统。
历史数据自动同步
故障备库恢复后,可以自动同步历史数据,无需用户干预,并在同步完成以后,自动恢复为可切换备库。
自动负载均衡
配置读写分离集群,可以将只读操作分流到备库上执行,减轻主库访问压力,提高数据库系统的吞吐量。读写分离的过程由 JDBC 等接口配合服务器自动完成,无需用户干预,也不需要修改应用程序。
滚动升级
可以在不中断数据库服务的情况下,滚动地对数据守护系统中的主备库进行数据库软件版本升级。
灵活的搭建方式
可以在不中断数据库服务的情况下,将单节点数据库升级为主备系统。DM 提供多种工具来完成数据守护搭建,如 SHELL 脚本或 DEM 工具,均能方便地完成数据守护搭建。
完备的监控工具
通过命令行监控工具 dmmonitor、DEM 工具可以实时更新、监控主备库的状态和数据同步情况。
完善的监控接口
提供完善的数据守护监控接口,可以定制监控项,并方便地集成到应用系统中。
丰富的守护命令
提供主备库切换、强制接管等功能,通过简单的命令就可以实现主备库角色互换、故障接管等功能。
支持 DMDSC 守护
支持 DMDSC 和单节点、单节点和 DMDSC 之间互为主备的数据守护环境。
DM 的单节点和主库提供读未提交(Read Uncommitted)、读提交(Read Committed)和串行化(Seriablizable)三种事务隔离级,可重复读(Repeatable Read)升级为更严格的串行化事务隔离级。但是,备库只支持读提交(Read Committed)事务隔离级别:
1. 不能访问所有未提交事务的修改
2. 可以访问所有已提交事务的修改

2.1.2 主要改进(V2.0 版本)

1.检测并处理组分裂
检测并处理组分裂场景,是 DM 数据守护 V2.0 的一个重大改进。在 V1.0 版本中,主备库之间的数据一致性完全由用户保证,备库强制接管后,没有办法检查重新恢复的主库是否可以作为备库重新加入主备系统。V2.0 版本引入控制文件 dmwatcher.ctl,将备库接管时的相关信息记录在守护进程控制文件 dmwatcher.ctl 中,故障主库恢复后,根据dmwatcher.ctl 控制文件中信息来判断是否满足故障重加入条件。
2.支持 TCP 协议,取消 UDP 协议
数据库实例与守护进程、守护进程与守护进程、以及守护进程与监视器之间的信息传递,都是基于 TCP 协议完成的。相比于采用 UDP 协议的 DM 数据守护系统 V1.0 版本,使用 TCP 协议的 V2.0 版本,具有以下优势:

  1. 支持跨网段部署数据守护系统,降低部署的硬件要求;
  2. 支持在一台物理机器上搭建数据守护系统,方便测试环境搭建;
  3. 更加简化、统一的配置文件和配置参数。

3.实时主备/MPP 主备/读写分离集群均支持故障自动切换
数据守护系统配置为自动切换模式,主库故障时,备库可以自动切换为主库,这个过程叫作故障自动切换。在 V1.0 版本中,只有实时主备支持故障自动切换,在 V2.0 版本中,MPP 主备和读写分离集群也支持故障自动切换。
4.可配置、可中断的备库恢复流程
缺省情况下,备库故障重启后,系统会自动进行检测、并启动恢复流程(同步历史数据)。
某些情况下,用户可能需要对备库进行一些系统维护,并不希望备库启动后马上进行数据同步。V2.0 版本提供了备库维护功能,可以通过监视器命令将备库恢复功能暂时屏蔽。
当备库长时间中断后恢复,主备库之间数据差异很大情况下,同步历史数据可能需要很长一段时间。在这个过程中,如果出现新的故障场景需要处理,或者在监视器上执行其他命令,则允许中断当前的恢复流程,待故障处理(用户命令)执行完成后,再次启动恢复流程。
5.完善异步备库配置
异步备库一般用于历史数据统计、周期报表等对数据实时性要求不高的业务场合。异步归档时机一般选择在源库相对空闲的时候,以避免影响源库的性能。
V1.0 版本只支持在主库上配置异步备库,而 V2.0 版本则可以在主库或备库上配置各自的异步备库,提供了更大的灵活性,可以适应更广泛的应用场景。
6.任意场景支持强制接管,避免繁琐的手工 SQL 干预
实时主备/MPP 主备/读写分离三种类型全部实现了强制接管命令。
在 V1.0 版本中,实时守护没有监视器命令,需要手工执行一系列 SQL 语句完成强制接管,比较繁琐;读写分离集群和 MPP 主备提供了强制接管命令,但使用场景受限,比如待接管备库处于 MOUNT 状态的情况下,无法通过强制接管命令将备库切换为主库。并且强制接管后,用户无法判断主备库数据是否一致,存在较大的数据安全隐患。
在 V2.0 版本中,实时主备/MPP 主备/读写分离集群都支持强制接管命令,并且根据守护进程控制文件信息,可以判断强制接管后,是否产生组分裂,主备库数据是否可以恢复到一致状态。
7.配置参数调整,风格统一、步骤简化。提供多种搭建数据守护的自动化工具
在 V1.0 版本中,实时主备、MPP 主备和读写分离集群,各自有一套配置参数。在 V2.0版本中,将三类守护系统统一为一套配置参数,并且简化掉一部分配置,大大提高了数据守护系统的搭建效率。
在 V2.0 版本中,除了支持手动搭建数据守护系统, DM 还提供多种自动化工具来完成数据守护搭建过程,如 SHELL 脚本、DEM 工具均能简便灵活地完成数据守护系统的搭建。

2.1.3 主要改进(V2.1 版本)

1.统一 MARCH 和 REALTIME 归档实现逻辑
取消 MARCH 归档类型,保留 REALTIME 实时归档类型,MPP 主备和实时主备统一配置REALTIME 归档。
2.实时主备功能扩展
扩展实时主备的备库数量,允许最多配置 8 个实时备库(V2.0 只支持配置一个实时备库);实时主备增加 HUGE 表数据同步支持。
3.优化 Redo 日志重演性能
采用全新的预解析、预加载技术,大幅优化备库 Redo 日志重演性能,解决了高并发、高压力情况下,备库 Redo 日志堆积问题。
提高了极端情况下集群的整体性能,缩短了极端情况下的故障切换时间。读写分离集群在事务一致性模式下,主库需要等待备库 Redo 日志重演完成再响应用户,优化以后有效降低了主库延迟,提升了读写分离集群系统的吞吐量。
4.对备库进行实时的异常监控和异常恢复
主库守护进程可以实时监控主备之间的数据同步和备库的日志重演情况,一旦出现网络异常或备库自身软硬件异常(比如备库磁盘读写速度异常降低)等原因造成备库无法及时响应主库的情况时,主库守护进程可通知主库将此备库归档失效,暂停到此备库的数据同步,避免拖慢主库性能。
主库会根据配置的恢复间隔定时向异常备库同步数据,如果检测到归档发送速度和备库的重演速度恢复正常,则将其归档重新恢复有效,恢复正常的数据同步。
5.简化、统一守护进程配置参数
取消 dmwatcher.ini 中的 MARCH/REALTIME/TIMELY 类型配置,数据守护类型由服务器的类型(比如:是否 MPP 集群)、以及其配置的归档类型来决定。
守护进程可以配置为 GLOBAL、LOCAL 两种类型,表示是否需要进行全局信息同步、以及是否参与集群管理。

2.1.4 兼容性说明(V2.1 版本)

升级到 V2.1 版本后,数据守护可以继续使用 V2.0 的配置文件,不需要任何修改。守护进程 dmwatcher 可以读写、并正确解析 V2.0 版本的 dmwatcher.ini 配置文件。但V2.0 版本无法解析 V2.1 版本的配置文件。数据库服务器 dmserver 可以正确解析以前版本的归档配置,自动将 MARCH 归档转换成 REALTIME 归档进行处理。
但是,V2.1 版本与 V2.0 版本的 MPP 主备配置存在一定差异,从 V2.0 升级到 V2.1版本后,需要修改备库的 dm.ini 配置文件,将 MPP_INI 配置项设置为 1,并从主库拷贝MPP 控制文件 dmmpp.ctl 保存到 ctl_path目录。否则,数据守护升级到 V2.1 版本后,MPP 主备系统将无法正常运行。

2.1.5 主要改进(V3.0 版本)

1. 支持数据共享集群的守护系统
支持数据共享集群(DMDSC)的守护系统,DMDSC(主)和单节点(备)、单节点(主)和 DMDSC(备)之间都可以组成互为主备的数据守护系统。
2. DMDSC 集群守护增加 REMOTE 远程归档
用于 DMDSC 库的恢复以及主备库的异步恢复,发送日志时能够直接在本地访问到其他节点的归档日志。
3. 完善日志校验方式
主备库日志连续性校验方式,单节点日志的 LSN 值是连续递增的,日志 LSN 值都是唯一的(PWR 日志除外),如果把 DMDSC 集群作为一个整体看待,日志的 LSN 值也是连续递增的,但各个节点日志的 LSN 可能存在重复,每个节点的日志 LSN 是递增的但不一定是连续的。因此,DMDSC 主备库之间的日志校验更加复杂,新版本结合物理日志进行校验。
4. 引入适用于 DMDSC 主库的重演 APPLY_LSN 机制
如果主库是 DMDSC 集群,则需要发送所有节点的日志到备库的重演节点进行重演(如果备库是 DMDSC 集群,则重演节点是指备库的控制节点),在主备库需要同步历史数据时(比如备库故障重启),主库需要知道自己的每个节点在备库上的重演情况,以决定每个节点分别从哪里开始同步数据。备库记录 DMDSC 主库各个节点日志重做情况的 LSN,称为APPLY_LSN。主库是单节点时,备库的APPLY_LSN等同于CUR_LSN
5. 守护进程以库为单位管理 DMDSC 集群
守护进程以库为单位进行管理,对 DMDSC 集群是指包含有多个节点的库,对单节点则是只有一个节点的库,并新增若干状态进行 DMDSC 集群的管理。
6. 守护进程可以处理 DMDSC 主库或备库的重加入
控制文件 dmwatcher.ctl 改造,结合备库的重演 LSN 概念,将之前的 SLSN 字段变成重演 APPLY_LSN 数组,同时调整判断主备库是否可加入的逻辑。
7. 备库可执行创建、扩展日志文件
允许备库执行创建、扩展日志文件,备库不再重演主库创建、扩展日志文件产生的日志。
8. 监视器支持对 DMDSC 集群的监控和管理
监视器调整及扩展一批命令及接口,以适应 DMDSC 集群的监控及管理。

2.1.6 兼容性说明(V3.0 版本)

从 V2.0 或者 V2.1 升级到 V3.0 版本后,如果守护系统中不扩展新增 DMDSC 库,仍然是只包含单节点的数据守护环境, 则可以继续使用原来的配置文件,不需要任何修改。守护进程可以正确读写 dmwatcher.ctl 文件及其配置文件,数据库服务器和监视器也都可以正确读取版本升级前的配置文件,但是 V2.0 或 V2.1 无法正确解析 V3.0 的配置文件。
升级成 V3.0 版本后,为保持格式兼容,守护进程仍然是按照老的版本格式读写dmwatcher.ctl 文件的,如果在升级后的守护系统中要扩展新增 DMDSC 库,则要按照V3.0版本的配置要求重新修改相关的ini配置文件,并且要重新生成新版本的dmwatcher.ctl 文件。
另外如果是从 V2.0 直接升级到 V3.0,在 MPP 主备的配置上存在一定差异,从 V2.0升级到 V3.0 版本后,需要修改备库的 dm.ini 配置文件,将 MPP_INI 配置项设置为 1,并从主库拷贝 MPP 控制文件 dmmpp.ctl 保存到 ctl_path 目录。否则,数据守护升级到 V3.0 版本后,MPP 主备系统将无法正常运行。

2.1.7 主要改进(V4.0 版本)

  1. 主备库以 RLOG_PKG 为单位同步数据
    数据守护V4.0在RLOG_PKG改造基础上重新实现,主库产生的Redo日志以RLOG_PKG
    包的形式发送给备库重演。RLOG_PKG 具有自描述、自校验特征,数据的组织形式更加灵活、
    高效,支持 HUGE 表操作产生 Redo 日志,并且支持以 RLOG_PKG 为单位进行日志加密和
    压缩。
  2. 备库完整归档主库产生的日志
    备库在收到主库发送过来的 RLOG_PKG 后,直接将 RLOG_PKG 写入本地的归档日志文
    件,完整保留主库上的原始日志,备库重演 RLOG_PKG 产生的联机日志不再进行归档。
    采用这种备库归档策略后,不管主备库如何切换,集群中所有数据库的归档日志内容是完全一致的,简化了历史数据同步处理逻辑。
  3. 更简便的日志连续性校验
    由于 RLOG_PKG 包具有自校验特性,利用 RLOG_PKG 的 G_PKG_SEQNO 和 MIN_LSN、
    MAX_LSN、PREV_LSN 等信息,结合备库重演信息(APPLY STAT)记录的 P_DB_MAGIC、
    N_APPLY_EP、PKG_SEQNO_ARR 数组、 APPLY_LSN_ARR 数组,可以准确地校验出日志
    是否连续。简化了主备库(特别是 DSC 主备库)日志连续性校验逻辑,主库只负责发送日
    志,备库根据接收到的日志和自己维护的重演信息校验日志是否连续。
  4. 更可靠的主库变迁记录
    增加 SYSOPENHISTORY 系统表,记录数据库的Open 历史记录,在Primary或 Normal
    模式库 Open 时,向系统表写入记录(称之为 Open 记录)。主库切换、Open 等过程完整地
    记录在数据库中,并通过 Redo 日志传送到备库,完成主备库之间 Open 记录的同步。
    简化 dmwatcher.ctl 功能,取消 Open 记录,仅保留 status 和 desc 两个字段,在
    本地数据库分裂时,设置分裂状态和对应的分裂描述信息。并且,dmwatcher.ctl 文件不
    再需要在主备库之间进行同步。
  5. 更完备的库分裂检测机制
    优化了主备库分裂场景判断逻辑,守护进程根据主备库 Open 记录的包含关系、主库各
    节点 LSN 信息和备库日志重演信息,判断是否出现主备库分裂。在未出现分裂情况下,综
    合考虑各数据库模式、状态要素,选择正确的主库并进行自动 Open 数据库。
  6. 更完善的异步备库功能
    异步备库支持多源配置,允许 Realtime、Timely 主备库配置相同的异步备库,系统
    自动识别,仅从主库向异步备库同步历史数据。不管主备库如何切换,始终保持异步备库与
    主库的数据同步。

2.1.8 兼容性说明(V4.0 版本)

系统自动识别 dmwatcher.ctl 控制文件的版本号,忽略老版本控制文件。在数据库分裂时,自动覆盖并生成新格式的 dmwatcher.ctl 文件。
1. 从 V2.1 或者 V3.0 升级到 V4.0
如果守护系统不再扩展配置其他库(单节点或者 DSC 集群),则可以继续使用原来的配置文件,不需要做任何修改。同时,建议删除主备库各自目录下的 dmwatcher.ctl 文件。
2. 从 V2.0 升级到 V4.0
如果守护系统不再扩展配置其他库(单节点或者 DSC 集群),对实时主备和读写分离集群,则可以继续使用原来的配置文件,不需要做任何修改。同时,建议删除主备库各自目录下的 dmwatcher.ctl 文件。
MPP 主备还需要修改备库的 dm.ini 配置文件,将 MPP_INI 配置项设置为 1,并从主库拷贝 MPP 控制文件 dmmpp.ctl 保存到 ctl_path 目录。否则,数据守护升级到 V4.0 版本后,MPP 主备系统将无法正常运行。
3.数据库升级说明
由于 V4.0 的数据库 REDO 日志采用 RLOG_PKG 为单位在日志文件中进行保存,和 RLOG_BUF 机制的格式不兼容,V4.0 版本无法解析老库日志。为了避免库启动时进行重做 REDO 日志、归档文件修复等动作而导致无法升级的情况发生,因此要求升级前的库必须是使用之前版本的服务器执行码正常退出的库,否则无法自动升级。
数据库自动升级的动作包括:根据当前库信息,初始化联机日志文件头、创建一个初始的日志包格式化到文件中、创建 SYSOPENHISTORY 系统表等。
由于升级后老的归档文件无法再继续使用,因此需要确保备库在升级前和主库的数据处于一致状态,否则升级完成后,主库无法再从老的归档文件中收集数据同步到备库上。
4.数据库降级说明
对数据守护 V4.0 环境,支持将主库重新降级到 V3.0 版本(仅支持降级到 V8.1.0.182版本),备库不支持直接降级。
由于 REDO 日志格式降级前后是不兼容的,为了避免降级后的数据库启动时进行重做REDO 日志、归档文件修复等动作导致无法正常启动的情况发生,因此要求降级前的库必须是使用之前版本的服务器执行码正常退出的库,否则不允许执行降级。
数据库降级的动作包括:按照 V3.0 的格式降级联机日志文件头、降级数据字典版本号、删除 SYSOPENHISTORY 系统表、按照老的视图定义重建一批动态视图等。

2.2 基本概念

2.2.1 数据库

数据守护以库为单位进行管理,一个 DMDSC 集群的所有实例作为一个整体库来考虑。
DMDSC 集群的库信息,例如库的状态、模式等需要综合考虑集群内所有实例,同时需要结合 DMDSC 本身的状态。

2.2.2 DMDSC状态

DMDSC 状态标识 DMDSC 集群节点状态,和数据库的状态不同。包括以下几种:

  • Startup 节点启动状态,需要通过 DMCSS 工具交互,确定控制节点,执行日志重做等相关步骤,进入到 OPEN 状态。
  • Open 实例正常工作状态,当集群内发生节点故障或启动节点重加入步骤时,可以进入 crash_recv 或者 err_ep_add 状态,处理完成后会再回到 Open 状态。
  • Crash_recv 节点故障处理状态。
  • Err_ep_add 故障节点重加入状态。

2.2.3 数据库模式

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;

修改 DMDSC 库的模式必须在 DMDSC 库所有实例都处于 MOUNT 状态下才能进行,只需要在一个节点上执行以上语句即可。

2.2.4 数据库状态

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 状态,比如备库故障恢复后,在历史数据(归档日志)同步完成后,需要重新启用实时归档功能时:

  1. 将系统切换为 Suspend 状态,限制 Redo 日志写入联机 Redo 日志文件;
  2. 修改归档状态为 Valid;
  3. 重新将数据库切换为 Open 状态,恢复 Redo 日志写入功能;
  4. 备库与主库重新进入实时同步状态。
    另外,实时归档失败时(比如网络故障导致),Primary 实例将试图切换成 Suspend 状态,防止后续的日志写入。因为一旦写入,主备切换时有可能备库没有收到最后那次的RLOG_PKG,导致主库上多一段日志,很容易造成主备数据不一致。当实例成功切换为 SUSPEND 状态时,可直接退出,强制丢弃多余的日志,避免主备数据不一致。
    修改 DMDSC 库的状态为 SUSPEND 时,库内所有实例都不能处于 MOUNT 状态,只需要在一个节点上执行 ALTER DATABASE SUSPEND 语句即可。
    Shutdown 状态
    实例正常退出时设置为 Shutdown 状态。
    在这里插入图片描述
    对 DMDSC 集群,除了修改 Suspend 是同步操作,只需要在一个节点执行外,其他状态修改都需要在每个节点上各自单独执行。
//1. 将数据库修改为 Open 状态。当系统处于 Primary/Standby 模式时,必须强制加上 FORCE 子句。
ALTER DATABASE OPEN [FORCE]; 
//2. 将数据库修改为 Mount 状态。
ALTER DATABASE MOUNT; 
//3. 将数据库修改为 Suspend 状态。
ALTER DATABASE SUSPEND;

由于 dmwatcher 根据数据库模式、状态等信息作为故障处理、故障恢复的依据 , 建议在配置数据守护过程中,修改dm.ini参数 ALTER_MODE_STATUS 为 0,限制用户直接通过 SQL 语句修改数据库状态、模式以及 OGUID,避免 dmwatcher 做出错误的决策。

2.2.5 LSN介绍

LSN(Log Sequence Number)是由系统自动维护的 Bigint 类型数值,具有自动递增、全局唯一特性,每一个 LSN 值代表着 DM 系统内部产生的一个物理事务。物理事务(Physical Transaction,简称 ptx)是数据库内部一系列修改物理数据页操作的集合,与数据库管理系统中事务(Transaction)概念相对应,具有原子性、有序性、无法撤销等特性。
DM数据库中与LSN相关的信息,可以通过查询V$RLOGV$RAPPLY_PARALLEL_INFO表来获取。DM 主要包括以下几种类型的 LSN:

  • CUR_LSN 是系统已经分配的最大 LSN 值。物理事务提交时,系统会为其分配一个唯一的 LSN 值,大小等于 CUR_LSN + 1,然后再修改 CUR_LSN=CUR_LSN+1。
  • FILE_LSN 是已经写入联机 Redo 日志文件的日志包的最大 LSN 值。每次将 Redo日志包 RLOG_PKG 写入联机 Redo 日志文件后,都要修改 FILE_LSN 值。
  • FLUSH_LSN 是已经发起日志刷盘请求,但还没有真正写入联机 Redo 日志文件的最大 LSN 值。
  • CKPT_LSN 是检查点 LSN,所有 LSN <= CKPT_LSN 的物理事务修改的数据页,都已经从 Buffer 缓冲区写入磁盘,CKPT_LSN 由检查点线程负责调整。
  • APPLY_LSN 是备库已写入联机 Redo 日志文件的日志包的原始最大 LSN 值,此 LSN 取自主库对应的原始日志包中的最大 LSN 值。如果主库是 DMDSC 集群,备库分别为主库每一个节点维护一个 APPLY_LSN。
  • RPKG_LSN 是备库重演 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 是 Standby LSN 的缩写,表示备库明确可重演的最大 LSN 值。
  • KLSN 是 Keep LSN 的缩写,表示备库已经收到、但未明确是否可以重演的 RLOG_PKG 的最大 LSN 值。在读写分离集群中 KLSN == SLSN。

2.2.6 Redo日志

Redo 日志包含了所有物理数据页的修改内容,Insert/delete/update 等 DML 操作、Create Table 等 DDL 操作,最终都会转化为对物理数据页的修改,这些修改都会反映到 Redo 日志中。一般说来一条修改数据的SQL 语句(比如 Insert),在系统内部会转化为多个相互独立的物理事务来完成,物理事务提交时会将产生的 Redo 日志写入日志包 RLOG_PKG 中。
一个物理事务包含一个或者多个 Redo 记录(Redo Record),每条 Redo 记录(RREC)都对应一个修改物理数据页的动作。根据记录内容的不同,RREC 可以分为两类:物理 RREC 和逻辑 RREC。
物理 RREC 记录的是数据页的变化情况,内容包括:操作类型、修改数据页地址、页内偏移、数据页上的修改内容,如果是变长类型的 Redo 记录,在 RREC 记录头之后还会有一个两字节的长度信息。
逻辑 RREC 记录的是一些数据库逻辑操作步骤,主要包括:事务启动、事务提交、事务回滚、字典封锁、事务封锁、B 树封锁、字典淘汰等。
逻辑 RREC 记录是专门为数据守护增加的记录类型,用来解决备库重演 Redo 日志与用户访问备库之间的并发冲突,以及主库执行 DDL 后导致的主备数据库字典缓存不一致问题。
备库解析到逻辑 RREC 记录时,根据记录内容,生成相应的事务,封锁对应的数据库对象,并从字典缓存中淘汰过期的字典对象。
在这里插入图片描述

2.2.7 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 日志到备库。
在这里插入图片描述

2.2.8 包序列介绍

每个 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 是备库重演全局包序号,表示备库已经重演完成的最大全局包序号。

如果主库是 DSC 集群,备库分别为主库每一个节点维护一个 APPLY_SEQ。
DM 数据守护中也相应地定义了一批全局包序号:

  • CSEQ 全局已分配包序号,标识系统已经分配的最大 GSEQ 值。
  • FSEQ 全局文件包序号,标识已写入联机日志文件的最大 GSEQ 值。
  • ASEQ 原始全局文件包序号,标识备库已写入联机日志文件的原始 GSEQ 值。
  • RSEQ 全局重演包序号,标识备库已经重演的最大 GSEQ 值。
  • SSEQ 全局备库包序号,标识备库明确可重演的最大 GSEQ 值。
  • KSEQ 全局保留包序号,表示备库已经收到、未明确是否可以重演的最大 GSEQ 值。在读写分离集群中 SSEQ == KSEQ。

GSEQ 和 LSN 存在匹配关系,在判断归档连续性、备库归档恢复等场合一般都是同时使
用。

2.2.9 KEEP_RLOG_PKG

主库的RLOG_PKG日志通过实时归档机制发送到备库后,备库将最新收到的RLOG_PKG保存在内存中,不马上启动重演,这个 RLOG_PKG 我们称之为 KEEP_RLOG_PKG。引入KEEP_RLOG_PKG 的主要目的是,避免下述场景中,主库故障重启后不必要的主备切换,减少用户干预。
场景说明(实时主备或 MPP 主备):

  1. 用户登录主库 A 执行
    CREATE TABLE TX(C1 INT);
    INSERT INTO TX VALUES(1);
    COMMIT;
    
    其中 COMMIT 操作将触发实时归档,发送 RLOG_PKG 到备库 B。
  2. 备库 B 收到 RLOG_PKG,响应主库 A,并启动日志重演。
  3. 主库 A 在 RLOG_PKG 写入联机日志文件之前故障。
  4. 主库 A 重新启动后,由于 RLOG_PKG 没有写入联机日志文件,之前插入 TX 表的数据丢失;但此时备库 B 已经重演日志成功,TX 表中已经插入一行数据。

上述场景中,主备库数据不再保持一致,必须将备库 B 切换为主库,并重新从 B 同步数据到 A。如果配置的是手动切换模式,则必须要有用户干预,进行备库接管后,才能恢复数据库服务。
引入 KEEP_RLOG_PKG 后,备库 B 收到主库 A 发送的 RLOG_PKG,并不会马上启动日志重演,主库 A 重启后,守护进程 A 检测到备库 B 存在 KEEP_RLOG_PKG,通知备库 B 丢弃KEEP_RLOG_PKG 后,直接 Open 主库 A,就可以继续提供数据库服务。并且,这些操作是由守护进程自动完成,不需要用户干预

2.2.10 联机Redo日志文件

  • DM 数据库默认包含两个联机 Redo 日志文件(如 DAMENG01.log、DAMENG02.log),系统内部分别称为 0 号文件、1 号文件。
  • RLOG_PKG 顺序写入联机 Redo 日志文件中,当一个日志文件写满后,自动切换到另一个文件。其中 0 号文件是 Redo 日志主文件,在日志主文件头中保存了诸如 CKPT_LSN,CKPT_FILE,CKPT_OFFSET,FILE_LSN 等信息。
  • 系统故障重启时,从[CKPT_FILE, CKPT_OFFSET]位置开始读取 Redo 日志,解析 RREC 记录,并重新修改对应数据页内容,确保将数据恢复到系统故障前状态。
  • 随着检查点(Checkpoint)的推进,对应产生 Redo 日志的数据页从数据缓冲区(Data Buffer)写入磁盘后,联机 Redo 日志文件可以覆盖重用、循环使用,确保 Redo 日志文件不会随着日志量的增加而增长。
    任何数据页从 Buffer 缓冲区写入磁盘之前,必须确保修改数据页产生的 Redo 日志已经写入到联机 Redo 日志文件中。
    下图说明了联机日志文件、日志包 RLOG_PKG 以及相关各 LSN 之间的关系。
    在这里插入图片描述

在联机日志文件中,可以覆盖写入 Redo 日志的文件长度为可用日志空间;不能被覆盖,系统故障重启需要重做部分,为有效 Redo 日志,有效 Redo 日志的 LSN 取值范围是(CKPT_LSN,FILE_LSN];已经被发起日志刷盘请求,但还没有真正写入联机 Redo 日志文件的区间为(FILE_LSN,FLUSH_LSN],称为待写入日志空间。

2.2.11 归档介绍

归档是实现数据守护系统的重要技术手段,根据功能与实现方式的不同,DM 数据库的归档可以分为 6 类:本地归档、远程归档、实时归档、即时归档、异步归档和同步归档。其中,本地归档远程归档日志的内容与写入时机与数据库模式相关;主库 Redo 日志写入联机日志文件后,再进行本地归档和远程归档;备库收到主库产生的 Redo 日志后,直接进行本地归档和远程归档,同时启动 Redo 日志重演。

2.2.11.1 本地归档

Redo 日志本地归档(Local),就是将 Redo 日志写入到本地归档日志文件的过程。
配置本地归档情况下,Normal/Primary 模式库在 Redo 日志写入联机 Redo 日志文件后,将对应的 RLOG_PKG 由专门的归档线程写入本地归档日志文件中。Standby 模式库收到主库产生的 Redo 日志后,直接进行本地归档,写入本地归档日志文件中,同时启动 Redo 日志重演。
Normal/Primary 模式库归档日志文件保存的是当前节点产生的 Redo 日志,归档日志文件内容与联机日志内容保持一致。Standby 模式库重演日志重新产生的 Redo 日志只写入联机日志文件,归档日志文件保存主库产生的 Redo 日志,因此备库联机日志文件内容
和归档日志文件内容是不完全一致的。采用这种归档实现方式后,可以确保数据守护系统中所有节点的归档日志文件内容是完全一致的。
与联机 Redo 日志文件可以被覆盖重用不同,本地归档日志文件不能被覆盖,写入其中的 Redo 日志信息会一直保留,直到用户主动删除;如果配置了归档日志空间上限,系统会自动删除最早生成的归档 Redo 日志文件,腾出空间。本地归档文件在配置的归档目录下生
成并保存,如果磁盘空间不足,且没有配置归档日志空间上限(或者配置的上限超过实际空间),系统将自动挂起,直到用户主动释放出足够的空间后继续运行。
DM 提供了按指定的时间或指定的 LSN 删除归档日志的系统函数,分别为 SF_ARCHIVELOG_DELETE_BEFORE_TIME 和 SF_ARCHIVELOG_DELETE_BEFORE_LSN,但用户需要谨慎使用。例如,在守护系统中,如果备库故障了,主库继续服务,主库的日志在继续增长。此时如果删除尚未同步到备库的主库归档日志,那么备库重启之后,会由于备库收到的日志缺失导致主备库无法正常同步数据
为了最大限度地保护数据,当磁盘空间不足导致归档写入失败时,系统会挂起等待,直到用户释放出足够的磁盘空间。当磁盘损坏导致归档日志写入失败时,系统会强制 HALT。

2.2.11.2 远程归档

远程归档专门用于 DMDSC 环境中。
所谓远程归档(REMOTE ARCHIVE),顾名思义就是将归档目录配置在远程节点上。远程归档采用双向配置的方式,双向配置远程归档就是两个节点将自己的远程归档相互配置在对方机器上。集群中所有的节点,都拥有一套包括所有节点的,完整的归档日志文件。
具体有两种配置方式:一是共享本地归档的远程归档,即将远程归档目录配置为另一节点的本地归档目录,以此来共享它的本地归档日志文件;二是通过 MAL 发送的远程归档,即将写入本地归档的 REDO 日志信息,通过 MAL 发送到远程节点,并写入远程节点的指定归档目录中,形成远程归档日志文件。
配置远程归档后,DMDSC 集群中每个实例完整保存了集群所有实例产生的 Redo 日志,任意实例都可以像访问本地归档一样,访问所有实例产生的归档日志。
远程归档的使用场景:
1.执行数据库恢复时,恢复工具(如 DMRMAN)所在节点需要访问其他各节点归档日志。
2.DMDSC 守护系统中进行主、备库异步归档日志的同步或备库恢复时,DMDSC 控制节点作为发送端,需要访问其他从节点的归档日志。

2.2.11.3 归档文件

备库归档机制调整后,备库归档日志文件写入的并不是自己重演生成的 Redo 日志,而是直接将主库产生的 Redo 日志写入到本地归档日志文件中。为了区分生成 Redo 日志和写入 Redo 日志的库,归档日志文件头增加了几个 MAGIC 字段:

  • PMNT_MAGIC 永久魔数,用来唯一标识数据库,初始化数据库时生成并保持不变(DDL_CLONE 还原库除外),数据守护集群中所有主备库的 PMNT_MAGIC 是相同的。只有 DDL_CLONE 还原库的 PMNT_MAGIC 会发生改变,当一个库使用 DDL_CLONE 备份集还原并恢复之后,在执行 RECOVER DATABASE …… UPDATE DB_MAGIC 时,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_MAGIC 值相同。

Primary/Normal 模式库本地归档日志文件的命名方式调整为:

"ARCH_NAME_DB_MAGIC[SEQNO]_日期时间.log"

其中 ARCH_NAME 是在 dmarch.ini 中配置的 LOCAL/REMOTE 归档名称,DB_MAGIC 是生成日志的数据库魔数,SEQNO 代表 DSC 节点号,日期时间是归档日志文件的创建时间。
例如:

"ARCHIVE_LOCAL1_0x567891[0]_2019-03-20_10-35-34.log"

Standby 模式库(备库)生成的归档日志文件的命名方式调整为:

”STANDBY_ARCHIVE_DB_MAGIC[SEQNO]_日期时间.log“

其中 STANDBY_ARCHIVE 表示备库生成的归档日志文件,DB_MAGIC 是生成日志的数
据库(主库)魔数,SEQNO 代表主库对应的 DSC 节点号,日期时间是归档日志文件的创建
时间。
例如:

"STANDBY_ARCHIVE_0x123456[0]_2019-03-20_10-35-34.log"

由于 STANDBY_ARCHIVE 用于表示备库生成的归档日志,不允许将归档名称配置为 STANDBY_ARCHIVE。

2.2.11.4 实时归档

与本地归档写入保存在磁盘中的日志文件不同,实时归档(Realtime)将主库产生的 Redo 日志通过 MAL 系统传递到备库,实时归档是实时主备和 MPP 主备的实现基础。实时归档只在主库生效,一个主库可以配置 1~8 个实时备库。
实时归档的执行流程是,主库在 Redo 日志(RLOG_PKG)写入联机日志文件前,将 Redo 日志发送到备库,备库收到 Redo 日志(RLOG_PKG)后标记为 KEEP_RLOG_PKG,将原 KEEP_RLOG_PKG 加入日志重演任务系统,并马上响应主库,不需要等待 Redo 日志重演结束后再响应主库。主库收到备库的响应消息,确认备库已经收到 Redo 日志后,再将 Redo 日志写入联机日志文件中。
另外,实时归档也可以支持读写分离集群,实时归档也分为两种模式:事务一致模式和高性能模式,也可以通过分别配置备库的 WAIT_APPLY 配置项同时配置高性能备库和事务一致备库。这两种模式的具体含义和下一小节 2.2.11.5 中的说明完全相同,区别仅在于配置为实时归档时,dmarch.ini 中的 ARCH_WAIT_APPLY 配置项默认值为 0,即采用高性能模式,具体内容请参考 2.2.11.5 和 2.6.5 小节。

2.2.11.5即时归档

即时归档(Timely)在主库将 Redo 日志写入联机日志文件后,通过 MAL 系统将 Redo 日志发送到备库。即时归档与实时归档的主要区别是 Redo 日志的发送时机不同。一个主库可以配置 1~8 个即时备库。
根据备库重演 Redo 日志和响应主库时机的不同,即时归档分为两种模式:事务一致模式和高性能模式。即时归档模式根据配置文件 dmarch.ini 中的 ARCH_WAIT_APPLY 配置项(默认值为 1)来确定,1 表示事务一致模式,0 表示高性能模式。

  • 事务一致模式 主库事务提交触发 Redo 日志刷盘和即时归档,备库收到主库发送的 Redo 日志,并重演完成后再响应主库。主库收到备库响应消息后,再响应用户的提交请求。事务一致模式下,同一个事务的 SELECT 语句无论是在主库执行,还是在备库执行,查询结果都满足 READ COMMIT 隔离级要求。
  • 高性能模式 与实时归档一样,备库收到主库发送的 Redo 日志后,马上响应主库,再启动日志重演。高性能模式下,备库与主库的数据同步存在一定延时(一般情况下延迟时间非常短暂,用户几乎感觉不到),不能严格保证事务一致性。
    事务一致模式下,主备库之间严格维护事务一致性,但主库要等备库 Redo 日志重演完成后,再响应用户的提交请求,事务提交时间会变长,存在一定的性能损失。高性能模式则通过牺牲事务一致性获得更高的性能和提升系统的吞吐量。用户应该根据实际情况,选择合适的即时归档模式。
2.2.11.6 异步归档

异步归档(Async)由主、备库上配置的定时器触发,根据异步备库的 KEEP LSN 信息,扫描本地归档目录获取 Redo 日志,并通过 MAL 系统将 Redo 日志发送到异步备库。异步备库的 Redo 日志重演过程与实时归档等其他类型的归档完全一致。
每个 Primary 或 Standby 模式的数据库最多可以配置 8 个异步备库,Normal 模式下配置的异步备库会自动失效。异步备库可以级联配置,异步备库本身也可以作为源库配置异步备库。

2.2.11.7 同步归档

同步归档(Sync)在主库归档日志刷盘后,通过 MAL 系统将 Redo 日志发送到备库。同步备库的 Redo 日志重演过程与实时归档等其他类型的归档完全一致。一个主库可以配置 1~8 个同步备库。
同步归档的执行流程为:主库在归档日志刷盘后,将 Redo 日志发送到备库,备库收到 Redo 日志(RLOG_PKG)后,将其加入日志重演任务系统,并马上响应主库,不需要等待 Redo 日志重演结束后再响应主库。

2.2.11.8 归档区别

在这里插入图片描述
在这里插入图片描述
任意一个备库的实时归档/即时归档失败(即使其他备库归档成功了),主库都会切换为 Suspend 状态。

2.2.11.9 归档状态

本地归档、实时归档和即时归档均包含两种状态:Valid 和 Invalid。异步归档只有一种归档状态:Valid。同步备库有三种归档状态:Valid,Invalid 和 Async_send。

  • Valid 归档有效,正常执行各种数据库归档操作。
  • Invalid 归档无效,主数据库不发送联机 Redo 日志到备数据库。
  • Async_send 归档无效,但主库正在同步历史数据到同步备库。

在不同的归档类型中,归档状态转换时机不同。具体转换时机描述如下:

  1. 主备库启动后,主库到所有备库的归档默认为 Valid 状态,守护进程 Open 主库前,根据主备库日志同步情况,将数据不一致备库的归档修改为 Invalid 状态。
  2. 实时备库和即时备库故障恢复,从主库同步历史数据后,守护进程将主库修改为Suspend 状态,并将主库到备库的归档状态从 Invalid 修改为 Valid。当守护进程再次Open 主库后,主备库数据重新恢复为一致状态。
  3. 同步备库故障恢复,主库开始同步历史数据时,将备库归档状态从 Invalid 修改为 Async_send,中间会将日志刷盘线程挂起确保备库能够追到和主库数据完全一致,并将主库到备库的归档状态从 Async_send 修改为 Valid,然后唤醒日志刷盘线程,主备库数据重新恢复为一致状态。
  4. 主库发送日志到实时备库失败挂起,守护进程处理 Failover 过程中,将主库到备库的归档状态修改为 Invalid。
  5. 主库发送即时归档失败后,直接将主库到备库的归档改为 Invalid 状态。
  6. 主库发送同步归档失败后,直接将主库到备库的归档改为 Invalid 状态,并且不会有主库切换到 Suspend 状态的过程。
  7. 异步归档始终保持 Valid 状态,一旦归档失败马上返回,等待下一次触发再继续发送。
  8. 主库发现同步备库归档状态为 Invalid,且满足同步备库故障恢复的条件时,将主库到备库的归档状态从 Invalid 改为 Async_send,并开始同步历史数据到备库,同步完成后会将备库归档状态从 Async_send 修改为 Valid 有效状态。
    实时归档、即时归档只对 Primary 模式的主库有效,备库上配置的实时归档、即时归档状态没有实际意义,始终保持 Valid 状态。

2.2.12 MAL系统

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

2.2.13 OGUID

  • 数据守护唯一标识码,配置数据守护时,需要由用户指定 OGUID 值。其中数据库的 OGUID 在 MOUNT 状态下由系统函数 SP_SET_OGUID 设置,守护进程和监视器的 OGUID 值在配置文件中设定。
  • 同一守护进程组中的所有数据库、守护进程和监视器,都必须配置相同的 OGUID 值,数据守护唯一标识码,配置数据守护时,需要由用户指定 OGUID 值。其中数据库的 OGUID 在 MOUNT 状态下由系统函数 SP_SET_OGUID 设置,守护进程和监视器的 OGUID 值在配置文件中设定。
  • 同一守护进程组中的所有数据库、守护进程和监视器,都必须配置相同的 OGUID 值,

2.2.14 守护进程组

配置了相同 OGUID 的两个或多个守护进程,构成一个守护进程组。为方便管理,对每个守护进程组进行命名,守护进程组中的所有守护进程和监视器,必须配置相同的组名。

2.2.15 组分裂

同一守护进程组中,不同数据库实例的数据出现不一致,并且无法通过重演 Redo 日志重新同步数据的情况,我们称为组分裂。引发组分裂的主要原因包括:

  1. 即时归档中,主库在将 Redo 日志写入本地联机 Redo 日志文件之后,发送 Redo日志到备库之前出现故障,导致主备库数据不一致,为了继续提供服务,执行备库强制接管。此时,当故障主库重启后,就会引发组分裂。
  2. 故障备库重新完成数据同步之前,主库硬件故障,并且长时间无法恢复;在用户接受丢失部分数据情况下,为了尽快恢复数据库服务,执行备库强制接管,将备库切换为主库。此时,如果故障主库重启,也会造成组分裂。

检测到组分裂后,守护进程会修改控制文件为分裂状态,强制退出被分裂的库,被分裂出去的数据库需要通过备份还原等技术手段重新恢复。

2.2.16 脑裂

脑裂是同一个守护进程组中同时出现两个或者多个活动主库,并且这些主库都接收用户请求,提供完整数据库服务。一旦发生脑裂,将无法保证数据一致性,对数据安全造成严重后果。
DM 数据守护系统为预防脑裂做了大量工作,例如故障自动切换模式的数据守护必须配置确认监视器。确认监视器启动故障切换之前,会进行严格的条件检查,避免脑裂发生。守护进程一旦检测到脑裂发生,会马上强制退出所有活动主库,等待用户干预,避免数据差异进一步扩大。
造成脑裂的主要原因有两个:网络不稳定或错误的人工干预。为了避免出现脑裂,我们建议:

  1. 设置 dm.ini 参数 ALTER_MODE_STATUS=0,限制用户进行直接通过 SQL 修改数据库模式、状态以及 OGUID。
  2. 提供稳定、可靠的网络环境。
  3. 配置自动切换数据守护时,将确认监视器部署在独立的第三方机器上,不要与某一个数据库实例部署在一起,避免由于网络问题触发自动故障切换,导致脑裂发生。
  4. 通过人工干预,将备库切换为主库之前,一定要确认主库已经发生故障,避免主库活动情况下,备库强制接管,人为造成脑裂。

2.3 术语定义

数据守护系统包含主库、备库、守护进程、监视器等诸多部件,在主备库切换、故障处
理等场景下,仅以主库或者备库这些称谓,已经无法准确描述对应部件。为了更加清晰的描
述数据守护系统,特别定义以下术语。
在这里插入图片描述
在这里插入图片描述
配置数据守护时,数据库实例名不建议配置为 Primary/Standby,守护进程组名不建议配置成和实例名相同,避免在描述对象时产生歧义。

2.4 实时主备

实时主备系统由主库、实时备库、守护进程和监视器组成。通过部署实时主备系统,可以及时检测并处理各种硬件故障、数据库实例异常,确保持续提供数据库服务。

2.4.1 主要功能

  1. 实时数据同步
    主备库通过实时归档完成数据同步,实时归档要求主库将 RLOG_PKG 发送到备库后,再将 RLOG_PKG 写入本地联机 Redo 日志文件。但要注意的是,备库确认收到主库发送的Redo 日志,并不保证备库已经完成重演这些 Redo 日志,因此主备库之间的数据同步存在一定的时间差。
  2. 主备库切换
    主备库正常运行过程中,可以通过监视器的 Switchover 命令,一键完成主备库角色转换。主备库切换功能可以确保在软、硬件升级,或系统维护时,提供不间断的数据库服务。
  3. 自动故障处理
    备库故障,不影响主库正常提供数据库服务,守护进程自动通知主库修改实时归档为 Invalid 状态,将实时备库失效。
  4. 自动数据同步
    备库故障恢复后,守护进程自动通知主库发送归档 Redo 日志,重新进行主备库数据同步。并在历史数据同步后,修改主库的实时归档状态为 Valid,恢复实时备库功能。备库接管后,原主库故障恢复,守护进程自动修改原主库的模式为 Standby,并重新作为备库加入主备系统。
  5. 备库接管
    主库发生故障后,可以通过监视器的 Takeover 命令,将备库切换为主库,继续对外提供服务。如果配置为自动切换模式,确认监视器可以自动检测主库故障,并通知备库接管,这个过程不需要人工干预。
  6. 备库强制接管
    如果执行 Takeover 命令不成功,但主库可能由于硬件损坏等原因无法马上恢复,为了及时恢复数据库服务,DM 提供了 Takeover Force 命令,强制将备库切换为主库。但需要由用户确认主库故障前,主库与接管备库的数据是一致的(主库到备库的归档是 Valid状态),避免引发守护进程组分裂。
  7. 读写分离访问
    在备库查询的实时性要求不高的条件下,实时主备也可以配置接口的读写分离属性访问,实现读写分离功能特性。
    执行 Takeover Force 有可能引发组分裂,而 Takeover 命令是在确保不会产生组分裂情况下才允许执行。

2.4.2 归档流程

在这里插入图片描述
主库生成联机 Redo 日志,当触发日志写文件操作后,日志线程先将 RLOG_PKG 发送到备库,备库接收后进行合法性校验(包括日志是否连续、备库状态是否 Open 等),不合法则返回错误信息,合法则作为 KEEP_RLOG_PKG 保留在内存中,原有 KEEP_RLOG_PKG 的 Redo 日志加入 Apply 任务队列进行 Redo 日志重演,并响应主库日志接收成功。当有多个备库时,主库需要收到所有备库的响应消息才继续后续操作。

2.5 MPP主备

MPP 主备就是在 MPP 集群的基础上,为每一个 MPP 节点配置一套实时主备系统,这些实时主备系统一起构成了 MPP 主备系统。MPP 主备系统包含多个守护进程组,每个守护进程组都是一个相对独立的实时主备系统,具备实时主备的基本功能,可以进行主备切换、备库接管等操作。
MPP 主备的主要目的是为 DM MPP 集群提供数据可靠性保障,备库只做数据容灾、备份,MPP 备库并不是 MPP 集群的一部分,只是某个 MPP 节点(主库)的镜像。MPP 备库不参与 MPP 操作,与其他 MPP 备库之间也没有任何关系,MPP 备库只能以单节点方式提供只读服务,但不提供全局的 MPP 只读服务。
MPP 主备系统中,一个守护进程 dmwatcher 可以监控、管理多个守护进程组的数据库实例。一般来说,一台物理机器上,可以部署 1 个 MPP 节点的主库和多个其他 MPP 节点的备库,充分利用硬件资源,节省投资。
Global 守护类型的 MPP 主备库需要在 dm.ini 中配置 MPP_INI 为 1,并且 MPP 主备库的本地数据文件目录下都需要有 dmmpp.ctl 文件,如果 Global 守护类型的备库没有上述配置,守护进程和监视器无法正常使用,守护进程会切换到 Shutdown 状态,监视器上无法正常执行命令,会打印配置不一致的提示信息。
下图以三个 MPP 节点,每个节点配备两个备库为例,说明 MPP 主备系统的结构。
在这里插入图片描述

2.6 读写分离集群

读写分离集群是基于即时归档或实时归档实现的高性能数据库集群,不但提供数据保护、容灾等数据守护基本功能,还具有读写操作自动分离、负载均衡等特性。读写分离集群最多可以配置 8 个即时备库或 8 个实时备库,提供数据同步、备库故障自动处理、故障恢复自动数据同步等功能,也支持自动故障切换和手动故障切换两种守护模式。

一般情况下,应用系统中查询等只读操作的比例远大于 Insert/Delete/Update 等 DML 操作,修改对象定义等 DDL 操作的比例则更低。但是,这些操作往往混杂在一起,在高并发、高压力情况下,会导致数据库性能下降,响应时间变长。借助读写分离集群,将只读操作自动分发到备库执行,可以充分利用备库的硬件资源,降低主库的并发访问压力,进而提升数据库的吞吐量。

读写分离集群不依赖额外的中间件,而是通过数据库接口与数据库之间的密切配合,实现读、写操作自动分离特性。DM 的 JDBC、DPI、DCI、ODBC、Provider、dmPython 等接口都可以用来部署读写分离集群。

根据是否满足读提交事务隔离级特性,读写分离集群可以配置为事务一致模式和高性能两种模式。简单的说,事务一致模式下,不论一个 Select 语句是在备库执行、还是在主库执行,其查询结果集都是一样的。高性能模式则不能保证查询是一致的,备库的数据与主库的数据同步存在一定的延迟,当 Select 语句发送到备库执行时,返回的有可能是主库上一个时间点的数据。

2.7 DMDSC数据守护

DMDSC(数据共享集群)支持多个数据库实例同时访问、修改保存在共享存储中的数据,能够提供更高的数据库可用性和事务吞吐量。但由于数据是保存在共享存储上,当出现存储失效等故障时,数据库服务将会中断。
在这里插入图片描述

DM 数据守护包含多个数据库,主库和备库部署在不同的机器上,数据分别保存在各自的存储上,主库传递 Redo 日志到备库,备库重演 Redo 日志实现数据同步。因此,DM 数据守护在容灾(特别是异地容灾)方面具有明显的优势。为了进一步提高 DMDSC 集群的数据安全性,以及系统的可用性,DM 提供了 DMDSC 集群数据守护功能。

DMDSC 集群数据守护功能与单节点数据守护保持一致,支持故障自动切换,支持实时归档与读写分离集群。支持 DMDSC 集群的守护,DMDSC(主)和 DMDSC(备)、DMDSC(主)和单节点(备)、单节点(主)和 DMDSC(备)相互之间都可以作为主备库的数据守护。

2.8 异步备库

异步备库一般用于历史数据统计、周期报表等对数据实时性要求不高的业务场合。异步归档时机可以选择在源库空闲的时候,可避免源库的业务高峰期同步数据对性能的影响。

每个 Primary 或者 Standby 模式的库都可以配置最多 8 个异步备库。配置了异步备库的 Primary 或者 Standby 模式的库,统称为源库。可以在实时主备、MPP 主备和读写分离集群的主库和备库上配置异步备库,异步备库可级联配置,异步备库本身也可以作为源库配置异步备库。一个监视器最多可以同时监视 16 个异步备库。

配置了 Realtime 和 Timely 归档的主备库,允许配置同一个异步备库,也就是说一个异步备库允许有多个源库。系统自动识别,Primary 模式的源库负责向异步备库同步数据,主备库切换后,由新主库负责向异步备库同步数据。这种多源配置的异步备库,可以保证异步备库始终与当前的有效主库保持数据同步。但是,未配置 Realtime 和 Timely 归档的库,不能配置同一个异步备库。对于级联方式配置的异步备库,也就是异步备库自己作为源库的情况下,仍然需要由用户保证配置的正确性,避免数据同步异常。错误配置多个源库的情况下,多个源库可能同时、或交错向异步备库发送归档日志,导致备库日志连续性校验失败。

配置异步备库十分简单,在源库的 dm.ini 中打开定时器 TIMER_INI 开关,同时配置文件 dmtimer.ini,在 dmarch.ini 中增加异步归档配置,在 dmmal.ini 中增加异步备库的 mal 配置,由定时器定时触发源库发送归档日志到异步备库即可。异步归档的最小触发间隔是 1 分钟,详细的配置示例请参考 7.6 配置异步备库小节。异步备库可以不配置本地归档。

下图中,“源库 P”表示 Primary 模式的库,“源库 S”表示 Standby 模式的库,“源库 S”上允许配置到同一个异步备库的异步归档,但只有“源库 P”会向异步备库同步数据,对于级联方式配置的异步备库,不允许有多个源库。
在这里插入图片描述

2.9 同步备库

同步备库一般用于对主库性能要求较高,想要避免因备库故障或异步恢复引发的 Suspend 状态切换,但又希望备库的数据延迟不要太大的场合。与实时归档相比,同步归档时机为主库本地归档刷盘之后,主库发送归档到同步备库失败时,不会切换为 Suspend 状态,而是直接将备库的归档状态设置为无效。

同步备库不支持级联配置。Primary 模式的库可以配置最多 8 个同步归档,而 Standby 模式的库只有在配置了实时/即时归档的情况下才允许配置同步归档,这种情况下同样最多可以配置 8 个同步归档。只有 Primary 模式的库会向同步备库发送数据,Standby 模式的库即使配置了同步归档也不会生效。

与异步备库相似,同步备库的守护进程也需要配置为 LOCAL 类型,因此同步备库不支持主备库切换、备库接管等操作。若有将同步备库切换为主库的需要,可以手动执行 sql 语句将其切换为 PRIMARY 模式,但此时数据守护系统并不能保证该操作的正确性,需要由用户自身确认。

配置了 Realtime 和 Timely 归档的主备库,允许配置同一个同步备库。系统自动识别,Primary 模式的库负责向同步备库同步数据,主备库切换后,由新主库负责向同步备库同步数据。这种多源配置的同步备库,可以保证同步备库始终与当前的有效主库保持数据同步。Raft 和 Remote 归档不能与同步归档共存,并且当整个归档配置文件中存在归档目标为 DSC 库的配置项时,也不能再配置同步归档,反之亦然。

配置同步备库十分简单,在 dmarch.ini 中增加同步归档配置,在 dmmal.ini 中增加同步备库的 mal 配置项即可。详细的配置示例请参考[7.7 配置同步备库](#7.7 配置同步备库)小节。同步备库可以不配置本地归档。

2.10 Huge表

DM 的 Huge 表存储使用独立的存储机制,分别存储在数据文件和辅助表中。数据文件以数据区为单位进行管理,一个数据区可以存储单列数据的若干行,辅助表则是普通的行表,用于存放控制信息或者部分 Huge 表数据。
Huge 表又分为非事务型 Huge 表和事务型 Huge 表,其中非事务型 Huge 表不具备事务特性,因此数据守护 V4.0 不再对这种类型的 Huge 表进行支持,仅支持事务型 Huge 表的主备数据同步。
数据守护 V4.0 支持对事务型 Huge 表生成普通的 Redo 日志,和普通行表采用相同的数据同步机制,备库可以直接通过重演 Redo 日志来完成 Huge 表数据的同步,并且不区分实时主备、读写分离集群或者 MPP 主备,这三类数据守护系统都可以支持此功能,由于 Huge 表特殊的存储及管理方式,DMDSC 集群目前无法支持 Huge 表,也就是仅限于在单节点的数据守护系统中使用 Huge 表。
需要注意的是,在搭建数据守护系统时,需要将建库参数 HUGE_WITH_DELTA 和 RLOG_GEN_FOR_HUGE 都配置为 1,才能够正常生成 Huge 表 Redo 日志并发送给备库重演。对升级上来的老的数据守护系统,这两个建库参数则按照 0 值处理,Huge 表不会生成 Redo 日志并且不支持主备数据同步。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值