CPU架构:X86_64
操作系统:银河麒麟v10
数据库版本:DM8
集群环境:带一个实时备库的三节点DSC集群
在压测过程中,DSC主库到备库的实时归档状态变为了INVALID,DSC主库可继续提供服务,但备库已被分离,不再应用日志,且无法通过attach的方式重新加入主备集群。
正常的压测过程中,备库会被自动分离?在弄清楚这个问题之前,我们需要对数据守护的实现原理和机制进行深入研究。
达梦数据守护环境主要用到两种归档类型:实时归档和即时归档。当前测试环境的归档类型为实时归档加高性能模式。
主备环境中,主库在Redo日志写入联机日志文件之前,先通过MAL系统把自己的Redo日志发送给备库,等待备库响应后,再写入自己的联机日志文件。
主备环境中,主库在Redo日志写入联机日志文件之后,再通过MAL系统把自己的Redo日志发送给备库。
主库发送Redo日志的时机,分别为写入联机日志文件之前和之后。
高性能和事务一致性,在配置dmarch.ini时配置参数ARCH_WAIT_APPLY控制,0表示高性能,即备库收到主库Redo日志后马上响应主库;1表示事务一致性,即备库收到主库Redo日志后马上进行重演,待重演完毕后再响应主库。即时归档该参数默认值为1,实时归档该参数默认为0。
实时归档运行中,备库中设置了KEEP_PKG,用于存放备库收到的主库通过MAL系统发送的Redo日志包,并不马上进行重演;而即时归档则不存在这种机制。
如此设置的原因在于:实时归档是在收到主库Redo日志后马上响应主库,而主库在收到备库响应后再将Redo日志写入自己的联机日志文件,如果没有KEEP_PKG,备库收到后马上进行了重演,而主库在准备写入联机日志文件前故障,则会导致备库的数据比主库的还要多,造成数据不一致;即时归档中则由于主库在发给备库之前已经将Redo日志写入了联机日志文件中,所以不存在这种造成数据不一致的隐患。
实时归档进行重演的时机主要有:
1)备库收到新的 RLOG_PKG,会将当前保存的 KEEP_PKG 日志重演,并将新收到的RLOG_PKG 再次放入 KEEP_PKG 中。
2)主库会定时将 FILE_LSN (已写入联机日志文件的日志包的最大LSN)等信息发送到备库,当主库 FILE_LSN 等于备库 SLSN(备库明确可重演的最大 LSN 值) 时,表明主库已经将 KEEP_PKG 对应的 Redo 日志写入联机日志文件中,此时备库会启动KEEP_PKG 的日志重演。
3)备库切换为新主库,在监视器执行 SWITCHOVER 或 TAKEOVER 命令,或者确认监视器通知备库自动接管时,备库会在切换为 PRIMARY 模式之前,启动 KEEP_PKG 的日志重演。
下面通过一张图对上述原理和实际应用场景进行了一个总结
在发生故障的环境中,使用的是实时归档+高性能模式的组合,在该配置下,主库的Redo日志将在写入联机日志之前就发送给了备库,备库收到后即刻相应主库,并不马上进行重演。
压测完毕后,监视器发现备库的RSTAT状态变为了INVALID
且一直在自动进行OPEN>RECOVERY RECOVERY>OPEN动作,但是实际上备库并没有应用日志。
查询主备库中保存的FLSN号,发现并不一致,数据在中途停止了同步,主库直接将备库分离了。
select * from v$rlog;
主库三个节点的FLSN分别为3464530623、3464530626、3464530632
SELECT P_DB_MAGIC, N_EP, PKG_SEQ_ARR, APPLY_LSN_ARR from V$RAPPLY_LSN_INFO;
此时尝试attach备库,发现虽然能成功执行,但备库并没有继续进行重演,备库归档状态仍为INVALID,集群主备关系依然没有恢复正常。
此时查询主备库的归档日志
select name,first_change#,next_change# from V$ARCHIVED_LOG;
上图显示:
1)备库上已应用的来自节点1的日志最大LSN为3445958568.
2) 主库节点1的本地归档日志,对比发现主库节点1归档日志的最小的LSN为3479201234,比3445958568还大。
原因可能为备库在收到LSN为3445958568日志的时候,主库的归档日志大小已经达到了dmarch.ini中配置的ARCH_SPACE_LIMIT上限.
该参数当前配置值为30720,当超过上限时,系统会自动删除最早生成的归档日志文件,删掉的这部分归档还没来得及发送到备库上,主库就已经将其删除,故备库的归档状态被设置成了INVALID;
而由于备库的归档日志缺失也不能符合恢复的条件,从而在dmmonitor发起 Recovery 流程时,归档日志发送失败,备库无法正常重演进行数据的恢复,两边数据无法达到一致的状态。
监视器中执行show arch send info grp1.standby.
结合达梦手册DM8数据守护与读写分离集群V4.0.pdf中的解释,可以了解到:
1)FOR RECOVER SEND 表示主库的守护进程发起的 Recovery 流程中的归档日志发送;
2)SEND CODE:主库到指定备库的日志发送结果, Code 小于 0 表示发送失败,等于 0表示发送成功,等于 100 表示实际未发送。
综上所述,导致压测后备库RSTAT状态变为了INVALID且备库也不符合恢复条件的原因可能有:
1)备库重演日志速度较慢,导致APPLY任务队列有大量的待应用的重做日志堆积,如果队列有上限,达到上限后,主库是否会停止发送或者减慢发送日志,另外,备库收到新的日志后由于队列满导致需要等待,无法响应主库,主库收不到响应超过一定时间,就把备库设置为了INVALID;
2)主库本地归档日志文件累积大小超限。当备库应用日志的速度小于主库产生日志的速度,主库产生的日志还未来得及发送给备库供备库使用时已经由于到达空间上限而被清理,导致备库上日志缺失,备库丢失部分数据,应用日志过程中产生了中断,从而无法与主库保持数据一致。
重新搭建备库,根据服务器实际存储空间和业务压力(每小时或者每天产生的日志量),合理评估并设置归档日志文件累积大小限制参数ARCH_SPACE_LIMIT。这里调整为了512000。后面在相同环境和配置下进行同样的压测,整个过程中没有再次发生备库被分离的现象。
在压测加载数据过程中,与第三个数据库节点建立的连接突然中断,其余两个节点可正常提供服务。重启节点三的数据库服务,未报错,但从监视器dmcssm观察到CSS、ASM服务均正常,只是该节点DB中的inst_status变为了AFTER REDO的状态,无法OPEN,其他指标均为正常状态。
数据库的After Redo 状态为系统启动或者实例崩溃恢复过程中联机重做日志应用完成后,回滚活动事务前的一种中间状态。数据守护集群的主机服务状态变化是先以mount状态启动,然后切换成after redo,最后切换成open。其中 mount状态是完成数据库的redo操作,after redo状态是完成数据库的undo操作,redo和undo都完成后才会切换成open。
在解决DSC节点的问题之前,为尽量排除备库对DSC的影响,先在dmmonitor中将备库进行了分离,即DSC到备库的实时归档状态设置为了INVALID。
假设故障节点是在Undo过程中出现了异常,那么我们可以选择修改节点3的dmini参数PSEG_RECV=0,先将该节点的数据库服务正常启动,后再改回原来的值。
▲注:PSEG_RECV为系统故障重启时,对活动事务和已提交事务的处理方式。0:跳过回滚活动事务和 PURGE 已经提交事务的步骤。在回滚表空间出现异常、损坏、系统无法正常启动时,可将 PSEG_RECV设置为 0,让系统启动;但存在一定风险,未提交事务的修改将无法回滚,破坏事务的原子性;另外,已提交未 PURGE 的事务,将导致部分存储空间无法回收;1:回滚活动事务并PURGE 已经提交事务;2:延迟 PURGE 已提交事务,延迟回滚活动事务;3:回滚活动事务,延迟 PURGE 已提交事务。默认值为1。
修改后重启故障节点的数据库服务,观察到服务启动依然正常未报错,但状态依旧为AFTER REDO,未改变。
./dmasmcmd
ASM>export dcrdisk '/dev/dmasm_dcr' to '/dm/conf/dmdcr_cfg_bak.ini'
./dmasmtool dcr_ini=/dm/conf/dmdcr.ini
cd DGLOG01/LOG
rm -f “prod2_log*”
cd DGARCH01
rm -rf “LOCAL_ARCH_PROD2”
./DmCSSServicePROD stop
./DmASMServicePROD stop
./DmService stop
需要修改的配置文件为:
/dm/conf/dmmal.ini dmarch.ini dmasvrmal.ini
./dmasmcmd
init dcrdisk '/dev/dmasm_dcr' from '/dm/conf/dmdcr_cfg_bak.ini' identified by 'aaabbb'
init votedisk '/dev/dmasm_vote' from '/dm/conf/dmdcr_cfg_bak.ini'
发现由于删除了节点2的在线日志文件,报找不到该文件的错,意识到可能是数据库启动时会去控制文件中读取数据库的结构信息,而当前数据库控制文件dm.ctl中没有将节点3的信息删除。
./dmctlcvt TYPE=1 SRC=+DGDATA01/DATA/PROD/dm.ctl DEST=/dm/conf/dmctl.txt DCR_INI=/dm/conf/dmdcr.ini
./dmctlcvt TYPE=2 SRC=/dm/conf/dmctl.txt DEST=+DGDATA01/DATA/PROD/dm.ctl DCR_INI=/dm/conf/dmdcr.ini
删除部分为:
# table space name
ts_name=RLOG
# table space ID
ts_id=2
# table space status
ts_state=0
# table space cache
ts_cache=
# DSC node number
ts_nth=2
# DSC optimized node number
ts_opt_node=0
# table space create time
ts_create_time=DATETIME '2022-2-14 13:32:56'
# table space modify time
ts_modify_time=DATETIME '2022-2-14 13:32:56'
# table space encrypt flag
ts_encrypt_flag=0
# table space copy num
ts_copy_num=0
# table space region size flag
ts_size_flag=0
# file path
fil_path=+DGLOG01/LOG/prod2_log01.log
# mirror path
mirror_path=
# file id
fil_id=0
# whether the file is auto extend
autoextend=1
# file create time
fil_create_time=DATETIME '2022-2-14 13:32:56'
# file modify time
fil_modify_time=DATETIME '2022-2-14 13:32:56'
# the max size of file
fil_max_size=0
# next size of file
fil_next_size=0
# file path
fil_path=+DGLOG01/LOG/prod2_log02.log
# mirror path
mirror_path=
# file id
fil_id=1
# whether the file is auto extend
autoextend=1
# file create time
fil_create_time=DATETIME '2022-2-14 13:32:56'
# file modify time
fil_modify_time=DATETIME '2022-2-14 13:32:56'
# the max size of file
fil_max_size=0
# next size of file
fil_next_size=0
重新启动节点1、2上的数据库服务,正常。
a. 再次导出DCR磁盘信息(同上)
b. 登录节点1的disql,添加节点3的在线日志文件
./disql sysdba/SYSDBA:11236
SQL> alter database add node logfile '+DGLOG01/LOG/prod2_log01.log' size 2048,'+DGLOG01/LOG/prod2_log02.log' size 2048;
c. 修改导出的dmdcr_cfg_bak.ini文件,将组成员个数改为3,,节点号都加上2,各个组加上节点3的信息
d. 将三个节点的配置文件dmmal.ini、dmasvrmal.ini、dmarch.ini都加上节点3的信息
e. 将修改后的dmdcr_cfg_bak.ini扩展进磁盘中
./dmasmcmd
ASM>extend dcrdisk '/dev/dmasm_dcr' from '/dm/conf/dmdcr_cfg_bak.ini'
f. 保险起见,这里先卸载了3个前台服务后重新注册了3个服务,重新启动节点3的CSS、ASM和数据库服务,CSS、ASM均启动正常,数据库启动卡住,一直处于STARTUP状态
尝试在前台启动,也直接卡住
查看节点3的数据库日志
观察到在与备库133通信,猜测可能是由于实时备库存在的影响
g. 由于当前未找到带实时备库的DSC动态扩展节点的官方可靠说明,现尝试直接丢掉备库,恢复DSC集群为normal模式,然后将DSC备份,还原至133上,最后恢复主备关系。
h. 现节点1和2均正常,登录节点1、2的disql,修改数据库模式为normal
./disql sysdba/SYSDBA:11236
alter database mount;
alter database normal;
alter database open;
i. 此时启动第三个DSC节点的数据库服务,发现可成功启动,inst_status也变为了OPEN,三节点DSC集群至此全部恢复正常。
a. 已开归档,进行在线备份
backup database full backupset ‘/dm/backup/20220222’
b. 停止备库的守护进程、数据库服务,登录dmrman使用备份集20220222进行还原
restore database '/dm8/conf/dm.ini' from backupset '/dm8/backup/20220222'
recover database '/dm8/conf/dm.ini' from backupset '/dm8/backup/20220222'
recover database '/dm8/conf/dm.ini' update db_magic
c. 停止DSC集群节点1、2的数据库服务和守护进程,修改相关配置文件,加上备库信息,以mount方式启动DSC数据库和备库,重新配置各自的数据库模式和oguid,oguid和之前保持一致
d. 最后启动DSC和备库的守护进程,登录监视器,发现主备也恢复了正常
1、数据库服务启动时会读取控制文件dm.ctl,若人为手动删除了数据库相关文件,比如某个用户表空间文件、在线日志文件等,需同时删掉dm.ctl中的相关信息数据库才可正常启动。
2、带备库的DSC动态扩展节点,异常情况下,可先断开主库关系,并将数据库模式从primary置为normal。待集群节点全部正常启动后重新进行备份并还原到备库节点,最后恢复主备关系。
3、主备环境搭建时,归档配置文件dmarch.ini中参数ARCH_SPACE_LIMIT应根据实际存储空间和主库产生日志的速度进行合理的设置,太小则会导致主备关系异常。
文章
阅读量
获赞