DM数据守护一主一备或一主多备是一种集成化的高可用、高性能数据库解决方案,是数据库异地容灾的首选方案。通过部署 DM 数据守护,可以在硬件故障(如磁盘损坏)、自然灾害(地震、火灾)等极端情况下,避免数据损坏、丢失,保障数据安全,并且可以快速恢复数据库服务,满足用户不间断提供数据库服务的要求。与常规的数据库备份(Backup)、 还原(Restore)技术相比,数据守护可以更快地恢复数据库服务。随着数据规模不断增长,通过还原手段恢复数据,往往需要数个小时、甚至更长时间,而数据守护基本不受数据规模的影响,只需数秒时间就可以将备库切换为主库对外提供数据库服务。
DM 数据守护(DM Data Watch)的实现原理非常简单:将主库(生产库)产生的 Redo日志传输到备库,备库接收并重新应用 Redo 日志,从而实现备库与主库的数据同步。DM数据守护的核心思想是监控数据库状态,获取主、备库数据同步情况,为 Redo 日志传输与重演过程中出现的各种异常情况提供一系列的解决方案。
DM 数据守护系统结构图如下。主要由主库、备库、Redo 日志、Redo 日志传输、 Redo 日志重演、守护进程(dmwatcher)、监视器(dmmonitor)组成。
DM主备守护集群包括:实时主备、读写分离集群、MPP主备集群。都是基于redo日志来实现的,不同的集群采用不同的redo日志归档类型。
一、基本概念介绍
数据库与数据库实例
数据库(Database)是一个文件集合(包括数据文件、临时文件、重做日志文件和控制文件),保存在物理磁盘或文件系统中。
数据库实例(Instance)就是一组操作系统进程(或者是一个多线程的进程)以及一些内存。通过数据库实例,可以操作数据库,一般情况下,我们访问、修改数据库都是通过数据库实例来完成的。
数据守护以库为单位进行管理,一个 DMDSC 集群的所有实例作为一个整体库来考虑。DMDSC 集群的库信息,例如库的状态、模式等需要综合考虑集群内所有实例,同时需要结合 DMDSC 本身的状态。
数据库模式
DM 支持 3 种数据库模式:Normal 模式、Primary 模式和 Standby 模式。
Normal 模式
提供正常的数据库服务,操作没有限制。正常生成本地归档,但不发送实时归档
(Realtime)、即时归档(Timely)和异步归档(Async)。
Primary 模式
提供正常的数据库服务(可读写),操作有极少限制。该模式下部分功能受限,包括:不支持修改表空间文件名、不支持修改 arch_ini 参数。正常生成本地归档,支持实时归档 (Realtime)、即时归档(Timely)和异步归档(Async)。Primary 模式下,对临时表空间以外的所有的数据库对象的修改操作都强制生成 Redo 日志。
Standby 模式
可以执行数据库备份、查询等只读数据库操作。正常生成本地归档,正常发送异步归档Redo 日志;但实时归档(Realtime)、即时归档(Timely)均强制失效。该模式下时间触发器、事件触发器等都失效。
数据库状态
DM 的数据库状态包括:
Startup 状态
系统刚启动时设置为 Startup 状态。
After Redo 状态
系统启动过程中联机日志重做完成后,回滚活动事务前设置为 After Redo 状态。非 Standby 模式的实例在执行 alter database open 操作前,也会将系统设置为 After Redo 状态。
Open 状态
数据库处于正常提供服务的状态,但不能进行归档配置等操作。
Mount 状态
数据库在 Mount 状态下,不能修改数据,不能访问表、视图等数据库对象,但可以执行修改归档配置、控制文件和修改数据库模式等操作,也可以执行一些不修改数据库内容的操作,比如查询动态视图或者一些只读的系统过程。由于 Mount 状态不生成PWR 日志,因此数据页可以正常刷盘,也正常推进检查点。
Suspend 状态
数据库在 Suspend 状态下,可以访问数据库对象,甚至可以修改数据,但限制 Redo日志刷盘,一旦执行 COMMIT 等触发 Redo 日志刷盘的操作时,当前操作将被挂起。
Shutdown 状态
实例正常退出时设置为 Shutdown 状态。
LSN 介绍
LSN(Log Sequence Number)是由系统自动维护的 Bigint 类型数值,具有自动DM 数据守护与读写分离集群 V4.0递增、全局唯一特性,每一个 LSN 值代表着 DM 系统内部产生的一个物理事务。物理事务 (Physical Transaction,简称 ptx)是数据库内部一系列修改物理数据页操作的集合,
与数据库管理系统中事务(Transaction)概念相对应,具有原子性、有序性、无法撤销等特性。
Redo 日志
Redo 日志包含了所有物理数据页的修改内容,Insert/delete/update 等 DML 操作、Create Table 等 DDL 操作,最终都会转化为对物理数据页的修改,这些修改都会反映到 Redo 日志中。一般说来一条修改数据的 SQL 语句(比如 Insert),在系统内部会转化为多个相互独立的物理事务来完成,物理事务提交时会将产生的 Redo 日志写入日志包RLOG_PKG 中。
Redo 日志传输
主备库之间的 Redo 日志传输,以日志包 RLOG_PKG 为单位,主库通过 MAL 系统发送Redo 日志到备库。各种不同数据守护类型的区别,就在于主库日志包 RLOG_PKG 的发送时 机,以及备库收到 Redo 日志后的处理策略。
联机 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记录,并重新修改对应数据页内容,确保将数据恢复到系统故障前状态。
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 日志到备库。
KEEP_PKG 介绍
主库的RLOG_PKG日志通过实时归档机制发送到备库后,备库将最新收到的RLOG_PKG保存在内存中,不马上启动重演,这个 RLOG_PKG 我们称之为 KEEP_PKG。引入 KEEP_PKG的主要目的是,避免下述场景中,主库故障重启后不必要的主备切换,减少用户干预。
Redo 日志重演
Redo 日志重演的过程,就是备库收到主库发送的 Redo 日志后,在物理数据页上,重新修改数据的过程。Redo 日志重演由专门的 Redo 日志重演服务完成,重演服务严格按照Redo 日志产生的先后顺序,解析 Redo 日志、修改相应的物理数据页,并且重演过程中备库会生成自身的 Redo 日志写入联机日志文件。
守护进程
守护进程(dmwatcher)是数据守护系统的核心工具,监控数据库实例的运行状态和主备库数据同步情况,在出现故障时启动各种处理预案。守护进程是各种消息的中转站,接收数据库实例、其他守护进程、以及监视器发送的各种消息;同时,守护进程也会将收到的数据库实例消息转发给其他守护进程和监视器。守护进程必须和被守护的数据库实例部署在同一台机器上。
监视器
监视器(dmmonitor)用来监控守护系统内守护进程、数据库实例信息,执行用户输入命令、监控实例故障、实现自动切换等。监视器一般配置在数据库实例和守护进程以外的机器上。
归档介绍
归档是实现数据守护系统的重要技术手段,根据功能与实现方式的不同,DM 数据库的归档可以分为 5 类:本地归档、远程归档、实时归档、即时归档和异步归档。其中,本地归档和远程归档日志的内容与写入时机与数据库模式相关;主库 Redo 日志写入联机日志文件后,再进行本地归档和远程归档;备库收到主库产生的 Redo 日志后,直接进行本地归档和远程归档,同时启动 Redo 日志重演。
DM单机:本地归档
数守护集群:本地归档、实时归档、异步归档
读写分离集群:本地归档、即时归档
MPP主备集群:本地归档、实时归档
归档区别
MAL 系统
MAL 系统是基于 TCP 协议实现的一种内部通信机制,具有可靠、灵活、高效的特性。DM 通过 MAL 系统实现 Redo 日志传输,以及其他一些实例间的消息通讯。DM 数据守护与读写分离集群 V4.0
OGUID
数据守护唯一标识码,配置数据守护时,需要由用户指定 OGUID 值。其中数据库的OGUID 在 MOUNT 状态下由系统函数 SP_SET_OGUID 设置,守护进程和监视器的 OGUID 值在配置文件中设定。同一守护进程组中的所有数据库、守护进程和监视器,都必须配置相同的 OGUID 值,取值范围为 0~2147483647。
二、实时主备、MPP主备、读写分离集群介绍
实时主备
实时主备系统由主库、实时备库、守护进程和监视器组成。通过部署实时主备系统,可以及时检测并处理各种硬件故障、数据库实例异常,确保持续提供数据库服务。
实时主备由一个主库以及一个或者多个配置了实时(Realtime)归档的备库组成,其主要目的是保障数据库可用性,提高数据安全性。实时主备系统中,主库提供完整的数据库功能,备库提供只读服务。主库修改数据产生的Redo日志,通过实时归档机制,在写入联机Redo日志文件之前发送到备库,实时备库通过重演Redo日志与主库保持数据同步。当主库出现故障时,备库在将所有Redo日志重演结束后,就可以切换为主库对外提供数据库服务。
主要功能
- 实时数据同步
- 主备库切换
- 自动故障处理
- 自动数据同步
- 备库接管
- 备库强制接管
- 读写分离访问
归档流程
实时归档是实时主备数据同步的基础,其流程如下图所示:
主库生成联机 Redo 日志,当触发日志写文件操作后,日志线程先将 RLOG_PKG 发送到备库,备库接收后进行合法性校验(包括日志是否连续、备库状态是否 Open 等),不合法则返回错误信息,合法则作为 KEEP_PKG 保留在内存中,原有 KEEP_PKG 的 Redo 日志加入 Apply 任务队列进行 Redo 日志重演,并响应主库日志接收成功。
MPP主备
MPP主备就是在MPP集群的基础上,为每一个MPP节点配置一套实时主备系统,这些实时主备系统一起构成了MPP主备系统。我们将一个MPP节点对应的主备系统称为一个数据守护组(Group),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 主备系统的结构。
读写分离集群
读写分离集群由一个主库以及一个或者多个配置了即时(Timely)归档或实时 (Realtime)归档的备库组成,其主要目标是在保障数据库可用性基础上,实现读、写操作的自动分离,进一步提升数据库的业务支撑能力。读写分离集群通过配置事务一致模式保证主、备库数据一致性,并配合达梦数据库管理系统的各种接口(JDBC、DPI等),将只读操作自动分流到备库,有效降低主库的负载,提升系统吞吐量。
读写分离集群提供数据保护、容灾等数据守护基本功能,还具有读写操作自动分离、负载均衡等特性。读写分离集群最多可以配置 8 个即时备库或 8 个实时备库,提供数据同步、备库故障自动处理、故障恢复自动数据同步等功能,也支持自动故障切换和手动故障切换两种守护模式。
归档流程
读写分离集群可以配置为即时归档,也可以配置为实时归档,这两种配置方式仅仅是归档流程上有差别,读写分离集群的特性仍然是一致的。即时归档流程与实时归档流程存在一定差异。
实现原理
实现读写分离集群的基本思路是:利用备库提供只读服务、无法修改数据的特性,优先将所有操作发送到备库执行,一旦备库执行报错,则发送到主库重新执行。通过备库“试错” 这么一个步骤,自然地将只读操作分流到备库执行。并且,备库“试错”由接口层自动完成,对应用透明。
读写分离集群数据库连接创建流程:
1. 用户发起数据库连接请求。
2. 接口(JDBC、DPI 等)根据服务名配置(在 dm_svc.conf 中进行配置)登录主库。
3. 主库挑选一个有效即时备库的 IP/Port 返回给接口。
4. 接口根据返回的备库 IP 和 Port 信息,向备库发起一个连接请求。
5. 备库返回连接成功信息。
6. 接口响应用户数据库连接创建成功。
接口在备库上创建的连接是读写分离集群自动创建的;对用户而言,就是在主库上创建了一个数据库连接。下图以配置了两个备库的读写集群为例,说明了读写分离集群的连接创建流程。
读写分离集群语句分发流程:
1. 接口收到用户的请求。
2. 接口优先将 SQL 发送到备库执行。
3. 备库执行并返回执行结果。如果接口收到的是备库执行成功消息,则转到第 6 步,
如果接口收到的是备库执行失败消息,则转到第 4 步。
4. 重新将执行失败的 SQL 发送到主库执行。只要第 3 步中的 SQL 在备库执行失败,
则同一个事务后续的所有操作(包括只读操作)都会直接发送到主库执行。
5. 主库执行并返回执行结果给接口。一旦主库上执行的写事务提交,则下次继续从第
1 步开始执行。
6. 接口响应用户并将执行结果返回给用户。
高性能与事务一致性
高性能:备机收到重演日志,加到重演线程队列后响应主机,主机不需要等待备机重演完成后在响应主库。
事务一致性:备机收到重演日志,重演完成后响应主机,主机需要等待备机重演完成后响应主机。
数据守护集群的高性能与事务一致性是由归档参数ARCH_WAIT_APPLY参数控制的。
备库收到Redo日志后,是否需要重演完成后再响应主库。0表示收到马上响应(高性能模式),1表示重演完成后响应 (事务一致模式)。配置为即时归档的读写分离集群时,默
认值为1;配置为实时归档的读写分离集群时,默认值为0。
实时归档的读写分离
实时主备也可以配置接口的读写分离属性进行访问,实现读写分离功能特性。实时读写分离同样也支持事务一致模式和高性能模式,由配置文件 dmarch.ini 中的ARCH_WAIT_APPLY 配置项来确定,1 表示事务一致模式,0 表示高性能模式,实时读写分离下,默认值为 0,即采用高性能模式。这个参数在实时归档中的用法和在即时归档中是相同的,只是默认值不同。
和即时归档不同的是,实时归档先发送日志到备库,然后再写入本地联机日志,和即时归档相比,实时归档的读写分离可以有效避免备库自动接管后老主库的分裂,在对读写分离集群的可用性要求比较高的情况下,可以采用这种配置方式。
达梦在线服务平台:https://eco.dameng.com