在之前的博客我们看了实时主备环境的搭建,如下:
DM7 达梦 数据库 数据守护(Data Watch) (6) — 实时主备环境搭建
https://www.cndba.cn/dave/article/3675
本篇我们学习读写分离集群搭建。
1 环境说明
本示例中组名为“GRP2”,配置为实时主备,主库命名为“GRP2_RWW_01”,备库分别命名为“GRP2_RWW_02”和“GRP2_RWW_03”。
配置环境说明
主机类型 | IP地址 | 实例名 | 操作系统 |
---|---|---|---|
主库 | 192.168.20.193(外部服务) 192.168.56.193(内部通信) |
GRP2_RWW_01 | NeoKylin Linux General Server release 6.0 (Dhaulagiri) |
备库1 | 192.168.20.194(外部服务) 192.168.56.194(内部通信) |
GRP2_RWW_02 | NeoKylin Linux General Server release 6.0 (Dhaulagiri) |
备库2 | 192.168.20.195(外部服务) 192.168.56.195(内部通信) |
GRP2_RWW_03 | NeoKylin Linux General Server release 6.0 (Dhaulagiri) |
监控 | 192.168.56.190 | 确认监视器 | NeoKylin Linux General Server release 6.0 (Dhaulagiri) |
端口规划
实例名 | PORT_NUM | DW_PORT | MAL_HOST | MAL_PORT | MAL_DW_PORT |
---|---|---|---|---|---|
GRP2_RWW_01 | 5236 | 5336 | 192.168.56.193 | 5436 | 5536 |
GRP2_RWW_02 | 5237 | 5337 | 192.168.56.194 | 5437 | 5537 |
GRP2_RWW_03 | 5238 | 5338 | 192.168.56.195 | 5438 | 5538 |
2 数据准备
我们这里使用DMRMAN 备份进行数据同步。
2.1 创建主库实例
DM7 达梦数据库 通过dminit 创建 并 注册 数据库实例
https://www.cndba.cn/dave/article/3580
在主库使用dminit 创建GRP2_RWW_01实例:
[dave@www.cndba.cn3 ~]$ dminit PATH=/dm/dmdbms/data DB_NAME=CNDBA INSTANCE_NAME=GRP2_RWW_01
initdb V7.6.0.95-Build(2018.09.13-97108)ENT
db version: 0x7000a
file dm.key not found, use default license!
License will expire in 14 day(s) on 2029-03-26
log file path: /dm/dmdbms/data/CNDBA/CNDBA01.log
log file path: /dm/dmdbms/data/CNDBA/CNDBA02.log
write to dir [/dm/dmdbms/data/CNDBA].
create dm database success. 2029-03-12 08:58:50
[dave@www.cndba.cn3 ~]$
#注册服务:
[root@dm3 ~]# /dm/dmdbms/script/root/dm_service_installer.sh -t dmserver -i /dm/dmdbms/data/CNDBA/dm.ini -p GRP2_RWW_01
Move the service script file(/dm/dmdbms/bin/DmServiceGRP2_RWW_01 to /etc/rc.d/init.d/DmServiceGRP2_RWW_01)
Finished to create the service (DmServiceGRP2_RWW_01)
[root@dm3 ~]#
#启动DB:
[dave@www.cndba.cn3 bin]$ service DmServiceGRP2_RWW_01 start
Starting DmServiceGRP2_RWW_01: [ OK ]
[dave@www.cndba.cn3 bin]$
#启动归档模式:
[dave@www.cndba.cn3 bin]$ disql SYSDBA/SYSDBA
Server[LOCALHOST:5236]:mode is normal, state is open
login used time: 11.249(ms)
disql V7.6.0.95-Build(2018.09.13-97108)ENT
Connected to: DM 7.1.6.95
SQL> alter database mount;
executed successfully
used time: 00:00:01.766. Execute id is 0.
SQL> alter database add archivelog 'DEST=/dm/dmarch,TYPE=local,FILE_SIZE=128,space_limit=0';
executed successfully
used time: 2.975(ms). Execute id is 0.
SQL> alter database archivelog;
executed successfully
used time: 9.097(ms). Execute id is 0.
SQL> alter database open;
executed successfully
used time: 656.739(ms). Execute id is 0.
SQL>
2.2 使用DMRMAN备份主库
我们这里采用离线备份:
[dave@www.cndba.cn3 bin]$ service DmServiceGRP2_RWW_01 stop
Stopping DmServiceGRP2_RWW_01: [ OK ]
[dave@www.cndba.cn3 bin]$
[dave@www.cndba.cn3 bin]$ pwd
/dm/dmdbms/bin
[dave@www.cndba.cn3 bin]$ ./dmrman
dmrman V7.6.0.95-Build(2018.09.13-97108)ENT
RMAN> backup database '/dm/dmdbms/data/CNDBA/dm.ini' full backupset '/dm/rww_bak/db_full_bak_01';
backup database '/dm/dmdbms/data/CNDBA/dm.ini' full backupset '/dm/rww_bak/db_full_bak_01';
file dm.key not found, use default license!
checking if the database under system path [/dm/dmdbms/data/CNDBA] is running...[4].
checking if the database under system path [/dm/dmdbms/data/CNDBA] is running...[3].
checking if the database under system path [/dm/dmdbms/data/CNDBA] is running...[2].
checking if the database under system path [/dm/dmdbms/data/CNDBA] is running...[1].
checking if the database under system path [/dm/dmdbms/data/CNDBA] is running...[0].
checking if the database under system path [/dm/dmdbms/data/CNDBA] is running, write dmrman info.
EP[0] max_lsn: 44755
BACKUP DATABASE [CNDBA], execute......
CMD CHECK LSN......
BACKUP DATABASE [CNDBA], collect dbf......
CMD CHECK ......
DBF BACKUP SUBS......
total 1 packages processed...
total 3 packages processed...
total 4 packages processed...
DBF BACKUP MAIN......
BACKUPSET [/dm/rww_bak/db_full_bak_01] END, CODE [0]......
META GENERATING......
total 5 packages processed...
total 5 packages processed!
CMD END.CODE:[0]
backup successfully!
time used: 7069.838(ms)
#将备份分发到2个备库:
[dave@www.cndba.cn3 bin]$ cd /dm/rww_bak/
[dave@www.cndba.cn3 rww_bak]$ ls
db_full_bak_01
[dave@www.cndba.cn3 rww_bak]$ scp -r db_full_bak_01 192.168.20.194:`pwd`
dmdba@192.168.20.194's password:
db_full_bak_01.bak 100% 5326KB 5.2MB/s 00:00
db_full_bak_01.meta 100% 69KB 68.5KB/s 00:00
[dave@www.cndba.cn3 rww_bak]$ scp -r db_full_bak_01 192.168.20.195:`pwd`
dmdba@192.168.20.195's password:
db_full_bak_01.bak 100% 5326KB 5.2MB/s 00:01
db_full_bak_01.meta 100% 69KB 68.5KB/s 00:00
[dave@www.cndba.cn3 rww_bak]$
2.3 分别初始化2台备库并恢复数据
#初始化实例:
[dave@www.cndba.cn4 ~]$ dminit PATH=/dm/dmdbms/data DB_NAME=CNDBA INSTANCE_NAME=GRP2_RWW_02
initdb V7.6.0.95-Build(2018.09.13-97108)ENT
db version: 0x7000a
file dm.key not found, use default license!
License will expire in 14 day(s) on 2029-03-26
log file path: /dm/dmdbms/data/CNDBA/CNDBA01.log
log file path: /dm/dmdbms/data/CNDBA/CNDBA02.log
write to dir [/dm/dmdbms/data/CNDBA].
create dm database success. 2029-03-12 09:26:13
[dave@www.cndba.cn4 ~]$
#注册服务:
[root@dm4 ~]# /dm/dmdbms/script/root/dm_service_installer.sh -t dmserver -i /dm/dmdbms/data/CNDBA/dm.ini -p GRP2_RWW_02
Move the service script file(/dm/dmdbms/bin/DmServiceGRP2_RWW_02 to /etc/rc.d/init.d/DmServiceGRP2_RWW_02)
Finished to create the service (DmServiceGRP2_RWW_02)
[root@dm4 ~]#
#还原数据库
[dave@www.cndba.cn4 bin]$ ./dmrman CTLSTMT="RESTORE DATABASE '/dm/dmdbms/data/CNDBA/dm.ini' FROM BACKUPSET '/dm/rww_bak/db_full_bak_01'"
dmrman V7.6.0.95-Build(2018.09.13-97108)ENT
RESTORE DATABASE '/dm/dmdbms/data/CNDBA/dm.ini' FROM BACKUPSET '/dm/rww_bak/db_full_bak_01'
file dm.key not found, use default license!
Global parameter value of RT_HEAP_TARGET is illegal, use min value!
checking if the database under system path [/dm/dmdbms/data/CNDBA] is running...[4].
checking if the database under system path [/dm/dmdbms/data/CNDBA] is running...[3].
checking if the database under system path [/dm/dmdbms/data/CNDBA] is running...[2].
checking if the database under system path [/dm/dmdbms/data/CNDBA] is running...[1].
checking if the database under system path [/dm/dmdbms/data/CNDBA] is running...[0].
checking if the database under system path [/dm/dmdbms/data/CNDBA] is running, write dmrman info.
RESTORE DATABASE CHECK......
RESTORE DATABASE , dbf collect......
RESTORE DATABASE , dbf refresh ......
RESTORE BACKUPSET [/dm/rww_bak/db_full_bak_01] START......
total 4 packages processed...
RESTORE DATABASE , UPDATE ctl file......
RESTORE DATABASE , REBUILD key file......
RESTORE DATABASE , CHECK db info......
RESTORE DATABASE , UPDATE db info......
total 5 packages processed!
CMD END.CODE:[0]
restore successfully.
time used: 8341.679(ms)
[dave@www.cndba.cn4 bin]$
#恢复数据库:
[dave@www.cndba.cn4 bin]$ ./dmrman CTLSTMT="RECOVER DATABASE '/dm/dmdbms/data/CNDBA/dm.ini' FROM BACKUPSET '/dm/rww_bak/db_full_bak_01'"
dmrman V7.6.0.95-Build(2018.09.13-97108)ENT
RECOVER DATABASE '/dm/dmdbms/data/CNDBA/dm.ini' FROM BACKUPSET '/dm/rww_bak/db_full_bak_01'
file dm.key not found, use default license!
Global parameter value of RT_HEAP_TARGET is illegal, use min value!
checking if the database under system path [/dm/dmdbms/data/CNDBA] is running...[4].
checking if the database under system path [/dm/dmdbms/data/CNDBA] is running...[3].
checking if the database under system path [/dm/dmdbms/data/CNDBA] is running...[2].
checking if the database under system path [/dm/dmdbms/data/CNDBA] is running...[1].
checking if the database under system path [/dm/dmdbms/data/CNDBA] is running...[0].
checking if the database under system path [/dm/dmdbms/data/CNDBA] is running, write dmrman info.
EP[0] max_lsn: 44755
RESTORE RLOG CHECK......
CMD END.CODE:[603],DESC:[no log generates while the backupset [/dm/rww_bak/db_full_bak_01] created]
no log generates while the backupset [/dm/rww_bak/db_full_bak_01] created
recover successfully!
time used: 7050.939(ms)
[dave@www.cndba.cn4 bin]$
在另一个备库重复以上步骤。
3 配置主库 GRP2_RWW_01
3.1 配置 dm.ini
配置主库的实例名为 GRP2_RWW_01,dm.ini 参数修改如下:
#实例名,建议使用“组名_守护环境_序号”的命名方式,总长度不能超过 16
INSTANCE_NAME = GRP2_RWW_01
PORT_NUM = 5236 #数据库实例监听端口
DW_PORT = 5336 #守护环境下,监听守护进程连接端口
DW_ERROR_TIME = 60 #接收守护进程消息超时时间
ALTER_MODE_STATUS = 0 #不允许手工方式修改实例模式/状态
ENABLE_OFFLINE_TS = 2 #不允许备库 OFFLINE 表空间
MAL_INI = 1 #打开 MAL 系统
ARCH_INI = 1 #打开归档配置
HA_INST_CHECK_FLAG = 1 #检测是否多个实例进程同时启动
RLOG_SEND_APPLY_MON = 64 #统计最近 64 次的日志发送信息
3.2 配置 dmmal.ini
配置 MAL 系统,各主备库的 dmmal.ini 配置必须完全一致,MAL_HOST 使用内部网络 IP,MAL_PORT 与 dm.ini 中 PORT_NUM 使用不同的端口值,MAL_DW_PORT 是各实例对应的守护进程之间,以及守护进程和监视器之间的通信端口,配置如下:
MAL_CHECK_INTERVAL = 5 #MAL 链路检测时间间隔
MAL_CONN_FAIL_INTERVAL = 5 #判定 MAL 链路断开的时间
[MAL_INST1]
MAL_INST_NAME = GRP2_RWW_01 #实例名,和 dm.ini 中的 INSTANCE_NAME 一致
MAL_HOST = 192.168.56.193 #MAL 系统监听 TCP 连接的 IP 地址
MAL_PORT = 5436 #MAL 系统监听 TCP 连接的端口
MAL_INST_HOST = 192.168.20.193 #实例的对外服务 IP 地址
MAL_INST_PORT = 5236 #实例的对外服务端口,和 dm.ini 中的 PORT_NUM 一致
MAL_DW_PORT = 5536 #实例对应的守护进程监听 TCP 连接的端口
[MAL_INST2]
MAL_INST_NAME = GRP2_RWW_02
MAL_HOST = 192.168.56.194
MAL_PORT = 5437
MAL_INST_HOST = 192.168.20.194
MAL_INST_PORT = 5237
MAL_DW_PORT = 5537
[MAL_INST3]
MAL_INST_NAME = GRP2_RWW_03
MAL_HOST = 192.168.56.195
MAL_PORT = 5438
MAL_INST_HOST = 192.168.20.195
MAL_INST_PORT = 5238
MAL_DW_PORT = 5538
3.3 配置 dmarch.ini
修改 dmarch.ini,配置本地归档和即时归档。除了本地归档外,其他归档配置项中的 ARCH_DEST 表示实例是 Primary 模式时,需要同步归档数据的目标实例名。
当前实例 GRP2_RWW_01 是主库,需要向即时备库 GRP2_RWW_02/ GRP2_RWW_03同步数据,因此即时归档的 ARCH_DEST 分别配置为 GRP2_RWW_02 和 GRP2_RWW_03。
[ARCHIVE_TIMELY1]
ARCH_TYPE = TIMELY #即时归档类型
ARCH_DEST = GRP2_RWW_02 #即时归档目标实例名
[ARCHIVE_TIMELY2]
ARCH_TYPE = TIMELY #即时归档类型
ARCH_DEST = GRP2_RWW_03 #即时归档目标实例名
[ARCHIVE_LOCAL1]
ARCH_TYPE = LOCAL #本地归档类型
ARCH_DEST = /dm/dmarch #本地归档文件存放路径
ARCH_FILE_SIZE = 128 #单位 Mb,本地单个归档文件最大值
ARCH_SPACE_LIMIT = 0 #单位 Mb,0 表示无限制,范围 1024~4294967294M
3.4 配置 dmwatcher.ini
修改 dmwatcher.ini 配置守护进程,配置为全局守护类型,使用自动切换模式。
[GRP2]
DW_TYPE = GLOBAL #全局守护类型
DW_MODE = AUTO #自动切换模式
DW_ERROR_TIME = 10 #远程守护进程故障认定时间
INST_RECOVER_TIME = 60 #主库守护进程启动恢复的间隔时间
INST_ERROR_TIME = 10 #本地实例故障认定时间
INST_OGUID = 453332 #守护系统唯一 OGUID 值
INST_INI = /dm/dmdbms/data/CNDBA/dm.ini #dm.ini 配置文件路径
INST_AUTO_RESTART = 1 #打开实例的自动启动功能
INST_STARTUP_CMD = /dm/dmdbms/bin/dmserver #命令行方式启动
RLOG_SEND_THRESHOLD = 0 #指定主库发送日志到备库的时间阀值,默认关闭
RLOG_APPLY_THRESHOLD = 0 #指定备库重演日志的时间阀值,默认关闭
3.5 配置 dmwatcher.ctl
同一个守护进程组,必须使用同一份 dmwatcher.ctl。因此,只需要使用 dmctlcvt工具生成一份 dmwatcher.ctl 文件,然后分别拷贝到各个数据库目录下即可。
在配置完成 dmwatcher.ini 后,使用 dmctlcvt 工具生成 dmwatcher.ctl:
[dave@www.cndba.cn3 CNDBA]$ dmctlcvt TYPE=3 SRC=/dm/dmdbms/data/CNDBA/dmwatcher.ini DEST=/dm/dmdbms/data/CNDBA
DMCTLCVT V7.6.0.95-Build(2018.09.13-97108)ENT
Can not open ini file !
convert txt to ctl success!
#默认生成控制文件有个子目录,需要移动到父目录中:
#拷贝生成的 dmwatcher.ctl 文件到数据文件目录/dm/dmdbms/data/CNDBA。
[dave@www.cndba.cn3 CNDBA]$ cd GRP2/
[dave@www.cndba.cn3 GRP2]$ ls
dmwatcher.ctl
[dave@www.cndba.cn3 GRP2]$ mv dmwatcher.ctl ../
[dave@www.cndba.cn3 GRP2]$
3.6 启动主库
以 mount 方式启动主库
[dave@www.cndba.cn3 dmdbms]$ cd bin
[dave@www.cndba.cn3 bin]$ ./dmserver /dm/dmdbms/data/CNDBA/dm.ini mount
一定要以 mount 方式启动数据库实例,否则系统启动时会重构回滚表空间,生成 Redo 日志;并且,启动后应用可能连接到数据库实例进行操作,破坏主备库的数据一致性。数据守护配置结束后,守护进程会自动 Open 数据库。
3.7 设置 OGUID
启动命令行工具 DIsql,登录主库设置 OGUID 值。
SQL>sp_set_oguid(453332);
系统通过 OGUID 值确定一个守护进程组,由用户保证 OGUID 值的唯一性,并确保数据守护系统中,数据库、守护进程和监视器配置相同的 OGUID 值。
3.8 修改数据库模式
启动命令行工具 DIsql,登录主库修改数据库为 Primary 模式
SQL>alter database primary;
4 配置备库 GRP2_RWW_02
4.1 配置 dm.ini
配置备库的实例名为 GRP2_RWW_02,dm.ini 参数修改如下:
#实例名,建议使用“组名_守护环境_序号”的命名方式,总长度不能超过 16
INSTANCE_NAME = GRP2_RWW_02
PORT_NUM = 5237 #数据库实例监听端口
DW_PORT = 5337 #守护环境下,监听守护进程连接端口
DW_ERROR_TIME = 60 #接收守护进程消息超时时间
ALTER_MODE_STATUS = 0 #不允许手工方式修改实例模式/状态
ENABLE_OFFLINE_TS = 2 #不允许备库 OFFLINE 表空间
MAL_INI = 1 #打开 MAL 系统
ARCH_INI = 1 #打开归档配置
HA_INST_CHECK_FLAG = 1 #检测是否多个实例进程同时启动
RLOG_SEND_APPLY_MON = 64 #统计最近 64 次的日志重演信息
4.2 配置 dmmal.ini
配置 MAL 系统,各主备库的 dmmal.ini 配置必须完全一致,MAL_HOST 使用内部网络 IP,MAL_PORT 与 dm.ini 中 PORT_NUM 使用不同的端口值,MAL_DW_PORT 是各实例对应的守护进程之间,以及守护进程和监视器之间的通信端口,配置如下:
MAL_CHECK_INTERVAL = 5 #MAL 链路检测时间间隔
MAL_CONN_FAIL_INTERVAL = 5 #判定 MAL 链路断开的时间
[MAL_INST1]
MAL_INST_NAME = GRP2_RWW_01 #实例名,和 dm.ini 中的 INSTANCE_NAME 一致
MAL_HOST = 192.168.56.193 #MAL 系统监听 TCP 连接的 IP 地址
MAL_PORT = 5436 #MAL 系统监听 TCP 连接的端口
MAL_INST_HOST = 192.168.20.193 #实例的对外服务 IP 地址
MAL_INST_PORT = 5236 #实例的对外服务端口,和 dm.ini 中的 PORT_NUM 一致
MAL_DW_PORT = 5536 #实例对应的守护进程监听 TCP 连接的端口
[MAL_INST2]
MAL_INST_NAME = GRP2_RWW_02
MAL_HOST = 192.168.56.194
MAL_PORT = 5437
MAL_INST_HOST = 192.168.20.194
MAL_INST_PORT = 5237
MAL_DW_PORT = 5537
[MAL_INST3]
MAL_INST_NAME = GRP2_RWW_03
MAL_HOST = 192.168.56.195
MAL_PORT = 5438
MAL_INST_HOST = 192.168.20.195
MAL_INST_PORT = 5238
MAL_DW_PORT = 5538
4.3 配置 dmarch.ini
修改 dmarch.ini,配置本地归档和即时归档。除了本地归档外,其他归档配置项中的 ARCH_DEST 表示实例是 Primary 模式时,需要同步归档数据的目标实例名。
当前实例 GRP2_RWW_02 是备库,守护系统配置完成后,可能在各种故障处理中,GRP2_RWW_02 切换为新的主库,正常情况下,GRP2_RWW_01 会切换为新的备库,需要向GRP2_RWW_01 和 GRP2_RWW_03 同步数据,因此即时归档的 ARCH_DEST 分别配置为GRP2_RWW_01 和 GRP2_RWW_03。
[ARCHIVE_TIMELY1]
ARCH_TYPE = TIMELY #即时归档类型
ARCH_DEST = GRP2_RWW_01 #即时归档目标实例名
[ARCHIVE_TIMELY2]
ARCH_TYPE = TIMELY #即时归档类型
ARCH_DEST = GRP2_RWW_03 #即时归档目标实例名
[ARCHIVE_LOCAL1]
ARCH_TYPE = LOCAL #本地归档类型
ARCH_DEST = /dm/dmarch #本地归档文件存放路径
ARCH_FILE_SIZE = 128 #单位 Mb,本地单个归档文件最大值
ARCH_SPACE_LIMIT = 0 #单位 Mb,0 表示无限制,范围 1024~4294967294M
4.4 配置 dmwatcher.ini
修改 dmwatcher.ini 配置守护进程,配置为全局守护类型,使用自动切换模式。
[GRP2]
DW_TYPE =GLOBAL #全局守护类型
DW_MODE = AUTO #自动切换模式
DW_ERROR_TIME = 10 #远程守护进程故障认定时间
INST_RECOVER_TIME = 60 #主库守护进程启动恢复的间隔时间
INST_ERROR_TIME = 10 #本地实例故障认定时间
INST_OGUID = 453332 #守护系统唯一 OGUID 值
INST_INI = /dm/dmdbms/data/CNDBA/dm.ini #dm.ini 配置文件路径
INST_AUTO_RESTART = 1 #打开实例的自动启动功能
INST_STARTUP_CMD = /dm/dmdbms/bin/dmserver #命令行方式启动
RLOG_SEND_THRESHOLD = 0 #指定主库发送日志到备库的时间阀值,默认关闭
RLOG_APPLY_THRESHOLD = 0 #指定备库重演日志的时间阀值,默认关闭
4.5 配置 dmwatcher.ctl
同一个守护进程组,必须使用同一份 dmwatcher.ctl 文件,这里直接拷贝配置主库时已经生成的 dmwatcher.ctl 到本地数据文件目录。
[dave@www.cndba.cn3 CNDBA]$ scp dmwatcher.ctl 192.168.20.194:`pwd`
dmdba@192.168.20.194's password:
dmwatcher.ctl 100% 512 0.5KB/s 00:00
4.6 启动备库
以 mount 方式启动备库。
[dave@www.cndba.cn4 bin]$ cd /dm/dmdbms/bin
[dave@www.cndba.cn4 bin]$ ./dmserver /dm/dmdbms/data/CNDBA/dm.ini mount
一定要以 mount 方式启动数据库实例,否则系统启动时会重构回滚表空间,生成 Redo 日志;并且,启动后应用可能连接到数据库实例进行操作,破坏主备库的数据一致性。数据守护配置结束后,守护进程会自动 Open 数据库。
4.7 设置 OGUID
启动命令行工具 DIsql,登录备库设置 OGUID 值。
[dave@www.cndba.cn4 CNDBA]$ disql SYSDBA/SYSDBA@LOCALHOST:5237
Server[LOCALHOST:5237]:mode is normal, state is mount
login used time: 11.104(ms)
disql V7.6.0.95-Build(2018.09.13-97108)ENT
Connected to: DM 7.1.6.95
SQL> sp_set_oguid(453332);
DMSQL executed successfully
used time: 18.541(ms). Execute id is 1.
SQL>
系统通过 OGUID 值确定一个守护进程组,由用户保证 OGUID 值的唯一性,并确保数据守护系统中,数据库、守护进程和监视器配置相同的 OGUID 值。
4.8 修改数据库模式
启动命令行工具 DIsql,登录备库修改数据库为 Standby 模式。如果当前数据库不是 normal 模式,需要先修改 dm.ini 中 ALTER_MODE_STATUS 值 为 1,允许修改数据库模式,修改 Standby 模式成功后再改回为 0。如果是 normal 模式,请忽略下面的第 1 步和第 3 步。
SQL> SP_SET_PARA_VALUE(1, 'ALTER_MODE_STATUS', 1);
DMSQL executed successfully
used time: 12.447(ms). Execute id is 2.
SQL> alter database standby;
executed successfully
used time: 13.756(ms). Execute id is 0.
SQL> SP_SET_PARA_VALUE(1, 'ALTER_MODE_STATUS', 0);
DMSQL executed successfully
used time: 10.008(ms). Execute id is 3.
SQL>
4.9 注册服务
[root@dm4 ~]# /dm/dmdbms/script/root/dm_service_installer.sh -t dmserver -i /dm/dmdbms/data/CNDBA/dm.ini -p GRP2_RWW_02
5 配置备库 GRP2_RWW_03
5.1 配置 dm.ini
配置备库的实例名为 GRP2_RWW_03,dm.ini 参数修改如下:
#实例名,建议使用“组名_守护环境_序号”的命名方式,总长度不能超过 16
INSTANCE_NAME = GRP2_RWW_03
PORT_NUM = 5238 #数据库实例监听端口
DW_PORT = 5338 #守护环境下,监听守护进程连接端口
DW_ERROR_TIME = 60 #接收守护进程消息超时时间
ALTER_MODE_STATUS = 0 #不允许手工方式修改实例模式/状态
ENABLE_OFFLINE_TS = 2 #不允许备库 OFFLINE 表空间
MAL_INI = 1 #打开 MAL 系统
ARCH_INI = 1 #打开归档配置
HA_INST_CHECK_FLAG = 1 #检测是否多个实例进程同时启动
RLOG_SEND_APPLY_MON = 64 #统计最近 64 次的日志重演信息
5.2 配置 dmmal.ini
配置 MAL 系统,各主备库的 dmmal.ini 配置必须完全一致,MAL_HOST 使用内部网络 IP,MAL_PORT 与 dm.ini 中 PORT_NUM 使用不同的端口值,MAL_DW_PORT 是各实例对应的守护进程之间,以及守护进程和监视器之间的通信端口,配置如下:
MAL_CHECK_INTERVAL = 5 #MAL 链路检测时间间隔
MAL_CONN_FAIL_INTERVAL = 5 #判定 MAL 链路断开的时间
[MAL_INST1]
MAL_INST_NAME = GRP2_RWW_01 #实例名,和 dm.ini 中的 INSTANCE_NAME 一致
MAL_HOST = 192.168.56.193 #MAL 系统监听 TCP 连接的 IP 地址
MAL_PORT = 5436 #MAL 系统监听 TCP 连接的端口
MAL_INST_HOST = 192.168.20.193 #实例的对外服务 IP 地址
MAL_INST_PORT = 5236 #实例的对外服务端口,和 dm.ini 中的 PORT_NUM 一致
MAL_DW_PORT = 5536 #实例对应的守护进程监听 TCP 连接的端口
[MAL_INST2]
MAL_INST_NAME = GRP2_RWW_02
MAL_HOST = 192.168.56.194
MAL_PORT = 5437
MAL_INST_HOST = 192.168.20.194
MAL_INST_PORT = 5237
MAL_DW_PORT = 5537
[MAL_INST3]
MAL_INST_NAME = GRP2_RWW_03
MAL_HOST = 192.168.56.195
MAL_PORT = 5438
MAL_INST_HOST = 192.168.20.195
MAL_INST_PORT = 5238
MAL_DW_PORT = 5538
5.3 配置 dmarch.ini
修改 dmarch.ini,配置本地归档和即时归档。除了本地归档外,其他归档配置项中的 ARCH_DEST 表示实例是 Primary 模式时,需要同步归档数据的目标实例名。
当前实例 GRP2_RWW_03 是备库,守护系统配置完成后,可能在各种故障处理中,GRP2_RWW_03 切换为新的主库,正常情况下,GRP2_RWW_01 会切换为新的备库,需要向GRP2_RWW_01 和 GRP2_RWW_02 同步数据,因此即时归档的 ARCH_DEST 分别配置为GRP2_RWW_01 和 GRP2_RWW_02。
[ARCHIVE_TIMELY1]
ARCH_TYPE = TIMELY #即时归档类型
ARCH_DEST = GRP2_RWW_01 #即时归档目标实例名
[ARCHIVE_TIMELY2]
ARCH_TYPE = TIMELY #即时归档类型
ARCH_DEST = GRP2_RWW_02 #即时归档目标实例名
[ARCHIVE_LOCAL1]
ARCH_TYPE = LOCAL #本地归档类型
ARCH_DEST = /dm/dmarch #本地归档文件存放路径
ARCH_FILE_SIZE = 128 #单位 Mb,本地单个归档文件最大值
ARCH_SPACE_LIMIT = 0 #单位 Mb,0 表示无限制,范围 1024~4294967294M
5.4 配置 dmwatcher.ini
修改 dmwatcher.ini 配置守护进程,配置为全局守护类型,使用自动切换模式。
[GRP2]
DW_TYPE = GLOBAL #全局守护类型
DW_MODE = AUTO #自动切换模式
DW_ERROR_TIME = 10 #远程守护进程故障认定时间
INST_RECOVER_TIME = 60 #主库守护进程启动恢复的间隔时间
INST_ERROR_TIME = 10 #本地实例故障认定时间
INST_OGUID = 453332 #守护系统唯一 OGUID 值
INST_INI = /dm/dmdbms/data/CNDBA/dm.ini #dm.ini 配置文件路径
INST_AUTO_RESTART = 1 #打开实例的自动启动功能
INST_STARTUP_CMD = /dm/dmdbms/bin/dmserver #命令行方式启动
RLOG_SEND_THRESHOLD = 0 #指定主库发送日志到备库的时间阀值,默认关闭
RLOG_APPLY_THRESHOLD = 0 #指定备库重演日志的时间阀值,默认关闭
5.5 配置 dmwatcher.ctl
同一个守护进程组,必须使用同一份 dmwatcher.ctl 文件,这里直接拷贝配置主库时已经生成的 dmwatcher.ctl 到本地数据文件目录。
[dave@www.cndba.cn3 CNDBA]$ scp dmwatcher.ctl 192.168.20.195:`pwd`
dmdba@192.168.20.195's password:
dmwatcher.ctl 100% 512 0.5KB/s 00:00
[dave@www.cndba.cn3 CNDBA]$
5.6 启动备库
以 mount 方式启动备库。
[dave@www.cndba.cn5 bin]$ ./dmserver /dm/dmdbms/data/CNDBA/dm.ini mount
一定要以 mount 方式启动数据库实例,否则系统启动时会重构回滚表空间,生成 Redo 日志;并且,启动后应用可能连接到数据库实例进行操作,破坏主备库的数据一致性。数据守护配置结束后,守护进程会自动 Open 数据库。
5.7 设置 OGUID
启动命令行工具 DIsql,登录备库设置 OGUID 值。
[dave@www.cndba.cn5 CNDBA]$ disql SYSDBA/SYSDBA@LOCALHOST:5238
Server[LOCALHOST:5238]:mode is normal, state is mount
login used time: 12.368(ms)
disql V7.6.0.95-Build(2018.09.13-97108)ENT
Connected to: DM 7.1.6.95
SQL> sp_set_oguid(453332);
DMSQL executed successfully
used time: 8.887(ms). Execute id is 1.
SQL>
系统通过 OGUID 值确定一个守护进程组,由用户保证 OGUID 值的唯一性,并确保数据守护系统中,数据库、守护进程和监视器配置相同的 OGUID 值。
5.8 修改数据库模式
启动命令行工具 DIsql,登录备库修改数据库为 Standby 模式如果当前数据库不是 normal 模式,需要先修改 dm.ini 中 ALTER_MODE_STATUS 值 为 1,允许修改数据库模式,修改 Standby 模式成功后再改回为 0。如果是 normal 模式,请忽略下面的第 1 步和第 3 步。
SQL> SP_SET_PARA_VALUE(1, 'ALTER_MODE_STATUS', 1);
DMSQL executed successfully
used time: 37.874(ms). Execute id is 2.
SQL> alter database standby;
executed successfully
used time: 20.501(ms). Execute id is 0.
SQL>
SQL> SP_SET_PARA_VALUE(1, 'ALTER_MODE_STATUS', 0);
DMSQL executed successfully
used time: 7.305(ms). Execute id is 3.
SQL>
5.9 注册服务
[root@dm5 ~]# /dm/dmdbms/script/root/dm_service_installer.sh -t dmserver -i /dm/dmdbms/data/CNDBA/dm.ini -p GRP2_RWW_03
6 配置监视器
6.1 配置监控文件参数
由于主库和即时备库的守护进程配置为自动切换模式,因此这里选择配置确认监视器。
和普通监视器相比,确认监视器除了相同的命令支持外,在主库发生故障时,能够自动通知即时备库接管为新的主库,具有自动故障处理的功能。
故障自动切换模式下,必须配置确认监视器,且确认监视器最多只能配置一个。
在监控节点的/dm/dmdbms/data目录下创建并修改 dmmonitor.ini 配置确认监视器,,其中 MON_DW_IP 中的 IP 和 PORT 和dmmal.ini 中的 MAL_HOST 和 MAL_DW_PORT 配置项保持一致。
MON_DW_Confirm = 1 #确认监视器模式
MON_LOG_PATH = /dm7/data/log #监视器日志文件存放路径
MON_LOG_INTERVAL = 60 #每隔 60s 定时记录系统信息到日志文件
MON_LOG_FILE_SIZE = 32 #每个日志文件最大 32M
MON_LOG_SPACE_LIMIT = 0 #不限定日志文件总占用空间
[GRP2]
MON_INST_OGUID = 453332 #组 GRP1 的唯一 OGUID 值 #以下配置为监视器到组 GRP1 的守护进程的连接信息,以“IP:PORT”的形式配置
#IP 对应 dmmal.ini 中的 MAL_HOST,PORT 对应 dmmal.ini 中的 MAL_DW_PORT
MON_DW_IP = 192.168.56.193:5536
MON_DW_IP = 192.168.56.194:5537
MON_DW_IP = 192.168.56.195:5538
6.2 注册服务
在监视节点用root用户执行:
[root@monitor ~]# /dm/dmdbms/script/root/dm_service_installer.sh -t dmmonitor -i /dm/dmdbms/data/dmmonitor.ini -p dave
Move the service script file(/dm/dmdbms/bin/DmMonitorServicedave to /etc/rc.d/init.d/DmMonitorServicedave)
Finished to create the service (DmMonitorServicedave)
[root@monitor ~]#
6.3 启动监视器
[root@monitor ~]# service DmMonitorServicedave start
Starting DmMonitorServicedave: [ OK ]
[root@monitor ~]# ps -ef|grep monitor
avahi 1274 1 0 03:54 ? 00:00:00 avahi-daemon: running [monitor-2.local]
dmdba 22847 1 0 07:10 pts/1 00:00:00 /dm/dmdbms/bin/svc_ctl_linux dmmonitor /dm/dmdbms/data/dmmonitor.ini
root 22865 22525 0 07:11 pts/1 00:00:00 grep monitor
[root@monitor ~]#
7 注册并启动守护进程
7.1 注册守护进程服务
[root@dm3 ~]# /dm/dmdbms/script/root/dm_service_installer.sh -t dmwatcher -i /dm/dmdbms/data/CNDBA/dmwatcher.ini -p dm3
Move the service script file(/dm/dmdbms/bin/DmWatcherServicedm3 to /etc/rc.d/init.d/DmWatcherServicedm3)
Finished to create the service (DmWatcherServicedm3)
[root@dm3 ~]#
[root@dm4 ~]# /dm/dmdbms/script/root/dm_service_installer.sh -t dmwatcher -i /dm/dmdbms/data/CNDBA/dmwatcher.ini -p dm4
Move the service script file(/dm/dmdbms/bin/DmWatcherServicedm4 to /etc/rc.d/init.d/DmWatcherServicedm4)
Finished to create the service (DmWatcherServicedm4)
[root@dm4 ~]#
[root@dm5 ~]# /dm/dmdbms/script/root/dm_service_installer.sh -t dmwatcher -i /dm/dmdbms/data/CNDBA/dmwatcher.ini -p dm5
Move the service script file(/dm/dmdbms/bin/DmWatcherServicedm5 to /etc/rc.d/init.d/DmWatcherServicedm5)
Finished to create the service (DmWatcherServicedm5)
[root@dm5 ~]#
7.2 启动守护进程
[dave@www.cndba.cn3 ~]$ service DmWatcherServicedm3 start
Starting DmWatcherServicedm3: [ OK ]
[dave@www.cndba.cn3 ~]$
[dave@www.cndba.cn4 ~]$ service DmWatcherServicedm4 start
Starting DmWatcherServicedm4: [ OK ]
[dave@www.cndba.cn4 ~]$
[dave@www.cndba.cn5 ~]$ service DmWatcherServicedm5 start
Starting DmWatcherServicedm5: [ OK ]
[dave@www.cndba.cn5 ~]$
守护进程启动后,进入 Startup 状态,此时实例都处于 Mount 状态。守护进程开始广播自身和其监控实例的状态信息,结合自身信息和远程守护进程的广播信息,守护进程将本地实例 Open,并切换为 Open 状态。
8 验证
在之前的博客中,我们了解了读写分离集群的特点:
DM7 达梦 数据库 数据守护(Data Watch) (2) — 主备类型
https://www.cndba.cn/dave/article/3666
读写分离集群:
由一个主库以及一个或者多个配置了即时(Timely)归档的备库组成,其主要目标是在保障数据库可用性基础上,实现读、写操作的自动分离,进一步提升数据库的业务支撑能力。读写分离集群通过即时归档机制保证主、备库数据一致性,并配合达梦数据库管理系统的各种接口(JDBC、DPI等),将只读操作自动分流到备库,有效降低主库的负载,提升系统吞吐量。
8.1 数据同步测试
#主库:
[dave@www.cndba.cn3 ~]$ disql SYSDBA/SYSDBA
Server[LOCALHOST:5236]:mode is primary, state is open
login used time: 9.332(ms)
disql V7.6.0.95-Build(2018.09.13-97108)ENT
Connected to: DM 7.1.6.95
SQL> create table cndba as select * from sysobjects;
executed successfully
used time: 46.917(ms). Execute id is 4.
SQL>
#备库1,同步正常:
[dave@www.cndba.cn4 ~]$ disql SYSDBA/SYSDBA@LOCALHOST:5237
Server[LOCALHOST:5237]:mode is standby, state is open
login used time: 9.701(ms)
disql V7.6.0.95-Build(2018.09.13-97108)ENT
Connected to: DM 7.1.6.95
SQL> select count(1) from cndba;
LINEID COUNT(1)
---------- --------------------
1 1274
used time: 6.079(ms). Execute id is 4.
SQL>
备库2,同步正常:
[dave@www.cndba.cn5 ~]$ disql SYSDBA/SYSDBA@LOCALHOST:5238
Server[LOCALHOST:5238]:mode is standby, state is open
login used time: 9.902(ms)
disql V7.6.0.95-Build(2018.09.13-97108)ENT
Connected to: DM 7.1.6.95
SQL> select count(1) from cndba;
LINEID COUNT(1)
---------- --------------------
1 1274
used time: 5.562(ms). Execute id is 4.
SQL>
8.2 读写分离测试
实现原理:
实现读写分离集群的基本思路是:利用备库提供只读服务、无法修改数据的特性,优先将所有操作发送到备库执行,一旦备库执行报错,则发送到主库重新执行。通过备库“试错”这么一个步骤,自然地将只读操作分流到备库执行。并且,备库“试错”由接口层自动完成,对应用透明。
所以我们这里测试直接连备库1,创建测试表,看能否同步到主库:
[dave@www.cndba.cn4 ~]$ disql SYSDBA/SYSDBA@LOCALHOST:5237
Server[LOCALHOST:5237]:mode is standby, state is open
login used time: 9.701(ms)
disql V7.6.0.95-Build(2018.09.13-97108)ENT
Connected to: DM 7.1.6.95
SQL> create table sync as select * from sysobjects;
create table sync as select * from sysobjects;
[-710]:Try to modify user database at standby mode.
used time: 0.734(ms). Execute id is 0.
SQL>
备库是standby 模式,无法创建表。
查看了官方手册,这种读写分离需要通过接口来实现,以JDBC为例:
在 JDBC 连接串中增加了两个连接属性:rwSeparate 是否使用读写分离系统,默认 0;取值(0 不使用,1 使用)。 rwPercent 分发到主库的事务占主备库总事务的百分比,有效值 0~100,默认值 25。
<DRIVER>dm.jdbc.driver.DmDriver</DRIVER>
<URL>jdbc:dm://192.168.0.206:5236?rwSeparate=1&rwPercent=10</URL>
不过在disql中我们可以使用service name来进一步测试:
DM7 达梦数据库 disql 工具连接 数据库的三种方式
https://www.cndba.cn/dave/article/3572
在Monitor 节点配置service:
[dmdba@monitor data]$ cat /etc/dm_svc.conf
RWW=(192.168.20.194:5237,192.168.20.193:5236,192.168.20.195:5238)
TIME_ZONE=(480)
LANGUAGE=(en)
[dmdba@monitor data]$
#如果直接总是会连主库:
[dmdba@monitor data]$ disql SYSDBA/SYSDBA@RWW
Server[192.168.20.193:5236]:mode is primary, state is open
login used time: 38.923(ms)
disql V7.6.0.95-Build(2018.09.13-97108)ENT
Connected to: DM 7.1.6.95
SQL>
Disql 也可以启动读写分离集群:
[dmdba@monitor data]$ disql /nolog
disql V7.6.0.95-Build(2018.09.13-97108)ENT
SQL> login
server:RWW
username:SYSDBA
password:
port:
SSL path:
SSL PWD:
MPP TYPE:
read/write separate(y/n):Y
read/write separate percent(0-100):25
protocol type:
Server[192.168.20.193:5236]:mode is primary, state is open
login used time :23.928(ms)
SQL>
这里连接的还是主库,进一步测试,在service 里添加只有2个只读节点的RWW2:
[dmdba@monitor data]$ cat /etc/dm_svc.conf
RWW=(192.168.20.194:5237,192.168.20.193:5236,192.168.20.195:5238)
RWW2=(192.168.20.194:5237,192.168.20.195:5238)
TIME_ZONE=(480)
LANGUAGE=(en)
[dmdba@monitor data]$
#连接直接报错:
[dmdba@monitor data]$ disql SYSDBA/SYSDBA@RWW2
[-70019]:Network communication failure.
disql V7.6.0.95-Build(2018.09.13-97108)ENT
username:
因此根据以上测试,对读写分离集群的理解如下:
1.读写分离集群本质上还是一个数据守护环境,具备数据同步及容灾的功能。
2.程序在连接读写分离集群时连接的是主库,在接口中启用读写分离的特性后,将所有操作发送到备库执行,一旦备库执行报错,则发送到主库重新执行。通过这种方式实现读写分离,并且该过程对应用透明。
版权声明:本文为博主原创文章,未经博主允许不得转载。