zoukankan      html  css  js  c++  java
  • dd复制新库的block修复bootstrap

    问题背景:存储损坏导致数据库产生坏块无法启动,经过一堆动作以后,卡在file 1 block 45发生Fractured block坏块
    OS: windows 
    db: 11.1.0.6.0
    无备份,未开归档
    Hex dump of (file 1, block 45) in trace file d:appadministratordiag dbms...... race..._ora_3564.trc
    Corrupt block relative dba: 0x0040002d (file 1, block 45)
    Fractured block found during buffer read
    Data in bad block:
    type: 6 format: 2 rdba: 0x0040002d
    last change scn: 0x0000.5c7fd3a0 seq: 0x1 flg: 0x06
    spare1: 0x0 spare2: 0x0 spare3: 0x0
    consistency value in tail: 0x7b2c0601
    check value in block header: 0x1d5
    computed block checksum: 0xcfea
    Reread of rdba: 0x0040002d (file 1, block 45) found same corrupted data
    Errors in file d:appadministratordiag dbms...... race..._ora_3564.trc (incident=592148):
    ORA-01578: ORACLE 数据块损坏 (文件号 1, 块号 45)
    ORA-01110: 数据文件 1: 'G:DATAFILE...SYSTEM01.DBF'
    Incident details in: d:appadministratordiag dbms......incidentincdir_592148..._ora_3564_i592148.trc
    Errors in file d:appadministratordiag dbms...... race..._ora_3564.trc:
    ORA-00704: 引导程序进程失败
    ORA-00604: 递归 SQL 级别 1 出现错误
    ORA-01578: ORACLE 数据块损坏 (文件号 1, 块号 45)
    ORA-01110: 数据文件 1: 'G:DATAFILE...SYSTEM01.DBF'
    最后求助oracle,oracle找了个案例
    使用dd工具,在正常的数据库上进行dd
    dd if=XXXXSYSTEM01.DBF skip=45 of=XXX45.out bs=8k count=1   
    备份当前问题数据库的SYSTEM01.DBF文件,然后拷贝之前产生的45.out文件到本机,进行dd复制
    dd if=XXXX45.out seek=45 of=XXXXSYSTEM01.DBF bs=8k count=1
    然后启动数据库成功。
    大家对这种非常规的恢复方法有没有什么经验和心得?
    另外,之前还报错
    ORA-00704: 引导程序进程失败
    ORA-00704: 引导程序进程失败
    ORA-00604: 递归 SQL 级别 1 出现错误
    ORA-01555: 快照过旧: 回退段号 10 (名称为 "_SYSSMU10_1192467665$") 过小
    使用
    _CORRUPTED_ROLLBACK_SEGMENTS
      alter session  set events '10015 trace name adjust_scn level 10';
      _allow_error_simulation  = TRUE
      _smu_debug_mode = 268435456
      _minimum_giga_scn
    均没有跳过。

    最后用
    oradebug DUMPvar SGA kcsgscn_
    oradebug poke 
    直接修改scn搞定,但是oradebug poke的参数不是很明白,当时随便写了个数字。
    oradebug poke 地址 8 0xXXXXXX时报错第二个参数只能是1,2,4(未保留日志)
    改成4以后,0xXXXXXX写的是v$datafile_header里面的scn(所有文件都一样),但是报错值太大了。
    用SQL查current_scn是0,所以最后0xXXXXX随便写了个0A,报错过去了。
    但是最后两个参数的具体含义和算法不太清除,希望各位不吝赐教,多谢。

     
     
    测试环境1:
    大端序

    5~8字节表示SCN BASE:0002FB37
    kcslf kcsgscn_ [380016528, 380016558) = 00000000 0002FB37 00000000 00000000 0000D5E9 00000000 00000000 00000000 00000000 00000000 00000003 80016208
    SQL> oradebug dumpvar sga kcsgscn_
    00000000 0002FC5C 00000000 00000000 0000D634 00000000 00000000 00000000 00000000 00000000 00000003 80016208
    SQL> select to_char(checkpoint_change#,'XXXXXXXX') from v$database;
    TO_CHAR(C
        3C264
    SQL> select checkpoint_change#  from v$database;
    CHECKPOINT_CHANGE#
                246372
    1)设置SCN BASE值
    0x3C264  8表示修改8个字节的值
    BEFORE: [380016528, 380016530) = 00000000 00000000  (mount数据库时kcsgscn_=0)
    AFTER:  [380016528, 380016530) = 00000000   -->更改成功

    SQL> oradebug dumpvar sga kcsgscn_

    SQL> oradebug poke 0x380016528 4 0x00000001   --> 4表示修改前4个字节SCN_WRAP,改成1
    AFTER:  [380016528, 38001652C) = 00000001
    kcslf kcsgscn_ [380016528, 380016558) = --> 最终SCN_WRAP和SCN_BASE都修改成功
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000003 80016208

    SQL> alter database open;
    SQL>  select dbms_flashback.get_system_change_number from dual;
    GET_SYSTEM_CHANGE_NUMBER
                  4295213826 
    SQL> select to_char(dbms_flashback.get_system_change_number,'XXXXXXXXXXXXXXXX') from dual;
    TO_CHAR(DBMS_FLAS
              --> SCN WRAP跳了一位
    SQL>
    实际上用poke 地址 8 0x000000010003C264直接修改也可以
    SQL> oradebug dumpvar sga kcsgscn_
    SQL> select to_char(checkpoint_change#,'XXXXXXXXXXXXXXXX') from v$database;
    TO_CHAR(CHECKPOIN
            10003C482 
    SQL> oradebug poke 0x380016528 8 0x10003C482
    AFTER:  [380016528, 380016530) = 00000001 0003C482
    本测试说明大端序64位系统,语法
    oradebug poke 地址  8  SCN号
     
     
    测试环境2:
    linux x86-64
    小端序
    SQL> select to_char(current_scn,'XXXXXXXX') from v$database;
    TO_CHAR(CURRENT_SCN,'XXXXXX
    ---------------------------
        B49D9
    SQL> oradebug dumpvar sga kcsgscn_
    kcslf kcsgscn_ [060017008, 060017038) = 000B49DD 00000000 00000000 00000000 000169BF 00000000 00000000 00000000 00000000 00000000 60016CE8 00000000
    SQL>
    前4字节是SCN BASE:000B49DD 
    5~8字节是SCN WRAP:00000000 

    SQL> oradebug poke 0x060017008 8 0x000B56C400000001   -->值设为SCN_BASE SCN_WRAP
    BEFORE: [060017008, 060017010) = 00000000 00000000
    AFTER:  [060017008, 060017010) = 00000001 000B56C4  
    SQL> oradebug dumpvar sga kcsgscn_
    kcslf kcsgscn_ [060017008, 060017038) = 00000001 000B56C4   -->修改的值不对,前4字节成了SCN_WRAP,后4字节是SCN_BASE
    00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 60016CE8 00000000
    SQL> oradebug poke 0x060017008 8 0x00000001000B56C4   -->重新修改,不考虑大小端,直接写SCN号
    BEFORE: [060017008, 060017010) = 00000001 000B56C4
    AFTER:  [060017008, 060017010) = 000B56C4 00000001
    SQL> oradebug dumpvar sga kcsgscn_
    kcslf kcsgscn_ [060017008, 060017038) = 000B56C4 00000001 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 60016CE8 00000000
    SQL>

    SQL> alter database open;
    Database altered.
    SQL> select to_char(current_scn,'XXXXXXXXXXXXXXXX') from v$database;
    TO_CHAR(CURRENT_SCN,'XXXXXXXXXXXXXXXX')
    ---------------------------------------------------
            1000B579F  -->SCN_WRAP跳了1位
    SQL>
    测试说明小端序64位系统,修改SCN的方法也是
    oradebug poke 地址  8  SCN号
     
    测试环境3:
    windows 7 32bit
    小端序
    前4字节是SCN_WRAP
    后4字节是SCN_BASE
    SQL> oradebug setmypid
    已处理的语句
    SQL> oradebug dumpvar sga kcsgscn_
    kcslf kcsgscn_ [59852C8, 59852E8) = 00000000 00000000 00000000 00000000 00000000 00000000 00000000 059850C0
    SQL>
    SQL> select to_char(checkpoint_change#,'XXXXXXXXXXXXXXXX') from v$database;
    TO_CHAR(CHECKPOIN
    -----------------
                3378B
    SQL> oradebug poke 0x59852C8 8 0x000000010003378B  --> 32位系统寻址只能是4字节,不能填8
    ORA-00082: 8 的内存大小不在有效集合 [1], [2], [4] 之内
    SQL>
    SQL>   -->修改SCN_WRAP值
    BEFORE: [59852C8, 59852CC) = 00000000
    AFTER:  [59852C8, 59852CC) = 00000001
    SQL> oradebug poke 0x59852CC 4 0x01
    BEFORE: [59852CC, 59852D0) = 00000000
    AFTER:  [59852CC, 59852D0) = 00000001
    SQL> oradebug dumpvar sga kcsgscn_
    kcslf kcsgscn_ [59852C8, 59852E8) = 00000001 00000001 00000000 00000000 00000000 00000000 00000000 059850C0
    SQL> oradebug poke 0x59852CC 4 0x0003378B
      --->修改SCN_WRAP值,需要把内存地址+4字节
    BEFORE: [59852CC, 59852D0) = 00000001
    AFTER:  [59852CC, 59852D0) = 0003378B
    SQL>  oradebug dumpvar sga kcsgscn_
    kcslf kcsgscn_ [59852C8, 59852E8) =  00000000 00000000 00000000 00000000 00000000 059850C0
    SQL>
    SQL> alter database open;
    数据库已更改。
    SQL> select to_char(current_scn,'XXXXXXXXXXXXXXXX') from v$database;
    TO_CHAR(CURRENT_S
    -----------------
            10003381A
      --> SCN_WRAP跳了1位。
     测试表明对于32位系统,需要分别改SCN_WRAP和SCN_BASE来修改内存中的SCN
    ------道不行,乘桴浮于海!------ ------欲讷于言,而敏于行!-------
  • 相关阅读:
    URAL 2046 A
    URAL 2056 Scholarship 水题
    Codeforces Gym 100286I iSharp 水题
    Codeforces Gym H. Hell on the Markets 贪心
    Codeforces Gym 100286G Giant Screen 水题
    Codeforces Gym 100286B Blind Walk DFS
    Codeforces Gym 100286F Problem F. Fibonacci System 数位DP
    Codeforces Gym 100286A. Aerodynamics 计算几何 求二维凸包面积
    Codeforces Gym 100418K Cards 暴力打表
    Codeforces Gym 100418J Lucky tickets 数位DP
  • 原文地址:https://www.cnblogs.com/dh17/p/13752426.html
Copyright © 2011-2022 走看看