前几天,Oacle数据库启动不起来了,一启动就死机,经过多次测试差错发现是磁盘损坏,导致UNDOTBS01.DBF数据文件无法访问,访问就死机。无奈用冷备份的办法,将数据库迁移到另一台主机上。

    Oracle 11g, 安装在windows XP上,只是作为平时开发用的数据库,没有多少维护,也没有开启归档日志模式。(注:由于操作时没有保存操作信息,也没有可用的测试环境了,所以都是凭记忆还原步骤,不排除有不正确的操作和命令,仅作参考。)

    Step 1. 首先在目标主机上安装Oracle 11g(和源数据库相同),创建和源数据库相同SID的数据库。

    Step 2. 查找源数据库里的数据文件、REDO日志文件、控制文件、启动参数文件。

EXPRD是SID

 
  
  1. SQL> startup mount 
  2. ORACLE 例程已经启动。 
  3.  
  4. Total System Global Area  770019328 bytes 
  5. Fixed Size                  1374780 bytes 
  6. Variable Size             293602756 bytes 
  7. Database Buffers          469762048 bytes 
  8. Redo Buffers                5279744 bytes 
  9. 数据库装载完毕。 
  10. SQL> select name from v$datafile; 
  11.  
  12. NAME 
  13. ------------------------------------------------------ 
  14. D:\APP\ADMINISTRATOR\ORADATA\EXPRD\SYSTEM01.DBF 
  15. D:\APP\ADMINISTRATOR\ORADATA\EXPRD\SYSAUX01.DBF 
  16. D:\APP\ADMINISTRATOR\ORADATA\EXPRD\UNDOTBS01.DBF 
  17. D:\APP\ADMINISTRATOR\ORADATA\EXPRD\USERS01.DBF 
  18. D:\APP\ADMINISTRATOR\ORADATA\EXPRD\EXAMPLE01.DBF 
  19. D:\APP\ADMINISTRATOR\ADMIN\EXPRD\TS_YTCLT01.DBF 
  20. D:\APP\ADMINISTRATOR\ADMIN\EXPRD\TS_YTEXP01.DBF 
  21. SQL> select member from v$logfile; 
  22.  
  23. MEMBER 
  24. --------------------------------------------------------------- 
  25. D:\APP\ADMINISTRATOR\ORADATA\EXPRD\REDO03.LOG 
  26. D:\APP\ADMINISTRATOR\ORADATA\EXPRD\REDO02.LOG 
  27. D:\APP\ADMINISTRATOR\ORADATA\EXPRD\REDO01.LOG 
  28.  
  29. SQL> select name from v$controlfile; 
  30.  
  31. NAME 
  32. --------------------------------------------------------------- 
  33. D:\APP\ADMINISTRATOR\ORADATA\EXPRD\CONTROL01.CTL 
  34. D:\APP\ADMINISTRATOR\FLASH_RECOVERY_AREA\EXPRD\CONTROL02.CTL 

    Step 3. 关闭数据库,将上面找到文件,复制到目标机器的数据库目录或自定义目录内。由于知道UNDOTBS01.DBF文件损坏,一访问就死机,所以最后复制它,做完第四步以后再复制,只能复制一部分文件,不过也可以,后面解决。

(由于我目标数据库和源数据库目录结构不同,所以需要做4,5,6步。目录结构完全一样的可以省略4,5,6步。)

    Step 4. 在源数据库上,备份启动参数文件和控制文件创建sql,并拷贝到目标数据库上。

 
  
  1. SQL> startup mount 
  2. SQL> create pfile='D:\backup_pfile.ora' from spfile; 
  3. SQL> alter database backup controlfile to trace 
  4. as 'D:\backup_ctlfile_trace.sql'

    Step 5. 修改生成的backup_pfile.ora和backup_ctlfile_trace.sql文件中的目录,改成目标数据库上对应的目录结构。

    Step 6. 用backup_pfile.ora启动目标数据库,并运行backup_ctlfile_trace.sql重建控制文件。最好是按照sql文件中的顺序,单条命令手动执行,这样可以方便的定位是在哪一步出的错。

 
  
  1. SQL> startup nomount pfile='D:\backup_pfile.ora' 
  2. SQL> create spfile from pfile='D:\backup_pfile.ora'
  3. SQL> shutdown immediate 
  4. SQL> @backup_ctlfile_trace.sql 

    在执行backup_ctlfile_trace.sql重建控制文件的时候,会报错,因为我们的UNDOTBS01.DBF拷贝不全,是损坏的文件,所以导致重建控制文件失败。错误的意思是实际文件比记录的文件小(ORA-01200: 255360 的实际文件大小小于 264960 块的正确大小 / ORA-01200: actual file size of 255360 is smaller than correct size 264960 blocks)

    Step 7. 补全UNDOTBS01.DBF。

       1. 首先计算缺失的字节数(264960-255360) * 8192 = 78643200

       2. 生成一个指定大小的文件D:\fsutil file createnew append.dbf 78643200

       3. 附加到数据文件末尾D:\type append.dbf >> <path>\UNDOTBS01.DBF

       4. 再次执行backup-ctlfile_trace.sql执行成功

    Step 8. 由于undotbs01.dbf文件是损坏的,所以数据库还没有圆满解决。离线UNDOTBS01.DBF, 在重建UNDO TABLESPACE

 
  
  1. SQL> start mount 
  2. SQL> alter database datafile 'D:\oracle11g\data\UNDOTBS01.DBF' offline drop
  3. SQL> alter database open
  4. SQL> alter system set undo_management='MANUAL' scope=spfile; 
  5. SQL> create undo tablespace undotbs2 datafile 'D:\oracle11g\data\undotbs02.dbf' size 200M autoextend on
  6. SQL> alter system set undo_tablespace='undotbs2' scop=spfile; 
  7. SQL> alter system set undo_management='auto' scope=spfile; 
  8. SQL> shutdown immediate 
  9. SQL> startup