某现场因多次停电导致DM7DW集群数据库无法对外提供访问,配合现场检查确认集群状态显示组分裂GROUP SPLIT。确认监视器报错如下:
为了快速恢复业务,需将集群组分裂LSN较大实例转换为单机服务正常启停,在对实例做dmdbchk来确认坏表的明细和数量,再把坏表重命名并重建坏表,先单机启动后恢复业务,再将异常实例备份恢复到另一台主机,继续跟进坏表中可正常访问数据找回;再进行DMDW集群备库重建。
注:本文主库XXXDMSVR_01后续称为DB1,备库XXXDMSVR_02后续称为DB2。
处理思路如下:
2.1将集群组分裂中LSN较大实例修改为单机启动;
2.2单机启动过程中报错处理;
2.3为了单机快速启动替换回滚文件;
2.4单机启动后进行全库dmdbchk检测;
2.5正常数据并行逻辑导出及新实例并行导入和异常表数据找回;
2.6DMDW集群备库重建;
因DMDW集群处于脑裂状态已无法对外提供服务,需先将分裂集群实例调整为单机OPEN状态。
在进行DB1实例OPEN时一直卡住无响应,数据库进程有CPU,数据库日志5分钟刷一次,5分钟前后刷的内容一样如下:
因OPEN时一直卡主,需进行DB1数据库进程堆栈pstack打印来确认卡主原因;经堆栈确认卡在收集回滚信息上,信息如下:
跟进观察数据库进程,有CPU,磁盘IO基本空闲显示如下:
因DB1单机OPEN时卡在收集回滚信息上,需修改DB1实例dm.ini参数PSEG_RECV为0,重启数据库来跳过回滚。跳过回滚后,启动报错“mem2 magic check failed! system halt!”,报错如下:
继续修改DB1参数MEMORY_MAGIC_CHECK为0和调整归档dmarch.ini中只留本地配置注销远程归档配置,正常启动。
防止回滚文件损坏进行回滚文件替换。在DB1上按原实例dminit.log参数初始化一个新实例,正常启停后,将新初始化ROLL.DBF替换原实例路径的ROLL.DBF文件继续重启。前台重启时报错sys halt 0段错误(核心已转储),报错如下:
确认应用未停连库访问到坏表数据页,导致数据库进程掉了,调整端口重启服务,查看进程正常。
需确认单机实例坏表数量和明细,继续将DB1实例的端口修改启停后进行全库实例dmdbchk检测,确认1.3T数据损坏情况。进行如下操作:
nohup./dmdbchk ./dm.ini & ---进行操作系统后台检测
… … ---这里截取部分结果日志
[2023-12-16 01:12:36] DM DB CHECK END......
[2023-12-16 01:12:36] error count is 90
复制
1.3T数据经过5个多小时的检测,结果日志去重后坏表90张,都是2023年表。将坏表重命名及重建。
通过系统层面检测DB1相关的数据分区文件系统已异常(后续系统厂商已对DB1分区做了扫描修复),DB2分区系统文件正常,DB1报错如下:
在DB2实例把之前DB1备份恢复的实例通过dexp逻辑并行导出并排除导出坏表数据,在DB1文件系统已修复正常后重新初始化实例,将DB2上排除坏表导出正常的dmp文件导入到DB1。
在DB2上进行1.3T的数据并行逻辑导出耗时不到2小时,并行参数设置要根据物理主机cpu等资源进行调整,过滤多表的话继续在EXCLUDE参数后面继续添加。并行系统后台导出命令如下:
nohup ./dexp SYSDBA/SYSDBA:8236 file=/dbbak/all_data_dexp.dmp EXCLUDE=TABLES:SYSDBA.A_BAK_BAK,SYSDBA.B_BAK_BAK TABLESPACE=N PARALLEL=10 TABLE_PARALLEL=4 >>/dbbbak/all_data_dexp.log &
复制
继续在文件系统修复正常DB1新例上进行并行dimp导入,这里的并行使用需开启FAST_LOAD参数,否则TABLE_PARALLE不生效,并行参数设置要根据物理主机cpu等资源进行调整。实际导入时开启FAST_LOAD后,在开启PARALLEL参数也可并行导入。导入完成后建议进行源和目的约束等相关核对检查。并行系统后台导入命令如下:
nohup ./dimp SYSDBA/SYSDBA:8236 file=/dbbak/all_data_dexp.dmp REMAP_SCHEMA=SYSDBA:TEST FAST_LOAD=Y PARALLEL=10 >>/dbbbak/all_data_dimp.log &
复制
导入的时候需注意关闭记录日志,否则导致相关目录满影响逻辑导入效率。
在DB1正常数据逻辑导入完成后,可调整开启业务端口对外提供单机服务。
再在DB2上进行90张坏表ROWID二分法缩小确定坏的数据范围,将正常的数据通过DTS在线或逻辑导出导入回迁到DB1里。
因DM7普通表是以B*树形式存放的,ROWID是逻辑的ROWID,即从1一直增长下去,对于每一条数据都需要存储ROWID值,我们可以通过这个特性以二分法的方式更多找回异常表里正常的数据,就是过程比较耗时。找回样例语句如下:
select max(occur_time) from XXXX.YYYY_000007_OLD1 where ROWID>=1000 and ROWID<=204230;
复制
当查询到异常数据时,数据库进程会关闭,disql里会提示连接丢失,在进行数据库服务启动,继续调整ROWID范围,从而缩小坏的数据范围,当异常数据的范围确定后,通过查询语句和正常的ROWID范围将数据通过DTS或逻辑导出导入迁回至DB1环境正常表里。其它表依次这样找回异常表里正常数据。
将异常表的正常数据数据找回后在进行DB1和DB2集群搭建,具体步骤达梦云适配中心很多案例可参考。
PSEG_RECV参数:控制系统故障重启时,对活动事务和已提交事务的处理方式。0:跳过回滚活动事务和PURGE已经提交事务的步骤。在回滚表空间出现异常、损坏、系统无法正常启动时,可将PSEG_RECV设置为0,让系统启动。
MEMORY_MAGIC_CHECK参数:是否开启对所有内存池的校验。0:不开启;1:开启校验。
dmdbchk是DM 提供的用于检查数据库完整性、正确性的命令行工具。在服务器正常关闭后的脱机情况下,用户可以使用dmdbchk对数据库进行校验,包括校验 DM 数据库内部的 物理存储结构是否正常,对象信息是否合法等。
DEXP逻辑导出案例涉及参数:
PARALLEL用于指定导出的过程中所使用的线程数目。
TABLE_PARALLEL用于指定导出每张表所使用的线程数,在 MPP 模式下会转换成单线程。
EXCLUDE导出内容中忽略指定的对象。忽略指定的表,使用 TABLES:INFO 格式,如果使用表级导出方式导出,则使用 TABLES:INFO 格式的EXCLUDE 无效。例如:EXCLUDE= TABLES:
table1,table2。
DIMP逻辑导入案例涉及参数:
PARALLEL 用于指定导入的过程中所使用的线程数目。
TABLE_PARALLEL用于指定导入的过程中每个表所使用的子线程数目。
FAST_LOAD是否使用 dmfldr 进行数据导入(N)。
如上参数和命令使用详细解释见官方手册或DM云适配中心。
查看确认监视器日志,确认DB2实例LSN比主库DB1实例LSN值大,为了找回多的业务数据,尝试进行DB2实例调整为单机OPEN状态。此时,DB2备库状态是MOUNT状态;先停掉集群确认监视器,进行DB2备库实例OPEN,备库实例OPEN时提示连接丢失,查看数据库日志显示文件损坏,报错如下:
进行DB2实例ROLL.DBF替换,修改PSEG_RECV为0,跳过回滚启动服务,日志显示redo在线日志损坏,报错如下:
LSN更大些单机DB2库损坏严重,无法正常启动,后续只能用DB1数据单机启动。
UNDO LOG(回滚日志)是为了回滚用的。在事务提交之前就开始写数据,万一事务到最后又打算不提交了,要回滚,或者系统崩溃了,这些提前写入的数据就变成了脏数据,这时候就必须用UNDO LOG恢复了。
UNDO LOG还有一个作用,就是实现多个行版本控制(MVCC),当读取的某一行被其他事务锁定时,它可以从UNDO LOG中获取该行记录以前的数据是什么,从而提供该行版本信息,让用户读取(详细解释见官方手册)。UNDO的替换本文也有解释可以查阅。
“达梦数据库的重做日志,又叫REDO日志。指在 DM 数据库中添加、删除、修改对象,或者改变数据,DM 都会按照特定的格式,将这些操作执行的结果写入到当前的重做日志文件中。重做日志文件以 log 为扩展名。每个 DM 数据库实例必须至少有 2 个重做日志文件,默认两个日志文件为 DAMENG01.log、DAMENG02.log,这两个文件循环使用。
在DAMENG*.log里db_magic和pemnt_magic都是在数据库初始化时生成的随机数,记录在系统库上,为的是区分数据文件/REDOLOG/归档是否是属于自己当前的库,比如拷贝同名文件到数据文件目录下,会不把这个文件当作自己的文件日志组处理,在备份/恢复的时候,会更新db_magic和pemnt_magic这组魔数,这种时候新生成的归档等会更新恢复后的魔数一致,但是老的归档就不一致了。在特殊情况下,比如在线日志数据文件损坏、误删除、或者需要快速启动,需要替换在线数据文件,在线数据文件是由其它库生成,db_magic不一致,导致启动不了,需要修改db_magic到一致。但是db_magic和pemnt_magic的区别,暂未看到,应该都是一起更新一起校验。
REDO损坏或删除优先选择“备份+归档”恢复,从实例日志获取故障时间;
无备份归档的情况下,可以选择替换redo(达梦云适配中心案例很多供参考)日志临时启动数据库,然后将数据迁移出来。
另重做日志文件频繁切换会对数据库性能产生较大的影响。可以通过语句查询重做日志文件的信息:select * from v$rlogfile;
切记:不管替换在线日志还是回滚日志都是有丢数据风险,要根据现场实际情况而定。对数据库的运维操作前,最好做好相关备份。
简单而又普通的一个系统命令。故障处理前看一眼,可能就会缩短故障处理的时间。之前有个项目短信告警是HS同步延迟,现场各种HS、数据库排查,发现目的端io很少,查看空间才发现记录日志所在盘符满了,日志无法写入,手动清了几个记录日志后同步开始正常推进追数。
linux中curl是一个利用URL规则在命令行下工作的文件传输工具,用系统自带命令可以用简单快速测试直通网和跨隔离网络的ip和端口是否通。
一个Unix和类Unix系统上的命令,主要功能为转换和复制文件。我们可以模拟操作系统测试阵列分区类数据库io操作,具体参数可以网络搜索,这里不做赘述。之前遇到过的一些数据库或同步故障,会存在之前很快的语句突然很慢、应用堆积入库变慢、同步莫名延迟丢数等,应第一次时间获得现场允许后可以做一下相关分区的磁盘io检测,这样也能方便快速定位问题。
语句样例:dd bs=8k count=10000 if=/dev/zero of=/data/test oflag=dsync
tune2fs是调整和查看ext2或ext3文件系统的文件系统参数,通过相关参数可以初步查看系统层面文件系统状态是否正常,如本案例中,知道集群断电情况就应先使用此命令来检测下分区的文件系统是否正常,根据检测结果来确定下一步的处理思路。能尽可能缩短业务恢复的时间。
样例语句:tune2fs -l /dev/sdb3 |grep state
像如上1-4简单实用的操作系统命令、或开源工具、DM工具等很多,熟练使用它们不但能快速定位问题原因,还能加快业务恢复时间。同时故障救援中排查处理问题思路尤为重要;确认大方向,在跟进排查;排查思路和方向不对,不仅耗时还费力。
在进行紧急故障救援时应先保留已故障库现场:采用备份或者拷贝等方式;了解现场情况:确认故障发生大致时间,故障发生前有没有什么特别的操作,比如断电,或者大批量操作数据等,收集前台和日志报错信息,确认有无core文件等。
及时向上汇报:故障发生之后,将情况上报领导。确认恢复方案后,再执行恢复操作。切记,不要私自行动。
主备集群故障:单实例会遇到的问题,集群也会遇到,集群还受到网络、时间等其它因素的影响。
遇到故障时,除了检查数据库日志,还要看监视器的情况,查看确认集群的状态。可查看监视器日志辅助分析故障原因。有open状态的实例,可以做全备恢复搭建另外的备库;无open状态库紧需急处理为open状态。
核心思想:用备份或逻辑导出文件重新找回数据并重建集群。
经验可以积累,知识可以学习,但处理问题的思路是要多小结多沟通多分享。
文章
阅读量
获赞