数据库诊断之坏块诊断及修复

简介: -- 诊断数据库1.查看故障list failure [ALL | CRITICAL | HIGH | LOW | CLOSED | failnum[,failnum,...]][ EXCLUDE FAILURE failnum[,failnum,...]][ DETAIL]删除数据文件6[oracle@dbserver ~]$ rm -fr /u01/app/oracle/oradata/orcl/ts_inventory01.dbf列出故障,默认显示优先级为high的故障。
-- 诊断数据库
1.查看故障
list failure [ALL | CRITICAL | HIGH | LOW | CLOSED | failnum[,failnum,...]]
[ EXCLUDE FAILURE failnum[,failnum,...]]
[ DETAIL]
删除数据文件6
[oracle@dbserver ~]$ rm -fr /u01/app/oracle/oradata/orcl/ts_inventory01.dbf
列出故障,默认显示优先级为high的故障。
RMAN> list failure;
列出故障明细
RMAN> list failure detail;

2.故障修复建议
advise failure
注意,advise failure 必须在同一个窗口中紧跟 list failure 才能正常使用。
RMAN> advise failure;
上面命令系统会给出修复故障的脚本,查看脚本内容如下:
$ more /u01/app/oracle/diag/rdbms/orcl/orcl/hm/reco_1651608170.hm

3.修复故障
repair failure
[ using advise option integer ]
[ noprompt | review]
注意,repair failuer 必须在同一窗口中紧跟 advise failure 后才能正常使用。
修复预览
RMAN> repair failure preview;
修复故障,noprompt 表示不提示直接修复,不带将会出现修复提示。
RMAN> repair failure noprompt;

4.修改故障优先级和关闭故障 change failure
RMAN> list failure;
修改上面原来high的故障的优先级到low
RMAN> change failure 402 priority low;
再次查询将查不到low的故障
RMAN> list failure;
但可以指定查询low级别的故障
RMAN> list failure low;
RMAN> list failure all;
关闭故障
RMAN> change failure 402 closed;

5.故障恢复相关视图
v$ir_failure: 包含所有检测到的故障,包含已经关闭的故障。
v$ir_manual_checklist: 相关故障的手动修复建议
v$ir_repair: 相关故障的自动修复步骤
v$ir_failure_set: 存放故障ID和其修复建议ID的关联

6.主动监控数据库
使用EM健康监控或Rman命令 validate database
RMAN> validate database; --11g才开始提供的命令
11g之前使用dbv工具进行数据库文件校验(支持离线校验):
$ dbv file=/u01/app/oracle/oradata/orcl/ts_inventory01.dbf
11g之前还可以使用 dbms_repair 包中相关的函数进行坏块的处理

7.关于数据块校验的几个参数
DB_ULTRA_SAFE: 整合了DB_BLOCK_CHECKING,DB_BLOCK_CHECKSUM,DB_LOST_WRITE_PROTECT三个参数,属于11g的新参数。
DB_BLOCK_CHECKING: 启动对数据库块的检查,默认为false,即使关闭也会强制检查SYSTEM表空间的数据块。
DB_BLOCK_CHECKSUM: 修改块数据时加入并且验证块的校验位,默认为typical
DB_LOST_WRITE_PROTECT: 在DATA GUARD中保护数据成功写入物理备库,默认为typical

8.块介质恢复
恢复条件:
①开启归档
②存在全备或0级备份
③存在有效的闪回日志
v$database_block_corruption: 存放数据中所有坏块信息
数据库存在坏块时,默认是不允许进行备份的,因此需要经常检查备份的有效性。
可以允许跳过坏块进行备份,同时把坏块信息写入 v$database_block_corruption中:
RMAN> run {
set maxcorrupt for datafile 6 to 1000;
backup datafile 6;
}
修复一个块:
recover datafile 6 block 131;
修复多个块:
recovery datafile 2 block 43
datafile 2 block 70
datafile 6 block 110;
修复所有坏块:
recover corruption list;
修复好的块将不再出现在 v$database_block_corruption.

9.查看诊断知识库(11g开始才推出ADR)
使用 adrci 工具
$ adrci
adrci> help --查看adrci的帮助信息
adrci> show incident; --查看所有的事件信息
adrci> show alert; --查看所有的报警信息
也可以通过v$diag_info查看诊断信息
SQL> select*from v$diag_info;
11g中诊断信息相关目录参数不能修改,统一设置到ADR_HOME/ 目录下

10.健康监控
视图v$hm_check列出所有健康监控的内容
健康检查可以使用EM(EM中助手中心里的检查器)
也可以调用dbms_hm.run_check执行健康检查
tab$ 表示数据库中的所有基表
SQL> exec dbms_hm.run_check('Dictionary Integrity Check','mycheck',0,'TABLE_NAME=tab$'); 
SQL> set long 20000
SQL> select dbms_hm.get_run_report('mycheck') from dual;
在adrci中查看健康检查
adrci> show home
adrci> set home diag/rdbms/orcl/orcl
adrci> create report hm_run mycheck
adrci> show report hm_run mycheck




-- 坏块修复示例 --
-- 用内部事件来屏蔽全表扫描的时候忽略坏块。
alter system set events='10231 trace name context for ever,level 10'

-- 给定一个表空间,并在此表空间下建立维修表
exec DBMS_REPAIR.ADMIN_TABLES(TABLE_NAME => 'REPAIR_TABLE',TABLE_TYPE => DBMS_REPAIR.REPAIR_TABLE,ACTION => DBMS_REPAIR.CREATE_ACTION,TABLESPACE => 'USERS');

-- 对指定的<schema>.<object>检查并确认其中坏块(如果同时指定 PARTITION_NAME 也可以进行分区级别检查):
SET SERVEROUTPUT ON 
var NUM_CORRUPT NUMBER;
exec :NUM_CORRUPT :=0;
exec DBMS_REPAIR.CHECK_OBJECT(SCHEMA_NAME => 'SYS',OBJECT_NAME => 'IMPDP_STATS',REPAIR_TABLE_NAME => 'REPAIR_TABLE',CORRUPT_COUNT => :NUM_CORRUPT);
exec DBMS_OUTPUT.PUT_LINE('NUMBER CORRUPT: ' || TO_CHAR(:NUM_CORRUPT));
 
-- 对检查出的坏块,可选择性地进行标记:
SELECT BLOCK_ID, CORRUPT_TYPE, CORRUPT_DESCRIPTION FROM REPAIR_TABLE;
-- REM Mark the identified blocks as corrupted ( Soft Corrupt - reference Note 1496934.1 )
var NUM_FIX number;
exec :NUM_FIX := 0;
exec DBMS_REPAIR.FIX_CORRUPT_BLOCKS(SCHEMA_NAME => 'SYS',OBJECT_NAME => 'IMPDP_STATS',OBJECT_TYPE => DBMS_REPAIR.TABLE_OBJECT,REPAIR_TABLE_NAME => 'REPAIR_TABLE',FIX_COUNT => :NUM_FIX);
exec DBMS_OUTPUT.PUT_LINE('NUM FIX: ' || TO_CHAR(NUM_FIX));

-- 在将来进行DML操作时,对坏块进行跳过处理:
exec DBMS_REPAIR.SKIP_CORRUPT_BLOCKS (SCHEMA_NAME => '&schema_name',OBJECT_NAME => '&object_name',OBJECT_TYPE => dbms_repair.table_object,FLAGS => dbms_repair.SKIP_FLAG);

-- 注意:
使用DBMS_REPAIR访问坏块后,INDEX scan可能会出现报错,碰到这类报错,你需要重建这些索引。如果是唯一索引,那么相同数据的重新插入可能会报ORA-1错误。
如果在 dbms_repair.SKIP_FLAG 已经启用后,希望将跳块标记清除以重新访问坏块,可以在执行DBMS_REPAIR.SKIP_CORRUPT_BLOCKS时,使用dbms_repair.NOSKIP_FLAG进行参数设置。
使用DBMS_REPAIR.SKIP_CORRUPT_BLOCKS来跳块仅能针对出现ORA-1578报错的那些坏块情况。如果是针对其它类型坏块,就需要额外执行ADMIN_TABLES, CHECK_OBJECT 和FIX_CORRUPT_BLOCKS来对坏块进行标记处理。
在执行过SKIP_CORRUPT_BLOCKS后,如果需要将表中的坏块进行清理,可以对表使用”alter table <name> MOVE”,而不是重建或truncate掉它。然后使用dbms_repair.NOSKIP_FLAG去除掉跳块标记即可。注意,坏块中的数据会被丢失掉。



-----------------------------------------------------------------------------
-- 坏块问题
-- DB File Verify(DBV) 工具
-- 外部命令,物理介质数据结构完整性检查;
-- 只能用于数据文件(offline或online),不支持控制文件和重做日志文件的块检查;
-- 也可以验证备份文件(rman的copy命令备份或操作系统CP命令备份);
-- dbv file=DATA01.DBF blocksize=8192;

-- 解决坏块过程
找出数据文件上的表、分析出出现坏块的表、找出所有的坏块:

找出文件编号:
select * from dba_data_files t where t.FILE_NAME = '/u01/../../.DBF';
 
找出文件上的表:
select distinct t.segment_name , t.segment_type  from dba_extents t where t.FILE_ID = '12' order by t.segment_name, t.segment_type;

--使用select count(1) from tablename的办法,找出哪些表上有坏块。
SQL> select count(1) from schema.table;
ERROR at line 1:
ORA-01578: ORACLE data block corrupted (file # 12, block # 608129)
ORA-01110: data file 12: '/u01/../../.DBF'
从上面查询可知表tablename上有坏块,但可能不止一个坏块,所以我使用dbv找出这个表上所有坏块。办法是,找出表的segment_id:
select s.TS#, t.header_file, t.header_block , t.owner, t.* from dba_segments t
left join v$tablespace s
on t.tablespace_name = s.NAME 
where t.segment_name = 'TABLE_NAME';
6.5.1118066

在服务器上,执行dbv工具:
dbv logfile=/home/oracle/dbv_lkpspf_.log userid=ahern/oracle segment_id=6.5.1118066 -- 分析命令执行的结果

-- 1、使用rman修复坏块,但因为归档丢失,无法恢复。
RMAN> recover datafile 18 block 58630;

-- 2、使用 sys.dbms_repair修复:fix_corrupt_blocks修复失败、skip_corrupt_blocks忽略坏块、导出可以用数据、删除坏块的表。
--建repaire表:repair_table
SQL> begin
dbms_repair.admin_tables(
table_type=>dbms_repair.repair_table,
action=>dbms_repair.create_action,
tablespace=>'USERS'
);
end;
/
-- 检查坏块:
SQL> declare
cc number;
begin
dbms_repair.check_object(
  schema_name=>'LKPSPF',
  object_name=>'TB_ORDERS',
  object_type=>dbms_repair.table_object,
  repair_table_name=>'REPAIR_TABLE',
  corrupt_count=>cc
);
dbms_output.put_line(cc);
end;
/
--查询坏块:
SQL> col REPAIR_DESCRIPTION for a50
SQL> select block_id, repair_description from repair_table; 
608129 mark block software corrupt 
608193 mark block software corrupt  
-- 与dbv分析结果相同。
--使用 fix_corrupt_blocks 恢复坏块,但没有成功。
SQL> declare 
cc number;
begin
  dbms_repair.fix_corrupt_blocks(
    'LKPSPF',
    'TB_ORDERS',
    fix_count=>cc
  );
  dbms_output.put_line(cc);
end;
/

--只能跳过坏块,使用skip_corrupt_blocks过程。
SQL> declare
  cc number;
  begin
  dbms_repair.skip_corrupt_blocks(
    schema_name=>'LKPSPF',
    object_name=>'TB_ORDERS'
  );
  dbms_output.put_line(cc);
end;
/

--此时,存在坏块的表可以使用,但坏块中记录丢失了。
select count(1) from LKPSPF.TB_ORDERS;
66545839

--坏块还在数据文件中,仍就不能使用rman备份。
RMAN> backup datafile '/../../.DBF';
--此时,需要把存在坏块的表中的数据使用ctas方式迁移到其他表中。然后删除有坏块的表。再次执行rman备份:备份成功。
RMAN> backup datafile '/../../.DBF';

-- 附坏块查询 SQL
RMAN>backup check logical validate datafile n ; -- 检查数据文件是否包含坏块,同时并不产生实际的备份输出
-- 也可以直接使用RMAN的命令:backup validate check logical database;
rman target / nocatalog
RMAN> spool log to '/u01/../dbbak/rmanlog.log'; -- 指定输出rman日志文件
RMAN> run {
allocate channel d1 type disk;
allocate channel d2 type disk;
allocate channel d3 type disk;
allocate channel d4 type disk;
backup validate check logical database;
};
-- 结合V$DATABASE_BLOCK_CORRUPTION视图更方便
SELECT * FROM V$DATABASE_BLOCK_CORRUPTION;
-- --If V$DATABASE_BLOCK_CORRUPTION contains rows please run this query to find the objects that contains the corrupted blocks:
SELECT E.OWNER,
       E.SEGMENT_TYPE,
       E.SEGMENT_NAME,
       E.PARTITION_NAME,
       C.FILE#,
       GREATEST(E.BLOCK_ID, C.BLOCK#) CORR_START_BLOCK#,
       LEAST(E.BLOCK_ID + E.BLOCKS - 1, C.BLOCK# + C.BLOCKS - 1) CORR_END_BLOCK#,
       LEAST(E.BLOCK_ID + E.BLOCKS - 1, C.BLOCK# + C.BLOCKS - 1) -
       GREATEST(E.BLOCK_ID, C.BLOCK#) + 1 BLOCKS_CORRUPTED,
       NULL DESCRIPTION
  FROM DBA_EXTENTS E, V$DATABASE_BLOCK_CORRUPTION C
 WHERE E.FILE_ID = C.FILE#
   AND E.BLOCK_ID <= C.BLOCK# + C.BLOCKS - 1
   AND E.BLOCK_ID + E.BLOCKS - 1 >= C.BLOCK#
UNION
SELECT S.OWNER,
       S.SEGMENT_TYPE,
       S.SEGMENT_NAME,
       S.PARTITION_NAME,
       C.FILE#,
       HEADER_BLOCK CORR_START_BLOCK#,
       HEADER_BLOCK CORR_END_BLOCK#,
       1 BLOCKS_CORRUPTED,
       'Segment Header' DESCRIPTION
  FROM DBA_SEGMENTS S, V$DATABASE_BLOCK_CORRUPTION C
 WHERE S.HEADER_FILE = C.FILE#
   AND S.HEADER_BLOCK BETWEEN C.BLOCK# AND C.BLOCK# + C.BLOCKS - 1
UNION
SELECT NULL OWNER,
       NULL SEGMENT_TYPE,
       NULL SEGMENT_NAME,
       NULL PARTITION_NAME,
       C.FILE#,
       GREATEST(F.BLOCK_ID, C.BLOCK#) CORR_START_BLOCK#,
       LEAST(F.BLOCK_ID + F.BLOCKS - 1, C.BLOCK# + C.BLOCKS - 1) CORR_END_BLOCK#,
       LEAST(F.BLOCK_ID + F.BLOCKS - 1, C.BLOCK# + C.BLOCKS - 1) -
       GREATEST(F.BLOCK_ID, C.BLOCK#) + 1 BLOCKS_CORRUPTED,
       'Free Block' DESCRIPTION
  FROM DBA_FREE_SPACE F, V$DATABASE_BLOCK_CORRUPTION C
 WHERE F.FILE_ID = C.FILE#
   AND F.BLOCK_ID <= C.BLOCK# + C.BLOCKS - 1
   AND F.BLOCK_ID + F.BLOCKS - 1 >= C.BLOCK#
 ORDER BY FILE#, CORR_START_BLOCK#;
-- 执行下面语句的结果来自于上面的查询
SELECT TABLESPACE_NAME, SEGMENT_TYPE, OWNER, SEGMENT_NAME
  FROM DBA_EXTENTS
 WHERE FILE_ID = &FILEID
   AND &BLOCKID BETWEEN BLOCK_ID AND BLOCK_ID + BLOCKS - 1;
目录
相关文章
|
2天前
|
存储 数据库
LabVIEW如何修复或重置NI MAX数据库文件
LabVIEW如何修复或重置NI MAX数据库文件
|
7月前
|
SQL 监控 关系型数据库
数据库高效“体检”必备!详解阿里云AnalyticDB一键诊断功能
AnalyticDB MySQL诊断监控平台提供指标监控、查询和建表诊断、库表优化等多项诊断调优能力
数据库高效“体检”必备!详解阿里云AnalyticDB一键诊断功能
|
7月前
|
SQL 监控 关系型数据库
数据库高效“体检”必备!详解阿里云AnalyticDB MySQL一键诊断功能
AnalyticDB MySQL诊断监控平台则是一套全自研的、从零开始搭建的并紧密贴合分析型系统特征的诊断平台,包含数据的采集(诊断日志和监控数据)、数据缓存(削峰填谷)、清洗转换以及存储等,最终以多种服务形式提供实时的告警、监控、负载洞察、查询分析和诊断等功能。
|
10月前
|
存储 安全 网络安全
.360勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
近年来,随着互联网的普及和信息技术的快速发展,网络安全问题日益严峻。其中,勒索病毒成为网络安全领域的一大威胁。本文91数据恢复将重点介绍一种名为“.360勒索病毒”的恶意软件,并探讨被该病毒加密的数据文件如何进行恢复。
.360勒索病毒解密方法|勒索病毒解决|勒索病毒恢复|数据库修复
|
12月前
|
存储 XML SQL
Oracle 数据库自动诊断库 ADR(Automatic Diagnostic Repository)简介 发表在 数据和云
Oracle 数据库如果出现故障,我们的第一个反应是查看数据库的 alert log,但一些工程师对 alert log 不熟悉,实际上 alert log 位于Oracle 数据库自动诊断库(Automatic Diagnostic Repository,以下简称 ADR) 中,要熟悉 alert log,我们必需全面了解 ADR 的概念。
220 0
|
12月前
|
SQL 机器学习/深度学习 缓存
企业运维训练营之数据库原理与实践—数据库DAS简介和备份上云方案—性能诊断与优化(上)
企业运维训练营之数据库原理与实践—数据库DAS简介和备份上云方案—性能诊断与优化(上)
176 0
|
12月前
|
SQL 运维 5G
企业运维训练营之数据库原理与实践—数据库DAS简介和备份上云方案—性能诊断与优化(下)
企业运维训练营之数据库原理与实践—数据库DAS简介和备份上云方案—性能诊断与优化(下)
126 0
|
数据库
如何修复 WordPress 数据库?如何更正WordPress 数据库?
如何修复 WordPress 数据库?如何更正WordPress 数据库? 如果您想修复您的数据库而不是完全重置它,首先要做的是打开 WordPress 主机的控制面板区域并登录您的帐户。进入后,将在控制面板内看到主机提供的所有选项。找到 phpMyAdmin 图标并单击它。
如何修复 WordPress 数据库?如何更正WordPress 数据库?
|
存储 运维 安全
数据库运维之InnoDB存储引擎表损坏修复方法
InnoDB存储引擎表的损坏可能是多种因素导致的,比如服务器断电、系统崩溃、硬盘损坏、写数据过程中mysqld进程被kill掉。
930 0
|
数据库
LeetCode(数据库)- 修复表中的名字
LeetCode(数据库)- 修复表中的名字
97 0