当前位置: 首页 > BACKUP & RESTORE > 正文

         ORACLE中对核心对象进行重建基本上会遇到ORA-00701错误,可以通过将数据库启动到upgrade或者配置event 38003错误来解决,但是object_id小于59的错误不能通过此方法来解决。但是可以通过重建创建对象,修改obj$bootstrap$表来处理。下面是在自己的测试环境模拟一下对file$表及索引的操作,请非在生产环境操作,此实验也没有实际意思,只是为了好玩而以。

     注意不同平台,不同数据库版本操作方法都可能不一样。

1 环境介绍

www.htz.pw > select * from v$version where rownum=1;

 

BANNER

——————————————————————————–

Oracle Database 11g Enterprise Edition Release 11.2.0.3.0 – 64bit Production

 

www.htz.pw > !uname -a

Linux orcl9i 2.6.9-89.EL #1 Mon Apr 20 10:22:29 EDT 2009 x86_64 x86_64 x86_64 GNU/Linux

2 rebuild索引报ORA-00701错误

www.htz.pw > alter index sys.i_file1 rebuild;

alter index sys.i_file1 rebuild

*

ERROR at line 1:

ORA-00701: object necessary for warmstarting database cannot be altered

这里i_file1FILE$表的索引

www.cdhtz.com > @table_index.sql

Enter Search Table Owner (i.e. SCOTT|ALL(DEFAULT)) : sys

Enter Search Table Name (i.e. DEPT|DEFAULT(ALL)) : file$

Enter Search Index Name (i.e. DEPT|DEFAULT(ALL)) :

 

OWNER

TABLE_NAME                

INDEX_NAME                  POST COLUMNNAME

————————— —- ——————–

FILE$:I_FILE1                  1 FILE#

FILE$:I_FILE2                  1 TS#

                               2 RELFILE#

3 创建备用FILE$表及相关索引

www.cdhtz.com > create table FILE$_back as select * from file$;

 

Table created.

如果有相当的约束请创建相应的约束                                                                               

www.cdhtz.com > set long 1000000000

select dbms_metadata.get_ddl(‘INDEX’, INDEX_NAME, OWNER) as getddl

  2    from dba_indexes

  3   where table_name = ‘FILE$’

  4     AND table_owner = ‘SYS’;

 

GETDDL

————————————————————————–

 

  CREATE UNIQUE INDEX “SYS”.”I_FILE2″ ON “SYS”.”FILE$” (“TS#”, “RELFILE#”)

  PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS

  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645

  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1

  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)

  TABLESPACE “SYSTEM”

 

 

  CREATE UNIQUE INDEX “SYS”.”I_FILE1″ ON “SYS”.”FILE$” (“FILE#”)

  PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS

  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645

  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1

  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)

  TABLESPACE “SYSTEM”

2 rows selected.

创建索引信息

 www.cdhtz.com >  CREATE UNIQUE INDEX “SYS”.”I_FILE2_BACK” ON “SYS”.”FILE$_BACK” (“TS#”, “RELFILE#”)

  PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS

  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645

  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1

  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)

  TABLESPACE “SYSTEM”;

Index created.

www.cdhtz.com >   CREATE UNIQUE INDEX “SYS”.”I_FILE1_BACK” ON “SYS”.”FILE$_BACK” (“FILE#”)

  PCTFREE 10 INITRANS 2 MAXTRANS 255 COMPUTE STATISTICS

  STORAGE(INITIAL 65536 NEXT 1048576 MINEXTENTS 1 MAXEXTENTS 2147483645

  PCTINCREASE 0 FREELISTS 1 FREELIST GROUPS 1

  BUFFER_POOL DEFAULT FLASH_CACHE DEFAULT CELL_FLASH_CACHE DEFAULT)

  TABLESPACE “SYSTEM”;

Index created.

4 dd清空i_file1索引

www.cdhtz.com > @extent.sql

Enter value for owner: sys

Enter value for segment_name: I_FILE1

Enter value for tablespace_name:

                   

                     FILE                  BLOCK

OWNER:SEGMENT_NAME     ID   FNO  EXTENT_ID BEGIN_END

——————- —– —– ———- ———-

SYS.I_FILE1             1     1          0 392~399  

*******************                                 

1 row selected.

 

www.cdhtz.com > select name from v$dbfile;

 

NAME

————————————————-

/oracle/app/oracle/oradata/orcl1123/system01.dbf

/oracle/app/oracle/oradata/orcl1123/sysaux01.dbf

/oracle/app/oracle/oradata/orcl1123/undo1.dbf

/oracle/app/oracle/oradata/orcl1123/user02.dbf

/oracle/app/oracle/oradata/orcl1123/user01.dbf

这里将i_file1占用的块清空,以便后面查询file$表时走索引报错

www.cdhtz.com > !dd if=/dev/zero of=/oracle/app/oracle/oradata/orcl1123/system01.dbf bs=8192 seek=392 count=8 conv=notrunc

8+0 records in

8+0 records out

 

www.cdhtz.com > alter system flush buffer_cache;

 

System altered.

 

www.cdhtz.com > select max(file#) from file$;

select max(file#) from file$

*

ERROR at line 1:

ORA-01578: ORACLE data block corrupted (file # 1, block # 393)

ORA-01110: data file 1: ‘/oracle/app/oracle/oradata/orcl1123/system01.dbf’

5 更新OBJ$基表

www.cdhtz.com > SELECT OBJ#, DATAOBJ#, NAME, OWNER#

  FROM OBJ$

 WHERE NAME IN (‘I_FILE1_BACK’,

                ‘I_FILE2_BACK’,

                ‘FILE$_BACK’,

                ‘I_FILE1’,

                ‘I_FILE2’,

                ‘FILE$’);

 

      OBJ#   DATAOBJ# NAME                               OWNER#

———- ———- —————————— ———-

        17         17 FILE$                                   0

        43         43 I_FILE1                                 0

        44         44 I_FILE2                                 0

     82700      82700 FILE$_BACK                              0

     82701      82701 I_FILE2_BACK                            0

     82702      82702 I_FILE1_BACK                            0

下面的步骤我都是在自己的测试环境测试的,请不要用于生产环境。在ORACLE中我们都是通过对象名来访问对象,对象名最后在obj$表解析成对象ID再与其它的一些基表做映射,所以这里直接更改的obj$表。

将原来的file$及相应的索引更改为其它的名字

update obj$ set name=’FILE$_OLD’ where obj#=17;

update obj$ set name=’I_FILE1_OLD’ where obj#=43;

update obj$ set name=’I_FILE2_OLD’ where obj#=44;

将新创建的备份表及索引更改为原来的名字

update obj$ set name=’FILE$’ where obj#=82700;

update obj$ set name=’I_FILE1′ where obj#=82702;

update obj$ set name=’I_FILE2′ where obj#=82701;

更改后的信息

www.cdhtz.com > SELECT OBJ#, DATAOBJ#, NAME, OWNER#

  FROM OBJ$

 WHERE NAME IN (‘I_FILE1_BACK’,

                ‘I_FILE2_BACK’,

                ‘FILE$_BACK’,

                ‘I_FILE1’,

                ‘I_FILE2’,

                ‘FILE$’);

      OBJ#   DATAOBJ# NAME                               OWNER#

———- ———- —————————— ———-

     82700      82700 FILE$                                   0

     82701      82701 I_FILE2                                 0

     82702      82702 I_FILE1                                 0

6 更新bootstrap$

这里重新创建了一张bootstrap$表,名为htz,更直接更新htz表中的内容,不直接使用bootstrap$表。

更改前需要先查询到对象的block_id号,使用下面的命令

www.cdhtz.com >select owner, segment_name, block_id

  from dba_extents

 where segment_name in (‘I_FILE1_BACK’, ‘I_FILE2_BACK’, ‘FILE$_BACK’)

;

 

OWNER      SEGMENT_NAME           BLOCK_ID

———- ——————– ———-

SYS        FILE$_BACK                95816

SYS        I_FILE2_BACK              95824

SYS        I_FILE1_BACK              95832

www.cdhtz.com > col sql_text for a140

更新后的内容如下,我这里使用的pl/sql来修改的,修改的部分都被标记了

www.cdhtz.com > select * from htz where obj# in (17, 43, 44);

 

     LINE#       OBJ# SQL_TEXT

———- ———- ——————————————————————————————————————————————————

        17         17 CREATE TABLE FILE$(“FILE#” NUMBER NOT NULL,”STATUS$” NUMBER NOT NULL,”BLOCKS” NUMBER NOT NULL,”TS#” NUMBER,”RELFILE#” NUMBER,”MAXEXTEND” NUMBER,”INC”

                      NUMBER,”CRSCNWRP” NUMBER,”CRSCNBAS” NUMBER,”OWNERINSTANCE” VARCHAR2(30),”SPARE1″ NUMBER,”SPARE2″ NUMBER,”SPARE3″ VARCHAR2(1000),”SPARE4″ DATE) PCTFREE

                       10 PCTUSED 40 INITRANS 1 MAXTRANS 255 STORAGE (  INITIAL 64K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 2147483645 PCTINCREASE 0 OBJNO 82700 EXTENTS (FILE 1

                      BLOCK 95816))

 

        43         43 CREATE UNIQUE INDEX I_FILE1 ON FILE$(FILE#) PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE (  INITIAL 64K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 2147483645 PC

                      TINCREASE 0 OBJNO 82702 EXTENTS (FILE 1 BLOCK 95832))

 

        44         44 CREATE UNIQUE INDEX I_FILE2 ON FILE$(TS#,RELFILE#) PCTFREE 10 INITRANS 2 MAXTRANS 255 STORAGE (  INITIAL 64K NEXT 1024K MINEXTENTS 1 MAXEXTENTS 214748

                      3645 PCTINCREASE 0 OBJNO 82701 EXTENTS (FILE 1 BLOCK 95824))

这里也可以更改obj#为对应的object号,但是不改也不影响

7 替换bootstrap$

这里需要将数据库启动到upgrade状态,具体怎么替换bootstrap$BLOG:substituter-bootstrap

www.cdhtz.com > exec DBMS_DDL_INTERNAL.SWAP_BOOTSTRAP(‘HTZ’);

 

PL/SQL procedure successfully completed.

 

www.cdhtz.com > startup force;

ORACLE instance started.

 

Total System Global Area 2137886720 bytes

Fixed Size                  2230072 bytes

Variable Size            1493174472 bytes

Database Buffers          637534208 bytes

Redo Buffers                4947968 bytes

Database mounted.

Database opened.

数据库已经正常启动

8 访问file$

www.cdhtz.com > set autotrace on

www.cdhtz.com > select max(file#) from file$;

 

MAX(FILE#)

———-

         6

这里访问file$没有再报错了,可以看到是执行计划是走的索引的访问。

Execution Plan

———————————————————-

Plan hash value: 1331072393

 

————————————————————————————–

| Id  | Operation                  | Name    | Rows  | Bytes | Cost (%CPU)| Time     |

————————————————————————————–

|   0 | SELECT STATEMENT           |         |     1 |    13 |     1   (0)| 00:00:01 |

|   1 |  SORT AGGREGATE            |         |     1 |    13 |            |          |

|   2 |   INDEX FULL SCAN (MIN/MAX)| I_FILE1 |     1 |    13 |     1   (0)| 00:00:01 |

 

下面是10046的结果,在做10046之前,需要flush buffer_cache;

*** 2014-11-19 23:24:55.730

WAIT #182959581784: nam=’SQL*Net message from client’ ela= 4533024 driver id=1650815232 #bytes=1 p3=0 obj#=532 tim=1416410695730877

CLOSE #182959581784:c=0,e=40,dep=0,type=1,tim=1416410695731026

PARSE #182959385008:c=0,e=29,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=1331072393,tim=1416410695731094

EXEC #182959385008:c=0,e=37,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=1,plh=1331072393,tim=1416410695731225

WAIT #182959385008: nam=’SQL*Net message to client’ ela= 2 driver id=1650815232 #bytes=1 p3=0 obj#=532 tim=1416410695731249

WAIT #182959385008: nam=’db file sequential read’ ela= 18 file#=1 block#=95833 blocks=1 obj#=82702 tim=1416410695731347

FETCH #182959385008:c=0,e=118,p=1,cr=1,cu=0,mis=0,r=1,dep=0,og=1,plh=1331072393,tim=1416410695731386

WAIT #182959385008: nam=’SQL*Net message from client’ ela= 110 driver id=1650815232 #bytes=1 p3=0 obj#=82702 tim=1416410695731534

FETCH #182959385008:c=0,e=2,p=0,cr=0,cu=0,mis=0,r=0,dep=0,og=0,plh=1331072393,tim=1416410695731556

WAIT #182959385008: nam=’SQL*Net message to client’ ela= 1 driver id=1650815232 #bytes=1 p3=0 obj#=82702 tim=1416410695731570

 

这里我们可以看到是访问的95833这个块

9 使用bbed替换回原来的bootstrap$

BBED> set offset 96

        OFFSET          96

 

BBED> set count 20

        COUNT           20

 

BBED> dump

 File: /oracle/app/oracle/oradata/orcl1123/system01.dbf (0)

 Block: 1                Offsets:   96 to  115           Dba:0x00000000

————————————————————————

 60764100 07000000 00000000 60776c2d 748b7933

 

 <32 bytes per line>

 

BBED> set mode edit

        MODE            Edit

 

BBED> modify /x 08024000 offset 96

Warning: contents of previous BIFILE will be lost. Proceed? (Y/N) y

 File: /oracle/app/oracle/oradata/orcl1123/system01.dbf (0)

 Block: 1                Offsets:   96 to  115           Dba:0x00000000

————————————————————————

 08024000 07000000 00000000 60776c2d 748b7933

 

 <32 bytes per line>

 

BBED> dump offset 96 count 10

 File: /oracle/app/oracle/oradata/orcl1123/system01.dbf (0)

 Block: 1                Offsets:   96 to  105           Dba:0x00000000

————————————————————————

 08024000 07000000 0000

 

 <32 bytes per line>

 

BBED> p kcvfh.kcvfhrdb

ub4 kcvfhrdb                                @96       0x00400208

 

 

BBED> sum apply

Check value for File 0, Block 1:

current = 0x5c33, required = 0x5c33

 

BBED> verify

DBVERIFY – Verification starting

FILE = /oracle/app/oracle/oradata/orcl1123/system01.dbf

BLOCK = 1

 

 

DBVERIFY – Verification complete

 

Total Blocks Examined         : 1

Total Blocks Processed (Data) : 0

Total Blocks Failing   (Data) : 0

Total Blocks Processed (Index): 0

Total Blocks Failing   (Index): 0

Total Blocks Empty            : 0

Total Blocks Marked Corrupt   : 0

Total Blocks Influx           : 0

Message 531 not found;  product=RDBMS; facility=BBED

 

 

 

 

www.cdhtz.com > startup

ORACLE instance started.

 

Total System Global Area 2137886720 bytes

Fixed Size                  2230072 bytes

Variable Size            1493174472 bytes

Database Buffers          637534208 bytes

Redo Buffers                4947968 bytes

Database mounted.

Database opened.

 

 

www.cdhtz.com > select max(file#) from file$;

select max(file#) from file$

                       *

ERROR at line 1:

ORA-01578: ORACLE data block corrupted (file # 1, block # 393)

ORA-01110: data file 1: ‘/oracle/app/oracle/oradata/orcl1123/system01.dbf’

这里我们又看到了报错。

通过上面的方法我们可以达到重建对象号小于60的对象,但是没有任何的实际意义,请不要在生产环境操作

rebuild object that object id less than 60:等您坐沙发呢!

发表评论

gravatar

? razz sad evil ! smile oops grin eek shock ??? cool lol mad twisted roll wink idea arrow neutral cry mrgreen

快捷键:Ctrl+Enter