bash
作者:IT邦德
中国DBA联盟(ACDU)成员,10余年DBA工作经验
擅长主流数据Oracle、MySQL、PG、openGauss运维
备份恢复,安装迁移,性能优化、故障应急处理等
可提供技术业务:
1.DB故障处理/疑难杂症远程支援
2.Mysql/PG/Oracle/openGauss
数据库部署及数仓搭建
公众号:IT邦德
•••
@TOC
前言
凌晨的2点,我还做着美梦,被一阵电话吵醒,3套核心业务库发生了无法连接的报错,应用全部中断,客户着急,一起现场的小伙伴也慌了,我开始了远程。
1.1 监听报错
监听已经无法启动,应用连接报错
1.2 数据库down机
数据库down机,启动数据库报错提示,无法找到在线日志redo02.log
2.排查根因
首先跟现场确认,业务人员在发现应用无法连接后,登陆服务器发现,Oracle的根目录/u01,分区已经100%,磁盘爆了,所以直接将所有的在线日志全部删除,直接导致Oracle数据库DOWN,同时ALER日志当中也看到了同样的报错提示
3.处理过程
此次故障造成3套核心业务的DOWN机,有2套开了归档有备份,但是其中一套库没有开归档,也没有备份,同时将2套库的处理方式罗列如下
3.1 非CURRENT删除恢复
sql
select group#,sequence#,archived,status from v$log;
排查发现非CURRENT日志被删除,我们只需要清理即可
Alter database clear unarchived logfile group 1;
alter database clear unarchived logfile group 2;
ARCHIVED有两种状态:YES,NO;YES表示ARCH进程已经将该日志组的Online Redo LogFile拷贝到归档目的地,成为一个Archived Redo Logfile,NO表示还没有拷贝完成。日志组的状态和日志组是否归档之间是没有必然的联系,它们分别由不同的进程来控制。在出现故障,需要手动恢复的时候,我们应该注意观察最新的日志组状态及是否归档,这可能帮助到我们的恢复过程,另外,V$LOG的数据来源于控制文件,所以恢复的控制文件或重建的控制文件不能说明数据库最新的日志组状态。
sql
SQL> startup mount;
SQL> recover database until cancel;
SQL> alter database open resetlogs;
3.2 CURRENT删除恢复
sql
1、allow_resetlogs_corruptions参数设置启动到mount状态
2、alter database backup controlfile to trace生成控制文件备份(后续可能要使用)
3、recover database until cancel(选择cancel不需要恢复)
4、alter database open resetlogs
5、如果上述报出ora-00600 2662、2663错误,需要推进scn
6、启动数据库mount状态,推进scn
7、alter database open,如果提示依然需要恢复,
8、重复3操作
9、再进行scn推进10、推进成功后
最后alter database open resetlogs启动数据库
因为此次库没有开归档,导致在最后resetlogs启动数据库报了如下的错 警告日志报错:ORA-00600: internal error code, arguments: [4194], [], [], [], [], [], [], [], [], [], [], []Inc
[4193] [4194]错误常规手段就是设置手动管理undo tablespace和undo_tablespace system,需要注意的所有实例都要设置*.undo_management='MANUAL'
sql
alter system set "_allow_resetlogs_corruption"=true scope=spfile;
alter system set undo_management='MANUAL' scope=spfile;
SQL> shutdown immediate;
SQL> startup mount;
--删除原有UNDO
drop tablespace UNDOTBS1 including contents and datafiles;
--重新创建UNDO
create undo tablespace UNDOTBS1 datafile '/u01/app/oracle/oradata/MESDB/undotbs01.dbf' size 10G;
--RESETLOGS开库即可
SQL> recover database until cancel(选择cancel不需要恢复)
SQL> ALTER DATABASE OPEN RESETLOGS;
--恢复参数文件重启库
alter system set undo_management='auto' scope=spfile;
alter system reset "_allow_resetlogs_corruption" scope=spfile;
SQL> startup force;
4.监听日志定时删除
此次磁盘饱满的原因是监听日志没有定时清理,随着系统上线日志堆满了,故加了以下定时删除的任务
在oracle 10g时候,只有文本格式的listener.log; 在11.2版本时,由于ADR特性出现了xml/log两种格式的监听日志,xml格式的日志会达到一定大小后自动分片,形成log_1.xml 这种数字序号的文件;log格式的日志会达到一定大小后自动分片,形成log_1.log 这种数字序号的文件.
ini
Oracle11g的新特性自动诊断库(ADR)默认会启用,
监听日志默认以xml方式存放,如果空间占用太大,你可以关闭
建议调整监听参数文件DIAG_ADR_ENABLED_listener = OFF ,
然后reload监听,监听就不会存放为XML文件格式,而是使用10g老的方式。
同时建议在SQLNET.ORA文件中设置参数 DIAG_ADR_ENABLED = OFF
来屏蔽ADR向ALERT写入错误信息(如ORA-609),操作如下:
在listener.ora里面加入如下行:
DIAG_ADR_ENABLED_ LISTENER = OFF 其中LISTENER为监听名
sqlnet.ora加入如下行:
DIAG_ADR_ENABLED = OFF
重启监听:
lsnrctl reload
bash
监听进程的查询,RAC一般使用ASM的监听
ps -ef |grep tnslsnr
grid 12386 1 0 2023 ? 05:00:31 /u01/app/19.0.0/grid/bin/tnslsnr LISTENER -no_crs_notify -inherit
grid 12460 1 0 2023 ? 00:47:24 /u01/app/19.0.0/grid/bin/tnslsnr ASMNET1LSNR_ASM -no_crs_notify -inherit
oracle 70467 68189 0 08:40 pts/2 00:00:00 grep --color=auto tnslsnr
定时删除
bash
监听的位置在如下位置
cd $ORACLE_BASE/diag/tnslsnr/{hostname}
asmnet1lsnr_asm
listener
listener_scan1
crontable -l
0 23 * * * /home/oracle/scirpt/listener_clear.sh > /dev/null 2>&1;
#!/bin/sh
#listener
find /u01/app/grid/diag/tnslsnr/rac1/listener/alert -mtime +7 -name "log_*.xml" | xargs rm -rf \;
find /u01/app/grid/diag/tnslsnr/rac1/listener/trace -mtime +7 -name "listener_*.llog" | xargs rm -rf \;
#asmnet1lsnr_asm
find /u01/app/grid/diag/tnslsnr/rac1/asmnet1lsnr_asm/alert -mtime +7 -name "log_*.xml" | xargs rm -rf \;
find /u01/app/grid/diag/tnslsnr/rac1/asmnet1lsnr_asm/trace -mtime +7 -name "asmnet1lsnr_asm_*.log" | xargs rm -rf \;
5.故障反思
标准化的数据库部署需要加强,比如一些定时清理机制,一些定时巡检监控, 其次运维人员对数据库的学习待提升,不要盲目的去删除日志,确认确认再确认,相关数据库的运维需要专业的DBA介入,专业的人做专业的事