免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 4148 | 回复: 4
打印 上一主题 下一主题

多个控制文件版本号不一致,怎么恢复 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-11-23 23:37 |只看该作者 |倒序浏览
本帖最后由 帅哥露小缝 于 2011-11-23 23:41 编辑

数据库本身有3个控制文件的,有次出现数据库关闭后不能启动了:然后有人修改spfile文件来启动数据库,control_files只留了一个控制文件.后来将spfile文件的control_files恢复成3个控制文件的,在打开数据库时,就报ORA-00214:错误,其中一个控制文件和其他两个控制文件版本信息不一致.本来想通过拷贝覆盖的方式来恢复,可是控制文件放在裸设备上的,没办法直接拷贝,除了重建控制文件,还有什么法子?

因为那一个控制文件是可用的,如果编辑spfile,只保留一个控制文件,数据库是可以打开的,所以只要能从这一个控制文件恢复另外另外两个控制文件就可以了.

论坛徽章:
0
2 [报告]
发表于 2011-11-23 23:45 |只看该作者
用dd if=ctl_1 of=ctl_2的方法也不行,命令执行后,就死在那儿不动了,最后只好ctrl ^C结束

论坛徽章:
0
3 [报告]
发表于 2011-11-23 23:55 |只看该作者
查了一下:可能是dd拷贝的方式不对:
  1. 不同的UNIX对裸设备的管理不完全相同,特别要注意的是某些UNIX在每个裸设备的头部要保留一定的空间,应用程序在使用裸设备时不可以覆盖这一部分,否则会对裸设备造成损坏。所以一个裸设备的实际可用空间是分配给裸设备的空间再减去这部分操作系统保留空间。下面是常用UNIX的OS Reserved Size列表:
  2. UNIX     OS Reserved Size
  3. ------------         ----------------
  4. SUN Solaris        0
  5. HP-UX          0
  6. IBM AIX         4k
  7. Tru64 UNIX       64k
  8. Linux          0

  9. dd命令
  10. UNIX上读写裸设备不能使用cp, cpio, tar等命令,必须用dd,下面是几个dd常用参数的简单说明,更详细的信息请参考UNIX使用手册或用命令man dd。
  11. dd [ operand=value ... ]
  12. if=file 指定输入文件,缺省值是标准输入
  13. of=file 指定输出文件,缺省值是标准输出
  14. bs=n 设置输入和输出的块大小为n字节,也可以用“k”作单位
  15. skip=n 在拷贝之前跳过n个输入块,缺省值是0
  16. seek=n 在拷贝之前从输出文件首部跳过n块,缺省值是0
  17. count=n 指定拷贝的块数,缺省拷贝到输入文件结束

  18. 从文件系统迁移到裸设备时,按下表公式确定dd的参数

  19.        | OS_RESERVED_SIZE>0       | OS_RESERVED_SIZE=0
  20. ----------+------------------------------------------+---------------------------------
  21. bs    | OS_RESERVED_SIZE         |  1024k or larger
  22. seek  |  1                          |  0

  23. 从裸设备迁移到文件系统时,按下表公式确定dd的参数,min表示二者之中取较小的

  24.        | OS_RESERVED_SIZE>0                 | OS_RESERVED_SIZE=0
  25. ----------+---------------------------------------------------------+------------------
  26. bs     | min(db_block_size,OS_RESERVED_SIZE) |  db_block_size
  27. skip   |  OS_RESERVED_SIZE /bs               |  0
  28. count  |  file_size /bs                           |  file_size /bs
复制代码
数据库经常使用在裸设备上面,因为这样对数据库来说,绕过OS的cache达到连续的读写性能会更好,正因为这样,我们会经常有需求,需要将数据文件从锣设备拷贝到文件系统或者是从文件系统拷贝到裸设备。
1、使用dd进行拷贝
dd可以实现从裸设备到文件系统或者是文件系统到锣设备的拷贝,但是使用dd拷贝的时候,要注意裸设备的头部保留大小,下面是常用UNIX的OS Reserved Size列表:

代码:--------------------------------------------------------------------------------
UNIX     OS Reserved Size
------------ ----------------
SUN Solaris     0
HP-UX       0
IBM AIX      4k
Tru64 UNIX     64k
Linux        0
.--------------------------------------------------------------------------------

注意:在aix中,如果使用big VG,并且使用-O T创建的lv,是没有4k大小的头部保留区域的。
然后就是要确定dd的count数目,在从裸设备拷贝到文件系统的时候可以用到,假定数据文件的块大小为8K的话,count数目可以认为是 dba_data_files中的blocks加1,这是因为ORACLE建立DATAFILE时,在命令中SIZE指定的大小之外,还要在文件头另加一个BLOCK,叫作“Oracle OS Header Block”,里面保存有这个文件的逻辑块大小和文件块数等信息。这一点并不是在 RAW DEVICE上建DATAFILE特有的,如果你在文件系统上建一个DATAFILE,指定SIZE 1000k的话,你用ls -l或dir命令看到的文件大小将是1008k (DB_BLOCK_SIZE=8K)。如

代码:--------------------------------------------------------------------------------
SQL>SELECT bytes, blocks, bytes/blocks db_block_size, bytes+bytes/blocks file_size
FROM dba_data_files WHERE file_name=''/dev/rlv_data'';
BYTES  BLOCKS  DB_BLOCK_SIZE FILE_SIZE
----------     --------        -------------          ---------
4194304  512    8192         4202496
.--------------------------------------------------------------------------------

所以,从裸设备dd到文件系统的命令为:

代码:--------------------------------------------------------------------------------
AIX$ dd if=/dev/rlv_data f=/u01/oradata/test.dbf bs=4k skip=1 count=1026
1026+0 records in
1026+0 records out
Tru64$ dd if=/dev/rlv_data f=/u01/oradata/test.dbf bs=8k skip=8 count=513
513+0 records in
513+0 records out
Other$ dd if=/dev/rlv_data f=/u01/oradata/test.dbf bs=8k count=513
513+0 records in
513+0 records out
.--------------------------------------------------------------------------------

与此对应的从文件系统到裸设备的命令为:

代码:--------------------------------------------------------------------------------
AIX$ dd if=/u01/oradata/test.dbf f=/dev/rlv_data bs=4k seek=1
1026+0 records in
1026+0 records out
Tru64$ dd if=/u01/oradata/test.dbf f=/dev/rlv_data bs=64k seek=1
64+1 records in
64+1 records out
Other$ dd if=/u01/oradata/test.dbf f=/dev/rlv_data bs=1024k
4+1 records in
4+1 records out
.--------------------------------------------------------------------------------

从文件系统到裸设备可以不指定count数目,但是必须保证裸设备大小大于或等于文件大小+一个数据块大小+保留空间大小(RAW DEVICE SIZE>= BD_FILE_SIZE + OS_RESERVED_SIZE + DB_BLOCK_SIZE)
注意,如果aix没有头部保留区域的big vg的lv,可以参考other的命令(第三个命令)。


还可以直接用rman来拷贝:http://space.itpub.net/196700/viewspace-667362
使用rman来进行拷贝
使用rman来拷贝数据文件相对就简单多了,可以用Rman 来轻松搞定裸设备/文件系统之间数据文件的迁移。在传统方法里面,我们必须对于每个 Unix 不同的Block 大小,OS 卷管理的overhead 的值作计算,才能非常小心的用dd 来做这些拷贝和移动,但是现在在Rman 的帮助下,我们可以完全忽略这些不同的地方,在所有Unix 平台/NT 平台上直接在Oracle 内部实现这种数据。
如,从文件系统拷贝到裸设备

代码:--------------------------------------------------------------------------------
rman>sql ''alter tablespace test offline'';
rman>copy datafile ''/u01/test/datafile/test01.dbf'' to ''/dev/rlvorarbs'';
.--------------------------------------------------------------------------------

从裸设备拷贝到文件系统

代码:--------------------------------------------------------------------------------
rman>sql ''alter tablespace test offline'';
rman>copy datafile ''/dev/rlvrawtest'' to ''/u01/test/datafile/test01.dbf'';
.--------------------------------------------------------------------------------

值得注意的是,rman拷贝的一方必须是数据库,因为rman只有连接到数据库才能进行拷贝,另外,以上的offline不是必须的,但是,如果想要一致性的文件,则需要加入offline关键字。
在数据库的迁移方面,我们可以采用rman把文件从数据库中拷贝到文件系统,然后从文件系统dd到新的数据库;或者是采用rman备份,把备份restore到新的数据库即可。

如果仅仅是在数据库内部进行数据文件的迁移(换位置),都可以单独用dd或者rman完成,但是文件迁移完成后,别忘记用如下命令更新控制文件:

代码:--------------------------------------------------------------------------------
SQL> alter database rename file ''old file'' to ''new file'';
.--------------------------------------------------------------------------------


这里的更详细一些:http://warehouse.itpub.net/post/777/467987
利用dd命令实现raw db到file系统db的转换!
特别需要主要的就是要清楚的知道各类文件(ctl,dbf,redo)文件头占用了几个block,当然还要知道各类文件他们的block的大小和单位!

下面文件raw__convert_fs.sql 中记录的是一个raw db到file系统db的大致过程!

[oracle@xys orcl]$ more raw_convert_fs.sql
SQL> !

SQL> @ dbf.sql

FILE_NAME BYTES TABLESPACE BLOCKS BYTES+BYTES/BLOCKS
---------------- ---------- ---------- ---------- ------------------
/dev/raw/raw1 314572800 SYSTEM 38400 314580992
/dev/raw/raw3 157286400 UNDOTBS1 19200 157294592
/dev/raw/raw2 125829120 SYSAUX 15360 125837312
/dev/raw/raw6 5242880 USERS 640 5251072
/dev/raw/raw14 5242880 TRANS 640 5251072

SQL> ! dd if=/dev/raw/raw14 of=trans.dbf bs=8k count=641

SQL> !

SQL> spool raw_convert_fs.sql append
SQL> ! dd if=/dev/raw/raw6 of=users01.dbf bs=8k count=641

SQL> ! dd if=/dev/raw/raw2 of=sysaux01.dbf bs=8k count=15361

SQL> @ dbf.sql

FILE_NAME BYTES TABLESPACE BLOCKS BYTES+BYTES/BLOCKS
---------------- ---------- ---------- ---------- ------------------
/dev/raw/raw1 314572800 SYSTEM 38400 314580992
/dev/raw/raw3 157286400 UNDOTBS1 19200 157294592
/dev/raw/raw2 125829120 SYSAUX 15360 125837312
/dev/raw/raw6 5242880 USERS 640 5251072
/dev/raw/raw14 5242880 TRANS 640 5251072

SQL> ! dd if=/dev/raw/raw3 of=undotbs01.dbf bs=8k count=19201

SQL> ! dd if=/dev/raw/raw1 of=system01.dbf bs=8k count=38401

SQL> desc v$controlfile;
Name Null? Type
----------------------------------------- -------- ----------------------------
STATUS VARCHAR2(7)
NAME VARCHAR2(513)
IS_RECOVERY_DEST_FILE VARCHAR2(3)
BLOCK_SIZE NUMBER
FILE_SIZE_BLKS NUMBER

SQL> select name , block_size , file_size_blks from v$controlfile;

NAME
--------------------------------------------------------------------------------
BLOCK_SIZE FILE_SIZE_BLKS
---------- --------------
/dev/raw/raw7
16384 430

/dev/raw/raw8
16384 430

SQL> col name format a20
SQL> select name , block_size , file_size_blks from v$controlfile;

NAME BLOCK_SIZE FILE_SIZE_BLKS
-------------------- ---------- --------------
/dev/raw/raw7 16384 430
/dev/raw/raw8 16384 430

SQL> ! dd if=/dev/raw/raw7 of=control01.ctl bs=16k count=430

SQL> ! dd if=/dev/raw/raw8 of=control02.ctl bs=16k count=430

SQL> host pwd

SQL> host pwd ls -l

SQL> host ls -l

SQL> desc v$logfile;
Name Null? Type
----------------------------------------- -------- ----------------------------
GROUP# NUMBER
STATUS VARCHAR2(7)
TYPE VARCHAR2(7)
MEMBER VARCHAR2(513)
IS_RECOVERY_DEST_FILE VARCHAR2(3)

SQL> col member format a20
SQL> select member , bytes/512 from v$logfile;
select member , bytes/512 from v$logfile
*
ERROR at line 1:
ORA-00904: "BYTES": invalid identifier


SQL> select member from v$logfile;

MEMBER
--------------------
/dev/raw/raw9
/dev/raw/raw10
/dev/raw/raw11

SQL> select bytes/512 from v$log;

BYTES/512
----------
20480
20480
20480

SQL> select bytes/1024/512 from v$log;

BYTES/1024/512
--------------
20
20
20

SQL> select distinct block_size from v$archived_log;

BLOCK_SIZE
----------
512

SQL> ! dd if=/dev/raw/raw9 of=redo01.log bs=512k count=20

SQL> select member from v$logfile;

MEMBER
--------------------
/dev/raw/raw9
/dev/raw/raw10
/dev/raw/raw11

SQL> ! dd if=/dev/raw/raw10 of=redo02.log bs=512k count=20

SQL> ! dd if=/dev/raw/raw11 of=redo03.log bs=512k count=20

SQL> create pfile from spfile;

File created.

--=============================

raw db下各类文件如下:

[oracle@xys orcl]$ sqlplus sys/system@test as sysdba

SQL*Plus: Release 10.2.0.1.0 - Production on Sat Aug 2 22:40:40 2008

Copyright (c) 1982, 2005, Oracle. All rights reserved.


Connected to:
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 - Production
With the Partitioning, OLAP and Data Mining options

SQL> col file_name fromat a50
SP2-0158: unknown COLUMN option "fromat"
SQL> col file_name format a50
SQL> select file_name from dba_data_files;

FILE_NAME
--------------------------------------------------
/opt/app/oracle/oradata/orcl/system01.dbf
/opt/app/oracle/oradata/orcl/undotbs01.dbf
/opt/app/oracle/oradata/orcl/sysaux01.dbf
/opt/app/oracle/oradata/orcl/users01.dbf
/opt/app/oracle/oradata/orcl/trans.dbf

SQL> select name from v$controlfile;

NAME
--------------------------------------------------------------------------------
/opt/app/oracle/oradata/orcl/control01.ctl
/opt/app/oracle/oradata/orcl/control02.ctl

SQL> select member from v$logfile;

MEMBER
--------------------------------------------------------------------------------
/opt/app/oracle/oradata/orcl/redo01.log
/opt/app/oracle/oradata/orcl/redo02.log
/opt/app/oracle/oradata/orcl/redo03.log

SQL>

转化之后db_name并没有发生变化,因此要想在同一台os上启动转化后的db,需要创建bdump,cdump,udmp等各类文件以及需要编辑参数文件创建口令文件。

转换为文件系统 db各类文件如下:

SQL> connect sys/system@orcl as sysdba
Connected.
SQL> col file_name format a50
SQL> select file_name from dba_data_files;

FILE_NAME
--------------------------------------------------
/opt/app/oracle/oradata/orcl/system01.dbf
/opt/app/oracle/oradata/orcl/undotbs01.dbf
/opt/app/oracle/oradata/orcl/sysaux01.dbf
/opt/app/oracle/oradata/orcl/users01.dbf
/opt/app/oracle/oradata/orcl/trans.dbf

SQL> select name from v$controlfile;

NAME
--------------------------------------------------------------------------------
/opt/app/oracle/oradata/orcl/control01.ctl
/opt/app/oracle/oradata/orcl/control02.ctl

SQL> select member from v$logfile;

MEMBER
--------------------------------------------------------------------------------
/opt/app/oracle/oradata/orcl/redo01.log
/opt/app/oracle/oradata/orcl/redo02.log
/opt/app/oracle/oradata/orcl/redo03.log

SQL>

论坛徽章:
0
4 [报告]
发表于 2011-11-23 23:56 |只看该作者
很晚了,不搞了,明天再恢复吧,恢复完了,再来报告一下结果

论坛徽章:
0
5 [报告]
发表于 2011-11-24 19:49 |只看该作者
本帖最后由 帅哥露小缝 于 2011-11-24 19:57 编辑

数据库今天恢复了,嘿嘿,恢复方法如下:当前有三个控制文件,/dev/raw/raw5,/dev/raw/raw6,/dev/raw/raw7,控制文件/dev/raw/raw5版本与其他两个控制文件版本不一致,/dev/raw/raw5与当前检查点信息是一致的,所以昨天可以先用/dev/raw/raw5启动数据库.
今天上班后,用上面帖子中的方法,查询控制文件的信息:select name , block_size , file_size_blks from v$controlfile;
显示 block_size , file_size_blks,结果为/dev/raw/raw5,16384,614

然后关闭数据库,执行dd if=/dev/raw/raw5 of=/dev/raw/raw6 bs=16k count=614和dd if=/dev/raw/raw5 of=/dev/raw/raw7 bs=16k count=614,重新将/dev/raw/raw6,/dev/raw/raw7加入到启动参数中,启动数据库正常了
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP