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
    ------道不行,乘桴浮于海!------ ------欲讷于言,而敏于行!-------
  • 相关阅读:
    模拟_大数字符串(HDU_2054)
    DP_字串匹配(HDU_1501)
    动态字典树_字串标记查找+大数(HDU_4099)
    动态字典树_字串查找匹配(HDU_1075)
    动态字典树+DFS(HDU_1298)
    动态字典树_拆分查找(HDU_1247)
    动态字典树_统计前缀子串(HDU_1251)
    动态字典树_统计子串(HDU_2846)
    字典树讲解
    HTML5语义标签的实践(blog页面)
  • 原文地址:https://www.cnblogs.com/dh17/p/13752426.html
Copyright © 2011-2022 走看看