暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Oracle数据库损坏,只剩两个文件,如何恢复数据?

XXX:
小陈,有套Oracle数据库文件丢失了,抢救出来两个文件在这个U盘里,你去恢复一下数据,1分钟够了吧!
小陈:
哪两个文件,不会是temp01.dbf、temp02.dbf吧,那不用1分钟,现在就可以答复你,恢复不了。
XXX:
别那么悲观吗,说不定是alert_cjc.log、listener.log呢。
小陈:
漂亮,还是小瞧您了,真会抢救啊,专业!
......
小陈打开U盘,看到如下两个文件:

    -rw-r----- 1 oracle oinstall  11M Aug 20 22:05 cjc01.dbf
    -rw-r----- 1 oracle oinstall 1.2G Aug 21 12:15 system01.dbf
    复制

    运气似乎还不错,有系统表空间文件和一个数据文件,理论上是能抢救出cjc01.dbf部分数据。
    那么如何恢复呢?
    1.需要知道具体的数据库版本号,然后安装相同版本的数据库软件。
    这个可以在system01.dbf文件中查到。
    2.需要知道db_name,创建参数文件时会用到。
    这个也可以在system01.dbf中查到。
    3.需要知道数据库字符集,创建控制文件时会用到。
    这个可以在system01.dbf中查到。
    4.需要知道回滚段名称,open数据库跳过回滚段时会用到。
    没错,还是可以在system01.dbf中查到。
    恢复步骤如下:

    一:获取数据库版本号

      oracle@cjc-db-01$strings system01.dbf |grep "RDBMS version"
      11.2.0.4.0 RDBMS version for NLS parameters,
      复制

      或者通过bbed应该也可以查到。

      可以看到版本是11.2.0.4.0,安装Oracle 11.2.0.4.0软件,或将文件上传到同版本测试数据库。

      二:创建参数文件

      创建参数文件需要知道几个信息:
      1.compatible参数
      和 version相同,等于 11.2.0.4.0。
      2.db_name
      可以通过bbed查询,db_name等于cjc,也可以strings查询。

        BBED> set file 1 block 1
        FILE# 1
        BLOCK# 1


        BBED> map v
        BBED> p kcvfh
        struct kcvfhhdr, 76 bytes @20
        ......
        text kccfhdbn[0] @32 C
        text kccfhdbn[1] @33 J
        text kccfhdbn[2] @34 C
        text kccfhdbn[3] @35
        复制

        3.获取回滚段名称

          [oracle@cjc-db-01 cjc]$ strings system01.dbf |grep -i _SYSSMU|cut -d $ -f 1|sort -u |awk '{ print $1"$"}'
          _SYSSMU10_1197734989$
          _SYSSMU10_3470984480$
          _SYSSMU11_894599432$
          _SYSSMU12_1573055333$
          _SYSSMU1_2603659607$
          _SYSSMU13_3860906822$
          _SYSSMU1_3724004606$
          _SYSSMU14_3319140121$
          _SYSSMU15_1436577151$
          _SYSSMU16_1689093467$
          _SYSSMU17_1049158485$
          _SYSSMU18_1557221903$
          _SYSSMU19_2284825117$
          _SYSSMU20_2312497597$
          _SYSSMU2_2996391332$
          _SYSSMU2_73114111$
          _SYSSMU3_1723003836$
          _SYSSMU3_596277271$
          _SYSSMU4_1254879796$
          _SYSSMU4_2523322691$
          _SYSSMU5_4008018903$
          _SYSSMU5_898567397$
          _SYSSMU6_1263032392$
          _SYSSMU6_4235600416$
          _SYSSMU7_2070203016$
          _SYSSMU7_2271882308$
          _SYSSMU8_517538920$
          _SYSSMU8_854328387$
          _SYSSMU9_1650507775$
          _SYSSMU9_508477954$
          复制

          4.生成最终参数文件
          通过 _corrupted_rollback_segments 屏蔽掉活动的回滚段。

            [oracle@cjc-db-01 dbs]$ vi initcjc.ora
            *.compatible='11.2.0.4.0'
            *.db_name='cjc'
            *.control_files='/db/oradata/cjc/control01.ctl'
            *.pga_aggregate_target=1593835520
            *.sga_target=4783603712
            *.undo_management='MANUAL'
            *._allow_resetlogs_corruption=TRUE
            *._corrupted_rollback_segments='_SYSSMU10_1197734989$','_SYSSMU10_3470984480$','_SYSSMU11_894599432$','_SYSSMU12_1573055333$','_SYSSMU1_2603659607$','_SYSSMU13_3860906822$','_SYSSMU1_3724004606$','_SYSSMU14_3319140121$','_SYSSMU15_1436577151$','_SYSSMU16_1689093467$','_SYSSMU17_1049158485$','_SYSSMU18_1557221903$','_SYSSMU19_2284825117$','_SYSSMU20_2312497597$','_SYSSMU2_2996391332$','_SYSSMU2_73114111$','_SYSSMU3_1723003836$','_SYSSMU3_596277271$','_SYSSMU4_1254879796$','_SYSSMU4_2523322691$','_SYSSMU5_4008018903$','_SYSSMU5_898567397$','_SYSSMU6_1263032392$','_SYSSMU6_4235600416$','_SYSSMU7_2070203016$','_SYSSMU7_2271882308$','_SYSSMU8_517538920$','_SYSSMU8_854328387$','_SYSSMU9_1650507775$','_SYSSMU9_508477954$'
            *.job_queue_processes=0
            复制

            5.启动数据库到nomount

              SQL> startup nomount
              复制

              三:创建控制文件
              创建控制文件需要知道数据库字符集,数据库字符集记录在props$基表里,找到另一套相同版本的数据库,执行如下命令,找到props$位置。

                select distinct 
                dbms_rowid.rowid_relative_fno(rowid) file#,
                dbms_rowid.rowid_block_number(rowid) block#
                from props$;
                ###
                FILE# = 1 BLOCK# = 801
                复制

                默认是在1号文件801号块上。
                如果system01.dbf较大,可将对应的块dd出来然后进行查询:

                  [oracle@cjc-db-01 trace]$ dd if=/oracle/app/oracle/oradata/cjc/system01.dbf of=/home/oracle/tmp/props bs=8192 skip=801 count=1
                  1+0 records in
                  1+0 records out
                  8192 bytes (8.2 kB) copied, 0.000220592 s, 37.1 MB/s
                  复制

                  可以看到字符集是AL32UTF8

                    [oracle@cjc-db-01 trace]$ strings home/oracle/tmp/props |more
                    ......
                    NLS_CHARACTERSET
                    AL32UTF8
                    Character set
                    复制

                    生成创建控制文件的脚本
                    其中:

                      1.归档模式部分写NOARCHIVELOG或ARCHIVELOG都可以,由于参数文件没配置归档,控制文件里写的是NOARCHIVELOG。
                      2.redo文件全部丢失,肯定需要RESETLOGS。
                      3.DATAFILE部分添加仅剩的两个文件。
                      复制
                        [oracle@cjc-db-01 trace]$ vi home/oracle/tmp/0821/ctl01.sql
                        CREATE CONTROLFILE REUSE DATABASE "CJC" RESETLOGS NOARCHIVELOG
                        MAXLOGFILES 16
                        MAXLOGMEMBERS 3
                        MAXDATAFILES 100
                        MAXINSTANCES 8
                        MAXLOGHISTORY 292
                        LOGFILE
                        GROUP 1 '/db/oradata/cjc/redo01.log' SIZE 50M BLOCKSIZE 512,
                        GROUP 2 '/db/oradata/cjc/redo02.log' SIZE 50M BLOCKSIZE 512,
                        GROUP 3 '/db/oradata/cjc/redo03.log' SIZE 50M BLOCKSIZE 512
                        DATAFILE
                        '/db/oradata/cjc/system01.dbf',
                        '/db/oradata/cjc/cjc01.dbf'
                        CHARACTER SET AL32UTF8;
                        复制

                        重建控制文件

                          SQL> @/home/oracle/tmp/0821/ctl01.sql
                          Control file created.


                          SQL> select instance_name,status from v$instance;
                          INSTANCE_NAME STATUS
                          ---------------- ------------
                          cjc MOUNTED


                          SQL> col name for a50
                          SQL> select file#,name,status from v$datafile;
                          FILE# NAME STATUS
                          ---------- ---------------------------------------- -------
                          1 db/oradata/cjc/system01.dbf SYSTEM
                          5 db/oradata/cjc/cjc01.dbf RECOVER
                          复制

                          四:启动数据库

                            SQL> alter database open RESETLOGS;
                            Database altered.
                            复制

                            对应告警日志如下:

                              Wed Aug 21 12:41:16 2024
                              SMON: enabling cache recovery
                              Undo initialization finished serial:0 start:3204739012 end:3204739022 diff:10 (0 seconds)
                              Dictionary check beginning
                              Tablespace 'SYSAUX' #1 found in data dictionary,
                              but not in the controlfile. Adding to controlfile.
                              Tablespace 'UNDOTBS1' #2 found in data dictionary,
                              but not in the controlfile. Adding to controlfile.
                              Tablespace 'TEMP' #3 found in data dictionary,
                              but not in the controlfile. Adding to controlfile.
                              Tablespace 'USERS' #4 found in data dictionary,
                              but not in the controlfile. Adding to controlfile.
                              File #2 found in data dictionary but not in controlfile.
                              Creating OFFLINE file 'MISSING00002' in the controlfile.
                              This file can no longer be recovered so it must be dropped.
                              File #3 found in data dictionary but not in controlfile.
                              Creating OFFLINE file 'MISSING00003' in the controlfile.
                              This file can no longer be recovered so it must be dropped.
                              File #4 found in data dictionary but not in controlfile.
                              Creating OFFLINE file 'MISSING00004' in the controlfile.
                              This file can no longer be recovered so it must be dropped.
                              Dictionary check complete
                              Verifying file header compatibility for 11g tablespace encryption..
                              Verifying 11g file header compatibility for tablespace encryption completed
                              复制

                              检查数据:

                                SQL> col name for a55
                                SQL> select file#,name,status from v$datafile;
                                FILE# NAME STATUS
                                ---------- ------------------------------------------------------- -------
                                1 db/oradata/cjc/system01.dbf SYSTEM
                                2 db/oracle/app/oracle/product/11.2/db/dbs/MISSING00002 RECOVER
                                3 db/oracle/app/oracle/product/11.2/db/dbs/MISSING00003 RECOVER
                                4 db/oracle/app/oracle/product/11.2/db/dbs/MISSING00004 RECOVER
                                5 db/oradata/cjc/cjc01.dbf ONLINE


                                SQL> select * from cjc.t1;
                                ID NAME XXX
                                ---------- ------------ ----------
                                1 cjc 2
                                复制

                                如果存在活跃事物的情况下,丢失全部redo及其他文件,可能丢失一部分数据,特别是已提交但还没刷入数据文件的数据将会丢失。
                                五:后续操作
                                此时数据库不支持写操作

                                  SQL> update cjc.t1 set name='CJC' where id=1;
                                  update cjc.t1 set name='CJC' where id=1
                                  *
                                  ERROR at line 1:
                                  ORA-01552: cannot use system rollback segment for non-system tablespace 'CJC'
                                  复制

                                  删除、重建UNDO表空间

                                    SQL> drop tablespace UNDOTBS1 including contents and datafiles;
                                    Tablespace dropped.


                                    SQL> create undo tablespace UNDOTBS1 datafile '/db/oradata/cjc/undotbs01.dbf' size 100M autoextend on;
                                    Tablespace created.
                                    复制

                                    修改参数文件,重新启动数据库

                                      [oracle@cjc-db-01 dbs]$ vi initcjc.ora
                                      ......
                                      *.undo_tablespace='UNDOTBS1'
                                      #*.undo_management='MANUAL'
                                      #*._allow_resetlogs_corruption=TRUE
                                      #*._corrupted_rollback_segments='_SYSSMU10_1197734989$','_SYSSMU10_3470984480$','_SYSSMU11_894599432$','_SYSSMU12_1573055333$','_SYSSMU1_2603659607$','_SYSSMU13_3860906822$','_SYSSMU1_3724004606$','_SYSSMU14_3319140121$','_SYSSMU15_1436577151$','_SYSSMU16_1689093467$','_SYSSMU17_1049158485$','_SYSSMU18_1557221903$','_SYSSMU19_2284825117$','_SYSSMU20_2312497597$','_SYSSMU2_2996391332$','_SYSSMU2_73114111$','_SYSSMU3_1723003836$','_SYSSMU3_596277271$','_SYSSMU4_1254879796$','_SYSSMU4_2523322691$','_SYSSMU5_4008018903$','_SYSSMU5_898567397$','_SYSSMU6_1263032392$','_SYSSMU6_4235600416$','_SYSSMU7_2070203016$','_SYSSMU7_2271882308$','_SYSSMU8_517538920$','_SYSSMU8_854328387$','_SYSSMU9_1650507775$','_SYSSMU9_508477954$'
                                      #*.job_queue_processes=0


                                      SQL> shutdown immediate
                                      SQL> startup


                                      SQL> update cjc.t1 set name='CJC' where id=1;
                                      1 row updated.
                                      SQL> commit;
                                      Commit complete.
                                      复制

                                      可以正常更新数据,但是由于SYSAUX表空间数据文件丢失,某些功能是存在问题的,比如AWR报告无法生成:

                                        SQL> @?/rdbms/admin/awrrpt.sql


                                        Current Instance
                                        ~~~~~~~~~~~~~~~~


                                        DB Id DB Name Inst Num Instance
                                        ----------- ------------ -------- ------------
                                        3807474232 CJC 1 cjc


                                        Specify the Report Type
                                        ~~~~~~~~~~~~~~~~~~~~~~~
                                        Would you like an HTML report, or a plain text report?
                                        Enter 'html' for an HTML report, or 'text' for plain text
                                        Defaults to 'html'
                                        Enter value for report_type: html


                                        Type Specified: html


                                        Instances in this Workload Repository schema
                                        ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
                                        from dba_hist_database_instance wr, v$database cd, v$instance ci
                                        *
                                        ERROR at line 14:
                                        ORA-00376: file 2 cannot be read at this time
                                        ORA-01111: name for data file 2 is unknown - rename to correct file
                                        ORA-01110: data file 2:
                                        '/db/oracle/app/oracle/product/11.2/db/dbs/MISSING00002'
                                        复制

                                        最后可以导出数据,重建库,导入数据。

                                          oracle@cjc-db-01$exp cjc/***** file=/home/oracle/tmp/t1a.dmp log=/home/oracle/tmp/t1a.log tables=t1


                                          Export: Release 11.2.0.4.0 - Production on Wed Aug 21 12:49:55 2024


                                          Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved.


                                          Connected to: Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
                                          With the Partitioning, OLAP, Data Mining and Real Application Testing options
                                          Export done in AL32UTF8 character set and AL16UTF16 NCHAR character set


                                          About to export specified tables via Conventional Path ...
                                          . . exporting table T1 1 rows exported
                                          Export terminated successfully without warnings.
                                          复制

                                          小陈:
                                          搞定了,数据导出来了!
                                          XXX:
                                          哦,忘和你说了,其实这套库有异地备份!
                                          小陈:
                                          ......

                                          欢迎关注我的公众号《IT小Chen》

                                          文章转载自小周的数据库进阶之路,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

                                          评论