环境:CentOS 6.6
   oracle 11.2.0.4.0

前几天开发一都比调试存储过程时开了DEBUG,把测试服务器直接搞挂了,最后把测试服务器搞起来了,结果发现oracle数据库也挂了,原因是oracle的控制文件 control02.ctl 损坏了,因为是测试环境,所以没有备份…xxx

控制文件(control file)是一个相当小的文件(最多能增长到64M左右),其中包含Oracle需要的其他文件的一个目录。参数文件告知实例控制文件的位置,控制文件则告知示例数据库和在线重做日志文件的位置。控制文件还告知了Oracle其他一些事情,如已发生检查点的有关信息、数据库名(必须和db_name参数匹配)、创建数据库的时间戳、归档重做日志的历史(有时这会让控制文件变大)、RMAN信息等。
控制文件应该通过硬件(RAID)多路保存,如果不支持镜像,则要通过Oracle多路保存。应该有不止一个副本,而且它们应该保存在不同的磁盘上,以防止万一出现磁盘故障而丢失控制文件。丢失控制文件并不是致命的,但是会使恢复变得困难很多。
如果丢失了所有的控制文件并且没有任何的备份,我们可以通过重建控制文件来打开数据库。其中,重建控制文件至少需要以下信息:

  1. 数据库名
  2. 字符集
  3. 数据文件名称
  4. 初始化参数,包括MAXLOGFILES、MAXLOGMEMBERS、MAXDATAFILES、MAXINSTANCES、MAXLOGHISTORY等;
1
2
3
4
5
6
7
8
9
10
11
12
#查看oracle版本信息
SQL> select * from v$version;
BANNER
-----------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
PL/SQL Release 11.2.0.4.0 - Production
CORE 11.2.0.4.0 Production
TNS for Linux: Version 11.2.0.4.0 - Production
NLSRTL Version 11.2.0.4.0 - Production
SQL>
1
2
3
4
5
6
7
8
#查看oracle控制文件位置
SQL> show parameter control_files
NAME TYPE VALUE
------------------------------------ ------- -----------
control_files string /u01/data/orcl/control01.ctl,
/u01/data/orcl/control02.ctl
SQL>

如果oracle控制文件损坏,强制关闭数据库,然后重启数据库,报ORA-00205错误。需要注意的是,此时执行shutdown immediate命令,数据库无法正常关闭,只能关闭到mounted状态;需要使用shutdown abort命令强制关闭数据库。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
SQL> shutdown immediate
Database closed.
ORA-00210: cannot open the specified control file
ORA-00202: control file: '/u01/data/orcl/control02.ctl'
ORA-27041: unable to open file
Linux Error: 2: No such file or directory
Additional information: 3
SQL> select status from v$instance;
STATUS
------------
MOUNTED
SQL> shutdown abort
ORACLE instance shut down.
SQL>
SQL> startup
ORACLE instance started.
Total System Global Area 941600768 bytes
Fixed Size 1348860 bytes
Variable Size 515902212 bytes
Database Buffers 419430400 bytes
Redo Buffers 4919296 bytes
ORA-00205: error in identifying control file, check alert log for more info
SQL>

获取数据库名

1
2
3
4
5
#生成文本格式的参数文件
$ sqlplus / as sysdba
SQL> create pfile from spfile;
File created.
SQL>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#打开参数文件,查看db_name参数值,即为数据库名称
[oracle@orcl ~]$ cd $ORACLE_HOME/dbs
[oracle@orcl dbs]$ cat initorcl.ora
orcl.__db_cache_size=1107296256
orcl.__java_pool_size=16777216
orcl.__large_pool_size=33554432
orcl.__oracle_base='/u01/app/oracle'#ORACLE_BASE set from environment
orcl.__pga_aggregate_target=1140850688
orcl.__sga_target=2130706432
orcl.__shared_io_pool_size=0
orcl.__shared_pool_size=369098752
orcl.__streams_pool_size=0
*.audit_file_dest='/u01/app/oracle/admin/orcl/adump'
*.audit_trail='db'
*.compatible='11.2.0.4.0'
*.control_files='/u01/data/orcl/control01.ctl','/u01/data/orcl/control02.ctl'
*.db_block_size=8192
*.db_domain=''
*.db_name='orcl' #oracle数据库名称
*.diagnostic_dest='/u01/app/oracle'
*.dispatchers='(PROTOCOL=TCP) (SERVICE=orclXDB)'
*.memory_target=3267362816
*.nls_language='SIMPLIFIED CHINESE'
*.open_cursors=300
*.processes=1500
*.remote_login_passwordfile='EXCLUSIVE'
*.sessions=1655
*.undo_tablespace='UNDOTBS1'
[oracle@orcl dbs]$

启动到nomount状态,获取字符集

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#需要执行查询语句select userenv('language') from dual;来获取字符集,因此需要将数据库启动到nomount状态
SQL> startup nomount
ORACLE instance started.
Total System Global Area 941600768 bytes
Fixed Size 1348860 bytes
Variable Size 515902212 bytes
Database Buffers 419430400 bytes
Redo Buffers 4919296 bytes
SQL>
SQL> select userenv('language') from dual;
USERENV('LANGUAGE')
----------------------------------------------------
SIMPLIFIED CHINESE_CHINA.US7ASCII
SQL>

获取数据文件名称

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
SQL> select FILE_NAME,TABLESPACE_NAME from dba_data_files;
FILE_NAME TABLESPACE_NAME
----------------------------------- ------------------------------
/u01/data/orcl/dev_payboxdb.dbf DEV_PAYBOXDB
/u01/data/orcl/dev_paydb.dbf DEV_PAYDB
/u01/data/orcl/PAYBOX_FG_PRO.dbf PAYBOX_FG_PRO
/u01/data/orcl/PAYBOX_TEST2SP.dbf PAYBOX_TEST2SP
/u01/data/orcl/ticket.dbf LOTTERYDB
/u01/data/orcl/users01.dbf USERS
/u01/data/orcl/undotbs01.dbf UNDOTBS1
/u01/data/orcl/sysaux01.dbf SYSAUX
/u01/data/orcl/system01.dbf SYSTEM
9 rows selected.
SQL>
#获取数据库文件列表
[oracle@orcl orcl]$ ls -lth
总用量 8.1G
-rw-r----- 1 oracle oinstall 51M 2月 27 15:09 redo02.log
-rw-r----- 1 oracle oinstall 503M 2月 27 15:09 users01.dbf
-rw-r----- 1 oracle oinstall 511M 2月 27 15:09 undotbs01.dbf
-rw-r----- 1 oracle oinstall 3.7G 2月 27 15:07 system01.dbf
-rw-r----- 1 oracle oinstall 1.3G 2月 27 15:06 sysaux01.dbf
-rw-r----- 1 oracle oinstall 513M 2月 27 15:00 temp01.dbf
-rw-r----- 1 oracle oinstall 501M 2月 27 12:31 ticket.dbf
-rw-r----- 1 oracle oinstall 501M 2月 27 12:31 dev_payboxdb.dbf
-rw-r----- 1 oracle oinstall 501M 2月 27 12:31 dev_paydb.dbf
-rw-r----- 1 oracle oinstall 201M 2月 27 12:31 PAYBOX_TEST2SP.dbf
-rw-r----- 1 oracle oinstall 201M 2月 27 12:31 PAYBOX_FG_PRO.dbf
-rw-r----- 1 oracle oinstall 51M 2月 27 12:26 redo01.log
-rw-r----- 1 oracle oinstall 51M 2月 27 12:26 redo03.log
-rw-r----- 1 oracle oinstall 51M 2月 25 08:05 redo05.log
-rw-r----- 1 oracle oinstall 51M 2月 25 06:00 redo04.log
[oracle@orcl orcl]$

生成创建控制文件脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
#DATABASE后面的orcl是示例名,正确设置LOGFILE和DATAFILE的路径及名称,字符集
[oracle@orcl orcl]$ cat create_control.sql
STARTUP NOMOUNT
CREATE CONTROLFILE REUSE DATABASE orcl NORESETLOGS ARCHIVELOG
MAXLOGFILES 5
MAXLOGMEMBERS 3
MAXDATAFILES 100
MAXINSTANCES 1
MAXLOGHISTORY 226
LOGFILE
GROUP 1 '/u01/data/orcl/redo01.log' SIZE 50M,
GROUP 2 '/u01/data/orcl/redo02.log' SIZE 50M,
GROUP 3 '/u01/data/orcl/redo03.log' SIZE 50M
DATAFILE
'/u01/data/orcl/system01.dbf',
'/u01/data/orcl/sysaux01.dbf',
'/u01/data/orcl/undotbs01.dbf',
'/u01/data/orcl/users01.dbf',
'/u01/data/orcl/ticket.dbf',
'/u01/data/orcl/PAYBOX_TEST2SP.dbf',
'/u01/data/orcl/PAYBOX_FG_PRO.dbf',
'/u01/data/orcl/dev_paydb.dbf',
'/u01/data/orcl/dev_payboxdb.dbf'
CHARACTER SET US7ASCII
;
[oracle@orcl orcl]$

重建控制文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
#如果上述创建控制文件的脚本的DATAFILE中有系统临时文件,则会报下面的错误:
#创建控制文件脚本里面不能有左斜杠(\),否则报错
#DATAFILE中不能有临时文件/u01/data/orcl/temp01.dbf
#如果执行出错,执行shutdown abort关闭数据库后,再执行创建控制文件的sql,因为执行了创建控制文件的sql会让oracle处理mount状态
SQL> @/u01/data/orcl/create_control.sql
ORA-01081: cannot start already-running ORACLE - shut it down first
CREATE CONTROLFILE REUSE DATABASE \"oracle\" NORESETLOGS ARCHIVELOG
*
ERROR at line 1:
ORA-01503: CREATE CONTROLFILE failed
ORA-01160: file is not a data file
ORA-01110: data file : '/u01/data/orcl/temp01.dbf'
SQL>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
SQL> @/u01/data/orcl/create_control.sql
ORACLE instance started.
Total System Global Area 941600768 bytes
Fixed Size 1348860 bytes
Variable Size 515902212 bytes
Database Buffers 419430400 bytes
Redo Buffers 4919296 bytes
Control file created.
SQL>
SQL> select status from v$instance;
STATUS
------------
MOUNTED
SQL>

打开数据库

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
#在打开数据库时,会报错,提示system01数据文件需要执行介质恢复,我们执行recover database即可
SQL> alter database open;
alter database open
*
ERROR at line 1:
ORA-01113: file 1 needs media recovery
ORA-01110: data file 1: \'/u01/app/oracle/oradata/HOEGH/system01.dbf\'
SQL>
SQL> recover database;
Media recovery complete.
SQL>
SQL> alter database open;
Database altered.
SQL>
SQL> select * from v$version;
BANNER
-----------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
PL/SQL Release 11.2.0.4.0 - Production
CORE 11.2.0.4.0 Production
TNS for Linux: Version 11.2.0.4.0 - Production
NLSRTL Version 11.2.0.4.0 - Production
SQL>
SQL> select tablespace_name from dba_tablespaces;
TABLESPACE_NAME
------------------------------
SYSTEM
SYSAUX
UNDOTBS1
TEMP
USERS
PAYBOX_FG_PRO
PAYBOX_TEST2SP
DEV_PAYDB
DEV_PAYBOXDB
LOTTERYDB
10 rows selected.
SQL>

总结
下面总结一下重建控制文件的步骤:

  1. 获取数据库名;
  2. 获取字符集名;
  3. 获取数据文件名;
  4. 重建控制文件;
  5. 执行介质恢复;
  6. 打开数据库。

本文出自”Jack Wang Blog”:http://www.yfshare.vip/2017/02/27/重建oracle控制文件/