• Oracle 坏快处理:Undo 与 datafile


    数据库版本:9.2.0.5.0
    平台:windows2003

    下午接到通知以数据库出现坏块现象,无备份,应用无法正常使用,要予以解决由于没有备份,无法恢复,只能采用跳过坏块方法,然后通过业务补数据。

    首先要通知业务需要停服务,其次用PL/SQL登录把OPTCABLE表的sql导出来。
    首先要查出坏块中的对象是什么 file_id为截图中文件号,and 为数据库的块号。
    SQL> SELECT tablespace_name,segment_type, owner, segment_name FROM dba_extents WHERE file_id =82 AND 326677between block_id AND block_id + blocks - 1;

    TABLESPACE_NAME SEGME OWNER    SEGMENT_NAME
    ------------------------------ ----------  ---------        --------
    USERS                        TABLE   GISTAR      OPTCABLE

    然后需要查询数据对象的id(用于查询rowid的参数)
    SQL> SELECT data_object_id FROMdba_objects WHERE object_name = 'OPTCABLE' and owner='GISTAR';
    DATA_OBJECT_ID
    --------------
    97248

    找出坏块最小的rowid (1, DATA_OBJECT_ID ,file_id,数据库的块号,0)
    SQL> select dbms_rowid.rowid_create(1,97248,82,326677,0) from dual;

    DBMS_ROWID.ROWID_C
    ------------------
    AAAXvgABSAABPwVAAA

    找出坏块最大的rowid (1, DATA_OBJECT_ID ,file_id,数据库的块号+1,0)

    SQL> select dbms_rowid.rowid_create(1,97248,82,326678,0) from dual;

    DBMS_ROWID.ROWID_C
    ------------------
    AAAXvgABSAABPwWAAA

    然后通过rowid来确定坏块数据的范围,以便排除

    这里要注意,rowid的取值一定要大于大的,小于小的(上步骤查询出来的2个rowid)

    SQL> SELECT /*+ ROWID(A) */ COUNT(*)FROM OPTCABLE A WHERE ROWID>='AAAXvgABSAABPwWAAA';

    当进行查询时又报出undo表空间也有坏块

    ERROR 位于第 1 行:

    ORA-01578: ORACLE 数据块损坏(文件号107,块号225)

    ORA-01110: 数据文件 107:'D:ORACLEORADATALNXCUNDOTBS07.DBF'

    解决此问题要替换undo表空间(注意未结束的回滚段)

    create undo tablespace undo2 datafile'd:oracleoradatalnxcundo02_01.dbf' size 2048M;

    alter system set undo_tablespace=undo2;

    重启数据库后查询undo信息(undo已经更换)

    SQL> show parameter undo;

    NAME TYPE VALUE
    -------------------------------------------- ------------------------------
    undo_management string AUTO

    undo_retention integer 10800

    undo_suppress_errors boolean FALSE

    undo_tablespace string UNDO2

    删除老undo表空间报错,发现了未结束的回滚段

    SQL> drop tablespace UNDOTBS1 includingcontents and datafiles;

    drop tablespace UNDOTBS1 including contentsand datafiles

    *

    ERROR 位于第 1 行:

    ORA-01548: 已找到活动回退段'_SYSSMU5$',终止删除表空间

    创建pfile

    SQL> create pfile='d: .txt' fromspfile;
    关闭实例
    SQL> shutdown immediate
    编辑pfile加入如下参数(注意,CORRUPTED_ROLLBACK_SEGMENTS中一定要包含未结束的回滚段)

    *.undo_management='MANUAL'

    *._CORRUPTED_ROLLBACK_SEGMENTS=(_SYSSMU5$,_SYSSMU6$,_SYSSMU7$,_SYSSMU8$,_SYSSMU9$,_SYSSMU10$)

    用pfile启动数据库
    SQL> startup pfile='d: .txt';
    删除原来的undo表空间(数据文件也删除)
    SQL> drop tablespace UNDOTBS1 includingcontents and datafiles;
    再用spfile重启数据库,因为我们要用undo2表空间进行修复(不用指定参数文件,默认)
    startup
    查询undo段信息
    SQL> selectsegment_name,status,tablespace_name from dba_rollback_segs;
    SEGMENT_NAME STATUS TABLESPACE_NAME
    -------------------- ----------------------------------------------
    SYSTEM ONLINE SYSTEM

    _SYSSMU17$ ONLINE UNDO2

    _SYSSMU18$ ONLINE UNDO2

    _SYSSMU19$ ONLINE UNDO2

    _SYSSMU20$ ONLINE UNDO2

    _SYSSMU21$ ONLINE UNDO2

    _SYSSMU22$ ONLINE UNDO2

    _SYSSMU23$ ONLINE UNDO2

    _SYSSMU24$ ONLINE UNDO2

    _SYSSMU25$ ONLINE UNDO2

    _SYSSMU26$ ONLINE UNDO2

    发现没有问题,切换生产用户,继续修复坏块
    然后通过rowid来确定坏块数据的范围,以便排除
    这里要注意,rowid的取值一定要大于大的,小于小的(上步骤查询出来的2个rowid)


    SQL> SELECT /*+ ROWID(A) */ COUNT(*)FROM OPTCABLE A WHERE ROWID>='AAAXvgABSAABPwWAAA';
    COUNT(*)
    ----------
    151362

    SQL> SELECT /*+ ROWID(A) */ COUNT(*)FROM OPTCABLE A WHERE ROWID<'AAAXvgABSAABPwVAAA';
    COUNT(*)
    ----------
    27699


    以原表结构创建一个新表,用来存放该表完好的数据(rowid依然大于大的小于小的)

    SQL> CREATE TABLE OPTCABLE_BAK AS SELECT/*+ ROWID(A) */ * FROM OPTCABLE A WHERE ROWID>='AAAXvgABSAABPwWAAA';
    SQL> INSERT INTO OPTCABLE_BAK SELECT /*+ ROWID(A) */ * FROMOPTCABLE A WHERE ROWID<'AAAXvgABSAABPwVAAA';
    SQL> commit;


    现在就把完好的数据成功找回,这里注意不要用rename的方式去修改表名让业务使用,因为新创建表字段的默认值已经丢失,还需要重新加默认值。
    按照一开始用PL/SQL导出的表sql去重新创建表结构,非表对象等等。
    然后重新插入数据
    SQL> insert into optcable select * fromoptcable_bak;
    SQL> commit;
    删除创建的临时表(9i或9i以上没有开回收站的数据库不用加purge,其他建议加purge)
    SQL> drop table optcable_bak;
    SQL> drop table optcable_bak1;
    到此坏块问题解决,如果11G版本还有统计信息的,建议追加统计信息。


    原文链接:https://blog.csdn.net/roc_phoneix/article/details/39637235

  • 相关阅读:
    通过注册表实现开机自启的取消
    数据库为什么要使用B+树
    PHP的一种缓存方案静态化
    wordpress源码阅读
    最近在搞的东西有点多Gradle,Python,java,groove搞的脑子都要炸了,还得了流感。满满的负能量。
    编写一个自己的PHP框架(一)写在前面
    cookie,session机制
    __autoload和spl_autoload_register区别
    _initialize()和__construct()
    在往数据库中插入复杂的字符串时,单双引号混用经常会搞的很乱
  • 原文地址:https://www.cnblogs.com/xibuhaohao/p/15132783.html
Copyright © 2020-2023  润新知