怎么修復數(shù)據(jù)庫?下面以修復數(shù)據(jù)庫壞塊為例,為大家介紹修復數(shù)據(jù)庫壞塊方法,詳細如下:
PART1
修復數(shù)據(jù)庫壞塊
dbv
你也可以用dbv工具看一下你現(xiàn)在其他的數(shù)據(jù)文件有沒有還有壞塊的
dbv file='yourfilename'
恢復方法:
當Oracle數(shù)據(jù)庫出現(xiàn)壞塊時,Oracle會在警告日志文件(alert_SID.log)中記錄壞塊的信息:
ORA-01578: ORACLE data block corrupted (file # 7, block # )
ORA-01110: data file : '/oracle1/oradata/V920/oradata/V816/users01.dbf'
其中,<AFN>代表壞塊所在數(shù)據(jù)文件的絕對文件號,代表壞塊是數(shù)據(jù)文件上的第幾個數(shù)據(jù)塊
出現(xiàn)這種情況時,應該首先檢查是否是硬件及操作系統(tǒng)上的故障導致Oracle數(shù)據(jù)庫出現(xiàn)壞塊。在排除了數(shù)據(jù)庫以外的原因后,再對發(fā)生壞塊的數(shù)據(jù)庫對象進行處理。
1.確定發(fā)生壞塊的數(shù)據(jù)庫對象
SELECT tablespace_name,
segment_type,
owner,
segment_name
FROM dba_extents
WHERE file_id =
AND between block_id AND block_id+blocks-1;
2.決定修復方法
如果發(fā)生壞塊的對象是一個索引,那么可以直接把索引DROP掉后,再根據(jù)表里的記錄進行重建;
如果發(fā)生壞塊的表的記錄可以根據(jù)其它表的記錄生成的話,那么可以直接把這個表DROP掉后重建;
如果有數(shù)據(jù)庫的備份,則恢復數(shù)據(jù)庫的方法來進行修復;
如果表里的記錄沒有其它辦法恢復,那么壞塊上的記錄就丟失了,只能把表中其它數(shù)據(jù)壞上的記錄取出來,然后對這個表進行重建。
3.用Oracle提供的DBMS_REPAIR包標記出壞塊
exec DBMS_REPAIR.SKIP_CORRUPT_BLOCKS('','');
4.使用Create table as select命令將表中其它塊上的記錄保存到另一張表上
create table corrupt_table_bak
as
select * from corrupt_table;
5.用DROP TABLE命令刪除有壞塊的表
drop table corrupt_table;
6.用alter table rename命令恢復原來的表
alter table corrupt_table_bak
rename to corrupt_table;
7.如果表上存在索引,則要重建表上的索引
PART2
2014.7.22研究恢復數(shù)據(jù)庫壞塊:
Oracle調(diào)用標準C的系統(tǒng)函數(shù),對數(shù)據(jù)塊進行讀寫操作,因此,壞塊是有可能由以下幾種原因產(chǎn)生:
硬件的I/O錯誤
操作系統(tǒng)的I/O錯誤或緩沖問題
內(nèi)存或paging問題
磁盤修復工具
一個數(shù)據(jù)文件的一部分正在被覆蓋
Oracle試圖訪問一個未被格式化的系統(tǒng)塊失敗
數(shù)據(jù)文件部分溢出
Oracle或者操作系統(tǒng)的bug
遇到“ORA-01578:ORACLE data block corrupted”錯誤
處理方法:1.rman的recover命令可以在數(shù)據(jù)庫保持open狀態(tài)下只恢復受損的數(shù)據(jù)塊
2.如果沒有備份,萬不得已之下也可以采用DBMS_REPAIR包的存儲過程將受損壞塊隔離,同時盡可能地挽救部分數(shù)據(jù)。
rman backup命令也是檢查壞數(shù)據(jù)塊的好工具 一旦讀取ORA-19566 即可有問題
此時可用backup validate tablespace user觀察詳細的信息,可查看到壞塊數(shù)與跟蹤文件
grep‘corrupt’/u01/app/oracle/diag/rdbms/br/br/trace/**.trc
恢復數(shù)據(jù)塊:rman》recover datafile 5 block 203;
批量恢復受損的數(shù)據(jù)塊:recover corruption list;
數(shù)據(jù)塊壞塊一號壞塊,需要做:
run{
sql 'alter database datafile 5 offline';
restore datafile 5;
recover datafile 5;
sql'alter database datafile 5 online'
}
使用exp/imp恢復
在這種情況下肯定會造成數(shù)據(jù)的丟失,在這種情況下應采取將數(shù)據(jù)導出然后重建表再進行導入的方法,來盡量恢復損壞數(shù)據(jù)塊中的數(shù)據(jù),但是在有壞塊的情況下是不允許導出的,如下命令:Exp test/test file=t.dmp tables=t;
導出命令在執(zhí)行中會報ORA-01578錯誤,在這錯誤提示中會提示那個文件號的文件以及這個文件中的哪個塊被損壞,如:ORA—01578:ORACLE 數(shù)據(jù)塊損壞(文件號 4,塊號 35)
針對以上的提示首先查詢那些對象被損壞:
Select tablespace_name,segment_type,owner,segment_name From dba_extents Where file_id=4 and 35 between block_id and block_id+blocks-1;
如果被損壞的塊是索引,通?梢酝ㄟ^索引重建來解決,如果損壞的是數(shù)據(jù)(segment_type為table),那么通過設置如下內(nèi)部事件使得Exp操作跳過壞塊。
Alter session set events=’10231 trace name context forever,level 10’;
然后重新執(zhí)行導出命令,導出相關的表,然后執(zhí)行Drop Table命令刪除相關表,之后重建表最后導入數(shù)據(jù)。
使用DBMS_REPAIR恢復
用DBMS_REPAIR當然也會丟失數(shù)據(jù)。這里不做詳細的介紹,有興趣的可以查看oracle的在線文
3、使用dbms_repair包進行壞塊處理
1)首先建立repair_table,用于存放dbms_repair.check_object檢測出來的壞塊信息
SQL> declare
2begin
3dbms_repair.admin_tables
4(table_name => 'REPAIR_TABLE',--表名
5table_type => dbms_repair.repair_table,
6action => dbms_repair.create_action,
7tablespace => 'USERS');--用于指定該表存放的表空間
8end;
9/
PL/SQL 過程已成功完成。
SQL> col owner format a10
SQL> col object_name format a20
SQL> col object_type format a20
SQL> select owner, object_name, object_type
2from dba_objects
3where object_name like '%REPAIR_TABLE';
OWNEROBJECT_NAMEOBJECT_TYPE
---------- -------------------- --------------------
SYSREPAIR_TABLETABLE
SYSDBA_REPAIR_TABLEVIEW
Oracle自動創(chuàng)建了一個DBA_REPAIR_TABLE視圖。
2)使用dbms_repair.check_object進行壞塊檢測
SQL> set serveroutput on size 100000;
SQL> declare
2rpr_count int;
3begin
4rpr_count := 0;
5dbms_repair.check_object(
6schema_name => 'SYS',--指定對象模式,也就是對象的所有者
7object_name => 'TEST',--指定對象名,也就是表名
8repair_table_name => 'REPAIR_TABLE',
9corrupt_count => rpr_count);
10dbms_output.put_line('repair block count: '
11||to_char(rpr_count));
12end;
13/
repair block count: 4
PL/SQL 過程已成功完成。
SQL> select object_name, block_id, corrupt_type, marked_corrupt,
2corrupt_description, repair_description
3from repair_table;
OBJECT_NAMEBLOCK_ID CORRUPT_TYPE MARKED_COR
-------------------- ---------- ------------ ----------
CORRUPT_DESCRIPTION
-------------------------------------------------------------------------------
REPAIR_DESCRIPTION
-------------------------------------------------------------------------------
TEST196148 TRUE
mark block software corrupt
TEST206148 TRUE
mark block software corrupt
TEST236148 TRUE
mark block software corrupt
TEST316148 TRUE
mark block software corrupt
通過運行dbms_repair.check_object,將壞塊信息存放到了repair_table表中,其中有個字段marked_corrupt,用于標識該塊是否被標識為壞塊,當被標識為true時,即該塊被標識為壞塊。其中這一步跟oracle文檔中的描述有點進入,根據(jù)oracle文檔,當執(zhí)行完dbms_repair.check_object時,并不會進行壞塊標識,也就是marked_corrupt列的值應該為false,而只有當執(zhí)行dbms_repair.fix_corrupt_blocks過程后才會進行壞塊標識。
3)使用dbms_repair.fix_corrupt_blocks進行壞塊標識
SQL> declare
2fix_block_count int;
3begin
4fix_block_count := 0;
5dbms_repair.fix_corrupt_blocks (
6schema_name => 'SYS',
7object_name => 'TEST',
8object_type => dbms_repair.table_object,
9repair_table_name => 'REPAIR_TABLE',
10fix_count => fix_block_count);
11dbms_output.put_line('fix blocks count: ' ||
12to_char(fix_block_count));
13end;
14/
fix blocks count: 0
PL/SQL 過程已成功完成。
我們可以見到到fix blocks count=0,即在上一步進行check_object時已經(jīng)進行了壞塊標識了,這一步其實可以省略。(不過沒有測試過。
SQL> select count(*) from test;
select count(*) from test
*
第 1 行出現(xiàn)錯誤:
ORA-01578: ORACLE 數(shù)據(jù)塊損壞 (文件號 7, 塊號 19)
ORA-01110: 數(shù)據(jù)文件 7: 'G:\ORACLE\PRODUCT\10.2.0\ORADATA\ORA10G\TEST01.DBF'
此時進行查詢?nèi)匀粓箦e,因為我們只是將壞塊進行了標識,當進行全表掃描的時候,仍然會查詢到壞塊而報錯。
4)使用dbms_repair.dump_orphan_keys過程來保存壞塊的索引鍵值,然后再執(zhí)行skip_corrupt_blocks過程之后,我們才能重建索引,不然重建索引時新的索引仍然會引用壞塊。首先要建立ORPHAN_KEY_TABLE,此表就是用來存放壞塊的索引鍵值。
SQL> declare
2begin
3dbms_repair.admin_tables
4(table_name => 'ORPHAN_KEY_TABLE',
5table_type => dbms_repair.orphan_table,
6action => dbms_repair.create_action,
7tablespace => 'USERS');
8end;
9/
PL/SQL 過程已成功完成。
然后執(zhí)行過程dbms_repair.dump_orphan_keys將壞塊鍵值存放到上面所創(chuàng)建的表中:
SQL> declare
2orph_count int;
3begin
4orph_count:= 0;
5dbms_repair.dump_orphan_keys (
6schema_name => 'SYS',
7object_name => 'ID_INX',--索引的名字
8object_type => dbms_repair.index_object,
9repair_table_name => 'REPAIR_TABLE',--從這個表中獲得壞塊的信息
10orphan_table_name => 'ORPHAN_KEY_TABLE',
11key_count => orph_count);
12dbms_output.put_line('orphan-index entries: ' || to_char(orph_count));
13end;
14/
orphan-index entries: 491
PL/SQL 過程已成功完成。
SQL> declare
2orph_count int;
3begin
4orph_count:= 0;
5dbms_repair.dump_orphan_keys (
6schema_name => 'SYS',
7object_name => 'NAME_INX',
8object_type => dbms_repair.index_object,
9repair_table_name => 'REPAIR_TABLE',
10orphan_table_name => 'ORPHAN_KEY_TABLE',
11key_count => orph_count);
12dbms_output.put_line('orphan-index entries: ' || to_char(orph_count));
13end;
14/
orphan-index entries: 491
PL/SQL 過程已成功完成。
對每個索引都要進行dump_orphan_keys。
SQL> select index_name, count(*) from orphan_key_table
2group by index_name;
INDEX_NAMECOUNT(*)
------------------------------ ----------
ID_INX491
NAME_INX491
5)使用skip_corrupt_blocks,使查詢或者DML時跳過壞塊
SQL> declare
2begin
3dbms_repair.skip_corrupt_blocks (
4schema_name => 'SYS',
5object_name => 'TEST',
6object_type => dbms_repair.table_object,
7flags => dbms_repair.skip_flag);
8end;
9/
PL/SQL 過程已成功完成。
SQL> select table_name, skip_corrupt from dba_tables
2where table_name = 'TEST';
TABLE_NAMESKIP_COR
------------------------------ --------
TESTENABLED
6)使用dbms_repair.rebuild_freelists重建freelists,使得該塊不再被放到freelists,當中,也就是該塊將不會再被使用。
SQL> declare
2begin
3dbms_repair.rebuild_freelists (
4schema_name => 'SYS',
5object_name => 'TEST',
6object_type => dbms_repair.table_object);
7end;
8/
declare
*
第 1 行出現(xiàn)錯誤:
ORA-10614: Operation not allowed on this segment
ORA-06512: 在 "SYS.DBMS_REPAIR", line 400
ORA-06512: 在 line 3
不過我們可以看到,對于SYS用戶下面的對象好像不能進行此操作。
4、重建索引
SQL> select count(id) from test;
COUNT(ID)
----------
19998
SQL> select count(name) from test;
COUNT(NAME)
-----------
19998
SQL> select count(*) from test;
COUNT(*)
----------
19507
我們可以看到上面的三個查詢,對于第1和第2個使用索引進行查詢和不使用索引進行查詢的結(jié)果是不一樣的。下面我們使用rebuild試試。
SQL> alter index id_inx rebuild;
索引已更改。
SQL> alter index name_inx rebuild;
索引已更改。
SQL> select count(id) from test;
COUNT(ID)
----------
19998
SQL> select count(name) from test;
COUNT(NAME)
-----------
19998
SQL> select count(*) from test;
COUNT(*)
----------
19507
可以是不能通過rebuild來重建索引的。只能通過DROP然后再CREATE。
SQL> drop index id_inx;
索引已刪除。
SQL> drop index name_inx;
索引已刪除。
SQL> create index id_inx on test(id);
索引已創(chuàng)建。
SQL> create index name_inx on test(name);
索引已創(chuàng)建。
SQL> select count(id) from test;
COUNT(ID)
----------
19507
SQL> select count(name) from test;
COUNT(NAME)
-----------
19507
SQL> select count(*) from test;
COUNT(*)
----------
19507
到此該表已經(jīng)可以正常使用了,但同時也丟失了一些數(shù)據(jù),所以在使用dbms_repair進行恢復的時候要充分考慮到數(shù)據(jù)的重要性和恢復的后果。同時也應該考慮是否有其它別的恢復方法,不然貿(mào)貿(mào)然的行事最后可能得不償失。
PART2
2014.7.22研究恢復數(shù)據(jù)庫壞塊:
Oracle調(diào)用標準C的系統(tǒng)函數(shù),對數(shù)據(jù)塊進行讀寫操作,因此,壞塊是有可能由以下幾種原因產(chǎn)生:
硬件的I/O錯誤
操作系統(tǒng)的I/O錯誤或緩沖問題
內(nèi)存或paging問題
磁盤修復工具
一個數(shù)據(jù)文件的一部分正在被覆蓋
Oracle試圖訪問一個未被格式化的系統(tǒng)塊失敗
數(shù)據(jù)文件部分溢出
Oracle或者操作系統(tǒng)的bug
遇到“ORA-01578:ORACLE data block corrupted”錯誤
處理方法:1.rman的recover命令可以在數(shù)據(jù)庫保持open狀態(tài)下只恢復受損的數(shù)據(jù)塊
2.如果沒有備份,萬不得已之下也可以采用DBMS_REPAIR包的存儲過程將受損壞塊隔離,同時盡可能地挽救部分數(shù)據(jù)。
rman backup命令也是檢查壞數(shù)據(jù)塊的好工具 一旦讀取ORA-19566 即可有問題
此時可用backup validate tablespace user觀察詳細的信息,可查看到壞塊數(shù)與跟蹤文件
grep‘corrupt’/u01/app/oracle/diag/rdbms/br/br/trace/**.trc
恢復數(shù)據(jù)塊:rman》recover datafile 5 block 203;
批量恢復受損的數(shù)據(jù)塊:recover corruption list;
數(shù)據(jù)塊壞塊一號壞塊,需要做:
run{
sql 'alter database datafile 5 offline';
restore datafile 5;
recover datafile 5;
sql'alter database datafile 5 online'
}
使用exp/imp恢復
在這種情況下肯定會造成數(shù)據(jù)的丟失,在這種情況下應采取將數(shù)據(jù)導出然后重建表再進行導入的方法,來盡量恢復損壞數(shù)據(jù)塊中的數(shù)據(jù),但是在有壞塊的情況下是不允許導出的,如下命令:Exp test/test file=t.dmp tables=t;
導出命令在執(zhí)行中會報ORA-01578錯誤,在這錯誤提示中會提示那個文件號的文件以及這個文件中的哪個塊被損壞,如:ORA—01578:ORACLE 數(shù)據(jù)塊損壞(文件號 4,塊號 35)
針對以上的提示首先查詢那些對象被損壞:
Select tablespace_name,segment_type,owner,segment_name From dba_extents Where file_id=4 and 35 between block_id and block_id+blocks-1;
如果被損壞的塊是索引,通?梢酝ㄟ^索引重建來解決,如果損壞的是數(shù)據(jù)(segment_type為table),那么通過設置如下內(nèi)部事件使得Exp操作跳過壞塊。
Alter session set events=’10231 trace name context forever,level 10’;
然后重新執(zhí)行導出命令,導出相關的表,然后執(zhí)行Drop Table命令刪除相關表,之后重建表最后導入數(shù)據(jù)。
使用DBMS_REPAIR恢復
用DBMS_REPAIR當然也會丟失數(shù)據(jù)。這里不做詳細的介紹,有興趣的可以查看oracle的在線文
3、使用dbms_repair包進行壞塊處理
1)首先建立repair_table,用于存放dbms_repair.check_object檢測出來的壞塊信息
SQL> declare
2begin
3dbms_repair.admin_tables
4(table_name => 'REPAIR_TABLE',--表名
5table_type => dbms_repair.repair_table,
6action => dbms_repair.create_action,
7tablespace => 'USERS');--用于指定該表存放的表空間
8end;
9/
PL/SQL 過程已成功完成。
SQL> col owner format a10
SQL> col object_name format a20
SQL> col object_type format a20
SQL> select owner, object_name, object_type
2from dba_objects
3where object_name like '%REPAIR_TABLE';
OWNEROBJECT_NAMEOBJECT_TYPE
---------- -------------------- --------------------
SYSREPAIR_TABLETABLE
SYSDBA_REPAIR_TABLEVIEW
Oracle自動創(chuàng)建了一個DBA_REPAIR_TABLE視圖。
2)使用dbms_repair.check_object進行壞塊檢測
SQL> set serveroutput on size 100000;
SQL> declare
2rpr_count int;
3begin
4rpr_count := 0;
5dbms_repair.check_object(
6schema_name => 'SYS',--指定對象模式,也就是對象的所有者
7object_name => 'TEST',--指定對象名,也就是表名
8repair_table_name => 'REPAIR_TABLE',
9corrupt_count => rpr_count);
10dbms_output.put_line('repair block count: '
11||to_char(rpr_count));
12end;
13/
repair block count: 4
PL/SQL 過程已成功完成。
SQL> select object_name, block_id, corrupt_type, marked_corrupt,
2corrupt_description, repair_description
3from repair_table;
OBJECT_NAMEBLOCK_ID CORRUPT_TYPE MARKED_COR
-------------------- ---------- ------------ ----------
CORRUPT_DESCRIPTION
-------------------------------------------------------------------------------
REPAIR_DESCRIPTION
-------------------------------------------------------------------------------
TEST196148 TRUE
mark block software corrupt
TEST206148 TRUE
mark block software corrupt
TEST236148 TRUE
mark block software corrupt
TEST316148 TRUE
mark block software corrupt
通過運行dbms_repair.check_object,將壞塊信息存放到了repair_table表中,其中有個字段marked_corrupt,用于標識該塊是否被標識為壞塊,當被標識為true時,即該塊被標識為壞塊。其中這一步跟oracle文檔中的描述有點進入,根據(jù)oracle文檔,當執(zhí)行完dbms_repair.check_object時,并不會進行壞塊標識,也就是marked_corrupt列的值應該為false,而只有當執(zhí)行dbms_repair.fix_corrupt_blocks過程后才會進行壞塊標識。
3)使用dbms_repair.fix_corrupt_blocks進行壞塊標識
SQL> declare
2fix_block_count int;
3begin
4fix_block_count := 0;
5dbms_repair.fix_corrupt_blocks (
6schema_name => 'SYS',
7object_name => 'TEST',
8object_type => dbms_repair.table_object,
9repair_table_name => 'REPAIR_TABLE',
10fix_count => fix_block_count);
11dbms_output.put_line('fix blocks count: ' ||
12to_char(fix_block_count));
13end;
14/
fix blocks count: 0
PL/SQL 過程已成功完成。
我們可以見到到fix blocks count=0,即在上一步進行check_object時已經(jīng)進行了壞塊標識了,這一步其實可以省略。(不過沒有測試過!)
SQL> select count(*) from test;
select count(*) from test
*
第 1 行出現(xiàn)錯誤:
ORA-01578: ORACLE 數(shù)據(jù)塊損壞 (文件號 7, 塊號 19)
ORA-01110: 數(shù)據(jù)文件 7: 'G:\ORACLE\PRODUCT\10.2.0\ORADATA\ORA10G\TEST01.DBF'
此時進行查詢?nèi)匀粓箦e,因為我們只是將壞塊進行了標識,當進行全表掃描的時候,仍然會查詢到壞塊而報錯。
4)使用dbms_repair.dump_orphan_keys過程來保存壞塊的索引鍵值,然后再執(zhí)行skip_corrupt_blocks過程之后,我們才能重建索引,不然重建索引時新的索引仍然會引用壞塊。首先要建立ORPHAN_KEY_TABLE,此表就是用來存放壞塊的索引鍵值。
SQL> declare
2begin
3dbms_repair.admin_tables
4(table_name => 'ORPHAN_KEY_TABLE',
5table_type => dbms_repair.orphan_table,
6action => dbms_repair.create_action,
7tablespace => 'USERS');
8end;
9/
PL/SQL 過程已成功完成。
然后執(zhí)行過程dbms_repair.dump_orphan_keys將壞塊鍵值存放到上面所創(chuàng)建的表中:
SQL> declare
2orph_count int;
3begin
4orph_count:= 0;
5dbms_repair.dump_orphan_keys (
6schema_name => 'SYS',
7object_name => 'ID_INX',--索引的名字
8object_type => dbms_repair.index_object,
9repair_table_name => 'REPAIR_TABLE',--從這個表中獲得壞塊的信息
10orphan_table_name => 'ORPHAN_KEY_TABLE',
11key_count => orph_count);
12dbms_output.put_line('orphan-index entries: ' || to_char(orph_count));
13end;
14/
orphan-index entries: 491
PL/SQL 過程已成功完成。
SQL> declare
2orph_count int;
3begin
4orph_count:= 0;
5dbms_repair.dump_orphan_keys (
6schema_name => 'SYS',
7object_name => 'NAME_INX',
8object_type => dbms_repair.index_object,
9repair_table_name => 'REPAIR_TABLE',
10orphan_table_name => 'ORPHAN_KEY_TABLE',
11key_count => orph_count);
12dbms_output.put_line('orphan-index entries: ' || to_char(orph_count));
13end;
14/
orphan-index entries: 491
PL/SQL 過程已成功完成。
對每個索引都要進行dump_orphan_keys。
SQL> select index_name, count(*) from orphan_key_table
2group by index_name;
INDEX_NAMECOUNT(*)
------------------------------ ----------
ID_INX491
NAME_INX491
5)使用skip_corrupt_blocks,使查詢或者DML時跳過壞塊
SQL> declare
2begin
3dbms_repair.skip_corrupt_blocks (
4schema_name => 'SYS',
5object_name => 'TEST',
6object_type => dbms_repair.table_object,
7flags => dbms_repair.skip_flag);
8end;
9/
PL/SQL 過程已成功完成。
SQL> select table_name, skip_corrupt from dba_tables
2where table_name = 'TEST';
TABLE_NAMESKIP_COR
------------------------------ --------
TESTENABLED
6)使用dbms_repair.rebuild_freelists重建freelists,使得該塊不再被放到freelists,當中,也就是該塊將不會再被使用。
SQL> declare
2begin
3dbms_repair.rebuild_freelists (
4schema_name => 'SYS',
5object_name => 'TEST',
6object_type => dbms_repair.table_object);
7end;
8/
declare
*
第 1 行出現(xiàn)錯誤:
ORA-10614: Operation not allowed on this segment
ORA-06512: 在 "SYS.DBMS_REPAIR", line 400
ORA-06512: 在 line 3
不過我們可以看到,對于SYS用戶下面的對象好像不能進行此操作。
4、重建索引
SQL> select count(id) from test;
COUNT(ID)
----------
19998
SQL> select count(name) from test;
COUNT(NAME)
-----------
19998
SQL> select count(*) from test;
COUNT(*)
----------
19507
我們可以看到上面的三個查詢,對于第1和第2個使用索引進行查詢和不使用索引進行查詢的結(jié)果是不一樣的。下面我們使用rebuild試試。
SQL> alter index id_inx rebuild;
索引已更改。
SQL> alter index name_inx rebuild;
索引已更改。
SQL> select count(id) from test;
COUNT(ID)
----------
19998
SQL> select count(name) from test;
COUNT(NAME)
-----------
19998
SQL> select count(*) from test;
COUNT(*)
----------
19507
可以是不能通過rebuild來重建索引的。只能通過DROP然后再CREATE。
SQL> drop index id_inx;
索引已刪除。
SQL> drop index name_inx;
索引已刪除。
SQL> create index id_inx on test(id);
索引已創(chuàng)建。
SQL> create index name_inx on test(name);
索引已創(chuàng)建。
SQL> select count(id) from test;
COUNT(ID)
----------
19507
SQL> select count(name) from test;
COUNT(NAME)
-----------
19507
SQL> select count(*) from test;
COUNT(*)
----------
19507
到此該表已經(jīng)可以正常使用了,但同時也丟失了一些數(shù)據(jù),所以在使用dbms_repair進行恢復的時候要充分考慮到數(shù)據(jù)的重要性和恢復的后果。同時也應該考慮是否有其它別的恢復方法,不然貿(mào)貿(mào)然的行事最后可能得不償失。