一.DMDW概念
DM 数据守护(DM Data Watch)的实现原理非常简单:将主库(生产库)产生的 Redo 日志传输到备库,备库接收并重新应用 Redo 日志,从而实现备库与主库的数据同步。DM 数据守护的核心思想是监控数据库状态,获取主、备库数据同步情况,为 Redo 日志传输与 重演过程中出现的各种异常情况提供一系列的解决方案。 DM 数据守护系统结构参考图 2.1。主要由主库、备库、Redo 日志、Redo 日志传输、 Redo 日志重演、守护进程(dmwatcher)、监视器(dmmonitor)组成。
1.1 主库
Primary 模式,提供完整数据库服务的实例,一般来说主库是用来直接支撑应用系统的 生产库。
1.2 备库
Standby 模式,提供只读数据库服务的实例。备库除了用于容灾,还可以提供备份、 查询等只读功能,并且备库还支持临时表的 Insert/Delete/Update 操作。 备库支持临时表修改主要基于两个因素:1.临时表数据的修改不会产生 Redo 日志,主 库对临时表的修改无法同步到备库;2.可以提供更大灵活性,适应更多应用场景。 根据数据同步情况,备库又可以分为可切换备库和不可切换备库。可切换备库是指,主 备库之间数据完全同步,主库发生故障、备库切换为主库后,不会造成任何数据丢失的备库。
1.3 Redo 日志
Redo 日志记录物理数据页内容变动情况,是数据库十分重要的一个功能,在数据库系 统故障(比如服务器掉电)重启时,利用 Redo 日志可以把数据恢复到故障前的状态。 Redo 日志也是数据守护的实现基础,数据库中 Insert、Delete、Update 等 DML 操作 以及 Create TABLE 等 DDL 操作最终都会体现为对某一个或者多个物理数据页的修改,因 此备库通过重做 Redo 日志可以与主库数据保持一致。
1.4 Redo 日志传输
主备库之间的 Redo 日志传输,以日志包 RLOG_PKG 为单位,主库通过 MAL 系统发 送 Redo 日志到备库。各种不同数据守护类型的区别,就在于主库日志包 RLOG_PKG 的发 送时机,以及备库收到 Redo 日志后的处理策略。
1.5 Redo 日志重演
DM8 数据守护与读写分离集群 V4.0 5 Redo 日志重演的过程,就是备库收到主库发送的 Redo 日志后,在物理数据页上,重 新修改数据的过程。Redo 日志重演由专门的 Redo 日志重演服务完成,重演服务严格按照 Redo 日志产生的先后顺序,解析 Redo 日志、修改相应的物理数据页,并且重演过程中备 库会生成自身的 Redo 日志写入联机日志文件。
1.6 守护进程
守护进程(dmwatcher)是数据守护系统的核心工具,监控数据库实例的运行状态和 主备库数据同步情况,在出现故障时启动各种处理预案。守护进程是各种消息的中转站,接 收数据库实例、其他守护进程、以及监视器发送的各种消息;同时,守护进程也会将收到的 数据库实例消息转发给其他守护进程和监视器。守护进程必须和被守护的数据库实例部署在 同一台机器上。
1.7 监视器
监视器(dmmonitor)用来监控守护系统内守护进程、数据库实例信息,执行用户输 入命令、监控实例故障、实现自动切换等。监视器一般配置在数据库实例和守护进程以外的 机器上。
(概念部分出自《DM8数据守护与读写分离集群V4.0》)
二.部署DMDW集群
2.1 安装达梦数据库:
三台虚拟机全都部署达梦数据库
[root@bogon ~]# mkdir /dm8 <!--安装目录-->
[root@bogon ~]# groupadd dinstall
[root@bogon ~]# useradd -g dinstall -m -d /home/dmdba -s /bin/bash dmdba
[root@bogon ~]# chown dmdba:dinstall -R /dm8/
[root@bogon ~]# chmod -R 755 /dm8/
[root@bogon ~]# passwd dmdba
[root@bogon ~]# mount -o loop /opt/dm8_20231109_x86_kylin10_64.iso /mnt
mount: /mnt: WARNING: source write-protected, mounted read-only.
[root@bogon ~]# su - dmdba
[dmdba@bogon ~]$ cd /mnt
[dmdba@bogon mnt]$ ./DMInstall.bin -i
[dmdba@bogon mnt]$ su - root
[root@bogon ~]# /dm8/script/root/root_installer.sh
2.2 主库操作:
[dmdba@master ~]$ cd /dm8/bin
<!--创建实例-->
[dmdba@master bin]$ ./dminit PATH=/dm8/data DB_NAME=TEST01 INSTANCE_NAME=TEST01 EXTENT_SIZE=16 PAGE_SIZE=8 CASE_SENSITIVE=Y
[dmdba@master root]$ su - root
[root@master ~]# cd /dm8/script/root/
<!--注册服务-->
[root@master root]# ./dm_service_installer.sh -t dmserver -p TEST01 -dm_ini /dm8/data/TEST01/dm.ini
[root@master root]# su - dmdba
[root@master root]# mkdir /dm8/backup <!--备份目录-->
[dmdba@master ~]$ cd /dm8/bin
<!--备份-->
[dmdba@master bin]$ ./dmrman
dmrman V8
RMAN> BACKUP DATABASE '/dm8/data/TEST01/dm.ini' FULL TO BK_01 BACKUPSET '/dm8/backup/BK_01'
[dmdba@master ~]$ ls /dm8/backup/BK_01/
BK_01.bak BK_01.meta
[dmdba@master ~]$ scp -r /dm8/backup/BK_01/ dmdba@192.168.200.193:/dm8/backup
2.2.1 修改配置文件:
<!--修改dm.ini-->
[dmdba@master bin]$ ./DmServiceTEST01 start
Starting DmServiceTEST_01: [ OK ]
[dmdba@master bin]$ ./disql SYSDBA/SYSDBA@LOCALHOST:5236
服务器[LOCALHOST:5236]:处于普通打开状态
登录使用时间 : 9.833(ms)
disql V8
SQL> ALTER DATABASE MOUNT;
SQL> ALTER DATABASE ARCHIVELOG;
SQL> ALTER DATABASE ADD ARCHIVELOG 'DEST=/dm8/arch, TYPE=LOCAL, FILE_SIZE=256, SPACE_LIMIT=51200';
SQL> ALTER DATABASE OPEN;
SQL> SP_SET_PARA_VALUE (2,'DW_INACTIVE_INTERVAL',60);
SQL> SP_SET_PARA_VALUE (2,'ALTER_MODE_STATUS',0);
SQL> SP_SET_PARA_VALUE (2,'ENABLE_OFFLINE_TS',2);
SQL> SP_SET_PARA_VALUE (2,'MAL_INI',1);
SQL> SP_SET_PARA_VALUE (2,'RLOG_SEND_APPLY_MON',64);
SQL> exit
<!--修改dmarch.ini-->
[dmdba@master ~]$ cd /dm8/data/TEST01/
[dmdba@master TEST01]$ vim dmarch.ini
[ARCHIVE_REALTIME]
ARCH_TYPE = REALTIME #实时归档类型
ARCH_DEST = TEST02 #实时归档目标实例名
[ARCHIVE_LOCAL1]
ARCH_TYPE = LOCAL #本地归档类型
ARCH_DEST = /dm8/arch #本地归档文件存放路径
ARCH_FILE_SIZE = 128 #单位 Mb,本地单个归档文件最大值
ARCH_SPACE_LIMIT = 0 #单位 Mb,0 表示无限制,范围 1024~2147483647M
<!--创建dmmal.ini-->
[dmdba@master TEST01]$ vim dmmal.ini
MAL_CHECK_INTERVAL = 5 #MAL 链路检测时间间隔
MAL_CONN_FAIL_INTERVAL = 5 #判定 MAL 链路断开的时间
[MAL_INST1]
MAL_INST_NAME = TEST01 #实例名,和 dm.ini 中的 INSTANCE_NAME 一致
MAL_HOST = 192.168.200.192 #MAL 系统监听 TCP 连接的 IP 地址
MAL_PORT = 55101 #MAL 系统监听 TCP 连接的端口
MAL_INST_HOST = 192.168.200.192 #实例的对外服务 IP 地址
MAL_INST_PORT = 5236 #实例的对外服务端口,和 dm.ini 中的 PORT_NUM 一致
MAL_DW_PORT = 65101 #实例本地的守护进程监听 TCP 连接的端口
MAL_INST_DW_PORT = 45101 #实例监听守护进程 TCP 连接的端口
[MAL_INST2]
MAL_INST_NAME = TEST02 #实例名,和 dm.ini 中的 INSTANCE_NAME 一致
MAL_HOST = 192.168.200.193 #MAL 系统监听 TCP 连接的 IP 地址
MAL_PORT = 55121 #MAL 系统监听 TCP 连接的端口
MAL_INST_HOST = 192.168.200.193 #实例的对外服务 IP 地址
MAL_INST_PORT = 5236 #实例的对外服务端口,和 dm.ini 中的 PORT_NUM 一致
MAL_DW_PORT = 65121 #实例本地的守护进程监听 TCP 连接的端口
MAL_INST_DW_PORT = 45121 #实例监听守护进程 TCP 连接的端口
<!--创建dmwatcher.ini-->
[dmdba@master TEST01]$ vim dmwatcher.ini
[GRP1]
DW_TYPE = GLOBAL #全局守护类型
DW_MODE = AUTO #自动切换模式
DW_ERROR_TIME = 10 #远程守护进程故障认定时间
INST_RECOVER_TIME = 60 #主库守护进程启动恢复的间隔时间
INST_ERROR_TIME = 10 #本地实例故障认定时间
INST_OGUID = 453331 #守护系统唯一 OGUID 值
INST_INI = /dm8/data/TEST01/dm.ini #dm.ini 配置文件路径
INST_AUTO_RESTART = 1 #打开实例的自动启动功能
INST_STARTUP_CMD = /dm8/bin/dmserver #命令行方式启动
RLOG_SEND_THRESHOLD = 0 #指定主库发送日志到备库的时间阈值,默认关闭
RLOG_APPLY_THRESHOLD = 0 #指定备库重演日志的时间阈值,默认关闭
2.2.2 打开主库模式
<!--用配置模式打开数据库服务,并修改oguid-->
./dmserver /dm8/data/TEST01/dm.ini mount
./disql SYSDBA/SYSDBA@LOCALHOST:5236
SQL> sp_set_para_value(1,'ALTER_MODE_STATUS',1);
SQL> sp_set_oguid(453331);
SQL> alter database primary;
SQL> sp_set_para_value(1,'ALTER_MODE_STATUS',0);
2.3 从库操作
[dmdba@slave ~]$ cd /dm8/bin
<!--创建实例-->
[dmdba@slave bin]$ ./dminit PATH=/dm8/data DB_NAME=TEST02 INSTANCE_NAME=TEST_02 EXTENT_SIZE=16 PAGE_SIZE=8 CASE_SENSITIVE=Y
[dmdba@slave bin]$ su - root
[root@slave ~]# cd /dm8/script/root/
<!--注册服务-->
[root@slave root]# ./dm_service_installer.sh -t dmserver -p TEST_02 -dm_ini /dm8/data/TEST02/dm.ini
[root@slave root]# su - dmdba
[dmdba@slave ~]$ mkdir /dm8/backup <!--备份目录-->
[dmdba@slave ~]$ ls /dm8/backup/BK_01/
BK_01.bak BK_01.meta
[dmdba@slave ~]$ cd /dm8/bin
<!--备份还原-->
[dmdba@slave bin]$ ./dmrman
RMAN> restore database '/dm8/data/TEST02/dm.ini' from backupset '/dm8/backup/BK_01';
RMAN> recover database '/dm8/data/TEST02/dm.ini' from backupset '/dm8/backup/BK_01';
RMAN> recover database '/dm8/data/TEST02/dm.ini' update db_magic;
2.3.1 修改配置文件:
<!--修改dm.ini-->
[dmdba@slave bin]$ ./DmServiceTEST02 start
Starting DmServiceTEST_02: [ OK ]
[dmdba@slave bin]$ ./disql SYSDBA/SYSDBA@LOCALHOST:5236
服务器[LOCALHOST:5236]:处于普通打开状态
登录使用时间 : 9.833(ms)
disql V8
SQL> ALTER DATABASE MOUNT;
SQL> ALTER DATABASE ARCHIVELOG;
SQL> ALTER DATABASE ADD ARCHIVELOG 'DEST=/dm8/data/arch, TYPE=LOCAL, FILE_SIZE=256, SPACE_LIMIT=51200';
SQL> ALTER DATABASE OPEN;
SQL> SP_SET_PARA_VALUE (2,'DW_INACTIVE_INTERVAL',60);
SQL> SP_SET_PARA_VALUE (2,'ALTER_MODE_STATUS',0);
SQL> SP_SET_PARA_VALUE (2,'ENABLE_OFFLINE_TS',2);
SQL> SP_SET_PARA_VALUE (2,'MAL_INI',1);
SQL> SP_SET_PARA_VALUE (2,'RLOG_SEND_APPLY_MON',64);
SQL> exit
<!--创建dmmal.ini-->
[dmdba@slave TEST02]$ vim dmmal.ini
MAL_CHECK_INTERVAL = 5 #MAL 链路检测时间间隔
MAL_CONN_FAIL_INTERVAL = 5 #判定 MAL 链路断开的时间
[MAL_INST1]
MAL_INST_NAME = TEST01 #实例名,和 dm.ini 中的 INSTANCE_NAME 一致
MAL_HOST = 192.168.200.192 #MAL 系统监听 TCP 连接的 IP 地址
MAL_PORT = 55101 #MAL 系统监听 TCP 连接的端口
MAL_INST_HOST = 192.168.200.192 #实例的对外服务 IP 地址
MAL_INST_PORT = 5236 #实例的对外服务端口,和 dm.ini 中的 PORT_NUM 一致
MAL_DW_PORT = 65101 #实例本地的守护进程监听 TCP 连接的端口
MAL_INST_DW_PORT = 45101 #实例监听守护进程 TCP 连接的端口
[MAL_INST2]
MAL_INST_NAME = TEST02 #实例名,和 dm.ini 中的 INSTANCE_NAME 一致
MAL_HOST = 192.168.200.193 #MAL 系统监听 TCP 连接的 IP 地址
MAL_PORT = 55121 #MAL 系统监听 TCP 连接的端口
MAL_INST_HOST = 192.168.200.193 #实例的对外服务 IP 地址
MAL_INST_PORT = 5236 #实例的对外服务端口,和 dm.ini 中的 PORT_NUM 一致
MAL_DW_PORT = 65121 #实例本地的守护进程监听 TCP 连接的端口
MAL_INST_DW_PORT = 45121 #实例监听守护进程 TCP 连接的端口
<!--修改dmarch.ini-->
[dmdba@slave ~]$ cd /dm8/data/TEST02/
[dmdba@slave TEST02]$ vim dmarch.ini
[ARCHIVE_REALTIME]
ARCH_TYPE = REALTIME #实时归档类型
ARCH_DEST = TEST01 #实时归档目标实例名
[ARCHIVE_LOCAL1]
ARCH_TYPE = LOCAL #本地归档类型
ARCH_DEST = /dm8/arch #本地归档文件存放路径
ARCH_FILE_SIZE = 128 #单位 Mb,本地单个归档文件最大值
ARCH_SPACE_LIMIT = 0 #单位 Mb,0 表示无限制,范围 1024~2147483647M
<!--修改dmwatcher.ini-->
[dmdba@slave TEST02]$ vim dmwatcher.ini
[GRP1]
DW_TYPE = GLOBAL #全局守护类型
DW_MODE = AUTO #自动切换模式
DW_ERROR_TIME = 10 #远程守护进程故障认定时间
INST_RECOVER_TIME = 60 #主库守护进程启动恢复的间隔时间
INST_ERROR_TIME = 10 #本地实例故障认定时间
INST_OGUID = 453331 #守护系统唯一 OGUID 值
INST_INI = /dm8/data/TEST02/dm.ini #dm.ini 配置文件路径
INST_AUTO_RESTART = 1 #打开实例的自动启动功能
INST_STARTUP_CMD = /dm8/bin/dmserver #命令行方式启动
RLOG_SEND_THRESHOLD = 0 #指定主库发送日志到备库的时间阈值,默认关闭
RLOG_APPLY_THRESHOLD = 0 #指定备库重演日志的时间阈值,默认关闭
2.3.2 打开从库模式:
<!--用配置模式打开数据库服务,并修改oguid-->
./dmserver /dm8/data/TEST02/dm.ini mount
./disql SYSDBA/SYSDBA@LOCALHOST:5236
SQL> sp_set_para_value(1,'ALTER_MODE_STATUS',1);
SQL> sp_set_oguid(453331);
SQL> alter database standby;
SQL> sp_set_para_value(1,'ALTER_MODE_STATUS',0);
2.4 主备启动守护进程
一定要先启动主库守护进程
2.4.1 监视器操作:
[dmdba@bogon dm8]$ vim dmmonitor.ini
MON_DW_CONFIRM = 1 #确认监视器模式
MON_LOG_PATH = /dm8/data/log #监视器日志文件存放路径
MON_LOG_INTERVAL = 60 #每隔 60s 定时记录系统信息到日志文件
MON_LOG_FILE_SIZE = 32 #每个日志文件最大 32M
MON_LOG_SPACE_LIMIT = 0 #不限定日志文件总占用空间
[GRP1]
MON_INST_OGUID = 453331 #组 GRP1 的唯一 OGUID 值
MON_DW_IP = 192.168.200.192:65101
MON_DW_IP = 192.168.200.193:65121
启动监视器
/dm8/bin/dmmonitor /dm8/dmmonitor.ini
show查看信息
tip查看状态
三.手动切换主备并验证数据是否同步
3.1 验证当前数据是否可以同步
3.2 手动切换主备
login登入
switchover进行主备切换
可以看到TEST02变成了主库
验证切换主备后数据是否同步