- 深入解析Oracle:数据库的初始化
- 盖国强
- 1064字
- 2020-06-26 13:50:32
2.3 克隆数据库
数据文件具备了,接下来是通过这些文件“克隆”一个数据库,这个工作由cloneDBCreation. sql脚本继续执行,这个脚本更为复杂,下面分开介绍一下。对于数据库的恢复
首先根据指定的数据库名称(测试数据库指定的名称为 eygle)创建一个控制文件,创建方式为RESETLOGS模式:
SET VERIFY OFF
connect "SYS"/"&&sysPassword" as SYSDBA
set echo on
spool D:\Oracle\admin\eygle\scripts\cloneDBCreation.log append
Create controlfile reuse set database "eygle"
MAXINSTANCES 8
MAXLOGHISTORY 1
MAXLOGFILES 16
MAXLOGMEMBERS 3
MAXDATAFILES 100
Datafile
'D:\Oracle\oradata\eygle\SYSTEM01.DBF',
'D:\Oracle\oradata\eygle\SYSAUX01.DBF',
'D:\Oracle\oradata\eygle\UNDOTBS01.DBF',
'D:\Oracle\oradata\eygle\USERS01.DBF'
LOGFILE GROUP 1 ('D:\Oracle\oradata\eygle\redo01.log') SIZE 51200K,
GROUP 2 ('D:\Oracle\oradata\eygle\redo02.log') SIZE 51200K,
GROUP 3 ('D:\Oracle\oradata\eygle\redo03.log') SIZE 51200K RESETLOGS;
创建了控制文件后,数据库随之MOUNT加载,这一步骤是为了以下工作的进行。
通过dbms_backup_restore包清空dbid等信息:
exec dbms_backup_restore.zerodbid(0);
这里再次使用到了dbms_backup_restore 包,zeroDbid 是包中的一个过程,用于清空数据文件头的部分信息,新的dbid在之后的控制文件创建时可以被计算,对于数据库克隆,这是必须的。
zeroDbid有一个输入参数,即文件号:
PROCEDURE zeroDbid(fno IN binary_integer);
当 fno==0 时,控制文件中包含的所有数据文件头都将被清零,zeroDbid 主要用于清除数据文件头的 3类信息:Database id信息、Checksum信息和Checksum符号位信息。
继续看这个脚本,清零完成之后,数据库重新启动,控制文件被重新创建,此时新的dbid被计算并最终写入新创建的控制文件中:
shutdown immediate;
startup nomount pfile="D:\Oracle\admin\eygle\scripts\initeygleTemp.ora";
Create controlfile reuse set database "eygle"
MAXINSTANCES 8
MAXLOGHISTORY 1
MAXLOGFILES 16
MAXLOGMEMBERS 3
MAXDATAFILES 100
Datafile
'D:\Oracle\oradata\eygle\SYSTEM01.DBF',
'D:\Oracle\oradata\eygle\SYSAUX01.DBF',
'D:\Oracle\oradata\eygle\UNDOTBS01.DBF',
'D:\Oracle\oradata\eygle\USERS01.DBF'
LOGFILE GROUP 1 ('D:\Oracle\oradata\eygle\redo01.log') SIZE 51200K,
GROUP 2 ('D:\Oracle\oradata\eygle\redo02.log') SIZE 51200K,
GROUP 3 ('D:\Oracle\oradata\eygle\redo03.log') SIZE 51200K RESETLOGS;
注意,在启动数据库时Oracle使用了一个临时的参数文件initeygleTemp.ora,在这个参数文件的最后一行设置了一个内部参数:
C:\Oracle\admin\eygle.t\scripts>tail -1 initeygleTemp.ora
_no_recovery_through_resetlogs=true
_no_recovery_through_resetlogs这个参数的作用是什么呢?可以从数据库中找到一点说明:
SQL> SELECT x.ksppinm NAME, y.ksppstvl VALUE, x.ksppdesc describ
2 FROM SYS.x$ksppi x, SYS.x$ksppcv y
3 WHERE x.inst_id = USERENV ('Instance')
4 AND y.inst_id = USERENV ('Instance')
5 AND x.indx = y.indx AND x.ksppinm LIKE '%&par%';
Enter value for par: no_reco
NAME VALUE DESCRIB
------------------------------ ----- ----------------------------------------------
_no_recovery_through_resetlogs FALSE no recovery through this resetlogs operation
这个参数用于限制恢复能否跨越resetlogs,对于数据库的恢复来说,resetlogs通常意味着不完全恢复,在数据库resetlogs打开之后,控制文件中的很多信息被改写,在Oracle 10g之前,如果数据库resetlogs打开,那么将不再能够通过当前的控制文件再次进行resetlogs点之前的恢复,而Oracle 10g改变了这个历史。
在Oracle 10g中,即使通过 resetlogs方式打开了数据库,Oracle仍然支持再次从 resetlogs时间点之前进行恢复;在Clone数据库时,Oracle设置这个参数为True,意思就是不允许再次进行跨越resetlogs时间点的恢复。关于这部分内容,我们将在后面章节进行更为详细的介绍。
继续解读这个脚本,接下来Oracle设置 restricted session模式,resetlogs打开数据库,然后删除了基于种子数据库的两个服务:
alter system enable restricted session;
alter database "eygle" open resetlogs;
exec dbms_service.delete_service('seeddata');
exec dbms_service.delete_service('seeddataXDB');
接下来修改global_name,添加临时文件等:
alter database rename global_name to "eygle";
ALTER TABLESPACE TEMP ADD TEMPFILE 'D:\Oracle\oradata\eygle\TEMP01.DBF' SIZE 20480K REUSE AUTOEXTEND ON NEXT 640K MAXSIZE UNLIMITED;
select tablespace_name from dba_tablespaces where tablespace_name='USERS';
alter system disable restricted session;
由于种子数据库的字符集通常与用户要求的不符,接下来 Oracle 通过内部操作强制更改了字符集、国家字符集(这个内容在后面的章节有详细的介绍):
alter database character set INTERNAL_CONVERT ZHS16GBK;
alter database national character set INTERNAL_CONVERT AL16UTF16;
最后修改用户口令,禁用 restricted session模式,这个克隆过程执行完毕:
alter user sys identified by "&&sysPassword";
alter user system identified by "&&systemPassword";
alter system disable restricted session;
至此,种子数据库已经按照用户的意图脱胎换骨得以重生。