单机搭建oracle dg 实验与总结
来源:互联网 发布:网络大型策略游戏 编辑:程序博客网 时间:2024/06/05 08:57
实验环境:
主库:windows xp + oracle 11.1.0.1
数据文件 D:\oracle\oradata\DG1\DATAFILE
复制到:windows xp + oracle 11.1.0.1
数据文件 G:\Oracle\oradata\DG2\DATAFILE
简称 主库和复制库
一、primary侧的环境准备:
1,确保数据库归档状态
SQL> select log_mode from v$database;
LOG_MODE
------------
ARCHIVELOG
2,Enable force logging
SQL> ALTER DATABASE FORCE LOGGING;
Database altered.
3,生成standby redolog
[sql]
alter database add standby logfile 'D:\ORACLE\ORADATA\DG1\ONLINELOG\redo05.log' size 50m;
alter database add standby logfile 'D:\ORACLE\ORADATA\DG1\ONLINELOG\redo06.log' size 50m;
alter database add standby logfile 'D:\ORACLE\ORADATA\DG1\ONLINELOG\redo07.log' size 50m;
alter database add standby logfile 'D:\ORACLE\ORADATA\DG1\ONLINELOG\redo08.log' size 50m;
4,修改primary参数文件spfile,需要设置以下8个参数
SQL> alter system set LOG_ARCHIVE_CONFIG='DG_CONFIG=(dg1,dg2)';
System altered.
SQL> alter system set LOG_ARCHIVE_DEST_1='LOCATION=D:\oracle\arch VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=dg1';
System altered.
SQL> alter system set LOG_ARCHIVE_DEST_2='SERVICE=dg2 LGWR ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=dg2';
System altered.
SQL> alter system set LOG_ARCHIVE_DEST_STATE_1=ENABLE;
System altered.
SQL> alter system set FAL_SERVER=dg2;
System altered.
SQL> alter system set FAL_CLIENT=dg1;
System altered.
SQL> alter system set DB_FILE_NAME_CONVERT='D:\ORACLE\ORADATA\DG1\DATAFILE\','G:\Oracle\oradata\DG2\DATAFILE' scope=spfile;
System altered.
SQL> alter system set LOG_FILE_NAME_CONVERT='D:\oracle\arch','G:\oracle\arch' scope=spfile;
System altered.
二、修改sql*net相关文件,确保网络环境准备,确保互相tnsping通
listener.ora
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = standby)
(ORACLE_HOME = /oracle/app/oracle/product/11.2.0/db_1)
(SID_NAME = standby3)
)
)
SID_LIST_LISTENER = ------此处需要手动编辑sid列,静态监听,否则报错ORA-12514
(SID_LIST =
(SID_DESC =
(SID_NAME = dg2)
(ORACLE_HOME = D:\oracle\product\11.2.0\dbhome_1)
)
)
LISTENER =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.6.190)(PORT = 1521))
)
tnsnames.ora
DG1 =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.6.190)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = dg1)
)
)
DG2 =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.6.190)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = dg2)
)
)
三、创建standby数据库
主库只需要复制密码文件 $ORACLE_HOME/dbs/orapwdg1 到 windows $ORACLE_HOME/database/目录下 改名为orapwdg2
如果是异机需要 在d:\app\administrator\admin\asm11g\目录下 新建adump,dpdump,pfile 三个目录 -----本次实验是同一台机器就不建了
创建备库instance
windows平台利用oradim工具创建一个新的instance,unix/linux平台设置新的ORACLE_SID即可,我的是linux平台,设置ORACLE_SID即可。
C:\Documents and Settings\Administrator>oradim -new -sid dg2 ----删除可用oradim -delete -sid dg2
实例已创建。
新建pfile文件
dg2.DB_NAME=dg1
dg2.DB_UNIQUE_NAME=dg2
*.audit_file_dest='D:\oracle\admin\dg2\adump'
*.control_files='G:\Oracle\oradata\DG2\DATAFILE\control01.ctl','G:\Oracle\oradata\DG2\DATAFILE\control02.ctl'
*.db_block_size=8192
*.db_recovery_file_dest='G:\Oracle\arch'
*.db_recovery_file_dest_size=10G
启动数据库到nomount状态
SQL> startup nomount pfile='D:\oracle\product\11.2.0\dbhome_1\database\initdg2.ora';
四、 执行duplicate 复制standby库
set ORACLE_SID=dg2
[oracle@db1 dbs]$ rman target sys/oracle@dg1 auxiliarysys/oracle@dg2
RMAN> run {
allocate channel prmy1 type disk;
allocate channel prmy2 type disk;
allocate channel prmy3 type disk;
allocate channel prmy4 type disk;
allocate auxiliary channel stby type disk;
duplicate target database for standby from active database
spfile
parameter_value_convert 'dg1','dg2'
set db_unique_name='dg2'
set db_file_name_convert='D:\ORACLE\ORADATA\DG1\DATAFILE\','G:\Oracle\oradata\DG2\DATAFILE\'
set log_file_name_convert='D:\oracle\arch','G:\oracle\arch'
set control_files='G:\Oracle\oradata\DG2\DATAFILE\control01.ctl','G:\Oracle\oradata\DG2\DATAFILE\control02.ctl'
set log_archive_max_processes='5'
set fal_client='dg2'
set fal_server='dg1'
set standby_file_management='AUTO'
set log_archive_config='dg_config=(dg1,dg2)'
set log_archive_dest_1='location=G:\Oracle\arch VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=dg2'
set log_archive_dest_2='service=dg1 ASYNC valid_for=(ONLINE_LOGFILE,PRIMARY_ROLE) db_unique_name=dg1'
;
}
五、standby数据库,开启dataguard
SQL> alter database mount standby database;
数据库已更改。
将备库置于自动恢复状态
SQL> alter database recover managed standby database disconnect from session;
数据库已更改。
六、对于active dataguard,可以再使用如下命令
停止日志应用:
SQL> alter database recover managed standby database cancel;
数据库已更改。
SQL> alter database open;
数据库已更改。
置于恢复状态:
SQL> alter database recover managed standby database disconnect;
数据库已更改。
开启物理standby的日志实时应用(从库):
SQL> alter database recover managed standby database using current logfile disconnect from session;
数据库已更改。
注:
(1)
------此处需要手动编辑sid列,静态监听,否则报错RMAN-00554: 内部恢复管理器程序包初始化失败
RMAN-04005: 目标数据库中存在错误:
ORA-12514: TNS: 监听程序当前无法识别连接描述符中请求的服务
standby监听器必须是静态监听
(2)db_file_name_convert要正确设置,否者会报错ORA-17628, ORA-19505
验证:
分别在主备库执行
SQL> select max(sequence#) from v$archived_log;
MAX(SEQUENCE#)
--------------
9
查看数据库角色和数据保护模式:
select protection_mode,database_role,protection_level from v$database;
------------------------------------------------------------------------------------------------------
主变从:
select switchover_status from v$database;
SWITCHOVER_STATUS
--------------------
TO STANDBY --可以直接切换
alter database commit to switchover to physical standby;
SWITCHOVER_STATUS
--------------------
SESSIONS ACTIVE --不能直接切换执行下列命令
alter database commit to switchover to physical standby with session shutdown;
切换过程:
SQL> alter database commit to switchover to physical standby with session shutdown;
数据库已更改。
SQL> shut immediate
ORA-01507: 未装载数据库
ORACLE 例程已经关闭。
SQL> startup nomount;
ORACLE 例程已经启动。
Total System Global Area 535662592 bytes
Fixed Size 1375792 bytes
Variable Size 243270096 bytes
Database Buffers 285212672 bytes
Redo Buffers 5804032 bytes
SQL> alter database mount standby database;
数据库已更改。
------------------------------------------------------------------------------------------------------
从变主:
select switchover_status from v$database;
SWITCHOVER_STATUS
--------------------
NOT ALLOWED --没有切换标记!不能切换
TO PRIMARY --可以直接切换
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE;
select switchover_status from v$database;
操作时遇到的问题:
SQL> select switchover_status from v$database; ---第一次切换查看状态是NOT ALLOWED
SWITCHOVER_STATUS
--------------------
NOT ALLOWED
SQL> alter database recover managed standby database cancel; ---执行切换报错
数据库已更改。
SQL> alter database commit to switchover to primary;
alter database commit to switchover to primary
*
第 1 行出现错误:
ORA-16139: 需要介质恢复
SQL> select sequence#, applied from v$archived_log; ---查看归档,有没应用的(no 状态)
SEQUENCE# APPLIED
---------- ---------
6 YES
7 YES
9 YES
10 YES
11 YES
12 YES
13 YES
8 YES
14 YES
16 YES
15 YES
SEQUENCE# APPLIED
---------- ---------
17 YES
18 YES
19 YES
20 NO
21 NO
22 NO
SQL> alter database recover managed standby database finish force; ---failover 使用
数据库已更改。
SQL> select sequence#, applied from v$archived_log;
SEQUENCE# APPLIED
---------- ---------
6 YES
7 YES
9 YES
10 YES
11 YES
12 YES
13 YES
8 YES
14 YES
16 YES
15 YES
SEQUENCE# APPLIED
---------- ---------
17 YES
18 YES
19 YES
20 YES
21 YES
22 YES
已选择17行。
SQL> select switchover_status from v$database;
SWITCHOVER_STATUS
--------------------
TO PRIMARY
--归档也应用了,状态也改变了
SQL> alter database commit to switchover to primary;
数据库已更改。
--成功切换
SQL> select protection_mode,database_role,protection_level from v$database;
PROTECTION_MODE DATABASE_ROLE PROTECTION_LEVEL
-------------------- ---------------- --------------------
MAXIMUM PERFORMANCE PRIMARY UNPROTECTED
SQL> alter database open;
数据库已更改。
在主库中查看第二存档终点是否有异常:
col dest_name for a30
col error for a20
select dest_name,status,error,target,process from v$archive_dest where substr(dest_name,-1) in (1,2);
注:
误在dg备库上执行了:
alter database recover managed standby database finish;(只有在failover时使用)
导致无法归档,上述语句只有在failover情况下使用,用来保障数据安全,之后备库要以primary启动。
报错:ORA-16143:终端恢复过程中或之后不允许进行 RFS 连接
恢复方法:
1.重建备库(所有问题的统一解决方法^_^)
2.从主库重建一份控制文件
然后覆盖备系统控制文件。
重新启动备库,ok。
--------------------------------------------------------------------------------------------------------------------------------
最高可用的物理standby
主库日志传输模式级别要更细致:
redo条目级别 网络同步 i/o同步
LGWR SYNC AFFIRM
SQL> alter system set log_archive_dest_2='SERVICE=dg1 LGWR ASYNC affirm VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=dg1';
在最大可用的物理standby要拥有自己的联机日志:接收主库传送过来的redo条目
alter database add standby logfile 'D:\ORACLE\ORADATA\DG2\ONLINELOG\redo05.log' size 50m;
alter database add standby logfile 'D:\ORACLE\ORADATA\DG2\ONLINELOG\redo06.log' size 50m;
alter database add standby logfile 'D:\ORACLE\ORADATA\DG2\ONLINELOG\redo07.log' size 50m;
alter database add standby logfile 'D:\ORACLE\ORADATA\DG2\ONLINELOG\redo08.log' size 50m;
从库要拥有归档路径:
当数据库角色为standby,联机日志类型为standby时使用log_archive_dest_3指向的路径保存归档
alter system set log_archive_dest_3='location=D:\oracle\oradata\DG1\arch\ valid_for=(STANDBY_LOGFILES,STANDBY_ROLE) db_unique_name=dg1';
将数据库转换为最高可用模式(主库):
shutdown immediate
startup mount
alter database set standby database to maximize availability;
alter database open;
查看数据库保护模式:
select protection_mode,database_role,protection_level from v$database;
--------------------------------------------------------------------------------------------------------
在Oracle 11g里,Data Guard 切换多了一个新的功能:flush redo。
Flush 能把没有发送的redo 从主库传送到standby库。
只要主库能启动到mount 状态,那么Flush 就可以把没有发送的归档和current online redo 发送到备库。
Flush语法:
SQL> ALTER SYSTEM FLUSH REDO TO 'target_db_name';
这里的target_db_name 是我们在备库的db_unique_name 名称。 Flush 会将未发送的redo 从主库传到备库,并且等待redo在standby 库上apply 之后返回成功。 所以只要Flush成功,那么Failover 就没有数据丢失。
--------------------------------------------------------------------------------------------------------
准备转换角色:(由物理到逻辑)
从库中停止管理恢复进程
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;
在主库中创建logical standby需要的数据字典
EXECUTE DBMS_LOGSTDBY.BUILD; --可能会01555
主库做一次归档,使字典信息能传送到从库
alter system switch logfile;
--alter system archive log current;
备库执行:
物理standby转逻辑standby:
alter database recover to logical standby db_name; --指定数据库名称,可以和主库不同
重新启动从库(resetlogs)
shutdown immediate
startup mount
alter database open resetlogs;
启动sql apply
alter database start logical standby apply;
为从库添加standby redo logfile
alter database add standby logfile 'D:\ORACLE\ORADATA\DG2\ONLINELOG\redo05.log' size 50m;
alter database add standby logfile 'D:\ORACLE\ORADATA\DG2\ONLINELOG\redo06.log' size 50m;
alter database add standby logfile 'D:\ORACLE\ORADATA\DG2\ONLINELOG\redo07.log' size 50m;
alter database add standby logfile 'D:\ORACLE\ORADATA\DG2\ONLINELOG\redo08.log' size 50m;
启动real time sql apply(日志实时应用)
alter database stop logical standby apply;
alter database start logical standby apply immediate;
查看逻辑standby操作日志:(只保留100条操作)
select event_time,status,event from dba_logstdby_events;
查看日志应用情况:
select sequence#,first_change#,next_change#,timestamp,applied from dba_logstdby_log;
停止sql应用:
alter database stop logical standbyapply;
--------------------------------------------------------------------------------------------------------
监控逻辑standby
与物理standby 的管理一样,oracle 提供了一系列动态性能视图来查看逻辑standby 的状态,有一些我们前面已经接触过,而有一些,我们还从未用过。
1、DBA_LOGSTDBY_EVENTS
可以把该视图看成逻辑standby 操作日志,因此如果发生了错误,可以通过该视图查看近期逻辑standby都做了些什么。默认情况下, 该视图保留100 条事件的记录, 不过你可以通过DBMS_LOGSTDBY.APPLY_SET()过程修改该参数。
例如:
JSSLDG2> select event_time,status,event from dba_logstdby_events;
EVENT_TIME STATUS EVENT
------------------- ----------------------------------------- ----------------------------------------
2008-03-06 08:58:11 ORA-16112: 日志挖掘和应用正在停止
2008-03-06 09:02:00 ORA-16111: 日志挖掘和应用正在启动
2008-03-06 09:52:53 ORA-16128: 已成功完成用户启动的停止应用操作
2008-03-12 15:52:53 ORA-16111: 日志挖掘和应用正在启动
2008-03-12 16:09:17 ORA-16226: 由于不支持而跳过DDL ALTER DATABASEOPEN
2008-03-05 17:21:46 ORA-16111: 日志挖掘和应用正在启动
..............................
2、DBA_LOGSTDBY_LOG
该视图用来记录当前的归档日志应用情况,等同于物理standby 中的v$archived_log,多数情况下,你只需要关注SEQUENCE#,APPLIED,即查看日志序号和是否应用,当然该视图还能提供更多信息,比如应用的scn,应用时间等,例如:
JSSLDG2> select sequence#,first_change#,next_change#,timestamp,applied from dba_logstdby_log;
SEQUENCE# FIRST_CHANGE# NEXT_CHANGE# TIMESTAMP APPLIED
---------- ------------- ------------ ------------------- --------
869 1319212 1319811 2008-03-12 16:09:15 CURRENT
通常情况下,该查询只会返回几条记录,如果说你的数据库操作非常频繁,可能记录数会稍多一些,但如果记录数非常多,那你可能就需要关注一下,是不是出了什么问题,难道sql 应用没有启动?
3、V$LOGSTDBY_STATS
从名字就大致猜的出来,该视图显示的是状态信息,没错,你猜对了,该视图就是用来显示LogMiner的统计信息及状态。
JSSLDG2> select *from v$logstdby_stats;
NAME VALUE
---------------------------------------- ---------------
number of preparers 1
number of appliers 5
maximum SGA for LCR cache 30
parallel servers in use 9
maximum events recorded 100
preserve commit order TRUE
transaction consistency FULL
record skip errors Y
record skip DDL Y
record applied DDL N
.........................
4、V$PROCESV$LOGSTDBY_PROCESS
该视图显示当前log 应用服务的相关信息。常用于诊断归档日志逻辑应用的性能问题(后面优化部分会有涉及),包含的信息也很广:
※ 身份信息:SID,SERIAL#,SPID
※ SQL 应用进程:COORDINATOR, READER, BUILDER, PREPARER, ANALYZER, 或APPLIER
※ 进程当前的状态:见status_code 或status 列
※ 该进程当前操作redo 记录最大SCN:high_scn 列
例如:
JSSLDG2> select sid,serial#,spid,type,status,high_scn from v$logstdby_process;
SID SERIAL# SPID TYPE STATUS HIGH_SCN
-------- ------- -------- --------------- ----------------------------------------------- ----------
145 1 508 COORDINATOR ORA-16116: 无可用工作 1319811
146 2 2464 READER ORA-16240: 正在等待日志文件(线程号1,序列号870) 1319811
143 1 1512 BUILDER ORA-16116: 无可用工作 1319742
142 1 4000 PREPARER ORA-16116: 无可用工作 1319741
139 1 2980 ANALYZER ORA-16116: 无可用工作 1319707
135 1 1648 APPLIER ORA-16116: 无可用工作 1319430
138 1 2332 APPLIER ORA-16116: 无可用工作 1319439
132 1 2200 APPLIER ORA-16116: 无可用工作 1319443
134 1 4020 APPLIER ORA-16116: 无可用工作
...........................................
5、V$PROGRESV$LOGSTDBY_PROGRESS
该视图显示log 应用服务当前进展状况,比如当前应用到逻辑standby 的scn 及时间,sql 应用开始应用的scn 及时间,最后接收及应用的scn 和时间等等。
例如:
JSSLDG2> select * from v$Logstdby_progress;
APPLIED_SCN APPLIED_TIME RESTART_SCN RESTART_TIME LATEST_SCNLATEST_TIME MINING_SCN MINING_TIME
----------- ------------------- ----------- ------------------- ---------- ------------------- ---------- -------------------
1319810 2008-03-12 16:06:51 1319662 2008-03-12 16:03:22 1319810 2008-03-12 16:45:331319811 2008-03-12 16:06:51
6、V$LOGSTDBY_STATE
该视图就最简单了,就是显示sql 应用的大致状态,比如primary 库的dbid 啦,是否启动了实时应用啦,当前sql 应用的状态啦之类。
注意state 列,该列可能有下述的几种状态:
※ INITIALIZING: LogMiner session 已创建并初始化
※ LOADING DICTIONARY: SQL 应用调用LogMiner 字典
※ WAITING ON GAP: SQL 应用正等待日志文件,可能有中断
※ APPLYING: SQL 应用正在工作
※ WAITING FOR DICTIONARY LOGS: SQL 应用等待LogMiner 字典信息
※ IDLE: SQL 应用工作非常出色,已经干的没什么可干了:)
例如:
JSSLDG2> select * from v$Logstdby_state;
PRIMARY_DBID SESSION_ID REALTIME_APPLY STATE
------------ ---------- -------------------- ----------------------
3408827880 42 Y APPLYING
--------------------------------------------------------------------------------------------------------
逻辑standby 一个极具实用价值的特性即是可以边查询边应用,因此将其做为报表服务器专供查询是个很不错的想法,而且逻辑standby 相对于物理standby 而言更具灵活性,比如我们可以在逻辑standby上,对一些表创建primary 库上并不方便创建的索引,约束,甚至可以做dml,ddl 操作(当然,需要注意不要破坏了与primary 之间同步的逻辑关系)。不过由于此时dg 仍然控制着对逻辑standby 表的读写操作,因此,如果你想对逻辑standby 中的数据做些什么的话,alter session database disable|enable guard 语句就必须牢记在心了,它拥有像“芝麻开门”一样神奇的能力,不信?下面我们就来感受一下吧。
1、逻辑standby端执行ddl
在逻辑standby 端开始了redo 应用的情况下,执行ddl 操作:
JSSLDG2> create table tmp55 as select * From b;
create table tmp55 as select * From b
*
第1 行出现错误:
ORA-01031: 权限不足
看看,出错了吧~~~
JSSLDG2> alter session disable guard;
会话已更改。
JSSLDG2> create table tmp55 as select * From b;
表已创建。
只有关闭了guard 保护之后,才能操作数据,然后别忘了再启用guard,以避免不经意的操作对逻辑standby 的配置造成影响。
JSSLDG2> alter session enable guard;
会话已更改。
提示:oracle 建议还是尽可能不要在逻辑standby 执行执行dml 之类操作,以免破解其与primary 之间同步的逻辑关系,当然,这只是个建议,如果你数据库表结构及存储结构了如指掌,那您就爱干嘛干嘛。
2、取消对象同步
如果说,某些表或者数据不需要dataguard 保护(比如一些在逻辑standby 端生成的统计表),这个时候就需要DBMS_LOGSTDBY.SKIP,前头已经介绍过了dbms_logstdby.skip 的基本用法,下面我们来具体演示一下!
下面我们假设standby 端有一批表名为tmp 开头的表,这张表不再需要保持与primary 的同步,那么按照步骤执行下列语句,sql 应用即可跳过这些表:
老规矩,先停了redo 应用
JSSLDG2> alter database stop logical standby apply;
数据库已更改。
JSSLDG2> executexecute dbms_logstdby.skip('SCHEMA_DDL','JSS','TMP%'); --跳过对象的ddl 操作
PL/SQL 过程已成功完成。
JSSLDG2> executedbms_logstdby.skip('DML','JSS','TMP%'); --跳过对象的dml 操作
PL/SQL 过程已成功完成。
JSSLDG2> ALTER DATABASE START LOGICAL STANDBY APPLY IMMEDIATE;
数据库已更改。
注意其中的%,该符号为通配符,作用与在sql 语句中的相同。
OK,下面来测试一下,先看看逻辑standby 中表的信息,我们选择两张表,一张是我们前面已经指定了跳过的表tmp1,另一张是普通表b:
JSSLDG2> select max(aa) from jss.tmp1;
Max(aa)
--------------------
h
JSSLDG2> select max(id) from jss.b;
Max(id)
----------
9
JSSLDG2> select sequence#,applied from dba_logstdby_log;
SEQUENCE# APPLIED
---------- --------
872 YES
然后在primary 数据库执行插入操作
JSSWEB> select max(aa) from jss.tmp1;
Max(aa)
--------------------
h
JSSWEB> insert into jss.tmp1 values ('i');
已创建1 行。
JSSWEB> insert into jss.b values (10);
已创建1 行。
JSSWEB> commit;
提交完成。
JSSWEB> alter system switch logfile;
系统已更改。
JSSWEB> select max(sequence#) from v$archived_log;
MAX(SEQUENCE#)
--------------
873
再来看看逻辑standby 端的同步情况:
JSSLDG2> select sequence#,applied from dba_logstdby_log;
SEQUENCE# APPLIED
---------- --------
873 YES
显然日志已经接收,再看看数据:
JSSLDG2> select max(id) from b;
Max(id)
----------
10
JSSLDG2> select max(aa) from jss.tmp1;
Max(aa)
--------------------
h
b 表已应用,而tmp1 表则无变化。
3、恢复对象同步
如果说某些表某个时候取消了同步,现在希望再恢复同步,没问题,DBMS_LOGSTDBY 家大业大,它还有个叫UNSKIP 的门生就是专干这个的。
我们来看一下dbms_logstdby.unskip 的语法:
DBMS_LOGSTDBY.UNSKIP (
stmt IN VARCHAR2,
schema_name IN VARCHAR2,
object_name IN VARCHAR2);
三项均为必选参数,各参数的定义与skip 过程相同,这里不再复述。
此处我们来演示恢复tmp%表的同步。
JSSLDG2> select *from dba_logstdby_skip;
ERROR STATEMENT_OPT OWNER NAME U E PROC
----- --------------- ---------- --------------- - - --------------------
N SCHEMA_DDL JSS TMP% Y
N DML JSS TMP% Y
N DML JSS TMP1 Y
........
JSSLDG2> alter database stop logical standby apply;
数据库已更改。
JSSLDG2> execute dbms_logstdby.unskip('DML','JSS','TMP1'); --本步操作是为解决历史遗留问题,不用关注
PL/SQL 过程已成功完成。
JSSLDG2> executexecute dbms_logstdby.unskip('DML','JSS','TMP%');
PL/SQL 过程已成功完成。
JSSLDG2> execute
dbms_logstdby.unskip('SCHEMA_DDL','JSS','TMP%');
PL/SQL 过程已成功完成。
跳过同步已经取消了,紧接着我们需要再调用dbms_logstdby.instantiate_table 过程重新同步一下跳地的对象,将skip 这段时间,primary 对tmp1 表所做的操作同步过来(就俺看来,instantiate_table 过程实际上是借助dblink 重建了一遍对象),以保持与primary 的一致。Dbms_logstdby.instantiate_table 的语法如下:
DBMS_LOGSTDBY.INSTANTIATE_TABLE (
schema_name IN VARCHAR2,
table_name IN VARCHAR2,
dblink IN VARCHAR2);
使用DBMS_LOGSTDBY.INSTANTIATE_TABLE 过程重新执行一下同步(执行前别忘了暂停redo 应用):
JSSLDG2> EXECUTE DBMS_LOGSTDBY.INSTANTIATE_TABLE('JSS','TMP1','GETJSSWEB');
PL/SQL 过程已成功完成。
JSSLDG2> select *from jss.tmp1;
AA
--------------------
a
b
c
d
e
f
g
h
i
已选择9 行。
数据已重建,下面测试一下该表的redo 应用是否恢复了。
JSSWEB> insert into jss.tmp1 values ('j');
已创建1 行。
JSSWEB> insert into jss.tmp1 values ('k');
已创建1 行。
JSSWEB> commit;
提交完成。
JSSWEB> alter system switch logfile;
系统已更改。
JSSWEB> select max(sequence#) from v$archived_log;
MAX(SEQUENCE#)
--------------
877
启动逻辑standby 端的redo 应用,看看对象的应用情况:
JSSLDG2> alter database start logical standby apply immediate;
数据库已更改。
JSSLDG2> select sequence#,applied from dba_logstdby_log;
SEQUENCE# APPLIED
---------- --------
875 YES
876 YES
877 YES
JSSLDG2> select *from jss.tmp1;
AA
--------------------
a
b
c
d
e
f
g
h
i
j
k
已选择11 行。
OK,恢复正常啦!
注意哟,此处我们清楚明白的知道我们之前只操作了tmp1 一张表,如果是正式应用的话,那你恐怕有必要将所有tmp 开头的表都同步一下,不然有可能会造成数据丢失的哟。
四、特殊事件的控制
1、导入传输表空间
※ 第一步:屏蔽guard 保护,逻辑standby 端操作
SQL> ALTER SESSION DISABLE GUARD;
※ 第二步:导入传输表空间,逻辑standby 端操作
具体操作步骤可参考三思之前的笔记:使用可传输表空间的特性复制数据!
※ 第三步:恢复guard 保护(或者直接退出本session 也成),逻辑standby 端操作
SQL> ALTER SESSION ENABLE GUARD;
※ 第四步:导入传输表空间,primary 端操作
同第二步。
2、使用物化视图
SQL 应用不支持下列对物化视图的ddl 操作:
※ create/alter/drop materialized view
※ create/alter/drop materialized view log
因此,对于现有逻辑standby,primary 端对物化视图的操作不会传播到standby 端。不过,对于primary创建物化视图之后创建逻辑standby,则物理视图也会存在于逻辑standby 端。
※ 对于同时存在于primary 和逻辑standby 的ON-COMMIT 物化视图,逻辑standby 会在事务提交时自动刷新,而对于ON-DEMAND 的物化视图不会自动刷新,需要手动调用dbms_mview.refresh 过程刷新。
※ 对于逻辑standby 端建立的ON-COMMIT 物化视图会自动维护,ON-DEMAND 物化视图也还是需要手工调用dbms_mview.refresh 过程刷新。
3、触发器及约束的运作方式
默认情况下,约束和触发器同样会在逻辑standby 端正常工作。
对于有sql 应用维护的约束和触发器:
※ 约束:由于约束在primary 已经检查过,因此standby 端不需要再次检查
※ 触发器:primary 端操作时结果被记录,在standby 端直接被应用。
没有sql 应用维护的约束和触发器:
※ 约束有效
※ 触发器有效
---------------------------------- ---------------------------------- ---------------------------------- -------------------------------
优化逻辑standbstandby
1、创建PrimaryKeyRELY约束
某些情况下能够有效提高sql 应用效率,具体可参见第三部分第一章。
2、生成统计信息
这个很容易理解嘛,因为cbo 要用,生成方式即可用analyze,也可以用dbms_stats 包。看你个人喜好了。
3、调整进程数
A).调整APPLIER进程数
首先查看当前空闲的applier 进程数:
JSSLDG2> SELECT COUNT(*) AS IDLE_APPLIER FROM V$LOGSTDBY_PROCESS
2 WHERE TYPE = 'APPLIER' and status_code = 16166;
IDLE_APPLIER
------------
0
提示:
status_code = 16166 表示进程是空闲状态,可以看到"STATS"为"ORA-16116: no work available",当然空闲的applier 进程数为0 不一定代表应用应用非常繁忙,也有可能是因为当前没什么需要应用的日志,因此甚至应用进程都没启动:)
检查事务的应用情况:
JSSLDG2> select name,value from v$logstdby_stats where name like 'TRANSACTION%';
NAME VALUE
--------------------- -------
transactions ready 896
transactions applied 871
如果ready-applied 的值比applier 进程数的两倍还要大,则说明你有必要考虑增加applier 进程的数目了,反之如果applied 与ready 的值差不多大,或者其差比applier 进程数还小,则说明applier 进程数偏多,你有必要考虑适当减小进程的数目。
如果确认当前applier 进程都非常繁忙,要增加applier 进程,可按如下步骤操作:
停止sql 应用
ALTER DATABASE STOP LOGICAL STANDBY APPLY;
调整applier 进程数为20,默认是5 个
EXECUTE DBMS_LOGSTDBY.APPLY_SET('APPLY_SERVERS', 20);
重启sql 应用
ALTER DATABASE START LOGICAL STANDBYAPPLY IMMEDIATE;
B).调整PREPARER进程数
需要调整preparer 进程数的机会不多,通常只有一种情况:applier 进程有空闲,transactions ready 还很多,但没有空闲的preparer 进程,这时候你可能需要增加一些preparer 进程。
要检查系统是否存在这种情况,可以通过下列的sql 语句:
首先检查空闲preparer 进程数量:
SELECT COUNT(*) AS IDLE_PREPARER FROM V$LOGSTDBY_PROCESS WHERE TYPE ='PREPARER' and status_code = 16166;
检查事务的应用情况:
select name,value from v$logstdby_stats where name like 'TRANSACTION%';
查看当前空闲的applier 进程数:
SELECT COUNT(*) AS IDLE_APPLIER FROM V$LOGSTDBY_PROCESS WHERE TYPE = 'APPLIER'and status_code = 16166;
如果确实需要调整preparer 进程数量,可以按照下列步骤,例如:
停止sql 应用
ALTER DATABASE STOP LOGICAL STANDBY APPLY;
调整preparer 进程数量为4(默认只有1 个preparer 进程)
EXECUTE DBMS_LOGSTDBY.APPLY_SET('PREPARE_SERVERS', 4);
重启sql 应用
ALTER DATABASE START LOGICAL STANDBYAPPLY IMMEDIATE;
4、调整LCR使用的内存
执行下列语句,查询当前LCR 可用的最大内存:
JSSLDG2> select * from v$logstdby_stats where name='maximum SGA for LCR cache';
NAME VALUE
------------------------------------ --------------------
maximum SGA for LCR cache 30
要增加LCR 可用的内存,按照下列步骤操作:
停止sql 应用:
JSSLDG2> alter database stop logical standby apply;
数据库已更改。
调整内存大小,注意默认单位是M:
JSSLDG2> execute dbms_logstdby.apply_set('MAX_SGA',100);
PL/SQL 过程已成功完成。
重启sql 应用
JSSLDG2> alter database start logical standby apply immediate;
数据库已更改。
5、调整事务应用方式
默认情况下逻辑standby 端事务应用顺序与primary 端提交顺序相同。
如果你希望逻辑standby 端的事务应用不要按照顺序的话,可以按照下列的步骤操作:
① 停止 sql 应用 :
SQL> ALTER DATABASE STOP LOGICAL STANDBYAPPLY;
② 允许事务不按照 primary 的提交顺序应用
SQL> EXECUTE DBMS_LOGSTDBY.APPLY_SET('PRESERVE_COMMIT_ORDER', 'FALSE');
③ 重新启动 sql 应用
SQL> ALTER DATABASE START LOGICAL STANDBYAPPLY IMMEDIATE;
恢复逻辑standby 按照事务提交顺序应用的话,按照下列步骤:
① 还是先停止 sql 应用:
SQL> ALTER DATABASE STOP LOGICAL STANDBYAPPLY;
② 重置参数 PRESERVE_COMMIT_ORDER 的初始值:
SQL> EXECUTE DBMS_LOGSTDBY.APPLY_UNSET('PRESERVE_COMMIT_ORDER');
③ 重新启动 sql 应用:
SQL> ALTER DATABASE START LOGICAL STANDBYAPPLY IMMEDIATE;
- 单机搭建oracle dg 实验与总结
- Oracle 12C DG 搭建(RAC-RAC/RAC-单机)
- 12c-单机Data Guard搭建--oracle DG
- oracle DG搭建
- Oracle DG broker搭建
- Oracle DG -Data Guard 搭建
- oracle 11g DG 搭建
- oracle DG模式搭建详解
- 实验DG Far Sync的搭建过程
- [oracle]Oracle 11g 逻辑DG搭建
- Oracle开机自启动到mount(DG单机目标端)
- DG实验
- DG实验
- Oracle之DataGurd(DG)环境搭建
- oracle DG搭建(使用DGbroker)
- ORACLE之搭建DG(ADG方式)
- ORACLE之搭建DG(ADG方式)
- Oracle之DataGurd(DG)环境搭建
- mini edit distance & minimum cost alignment
- Dex文件结构
- 把妹之道于品牌营销“精屁”
- java数据有效性检验的一些想法
- 迅雷安装脚本
- 单机搭建oracle dg 实验与总结
- SQL 中详解round(),floor(),ceiling()函数的用法和区别?
- 更改NavigationController的背景图片
- JUnit 4的参数化测试
- Count total set bits in all numbers from 1 to n
- Android 源代码在线查看
- 网页提示证书过期的时候,可能是因为系统时间不对造成的。
- 在cocos2d 1.0里面 如何描画图片的一部分. 实现j2me里面的setClip
- 暗暗