提示:
如果primary 或逻辑standby 是rac 结构,切记只保留一个实例启动,其它实例全部shutdown。等角色转换操作完成之后再启动其它实例,角色转换的操作会自动传播到这些实例上,并不需要你再对这些实例单独做处理。
1、检查primary 和逻辑standby 的初始化参数设置,常规的检查包括:
● 确保fal_server,fal_client 值设置正确
● 确保log_archive_dest_n 参数设置正确
更多可能涉及的初始化参数可以参考2.1 中的第4 小章
JSSWEB> show parameter fal
NAME TYPE VALUE
-------------------------- ----------- -------------------------------
fal_client string jssweb
fal_server string jsspdg
JSSWEB> show parameter name_convert
NAME TYPE VALUE
-------------------------- ----------- -------------------------------
db_file_name_convert string oradata\jsspdg, oradata\jssweb
log_file_name_convert string oradata\jsspdg, oradata\jssweb
JSSWEB> show parameter log_archive_dest
NAME TYPE VALUE
-------------------------- ----------- -------------------------------
log_archive_dest string
log_archive_dest_1 string LOCATION=E:\ora 10g \oradata\jssweb\arc
VALID_FOR=(ALL_LOGFILES,ALL_ROLES)
DB_UNIQUE_NAME=jssweb
log_archive_dest_2 string service=jsspdg OPTIONAL LGWR SYNC AFFIRM
VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE)
DB_UNIQUE_NAME=jsspdg
................
................
................
log_archive_dest_state_1 string ENABLE
log_archive_dest_state_2 string defer
JSSWEB> alter system set log_archive_dest_2='location=e:\ora 10g \oradata\jssweb\std\valid_for=(standby_logfiles,standby_role) db_unique_name=jssweb';
系统已更改。
JSSWEB> alter system set log_archive_dest_1='location=e:\ora 10g \oradata\jssweb\arc\valid_for=(online_logfiles,all_roles) db_unique_name=jssweb';
系统已更改。
JSSWEB> alter system set log_archive_dest_state_2='enable';
系统已更改。
JSSWEB> alter system set fal_server='jssldg';
系统已更改。
--xx_file_name_convert 这两个参数无法动态修改,因此我们首先修改 spfile ,然后再重启一下数据库
JSSWEB> alter system set db_file_name_convert='oradata\jssldg','oradata\jssweb' scope=spfile;
系统已更改。
JSSWEB> alter system set log_file_name_convert='oradata\jssldg','oradata\jssweb' scope=spfile;
系统已更改。
JSSWEB> startup force
JSSLDG> show parameter fal
NAME TYPE VALUE
---------------------- ----------- --------------------
fal_client string
fal_server string
JSSLDG> show parameter file_name
NAME TYPE VALUE
---------------------- ----------- --------------------
db_file_name_convert string oradata\jssweb, oradata\jssldg
log_file_name_convert string oradata\jssweb, oradata\jssldg
JSSLDG> show parameter log_archive
NAME TYPE VALUE
---------------------- ----------- --------------------
log_archive_config string DG_CONFIG=(jssweb,jsspdg,jssldg)
log_archive_dest string
log_archive_dest_1 string location=E:\ora 10g \oradata\jssldg\arc\
valid_for=(online_logfiles,all_roles)
db_unique_name=jssldg
log_archive_dest_10 string
log_archive_dest_2 string location=E:\ora 10g \oradata\JSSLDG\std\
valid_for=(standby_logfiles,standby_role)
db_unique_name=JSSLDG
.......................
.......................
JSSLDG> alter system set fal_server='jssweb';
系统已更改。
JSSLDG> alter system set fal_client='jssldg';
系统已更改。
JSSLDG> alter system set log_archive_dest_3='service=jssweb lgwr async valid_for=(online_logfiles,primary_role) db_unique_name=jssweb';
系统已更改。
JSSWEB> select * from v$standby_log;
未选定行
JSSWEB> alter database add standby logfile group 4 ('e:\ora10g\oradata\jssweb\standbyrd01.log') size 20m;
数据库已更改。
.....................
.......................
.........................
JSSWEB> alter database add standby logfile group 8 ('e:\ora10g\oradata\jssweb\standbyrd05.log') size 20m;
数据库已更改。
JSSWEB> select switchover_status from v$database;
SWITCHOVER_STATUS
--------------------
TO STANDBY
JSSWEB> alterdatabasepreparetoswitchovertologicalstandby;
数据库已更改。
JSSWEB> select switchover_status from v$database;
SWITCHOVER_STATUS
--------------------
PREPARING SWITCHOVER
JSSLDG> alterdatabasepreparetoswitchovertoprimary;
数据库已更改。
JSSLDG> select switchover_status from v$database;
SWITCHOVER_STATUS
--------------------
PREPARING SWITCHOVER
JSSWEB> select switchover_status from v$database;
SWITCHOVER_STATUS
--------------------
TO LOGICAL STANDBY
提示:
取消转换可以通过下列语句:
ALTER DATABASE PREPARE TO SWITCHOVER CANCEL;
需要分别在primary 和逻辑standby 执行。
六、转换primary为逻辑standby
JSSWEB> alterdatabasecommittoswitchovertologicalstandby;
数据库已更改。
该命令执行完之后,这个primary 就已经成为新的逻辑standby 了。不过在新primary 执行完转换之前,不要关闭当前这个数据库。
JSSLDG> select switchover_status from v$database;
SWITCHOVER_STATUS
--------------------
TO PRIMARY
JSSLDG> alterdatabasecommittoswitchovertoprimary;
数据库已更改。
最后启动新逻辑standby 的sql 应用。
JSSWEB> alter database start logical standby apply;
数据库已更改。
前面学习物理standby 的failover 时我们提到过,failover 有可能会丢失数据(视当前的数据库保护模式而定),对于逻辑standby 也一样;物理standby 在做failover 演示时还提到过,所有的操作都会在standby 端执行,对于逻辑standby 这也一样,甚至对于明确提及在前primary 执行的,你不执行,也没关系,毕竟对于failover,我们假设的就是,primary 已经over 了:)
JSSLDG> select max(sequence#) from v$archived_log;
MAX(SEQUENCE#)
--------------
24
JSSWEB> select sequence#,applied from dba_logstdby_log;
SEQUENCE# APPLIED
---------- --------
23 YES
24 YES
已选择2 行。
如果standby 与primary 的归档序号相同,但某些序号的applied 状态为no,建议你检查一下当前standby是否启动了SQL 应用:)。
可以通过查询v$logstdby_progress 视图:
JSSWEB> select applied_scn,latest_scn from v$logstdby_progress;
APPLIED_SCN LATEST_SCN
----------- ----------
1259449 1259453
确认待转换的逻辑standby 配置了正确的归档路径,不仅是写本地的归档,还要有写远程的归档,不然转换完之后,这台新的primary 就成了光杆司令了。
JSSWEB> show parameter log_archive_dest
.......................
二、激活新的primary数据库
JSSWEB> select database_role,force_logging from v$database;
DATABASE_ROLE FOR
---------------- ---
LOGICAL STANDBY YES
转换standby 角色为primary
JSSWEB> altealterdatabaseactivatelogicalstandbydatabasefinishapply;
数据库已更改。
JSSWEB> select database_role,force_logging from v$database;
DATABASE_ROLE FOR
---------------- ---
PRIMARY YES
JSSLDG2> alter session disable guard;
会话已更改。
JSSLDG2> create database link getjssweb connect to jss identified by jss using 'jssweb';
数据库链接已创建。
JSSLDG2> alter session enable guard;
会话已更改。
JSSLDG2> select sysdate from dual@getjssweb;
SYSDATE
--------------
23-2 月-08
提示:关于alter session enable|disable guard 语句,用于允许或禁止用户修改逻辑standby 中的结构。例如:
JSSLDG2> conn jss/jss
已连接。
JSSLDG2> select * from b;
ID
----------
1
2
3
4
5
6
7
8
已选择8 行。
JSSLDG2> alter table b rename to a;
alter table b rename to a
*
第1 行出现错误:
ORA-16224: Database Guard 已启用
JSSLDG2> alter session disable guard;
会话已更改。
JSSLDG2> alter table b rename to a;
表已更改。
在各个逻辑standby 执行下列语句启动sql 应用(注意更新dblinkName):
JSSLDG2> alter database start logical standby apply new primary getjssweb;
数据库已更改。
语句顺利执行完之后,我们来验证一下:
JSSWEB> alter system switch logfile;
系统已更改。
JSSWEB> select max(sequence#) from v$archived_log;
MAX(SEQUENCE#)
--------------
862
JSSLDG2> select sequence#,applied from dba_logstdby_log;
SEQUENCE# APPLIED
---------- --------
862 NO
JSSLDG2> select process,status,group#,thread#,sequence#,block#,blocks from v$managed_standby;
PROCESS STATUS GROUP# THREAD# SEQUENCE# BLOCK# BLOCKS
--------- ------------ --------- ---------- ---------- ---------- ----------
ARCH CLOSING 2 1 4 16385 1836
ARCH CLOSING 6 1 862 1 18
RFS IDLE N/A 0 0 0 0
RFS IDLE 3 1 863 2 1
看起来也是正常的,接收完了862,正在等待863,但是,为什么不应用呢。
JSSWEB> select sequence#,name,COMPLETION_TIME from v$archived_log where sequence#>855;
SEQUENCE# NAME COMPLETION_TIME
---------- -------------------------------------------------------- -------------------
856 E:\ORA10G\ORADATA\JSSWEB\ARC\LOG1_856_641301252.ARC 2008-02-21 10:15:42
857 E:\ORA10G\ORADATA\JSSWEB\ARC\LOG1_857_641301252.ARC 2008-02-21 10:16:46
858 E:\ORA10G\ORADATA\JSSWEB\ARC\LOG1_858_641301252.ARC 2008-02-23 14:15:18
859 E:\ORA10G\ORADATA\JSSWEB\ARC\LOG1_859_641301252.ARC 2008-02-23 14:56:55
860 E:\ORA10G\ORADATA\JSSWEB\ARC\LOG1_860_641301252.ARC 2008-02-23 14:57:03
861 E:\ORA10G\ORADATA\JSSWEB\ARC\LOG1_861_641301252.ARC 2008-02-23 16:58:14
861 jssldg2 2008-02-23 16:58:16
862 E:\ORA10G\ORADATA\JSSWEB\ARC\LOG1_862_641301252.ARC 2008-02-23 17:08:57
862 jssldg2 2008-02-23 17:08:57
863 E:\ORA10G\ORADATA\JSSWEB\ARC\LOG1_863_641301252.ARC 2008-02-23 17:19:48
863 jssldg2 2008-02-23 17:20:59
864 E:\ORA10G\ORADATA\JSSWEB\ARC\LOG1_864_641301252.ARC 2008-02-23 17:21:11
864 jssldg2 2008-02-23 17:21:13
已选择13 行。
发现了一点点痕迹,我们的切换操作是下午3 点左右进行的,期间还产生了序列号为860,861 之类的归档文件,但并未传输至standby,是不是因为这些文件中包含了一部分应被应用的数据,因此造成standby
接收到的新primary 传输过来的归档scn 与最后应用的scn 不连续,所以无法应用?再来验证一下:
JSSLDG2> select applied_scn,latest_scn from v$logstdby_progress;
APPLIED_SCN LATEST_SCN
----------- ----------
1259449 1284126
果然如此,应用的scn 与最后的scn 确实不匹配,剩下的就好解决了,把所有可疑的应传输到standby的归档文件手工复制到standby,然后通过alter 命令注册一下:
JSSLDG2> alter database register logical logfile 'E:\ora10g\oradata\jssldg2\std\LOG1_859_641301252.ARC';
数据库已更改。
JSSLDG2> alter database register logical logfile 'E:\ora10g\oradata\jssldg2\std\LOG1_860_641301252.ARC';
数据库已更改。
JSSLDG2> alter database register logical logfile 'E:\ora10g\oradata\jssldg2\std\LOG1_861_641301252.ARC';
数据库已更改。
859,860,861 全部复制过来。
JSSLDG2> select sequence#,applied from dba_logstdby_log;
SEQUENCE# APPLIED
---------- --------
862 CURRENT
863 CURRENT