在上篇博文中,使用了duplicate方式来创建物理standby http://blog.csdn.net/aaron8219/article/details/38434579 今天来说说在11g中采用非duplicate方式创建备库碰到的一些问题,并做个总结。 在10g中,通常可以使以下几种方法创建备库控制文件 rman backup
在上篇博文中,使用了duplicate方式来创建物理standby http://blog.csdn.net/aaron8219/article/details/38434579今天来说说在11g中采用非duplicate方式创建备库碰到的一些问题,并做个总结。
在10g中,通常可以使以下几种方法创建备库控制文件
rman> backup current controlfile for standby format 'c:\ctl_%u';
rman> backup full database format 'c:\backup\full_%u' include current controlfile for standby;
rman> copy current controlfile for standby to 'c:\backup\control01.ctl';
sql> alter database create standby controlfile as 'c:\backup\control01.ctl';
前两种生成的是备库控制文件的备份集,需要在nomount状态下,用rman命令restore,如:
sql> startup nomount
rman> restore controlfile from 'c:\backup\xxxx';
而后两种是直接创建备库控制文件。一种是通过rman命令的方式,另一种是通过sql命令的方式,创建出来的备库控制文件,可以直接复制到备库目标路径后用来启动备库到mount状态,如:
复制到c:\app\oracle\oradata\tc并冗余(control01.ctl,control02.ctl)后,可以直接在备库执行
sql> startup mount --直接启动到mount状态,不需要rman恢复
但是在11g中,rman备份不再支持以“backup current controlfile for standby”或“include current controlfile for standby”来创建备库控制文件,虽然命令仍然可以执行成功,但是当你在备库恢复完控制文件并启动到mount状态下,你会发现这个控制文件依旧是主库的控制文件,如:
rman> restore controfile from 'c:\backup\xxxx';
rman> alter database mount;
sql> select database_role from v$database;
database_role
----------------
primary --注意,数据库角色是由控制文件决定的,这里是primary,说明是用主库控制文件启动的
如果没有注意到这点,那么当你恢复完数据库文件,并启用redo apply的时候,就会报错,提示不是备用数据库。
所以,如果不是用duplicate方式来创建备库的话,要注意使用创建文件的方式直接生成备库控制文件,而不是生成rman备份集
上次使用了rman的duplicate方式来配置dg物理备库,那么这次就用非duplicate方式来做一次,其实步骤大致和10g是一致的,可以参考我以前搭建10g dg的博客,惟一不同的是,不再使用备份集来恢复备库控制文件
具体步骤(略),直接跳到完成数据库数据文件恢复后
--查看备库的日志文件
sql> set lin 120 pages 120
sql> col member for a60
sql> select group#,member from v$logfile;
group# member
---------- ------------------------------------------------------------
2 c:\app\oracle\oradata\tc\group_2.262.855057605
2 +fra/tc/onlinelog/group_2.258.855057607
1 c:\app\oracle\oradata\tc\group_1.261.855057597
1 +fra/tc/onlinelog/group_1.257.855057601
3 c:\app\oracle\oradata\tc\group_3.266.855058587
3 +fra/tc/onlinelog/group_3.259.855058591
4 c:\app\oracle\oradata\tc\group_4.267.855058593
4 +fra/tc/onlinelog/group_4.260.855058595
5 c:\app\oracle\oradata\tc\stb_redo05.log
6 c:\app\oracle\oradata\tc\stb_redo06.log
7 c:\app\oracle\oradata\tc\stb_redo07.log
8 c:\app\oracle\oradata\tc\stb_redo08.log
9 c:\app\oracle\oradata\tc\stb_redo09.log
--对比一下主库的日志文件
sql> set lin 120 pages 120
sql> col member for a60
sql> select group#,member from v$logfile;
group# member
---------- ------------------------------------------
2 +data/tc/onlinelog/group_2.262.855057605
2 +fra/tc/onlinelog/group_2.258.855057607
1 +data/tc/onlinelog/group_1.261.855057597
1 +fra/tc/onlinelog/group_1.257.855057601
3 +data/tc/onlinelog/group_3.266.855058587
3 +fra/tc/onlinelog/group_3.259.855058591
4 +data/tc/onlinelog/group_4.267.855058593
4 +fra/tc/onlinelog/group_4.260.855058595
由于主库没有创建备库日志文件,所以目前只有在线日志文件,共4组,分配给2个thread,每个thread使用2组,并且每组有2个member,一个放在+data,另一个放在+fra通过观察发现,此时在备库控制文件中记录的2个日志组位置,一个是通过log_file_name_convert参数指定的从'+data/tc/onlinelog'转换到了'c:\app\oracle\oradata\tc\',但是并没有指定过'+fra/tc/onlinelogfile',所以也就是现在看到的状态,+fra那部分依然是主库的结构,但是备库是采用单实例本地磁盘的结构,并没有使用asm磁盘组,那么这样2组日志,在备库应该怎么使用呢?
可以发现,其实此时在备库数据文件目录‘c:\app\oracle\oradata\tc\’中,并没有生成‘group_1.261.855057597’,‘group_2.262.855057605’,‘group_3.266.855058587’,‘group_4.267.855058593’这4个在线日志文件,更别说是+fra对应的4个文件了,即,在我们恢复数据库数据文件的时候,只会恢复数据文件和临时文件,那么应该如何创建这几个文件呢?
开始,我想到的是先把完全不可能存在的+fra那组在线日志文件的内容,从备库控制文件中删除
sql> alter database drop logfile '+fra/tc/onlinelog/group_1.257.855057601';
alter database drop logfile '+fra/tc/onlinelog/group_1.257.855057601'
*
第 1 行出现错误:
ora-01514: 日志说明中出现错误: 没有此类日志
ora-01517: 日志成员: '+fra/tc/onlinelog/group_1.257.855057601'
很正常,因为并没有这个路径,就算有,online redo log也不会在“rman> restore database;”命令中恢复
--尝试重建控制文件
sql> oradebug setmypid
已处理的语句
sql> alter database backup controlfile to trace;
数据库已更改。
sql> oradebug tracefile_name
c:\app\oracle\diag\rdbms\tcdg\tc\trace\tc_ora_1792.trc
用oradebug可以轻松地跟踪到具体的trace文件,而不需要执行复杂的sql查询语句
去目标路径打开这个tc_ora_1792.trc文件,可以发现创建控制文件的语句,这里选择noresetlogs,内容如下:
startup nomount
create controlfile reuse database tc noresetlogs force logging archivelog
maxlogfiles 192
maxlogmembers 3
maxdatafiles 1024
maxinstances 32
maxloghistory 292
*** 2014-08-13 09:30:03.000
logfile
*** 2014-08-13 09:30:04.265
group 1 (
'c:\app\oracle\oradata\tc\group_1.261.855057597',
'+fra/tc/onlinelog/group_1.257.855057601'
) size 50m blocksize 512,
group 2 (
'c:\app\oracle\oradata\tc\group_2.262.855057605',
'+fra/tc/onlinelog/group_2.258.855057607'
) size 50m blocksize 512,
group 3 (
'c:\app\oracle\oradata\tc\group_3.266.855058587',
'+fra/tc/onlinelog/group_3.259.855058591'
) size 50m blocksize 512,
group 4 (
'c:\app\oracle\oradata\tc\group_4.267.855058593',
'+fra/tc/onlinelog/group_4.260.855058595'
) size 50m blocksize 512
-- standby logfile
-- group 5 'c:\app\oracle\oradata\tc\stb_redo05.log' size 50m blocksize 512,
-- group 6 'c:\app\oracle\oradata\tc\stb_redo06.log' size 50m blocksize 512,
-- group 7 'c:\app\oracle\oradata\tc\stb_redo07.log' size 50m blocksize 512,
-- group 8 'c:\app\oracle\oradata\tc\stb_redo08.log' size 50m blocksize 512,
-- group 9 'c:\app\oracle\oradata\tc\stb_redo09.log' size 50m blocksize 512
datafile
*** 2014-08-13 09:30:04.765
'c:\app\oracle\oradata\tc\system.256.855057451',
'c:\app\oracle\oradata\tc\sysaux.257.855057453',
'c:\app\oracle\oradata\tc\undotbs1.258.855057453',
'c:\app\oracle\oradata\tc\users.259.855057453',
'c:\app\oracle\oradata\tc\example.264.855057687',
'c:\app\oracle\oradata\tc\undotbs2.265.855058289'
character set zhs16gbk
;
--去掉+fra在线日志文件内容后,执行创建语句
sql> startup nomount
sql> create controlfile reuse database tc noresetlogs force logging archivelog
2 maxlogfiles 192
3 maxlogmembers 3
4 maxdatafiles 1024
5 maxinstances 32
6 maxloghistory 292
7 logfile
8 group 1 (
9 'c:\app\oracle\oradata\tc\group_1.261.855057597'
10 ) size 50m blocksize 512,
11 group 2 (
12 'c:\app\oracle\oradata\tc\group_2.262.855057605'
13 ) size 50m blocksize 512,
14 group 3 (
15 'c:\app\oracle\oradata\tc\group_3.266.855058587'
16 ) size 50m blocksize 512,
17 group 4 (
18 'c:\app\oracle\oradata\tc\group_4.267.855058593'
19 ) size 50m blocksize 512
20 -- standby logfile
21 -- group 5 'c:\app\oracle\oradata\tc\stb_redo05.log' size 50m blocksize
512,
22 -- group 6 'c:\app\oracle\oradata\tc\stb_redo06.log' size 50m blocksize
512,
23 -- group 7 'c:\app\oracle\oradata\tc\stb_redo07.log' size 50m blocksize
512,
24 -- group 8 'c:\app\oracle\oradata\tc\stb_redo08.log' size 50m blocksize
512,
25 -- group 9 'c:\app\oracle\oradata\tc\stb_redo09.log' size 50m blocksize
512
26 datafile
27 'c:\app\oracle\oradata\tc\system.256.855057451',
28 'c:\app\oracle\oradata\tc\sysaux.257.855057453',
29 'c:\app\oracle\oradata\tc\undotbs1.258.855057453',
30 'c:\app\oracle\oradata\tc\users.259.855057453',
31 'c:\app\oracle\oradata\tc\example.264.855057687',
32 'c:\app\oracle\oradata\tc\undotbs2.265.855058289'
33 character set zhs16gbk
34 ;
create controlfile reuse database tc noresetlogs force logging archivelog
*
第 1 行出现错误:
ora-01503: create controlfile 失败
ora-01565: 标识文件 'c:\app\oracle\oradata\tc\group_1.261.855057597' 时出错
ora-27041: 无法打开文件
osd-04002: 无法打开文件
o/s-error: (os 2) 系统找不到指定的文件。
本地路径对应的在线日志不存在,刚才也已经说明了,那么是不是要把控制文件中的logfile整段都去掉呢?
这个我没有做测试,觉得应该不用这么复杂,确保主库远程归档路径没有error后,直接在备库启用redo apply
sql> recover managed standby database disconnect from session
完成介质恢复。
此时查看日志文件的状态,会发现,备库会对在线日志文件做clearing操作,从第1组到第4组,逐个进行,直到清除完毕,在清除的同时,会在数据文件目录中创建在线日志文件。
sql> select group#,members,status from v$log;
group# members status
---------- ---------- ----------------
1 3 current
2 3 clearing
3 2 inactive
4 2 inactive
sql> select group#,members,status from v$log;
group# members status
---------- ---------- ----------------
1 3 current
2 3 unused
3 3 clearing
4 2 inactive
sql> select group#,members,status from v$log;
group# members status
---------- ---------- ----------------
1 3 current
2 3 unused
3 3 unused
4 3 clearing
sql> select group#,members,status from v$log;
group# members status
---------- ---------- ----------------
1 3 current
2 3 unused
3 3 unused
4 3 unused
可以看到,clearing操作更新了原来备库控制文件中错误的在线日志文件路径,并且在原来的基础上,又加了1组在线日组,并且会把还未使用到的日志组状态变成unused。目前每个在线日志组有3个成员,一个在实例名tc下面,一个在db_unique_name(tcdg)下面,另一个在flash_recovery_area下面,这个可以通过查看v$logfile视图得到确认
sql> col member for a70
sql> select group#,member from v$logfile;
group# member
---------- ----------------------------------------------------------------------
2 c:\app\oracle\oradata\tc\group_2.262.855057605
2 c:\app\oracle\oradata\tcdg\onlinelog\o1_mf_2_9yokr04w_.log
1 c:\app\oracle\oradata\tc\group_1.261.855057597
1 c:\app\oracle\oradata\tcdg\onlinelog\o1_mf_1_9yokq7g5_.log
3 c:\app\oracle\oradata\tc\group_3.266.855058587
3 c:\app\oracle\oradata\tcdg\onlinelog\o1_mf_3_9yokrrj3_.log
4 c:\app\oracle\oradata\tc\group_4.267.855058593
4 c:\app\oracle\oradata\tcdg\onlinelog\o1_mf_4_9yoksh5v_.log
5 c:\app\oracle\oradata\tc\stb_redo05.log
6 c:\app\oracle\oradata\tc\stb_redo06.log
7 c:\app\oracle\oradata\tc\stb_redo07.log
8 c:\app\oracle\oradata\tc\stb_redo08.log
9 c:\app\oracle\oradata\tc\stb_redo09.log
1 c:\app\oracle\flash_recovery_area\tcdg\onlinelog\o1_mf_1_9yokqc7t_.log
2 c:\app\oracle\flash_recovery_area\tcdg\onlinelog\o1_mf_2_9yokrbmk_.log
3 c:\app\oracle\flash_recovery_area\tcdg\onlinelog\o1_mf_3_9yokry8s_.log
4 c:\app\oracle\flash_recovery_area\tcdg\onlinelog\o1_mf_4_9yoksk5c_.log
--查看数据文件
sql> select file#,ts#,name from v$datafile;
file# ts# name
---------- ---------- ------------------------------------------------------------
1 0 c:\app\oracle\oradata\tc\system.256.855057451
2 1 c:\app\oracle\oradata\tc\sysaux.257.855057453
3 2 c:\app\oracle\oradata\tc\undotbs1.258.855057453
4 4 c:\app\oracle\oradata\tc\users.259.855057453
5 6 c:\app\oracle\oradata\tc\example.264.855057687
6 5 c:\app\oracle\oradata\tc\undotbs2.265.855058289
--查看临时文件
sql> select file#,ts#,name from v$tempfile;
file# ts# name
---------- ---------- ------------------------------------------------------------
1 3 c:\app\oracle\oradata\tcdg\datafile\o1_mf_temp_9yoklbg5_.tmp
注意默认是的临时文件存放位置是在tcdg下面,而不是tc,可以不做处理。但如果觉得别扭,可以先增加一个临时表空间,指定临时文件存放到tc目录下,然后再删除现有的临时表空间,注意删除的时候要指定including contents and datafiles,才会在删除表空间的时候连数据文件一起删除
最后,再做一个dg同步测试(注意执行各命令时的time)
--主库:
sql> set time on; --为了使主备库两边的操作更加能说明问题,设置操作时间
10:47:59 sql> archive log list
数据库日志模式 存档模式
自动存档 启用
存档终点 use_db_recovery_file_dest
最早的联机日志序列 53
下一个存档日志序列 54
当前日志序列 54
10:48:05 sql> select group#,members,status from v$log;
group# members status
---------- ---------- ----------------
1 2 active
2 2 current --当前current在group2,注意后面切换日志后的status
3 2 inactive
4 2 inactive
10:48:31 sql> select sequence#,thread#,applied,archived fromv$archived_log where sequence#>49 order by 1;
sequence# thread# applied arc
---------- ---------- --------- ---
50 1 yes yes
50 1 no yes
51 1 yes yes
51 1 no yes
52 1 yes yes
52 1 no yes
53 1 no yes
53 1 yes yes
10:49:35 sql> create user zlm identified by aaron8219; --注意创建用户的时间,在备库是否能立即使用
用户已创建。
10:50:45 sql> conn zlm/aaron8219
error:
ora-01045: 用户 zlm 没有 create session 权限; 登录被拒绝
警告: 您不再连接到 oracle。
10:51:06 sql> grant create session,resource to zlm;
sp2-0640: 未连接
10:51:37 sql> conn /as sysdba
已连接。
10:51:43 sql> grant create session,resource to zlm;
授权成功。
10:51:52 sql> conn zlm/aaron8219
已连接。
10:51:59 sql> create table test1(int number,name varchar2(10));
表已创建。
10:52:27 sql> insert into test1 values(1,'aaron8219');
已创建 1 行。
10:52:48 sql> commit;
提交完成。
10:53:13 sql> alter system archive log current;
alter system archive log current
*
第 1 行出现错误:
ora-01031: 权限不足
10:53:29 sql> conn /as sysdba
已连接。
10:53:41 sql> alter system archive log current; --有了这个操作,备库才会接受到主库变更,才能登陆zlm用户
系统已更改。
10:54:16 sql> select group#,members,status from v$log;
group# members status
---------- ---------- ----------------
1 2 current --注意,由于是在节点1上做的操作,始终只会用到group1和group2这2个日志组
2 2 active
3 2 inactive
4 2 inactive
10:55:32 sql> drop user zlm;
drop user zlm
*
第 1 行出现错误:
ora-01922: 必须指定 cascade 以删除 'zlm'
10:57:05 sql> drop user zlm cascade; --注意drop用户的时间,对照备库此时对该用户的操作情况
用户已删除。
10:57:16 sql> conn zlm/aaron8219
error:
ora-01017: 用户名/口令无效; 登录被拒绝
警告: 您不再连接到 oracle。
10:58:32 sql> alter system archive log current;
sp2-0640: 未连接
10:58:43 sql> conn /as sysdba
已连接。
10:58:51 sql> alter system archive log current; --备库从这个时间点开始,无法再连接到zlm用户,因为已删除
系统已更改。
10:59:23 sql> select group#,members,status from v$log;
group# members status
---------- ---------- ----------------
1 2 active
2 2 current --再次切换日志后,current又回到group2
3 2 inactive
4 2 inactive
10:59:29 sql>
--备库:
sql> set time on;
10:48:46 sql> archive log list
数据库日志模式 存档模式
自动存档 启用
存档终点 use_db_recovery_file_dest
最早的联机日志序列 53
下一个存档日志序列 0
当前日志序列 54
10:48:48 sql> select group#,members,status from v$log;
group# members status
---------- ---------- ----------------
1 3 clearing
2 3 current --与主库一开始的status对应,主库每切换一次,备库也切换一次
3 3 unused
4 3 unused
10:49:07 sql> select sequence#,thread#,applied,archived from v$archived_log wher
e sequence#>49 order by 1;
sequence# thread# applied arc
---------- ---------- --------- ---
50 1 yes yes
51 1 yes yes
52 1 yes yes
53 1 yes yes
已选择8行。
10:50:00 sql> conn zlm/aaron8219 --主库是在10:53:41时刻才切换日志的,早于该时间点,并没有zlm用户
error:
ora-01017: 用户名/口令无效; 登录被拒绝
警告: 您不再连接到 oracle。
10:53:59 sql> conn zlm/aaron8219 --只有备库应用了主库切换的归档日志后,备库才能同步主库数据
已连接。
10:54:41 sql> select * from test1;
int name
---------- ------------------------------------------------------------
1 aaron8219
10:54:50 sql> conn /as sysdba
已连接。
10:55:58 sql> conn zlm/aaron8219
已连接。
10:56:21 sql> select group#,members,status from v$log;
select group#,members,status from v$log
*
第 1 行出现错误:
ora-00942: 表或视图不存在
10:56:33 sql> conn /as sysdba
已连接。
10:56:44 sql> select group#,members,status from v$log;
group# members status
---------- ---------- ----------------
1 3 current --此时主库已经发生过一次切换,所以current从group2到group1上
2 3 clearing
3 3 unused
4 3 unused
10:56:47 sql> conn zlm/aaron8219
已连接。
10:57:56 sql> select * from test1; --主库在10:57:05时刻进行了drop user,但zlm用户依然可以查询
int name
---------- ------------------------------------------------------------
1 aaron8219
10:59:06 sql> select * from test1; --主库在10:58:51时刻进行了日志切换,备库应用了这个归档,zlm无法查询
select * from test1
*
第 1 行出现错误:
ora-00942: 表或视图不存在
10:59:46 sql> conn zlm/aaron8219 --之后也无法继续连接zlm用户,因为删除用户的操作已经在备库生效
error:
ora-01017: 用户名/口令无效; 登录被拒绝
警告: 您不再连接到 oracle。
10:59:50 sql> conn /as sysdba
已连接。
11:00:02 sql> select group#,members,status from v$log;
group# members status
---------- ---------- ----------------
1 3 clearing
2 3 current --主库经过第2次切换日志后,备库在线日志又从group1回到了group2
3 3 unused
4 3 unused11:00:05 sql>
非duplicate方式搭建物理standby总结:
1.在11g中,用传统方法来创建备库可以和10g一样,但是要注意用直接创建文件的方式来生成备库控制文件,而不是用备份集。
2.开启redo apply以后,会自动清除控制文件中旧的信息(这里指存放路径),并立即逐个生成online redo logfile,会在原来的基础上再多加一组在线日志。
3.和采用duplicate方式创建的备库结果一致,每组也是生成3个在线日志成员,惟一的区别就是在duplicate中必须用set newname for tempfile 1 to 'c:\xxxx',来指定一个路径和文件名,否则会报冲突,无法完成duplicate。
4.需要拷贝主库密码文件到备库相应位置,而duplicate是自动在备库创建的,duplicate还能用spfile参数指定并在备库直接生成spfile,而普通方式在完成后需要手动创建一个spfile。