在本文中,我们将看到数据文件上存在块损坏时如何修复块损坏。
如果索引上存在“块损坏”,则可以通过删除并重新创建索引来解决问题。
在某些情况下,块损坏也可以出现在空闲页面上。
检测损坏的块
Oracle数据库中的块损坏并不是一个可怕的梦想。在处于Archivelog模式且由rman定期备份的数据库中,可以轻松地纠正块损坏。
连接到具有块损坏的数据库,并使用以下脚本检测块损坏。
如果您不知道要连接到Oracle,则可能需要阅读以下文章。
1
|
select * from v$database_block_corruption;
|
对于RAC数据库;
1
|
select * from gv$database_block_corruption;
|
使用RMAN修复块损坏
然后连接到RMAN并使用以下脚本修复块损坏。
要连接到RMAN,您可能需要阅读标题为“如何连接到RMAN ”的文章。
在下面的脚本中写入从上面的脚本返回的由“ x”表示的文件号。
在上面的脚本中写入从上面的脚本返回的块号,而不是“ y”。
1
2
|
blockrecover datafile x block y;
backup validate check logical datafile x;
|
查找损坏的对象
您可以使用以下查询来确定损坏的块上有哪些对象。
1
2
|
SELECT tablespace_name, segment_type, owner, segment_name FROM dba_extents WHERE file_id =x and y
between block_id AND block_id + blocks - 1;
|
要么
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
|
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#
, 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#
, 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#;
|
运行查询时,它将告诉您块损坏在哪里,如下所示。
修复所有块损坏
要修复此列表中的所有损坏,只需使用RMAN运行以下命令。
1
|
RMAN> blockrecover corruption list;
|
修复特定的块
1
|
RMAN> blockrecover datafile 151 block 3454464;
|
您可以从v$database_block_corruption
上面找到数据文件和块号。
最后,您需要检查相应的数据文件。使用以下命令,您可以扫描整个数据文件,看是否有问题。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
RMAN> backup validate check logical datafile 151;
Starting backup at 31-MAR-16
using channel ORA_disK_1
using channel ORA_disK_2
using channel ORA_disK_3
using channel ORA_disK_4
using channel ORA_disK_5
using channel ORA_disK_6
using channel ORA_disK_7
using channel ORA_disK_8
channel ORA_disK_1: starting full datafile backup set
channel ORA_disK_1: specifying datafile(s) in backup set
input datafile file number=00151 name=+DATA/orcl/datafile/data_ts.1491.871430401
channel ORA_disK_1: backup set complete, elapsed time: 00:01:35
List of Datafiles
=================
File Status Marked Corrupt Empty Blocks Blocks examined High SCN
---- ------ -------------- ------------ --------------- ----------
151 OK 0 153363 3932160 629800241304
File Name: +DATA/orcl/datafile/data_ts.1491.871430401
Block Type Blocks Failing Blocks Processed
---------- -------------- ----------------
Data 0 3718487
Index 0 3829
Other 0 56481
Finished backup at 31-MAR-16
|
如果像上面的输出中的“状态正常”和“失败的块”值为零,则可以说问题已解决。
如果要脱机检查数据文件,也可以使用DB验证工具。示例命令如下。
1
|
dbv file=+DATA/orcl/datafile/users.411.795847253 blocksize=8192 userid=sys/*****
|