oracle dataguard 安装配置手册
一、前言:
网络上关于dataguard的配置文章很多,但是很多打着oracle11g的文章实际都是只能在9 10 上运行,比如FAL_CLIENT在11g中已经废弃,但是现在网络上的文章都是没有标注这一点。而且对于具体含义语焉不详对于新手只能知其然而不知其所以然。这篇文章我就想让像我这样的人对于dataguard配置不仅仅知道怎么配置,还要知道为什么需要这样配置,这样的效果才是最好的。
这篇文章不仅仅是记录如何配置,还介绍了为什么是这样,以及注意要点,我希望这个文章可以作为进行dataguard配置的一个参考手册。
二、前提
1.主库是归档模式:
如果我们不清楚为什么是归档模式,那我们就应该也不会清楚dataguard是用来做什么的。透过很多修饰的官方语言,我们需要明确DG(dataguard简称,后同)实际上的作用就是用来高可用。而实现原理就是从主库获取数据到从库,在主库发生异常的时候,从库接管主库,完成身份的变化。可以一个主库,最多9个从库。同时分为逻辑standby和物理standby这里我们讨论的是物理standby.
一旦创建并配置成 standby 后,dg 负责传输 primary数据库 redo data 到 standby 数据库,standby 数据库通过应用接收到的 redo data 保持与 primary 数据库的事务一致。
这下清楚了吧,需要保证主从库一致,需要传输archive log和redo log到从库,如果不是归档模式无法保证主从库的数据一致。
2.从库只需要安装数据库软件,数据从主库传输后完成。
3.很多人说11g有了active dataguard(ADG),逻辑standby 实际上已经没什么用处了。
4.主从库硬件最好一致。oracle数据库版本需要一致。
(1)内存检查项:
# grep MemTotal /proc/meminfo
交换分区检查项:如果内存在1-2G,swap是1.5倍;2-16G,1倍;超过16G,设置为16G即可。
# grep SwapTotal /proc/meminfo
查看共享内存大小:
# df -h /dev/shm
(2)查看系统处理器架构,与oracle安装包一致
# uname -m
(3)空间空间 /tmp必须大于1G
# df -h /tmp
5.配置环境数据库用户必须有sysdba权限
6.后面的环境:主库 192.168.215.101 数据库实例名:orcl db_unique_name:orcl
从库 192.168.215.102 数据库实例名:orcl db_unique_name:orcldg
三、配置
1.判断DG是否已经安装:
select * from v$option where parameter = 'Oracle Data Guard';
如果是true表示已经安装可以配置,否则需要安装相应组件。
2.设置主库为强制记录日志。
默认情况下数据库操作会记录redo log,但是在一些特定的情况下可以使用nologging来不生成redo信息
(1)表的批量INSERT(通过/*+APPEND */提示使用“直接路径插入“。或采用SQL*Loader直接路径加载)。表数据不生成redo,但是
所有索引修改会生成redo,但是所有索引修改会生成redo(尽管表不生成日志,但这个表上的索引却会生成redo!)。
(2)LOB操作(对大对象的更新不必生成日志)。
(3)通过CREATE TABLE AS SELECT创建表
(4)各种ALTER TABLE操作,如MOVE和SPLIT
(5)在一些表迁移和表空间迁移中,可以使用alter table a nologging;或者alter tablespace snk nologging;在操作完成后再修改回logging状态。
这里需要多说一句,如果你使用nologging导入大批量数据,以后对这些数据的修改会在redo或者archive log中,但是基准的数据是没有的,所以一旦介质损坏是无法完全恢复的,必须在使用nologging完成切换回logging后,做一次全备或者0级备份。
(1)强制记录日志:sql>alter database force logging;
(2)检查状态(YEs为强制):sql>select name,force_logging from v$database;
(3)如果需要在主库添加或者删除数据文件时,这些文件也会在备份添加或删除,使用如下:
sql>alter system set standy_file_management='AUTO';
默认此参数是manual手工方式 sql>show parameter standby
3.创建standby log files(备用日志文件)
从库使用standby log files来保存从主库接收到的重做日志。既然主要是从库在使用,那为什么需要在主库上也建立
standby log files?原因主要由两个:一是主库可能转换为备库,而备库是需要有standby log files的 二是如果主库
建立了standby log files那备库会自动建立。
建立standby如要注意以下几点:
<1>standby log files的大小和redo log files一样。
查询redo log files文件大小(默认50M,3个):select group#,bytes/1024/1024 as M from v$log
<2>一般而言, standbyredo 日志文件组数要比 primary 数据库的 online redo 日志文件组数至少多一个。
推荐 standbyredo 日志组数量基于 primary 数据库的线程数(这里的线程数可以理解为 rac 结构中的 rac
节点数)。
有一个推荐的公式可以做参考:(每线程的日志组数+1)*最大线程数
假设现在节点是1个,则=(3+1)*1=4
如果是双节点 则=(3+1)*2=8
这里我们创建4个standby logfile:
另:不建议组号group#紧挨着redo,因为后续redo有可能调整,这里我们从建立从11到14的standby logfile
1
2
3
4
5
6
7
8
# cd $ORACLE_BASE/oradata/orcl/
# mkdir dg
# chown oracle:dba dg
sql> alter database add standby logfile group 11 '/opt/oracle/oradata/orcl/dg/standby11.log' size 50M;
sql> alter database add standby logfile group 12 '/opt/oracle/oradata/orcl/dg/standby12.log' size 50M;
sql> alter database add standby logfile group 13 '/opt/oracle/oradata/orcl/dg/standby13.log' size 50M;
sql> alter database add standby logfile group 14 '/opt/oracle/oradata/orcl/dg/standby14.log' size 50M;
4.密码文件和控制文件的创建传输
(1)一般数据库默认就有密码文件,存放在$ORACLE_HOME/dbs/orapwSID 这里为orapworcl
如果没有sql>orapwd file=$ORACLE_HOME/dbs/orapworcl password=oracle
(2)检查REMOTE_LOGIN_PASSWORDFILE值是否为 EXCLUSIVE
sql>show parameter REMOTE_LOGIN_PASSWORDFILE
如果值不是EXCLUSIVE,则:alter system set remote_login_passwordfile=exclusive scope=spfile;
(3)密码文件需要scp到从库
# scp orapworcl oracle@192.168.215.102:/opt/oracle/11.2/dbs 提示输入yes
(4)控制文件:
11g的控制文件一共两份,内容一样,一份在$ORACLE_BASE/oradata/orcl/control01.ctl
一份在/opt/oracle/flash_recovery_area/orcl/control02.ctl
生成standby控制文件:
1
2
3
4
sql>shutdown immediate
sql>startup mount
sql>alter database create standby controlfile as '/tmp/standby_control01.ctl';
sql>startup open;
然后在备库建立对应的目录,并授权
mkdir orcl--- chown oracle:oinstall(或dba) orcl
scp control01.ctl oracle@192.168.215.102:/opt/oracle/oradata/orcl
scp control02.ctl oracle@192.168.215.102:/opt/oracle/flash_recovery_area/orcl/
5.db_name和db_unique_name
默认db_name和db_unique_name和实例名是一致的,这里是orcl
需要注意在DG中主库和从库的db_unique_name是不能一致的,需要区分开的。
这里我们设置主库的db_unique_name为orcl,从库为orcldg
sql>show parameter db_unique_name
设置:alter system set db_unique_name=orcl scope=spfile;
--注意虽然默认db_unique_name和db_name是一致的,但是需要显式设置,否则在spfile中没有此参数
6.闪回数据库:
强烈建议开启数据库闪回功能。闪回允许你将数据库还原到以前的某一时间点。当发生故障转移时,这个功能非常有用,
它能让你将老的主库闪回到故障前,然后将其转换为备库。如果没有启用闪回功能,你就必须重建备库,意味着要再复制一次数据文件。
除了这个好处,闪回还能在某些情况下让你避免从备份恢复数据。
(1)快速恢复区(Flash/Fast Recovery Area),默认是配置的,但是需要确认这个区域的磁盘够大,至少300G以上(默认3G)
sql>show parameter db_recovery_file_dest
可以修改位置:sql>alter system set db_recovery_file_dest='新路径';
更改大小:sql>alter system set db_recovery_file_dest_size=400G;
(2)查看是否启用,默认是不开启的
sql>select flashback_on from v$database;
开启:sql>alter database flashback on;
如果你碰到 ORA-01153 报错,那一定是在备库进行此操作。你需要先取消重做日志应用,启用闪回日志,然后重新启用日志应用。
在主库启用闪回日志,不会同步备库也启用。你必须手动在主库和备库上均启用闪回日志。
如果不启用闪回日志,当出现故障转移时,你将需要完全重新开始创建一个备库。
7.SQL*NET设置
(1)配置主库的监听
虽然可以通过netca来进行配置,但是除了这个默认的外,我们还需要一个静态注册SID_LIST_LISTENER,如果没有此从参数而且
dataguard启动顺序不正确,主库会报PING[ARC1]:Heartbeat failed to connect to standby '***'.Error is 12514导致归档无法完成
配置如下
SID_LIST_LISTENER=
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = orcl)
(ORACLE_HOME = /opt/oracle/11.2)
(SID_NAME = orcl)
)
)
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = primaryDB)(PORT = 1521))
)
)
#vi $ORACLE_HOME/network/admin/listener.ora 加入上面的内容
(2)配置tnsnames
#vi $ORACLE_HOME/network/admin/tnsnames.ora
ORCL =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.215.101)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = orcl)
)
)
ORCLDG =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.215.102)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = orcldg)
)
)
(3)传输到备库并修改listener.ora和tnsnames.ora
scp $ORACLE_HOME/network/admin/listener.ora oracle@192.168.215.102:/opt/oracle/11.2/network/admin/
scp $ORACLE_HOME/network/admin/tnsnames.ora oracle@192.168.215.102:/opt/oracle/11.2/network/admin/
--listener.ora:
SID_LIST_LISTENER
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = orcldg)
(ORACLE_HOME = /opt/oracle/11.2)
(SID_NAME = orcl)
)
)
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = standbyDB)(PORT = 1521))
)
)
tnsnames.ora:不需要修改
8.重做日志传输配置
(1)配置归档日志位置:
查询已经设置的归档路径sql:archive log list或者show parameter log_archive_dest_1
sql> alter system set log_archive_dest_1='LOCATION=/opt/oracle/oradata/orcl/archive1 valid_for=(all_logfiles,primary_role) db_unique_name=orcl' scope=spfile;
还可以使用快速恢复区作为归档目录,如LOCATION=use_db_recovery_file_dest
官方文档里说使用 valid_for=(online_logfiles, all_roles),这将导致备库无法归档备用日志文件,因为它们不是在线日志。
但如果使用 all_logfiles 选项,主备库将都能归档在线以及备用日志。
如果你想在备库进行备份,并同时备份归档日志的话,必须使用 all_logfiles。
(2)配置重做日志到备份库:
sql>alter system set log_archive_dest_2='SERVICE=orcldg lgwr sync valid_for=(online_logfile,primary_role)
db_unique_name=orcldg';
(3)要注意STANDBY_ARCHIVE_DEST 参数不需要,已经被官方弃用。设置此参数后启动数据库,只会报 ORA-32004:
obsolete or deprecated parameter(s) specified for RDBMS instance 错。
9.配置FAL_SERVER
这个参数指定当日志传输出现问题时,备库到哪里去找缺少的归档日志。它用在备库接收的到的重做日志间有缺口的时候。
这种情况会发生在日志传输出现中断时,比如你需要对备库进行维护操作。在备库维护期间,没有日志传输过来,这时缺口就出现了。
设置了这个参数,备库就会主动去寻找那些缺少的日志,并要求主库进行传输。
你是主库,就填写:
fal_server=从库
从库上就反过来:
fal_server=主库
注意:FAL_CLIENT在11g中已经废弃,虽然可以配置但是已经不起作用了。
sql>alter system set FAL_SERVER='orcldg';
10.Data Guard 配置里的另外一个库的名字
sql> alter system set log_archive_config = 'dg_config=(orcl,orcldg)';
以上的办法是我们采用alter system的方式在线修改,还有一种比较方便的办法(但是容易出错,所以方便和安全什么时候都不可兼得)
sql>create pfile from spfile;
# 手工修改pfile
sql>create spfile from pfile;
然后用pfile生成spfile 同时传输pfile到从库修改后生成spfile
注意手工增加:
*.log_archive_dest_state_1=enable
*.log_archive_dest_state_2=enable
vi initorcl.ora
orcl.__db_cache_size=180355072
orcl.__java_pool_size=4194304
orcl.__large_pool_size=4194304
orcl.__oracle_base='/opt/oracle'#ORACLE_BASE set from environment
orcl.__pga_aggregate_target=264241152
orcl.__sga_target=494927872
orcl.__shared_io_pool_size=0
orcl.__shared_pool_size=289406976
orcl.__streams_pool_size=8388608
*.audit_file_dest='/opt/oracle/admin/orcl/adump'
*.audit_trail='db'
*.compatible='11.2.0.0.0'
*.control_files='/opt/oracle/oradata/orcl/control01.ctl','/opt/oracle/flash_recovery_area/orcl/control02.ctl'#Restore Controlfile
*.db_block_size=8192
*.db_domain=''
*.db_name='orcl'
*.db_recovery_file_dest='/opt/oracle/flash_recovery_area'
*.db_recovery_file_dest_size=4039114752
*.diagnostic_dest='/opt/oracle'
*.dispatchers='(PROTOCOL=TCP) (SERVICE=orclXDB)'
*.fal_server='orcldg'
*.job_queue_processes=1000
*.log_archive_config='dg_config=(orcl,orcldg)'
*.log_archive_dest_1='LOCATION=/opt/oracle/oradata/orcl/archive1 valid_for=(all_logfiles,primary_role) db_unique_name=orcl'
*.log_archive_dest_2='SERVICE=orcldg lgwr sync valid_for=(online_logfile,primary_role) db_unique_name=orcldg'
*.log_archive_format='orcl_%t_%s_%r.dbf'
*.memory_target=756023296
*.open_cursors=300
*.processes=150
*.remote_login_passwordfile='EXCLUSIVE'
*.standby_file_management='AUTO'
*.undo_tablespace='UNDOTBS1'
scp initorcl.ora oracle@192.168.215.102:/opt/oracle/11.2/dbs/
修改备库的initorcl.ora 修改参数如下:
*.db_name='orcl'
*.db_unique_name='orcldg'
*.fal_server='orcl'
*.log_archive_config='dg_config=(orcldg,orcl)'
*.log_archive_dest_1='LOCATION=/opt/oracle/oradata/orcl/archive1 valid_for=(all_logfiles,primary_role) db_unique_name=orcldg'
*.log_archive_dest_2='SERVICE=orcl lgwr sync valid_for=(online_logfile,primary_role) db_unique_name=orcl'
然后sql>create spfile from pfile;
11.传输主库数据到备库
(1)scp -l 8192 -rp /opt/oracle/oradata/orcl/ oracle@192.168.215.102:/opt/oracle/oradata/
注意目的地不要加orcl 会自动创建目录的
-l是limit限制,这样最大是8192/8=1M速度,是为了解决stalled问题
-rp 循环子目录文件
(2)建立spfile中需要的目录
如/opt/oracle/admin/orcl/adump dpdump pfile
12.启用物理备用数据库
sql>startup nomount
sql>alter database mount standby database;
(1)启动 redo 应用
SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT FROM SESSION;
启动实时应用
SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT FROM SESSION;
这个命令指示备库开始使用备用日志文件进行恢复。它也告诉备库命令完成后回到命令行界面
SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;
此时只是暂时 redo 应用,并不是停止 Standby 数据库,standby 仍会保持接收只不过不会再应用
接收到的归档,直到你再次启动 redo 应用为止
(2)停止standby
正常情况下,首先
SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;
然后再sql>shutdown immediate
当然也可以直接shutdown immediate
(3)备用服务器的管理模式与只读模式
<1>.启动到管理模式
SQL>shutdown immediate;
SQL>startup nomount;
SQL>alter database mount standby database;
SQL>alter database recover managed standby database disconnect from session;
<2>.启动到只读方式
SQL>shutdown immediate;
SQL>startup nomount;
SQL>alter database mount standby database;
SQL>alter database open read only;
<3>如果在管理恢复模式下到只读模式
SQL> recover managed standby database cancel;
SQL> alter database open read only;
这个时候,可以给数据库增加临时数据文件(这个在热备份的时候是没有备份过来的)
如alter tablespace temp add tempfile '/u02/oradata/test/temp01.dbf' size 100M;
<4>.从只读方式到管理恢复方式
SQL> recover managed standby database disconnect from session;
(4)应用物理备库的几点监控
如果上面出了问题或者我们不知道成功了没有,可以用下面的方法检测
<1>确认主备库里的归档目的地配置都是有效的
select DEST_ID, STATUS, DESTINATION, ERROR from V$ARCHIVE_DEST where DEST_ID<=2;
目的地状态status应该显示为 VALID,注意如果上面没有执行redo应用会有一条error信息
<2>确认重做日志是否真的被应用了,在主库执行
select SEQUENCE#, FIRST_TIME, NEXT_TIME, APPLIED, ARCHIVED from V$ARCHIVED_LOG where name = 'JED2' order by FIRST_TIME;
如果归档和日志应用均正常,APPLIED 和 ARCHIVED 列都应该是 YES。(如果没有应用redo,applied应该是NO)
很多教程里都让这个查询以 SEQUENCE# 列排序,但我不推荐。如果以 SEQUENCE# 列排序,当你做了一次故障转移后,序列号会再从1开始,
这时使用这个查询,你将不能在结果最后看到最新的记录。我曾经很奇怪为什么查不到新记录,其实是因为新记录不是出现在最后,
我没看到。所以,这个查询都是以 FIRST_TIME 列排序.
<3>主库上检查是否有重做日志缺口
如果你发现日志没有被应用,那可能是重做日志有了缺口,这种情况下备库无法进行日志应用。但如果你的 FAL_SERVER 参数设置正确,这应该不会有问题
select STATUS, GAP_STATUS from V$ARCHIVE_DEST_STATUS where DEST_ID = 2;
如果一切正常,应该返回 VALID 和 NO GAP .切记启用redo应用才能显示No GAP
<4>在主备库上执行以下查询查看数据库状态
select * from V$DATAGUARD_STATUS order by TIMESTAMP;
<5>检查是否成功:
主库上查看日志传送情况:
sql>select dest_name,status,error from v$archive_dest;
应该log_archive_dest_1和2状态应该是valid
切换几次日志:
sql>alter system switch logfile;
查看日志序号:
sql>select sequence# from v$archived_log;
备库验证:
sql>select sequence#,applied from v$archived_log;
13.dataguard启动关闭顺序
(1)监听
先启从库再起主库
#lsnrctl start
(2)启动
先启从库:
sql>startup nomount
sql>alter database mount standby database;
sql>alter database recover managed standby database using current logfile disconnect from session;
在启主库
sql>startup
(3)关闭:和开启正好相反
先关主库:
sql>shutdown immediate
再关从库:
sql>alter database recover managed standby database cancel;
sql>shutdown immediate;
四、switchover主备切换
DG的主要用途是HA高可用性,既然已经搭建好了主备环境,那现实环境中可能存在以下几种情况。
由于某种原因我们需要切换主备身份,即主备切换(Switchover)
主库故障,需要启用备库为主库,即故障转移(Failover)
客户端实现自动的故障转移-客户端故障转移(Client Failover)
下面就这几种情况以及使用闪回数据库重建库,活动数据卫士(Active Data Guard),进行讨论。
1.查看库所在的保护模式和身份
sql>select protection_mode,protection_level from v$database; --默认是最大性能模式(maximum performance)
sql>select database_role from v$database; --主库是primary备库是physical standby
SQL > alter database set standby database to maximize protection; --最大保护
SQL > alter database set standby database to maximize availability; --最高可用性
SQL > alter database set standby database to maximize performance; --最高性能
这里简要说明下这几种保护模式的区别:
最大保护:这种模式能够确保绝无数据丢失。要实现这一步当然是有代价的,它要求所有的事务在提交前其 redo 不仅
被写入到本地的 online redo log,还要同时提交到 standby 数据库的 standbyredo log,并确认 redo 数据至少在一
个 standby 数据库可用(如果有多个的话),然后才会在 primary 数据库上提交。如果出现了什么故障导致 standby
数据库不可用的话,primary 数据库会被 shutdown。
最高性能:这种模式提供在不影响 primary 数据库性能前提下最高级别的数据保护策略。事务可以随时提交,当前
primary 数据库的 redo 数据也需要至少写入一个 standby 数据库,不过这种写入可以是不同步的。
如果网络条件理想的话, 这种模式能够提供类似最高可用性的数据保护而仅对 primary 数据库有轻微的性能影响。
最高可用性:这种模式提供在不影响 primary 数据库可用前提下最高级别的数据保护策略。 其实现方式与最大保护模式类
似,也是要求所有事务在提交前必须保障 redo 数据至少在一个 standby 数据库可用,不过与之不同的是,如果
出现故障导入无法同时写入 standby 数据库 redo log,primary 数据库并不会 shutdown,而是自动转为最高性能
模式,等 standby 数据库恢复正常之后,它又会再自动转换成最高可用性模式。
2.故障转移配置
现在你已经配好了一个物理备库,你可能想试试主备切换(switchover),甚至故障转移(failover),但你先得确定客户端会跟着切换和转移。
我们需要配置数据库和客户端来支持这些功能。要确定你的客户端能连接到正确的数据库,你要在数据库里配置一个支持故障转移的服务,
并配置客户端的 TNS,让它知道如何在一个 Data Guard 集群里找到主库。
(1)主库创建自动转移服务:
此服务在数据库出现故障时会发送通知给客户端,允许查询语句在故障转移发生后继续运行。
我使用命名 SID_RW 显示这时一个可读写的数据库(主库)。
begin
DBMS_SERVICE.CREATE_SERVICE (
service_name => 'orcl_RW',
network_name => 'orcl_RW',
aq_ha_notifications => TRUE,
failover_method => 'BASIC',
failover_type => 'SELECT',
failover_retries => 30,
failover_delay => 5);
end; /
(2)创建存储过程确保只在主库运行
我们创建一个存储过程来实现此目的,如果当前数据库是主库它就启动此服务,如果是备库就停止。
create or replace procedure cmc_taf_service_proc
is
v_role VARCHAR(30);
begin
select DATABASE_ROLE into v_role from V$DATABASE;
if v_role = 'PRIMARY' then
DBMS_SERVICE.START_SERVICE('orcl_RW');
else
DBMS_SERVICE.STOP_SERVICE('orcl_RW');
end if;
end;
/
(3)创建触发器(2个)来确保服务可以运行
创建两个触发器,让数据库在启动和角色转换时运行此存储过程。注意有的文档说是建立一个,那可能会导致你
在重启你的数据库时,它不会重启故障转移服务
create or replace TRIGGER cmc_taf_service_trg_startup
after startup on database
begin
cmc_taf_service_proc;
end;
/
create or replace TRIGGER cmc_taf_manage_trg_rolechange
after db_role_change on database
begin
cmc_taf_service_proc;
end;
/
(4)启动服务
我们执行一次存储过程,确定服务正在运行,并归档当前日志,让以上更改同步到备库。
SQL> exec cmc_taf_service_proc;
SQL> alter system archive log current;
查看服务信息
SQL> show parameter service_names
(5)客户端配置TNS
服务名存在还不够,你必须配置客户端的 TNS 名去连接它。客户端的 TNS 名应该类似如下:
orcl_RW =
(DESCRIPTION =
(ADDRESS_LIST=
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.215.101)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.215.102)(PORT = 1521))
)
(CONNECT_DATA = (SERVICE_NAME = orcl_RW)
(FAILOVER_MODE=(TYPE=SELECT)(METHOD=BASIC)(RETRIES=30)(DELAY=5))
)
)
当你的客户端使用新 TNS 名后,它们能在主备切换和故障转移操作后找到主库。如果客户端在运行一个查询,
并且没有 DML 是在一个交易中,那在发生切换操作后,只要主备转换和故障转移在超过最大重试次数前完成,
这个查询会继续工作,只是会有延迟。你应该多做几次切换实验,以确定 RETRIES 和 DELAY 参数如何设置合适。
如果有一个正在进行中的交易,当客户端连接到新的主库后,
查询将报错(`ORA-25403: transaction must roll back),并回滚。
3.主备切换switchover
(1)主库确认没有日志缺口
SQL> select STATUS, GAP_STATUS from V$ARCHIVE_DEST_STATUS where DEST_ID = 2;
应该返回 VALID 和 NO GAP。
(2)查询v$tempfile视图确认备库的临时文件和主库一样。
(3)确认所有重做日志都已在备库应用,查询备库
SQL> select NAME, VALUE, DATUM_TIME from V$DATAGUARD_STATS;
不应该返回 transport lag 或 apply lag, finish time 应该为0.
关于V$DATAGUARD_STATS是这样描述的:
该动态性能视图显示出在主库上产生了多少重做日志数据,但是还没有被备库所应用。
所以,通过查询该视图可以基本确定如果万一主库出现崩溃的话,备库上将丢失多少重做日志数据。
我们可以在一套Dataguard环境下的任一备库的实例上从该视图里获取相关信息,
然而,在主库的实例上查询该视图返回的信息都将是空。也就是说,只可以从备库的实例上查询V$DATAGUARD_STATS,
从主库实例上是看不到任何有用信息的。
NAME:
apply lag,该值表示在通过在备库上应用主库传递过来的重做日志与主库同步所延迟的时间。
transport lag,该值表示在单位时间内主库上产生的重做日志还没有传输到备库上,或者主库上产生的重做日志还没有被备库所应用。
apply finish time,该值表示在备库上完成应用重做日志所需要的时间。
estimated startup time,该值表示启动和打开物理备库所需要的时间,该字段不是适用于逻辑备库。
standby has been open,该值表示物理备库自从上次启动以来,是否以OPEN READ ONLY方式打开过?
该参数值如果是Y,现在需要做FAILOVER,那么就需要先将该物理备库shutdown然后以OPEN READ WRITE方式打开。
11g的dataguard可以一边OPEN READ ONLY,一边执行redo apply,也就是11g 的ACTIVE Dataguard。
VALUE:给出各个参数的值。如第1个查询中的,apply finish time值为+00 00:00:00.1,说明该物理备库需要0.1秒的时间来完成应用剩余的重做日志数据。
UNIT:各个参数的时间单元。
TIME_COMPUTED:物理备库上估算各个参数的本地时间。
DATUM_TIME:在物理备库上获取元数据来估算 APPLY LAG 和 TRANSPORT LAG 这两个参数值的本地时间。如果从多次查询中看到该时间值对应的APPLY LAG 和 TRANSPORT LAG 这两个参数值保持不变的话,那么就说明该物理备库已经停止从主库接收到重做数据!该字段是11g中新出现的。
(4)确认主库可以进行角色切换,查询主库
SQL> select SWITCHOVER_STATUS from V$DATABASE;
如果返回 TO STANDBY 或 SESSIONS ACTIVE,那么主库就可以进行切换
(5)切换
<1>切换主库为备库命令为:
如果执行为TO STANDB执行
SQL> alter database commit to switchover to physical standby ;
SQL> shutdown immediate;
SQL> startup mount;
如果为SESSIONS ACTIVE执行
SQL> alter database commit to switchover to physical standby with session shutdown;
SQL> shutdown immediate;
SQL> startup mount;
<2>查询备库是否可以切换为主库,查询备库:
SQL> select SWITCHOVER_STATUS from V$DATABASE;
如果返回 TO PRIMARY 或 SESSIONS ACTIVE,就可以切换。如果返回 SWITCHOVER LATENT 或 SWITCHOVER PENDING,就要去检查告警日志,
看有什么问题,一般是需要应用一些日志。如果是需要应用日志的话,在备库执行如下命令:
SQL> recover standby database using backup controlfile;
完成应用后,会变成 TO PRIMARY 或 SESSIONS ACTIVE状态。
或者alter database recover managed standby database disconnect from session;
alter database recover managed standby database cancel;
切换备库为主库了:
SQL> select SWITCHOVER_STATUS from V$DATABASE;
如果是TO_PRIMARY 执行下面的
sql> alter database commit to switchover to primary;
SQL> alter database open;
如果是SESSIONS ACTIVE,执行下面的:
SQL> alter database commit to switchover to primary with session shutdown;
SQL> alter database open;
备库(现在的备库即101)上启用日志应用:
SQL> alter database recover managed standby database using current logfile disconnect from session;
此时在现在的备库101上执行:
sql>select SWITCHOVER_STATUS,DATABASE_ROLE from V$DATABASE; --not allowed PHYSICAL STANDBY
ora-16014错误,删除standby logfile然后alter database clear logfile清理数据库
从现在102主库上alter system switch logfile手工触发去传输standby logfile
注意的是:如果现在把101在切换回主库,102成从库。按照正常操作,先切换现在的主库102成从库,当操作完成的时候,101的 SWITCHOVER_STATUS就成
to_primary也就是说可以切换成主库了。
现在的主库102上执行:
sql> select SWITCHOVER_STATUS,DATABASE_ROLE from V$DATABASE; --RESOLVABLE GAP PRIMARY
检查alert日志发现ora-00312错误,删除错误的log日志,后状态为TO STANDBY,PRIMARY
sql>startup mount;
sql>alter database clear logfile '*****.LOG';
sql>alter database open
(6)问题
如果主备库的sequence#不同,而且主库切换switch logfile也不能传送到备库,可用下面的办法
手工同步归档日志文件到备库,然后在备库执行
sql>alter database register logfile '/opt/oracle/oradata/orcl/archive1/'
会报错,不需要管,会提示可以注册的已经注册进去了
sql>select sequence#,first_change#,next_change#,applied,activation# from v$archived_log;
检查主备库sequence#,然后主库切换logfile可以看到已经可以同步了
五、failover
一般情况下执行failover都是主库已经game over。故障转移将备库转换为主库,但不把原主库(有故障,无法正常工作)切换为备库。当故障转移发生后,你必须重建主库,或者使用闪回数据库功能将主库回退到故障发生前,然后转换其为备库并启用日志应用。
执行failover有几个前提条件如下
1.执行failover的前提
(1)检查归档文件是否连续
查询待转换 standby 数据库的 V$ARCHIVE_GAP 视图,确认归档文件是否连接:
SQL> SELECT THREAD#, LOW_SEQUENCE#, HIGH_SEQUENCE# FROM V$ARCHIVE_GAP;
未选定行
如果返回的有记录, 按照列出的记录号复制对应的归档文件到待转换的 standby 服务器。 这一步非常重
要,必须确保所有已生成的归档文件均已存在于 standby 服务器,不然可能会数据不一致造成转换时报错。
文件复制之后,通过下列命令将其加入数据字典:
SQL>ALTER DATABASE REGISTER PHYSICAL LOGFILE 'filespec1';
(2)检查归档文件是否完整
分别在 primary/standby 执行下列语句:
SQL> select distinct thread#,max(sequence#) over(partition by thread#) a from v$archived_log;
该语句取得当前数据库各线程已归档文件最大序号,如果 primary 与 standby 最大序号不相同,必须将
多出的序号对应的归档文件复制到待转换的 standby 服务器。 不过既然是 failover, 有可能 primary 数据库此
时已经无法打开,甚至无法访问,那只好听天由命了,但是如果可以到mounted,则可以传输归档日志。
所以应该在primary机器crashed之前做好准备。
加入此时结果是:
THREAD# A
---------- ----------
1 87
从库最大为87,主库也执行,如果也是87则ok,如果不一致需要scp 然后执行register
(3)如果当前备库是处于最大保护(maximum protection)模式,要进行故障转移,必须先修改为最大性能
(maximum performance)模式。修改方法:
SQL> alter database set standby database to maximize performance;
2,。执行切换
(1)在备库停止日志应用:
SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;
(2)结束应用任何日志:
SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE FINISH;
或者:
SQL> alter database recover managed standbydatabase finish force;
FORCE 关键字将会停止当前活动的 RFS 进程,以便立刻执行 failover。
(3)转换备库为主库
SQL> alter database commit to switchover to primary with session shutdown;
SQL> alter database open;
注意这个时候主库已经不在dataguard中了。
3.使用闪回重建数据库
(1)获得原备库转换为主库时的 SCN。查询现主库102:
SQL> SELECT to_char(STANDBY_BECAME_PRIMARY_SCN) from V$DATABASE;
(2)在原主库101上执行:
SQL> SHUTDOWN IMMEDIATE;
SQL> STARTUP MOUNT;
SQL> FLASHBACK DATABASE TO SCN &standby_became_primary_scn;输入之前查询到的SCN号
如果没有开始闪回日志,最后一条命令会报错 ORA-38726: Flashback database logging is not on.,
无法进行闪回。你就需要重新从新主库复制数据,重建原主库为备库。
如果命令成功执行,原主库101就可以使用新主库102的日志进行恢复。将原主库101转换成物理备库,并启动日志应用进程:
SQL> ALTER DATABASE CONVERT TO PHYSICAL STANDBY;
SQL> SHUTDOWN IMMEDIATE;
SQL> STARTUP MOUNT;
SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT FROM SESSION;
4.客户端故障转移
我很喜欢的一个功能是,当主备切换或故障转移发生后,客户端能够自动重连。在你的系统里,做下述实验,看结果如何。
orcl 是主库,orcldg 是备库。客户端使用支持故障转移的 orcl_RW 服务名。
首先,用 SYSTEM 用户和 orcl_RW 服务名在 SQL*Plus 里登录主库:
SQL> connect system@orcl_rw
SQL> select db_unique_name from v$database;
查询应该返回主库名 orcl。然后做一次主备切换,在将备库转换为主库
alter database commit to switchover to primary with session shutdown; 这一步时,主备库均处于 MOUNT 状态。
然后执行查询:
SQL> select db_unique_name from v$database;
这时查询应该挂住,这是因为客户端正在尝试寻找主库,但当前又没有可用的主库。然后继续完成主备切换。
当主备切换完成后,客户端应该会重连并重新执行查询,查询完成后成功返回结果 orcldg,因为现在主库已经切换为 orcldg,
不再是orcl。
另一个很酷的测试方法是,执行一个执行时间非常长的查询,当查询结果返回,屏幕一直滚动时开始主备切换。
你应该会看到屏幕暂停滚动一段时间,当切换完成后,又会继续滚动。
5.活动数据卫士(active dataguard)
活动数据卫士是 11g 的新功能,它允许你的物理备库在应用日志时处于只读打开状态。这明显是一个很有用的功能。
能够允许主库有一个物理备库作为备份,并能在保持备库数据更新的同时读取备库,这是一个很好的功能。
调整备库为“READ ONLY WITH APPLY”状态,这体现的便是Oracle 11g物理Active Data Guard功能中的“Active”真实含义。
在实际工作中,这个功能非常好用,经常用于检查实时数据同步情况。
(1)查看备库openmode
sql>select open_mode from v$database;--MOUNTED
(2)取消备库的自动恢复
sql>alter database recover managed standby database cancel;
sql>alter database open;
sql>select open_mode from v$database; --这时候为READ ONLY
(3)read only下备库恢复
sql>alter database recover managed standby database using current logfile disconnect;
sql>select open_mode from v$database; --这时为READ ONLY WITH APPLY
6.11g standby的一些变化:
(1)standby数据库可以直接执行
startup --就是read only打开数据库
startup mount --就是mount standby数据库
(2)read only的情况下可以执行managed recover standby命令。
SQL>startup
SQL>alter database recover managed standby database disconnect;
7.关于备份的引申
有了 Data Guard,你的 RMAN 备份在主库或者备库都可以执行。但既然你已经配置了物理备库,你应该减轻点主库的负载。
基本上,能在主库执行的标准的备份命令或脚本,也能在备库执行,但也有几个值得注意地方。这些 Oracle 官方文档都有,
我只提几个关键的事情:
你应该使用恢复目录(Recovery Catalog)。这是因为主库需要知道备库已经存在了哪些备份文件。你不需要在恢复目录中
注册备库,恢复目录能认出它是备库。
你不能备份备库的控制文件,所以不要在主库关掉所有的备份,至少需要在主库备份控制文件和参数文件。
备份和恢复可以写一整篇文章,我只是讲下我是如何配置备份的,让你能从这里开始,修改并形成自己的策略。
测试下,确认你能从你当前实现的备份设置中恢复。在运行备份前,你需要配置一些基本的东西。
(1)确认开启控制文件和 spfile 自动备份:
RMAN> CONFIGURE CONTROLFILE AUTOBACKUP ON;
(2)根据你的需要设置备份文件保留策略:
RMAN> CONFIGURE RETENTION POLICY TO RECOVERY WINDOW OF 3 DAYS;
(3)如果一个文件已经有备份,并且检查点 SCN 相同,就不备份:
RMAN> CONFIGURE BACKUP OPTIMIZATION ON;
(4)只在主库的归档日志已经在备库应用(或者配置为已经传输到备份)后才删除:
RMAN> CONFIGURE ARCHIVELOG DELETION POLICY TO APPLIED ON ALL STANDBY;
(5)允许 RMAN 在主备间重新同步:
RMAN> CONFIGURE DB_UNIQUE_NAME P10AC CONNECT IDENTIFIER ‘JED’;
RMAN> CONFIGURE DB_UNIQUE_NAME P11AC CONNECT IDENTIFIER 'JED2';
在主库我仍然备份归档日志。首先,在主备库都备份归档提供了冗余。其次,当发生需要恢复的事件(比如数据文件下线等)后,
我在主库已经有归档了。我需要删除过期的归档,以清理磁盘空间。
在 Data Guard 环境下,不能使用标准的在单机删除归档的命令,两者有一点小区别。因为我们必须使用恢复目录,
我创建了一个全局脚本(global script):
create global script dg_primary_arch
{
backup archivelog all;
delete noprompt archivelog all completed before 'sysdate-.5';
delete noprompt backup of archivelog all completed before 'sysdate-2';
}
在备库我运行标准的全库和归档备份,并删除过期的备份集。在 Data Guard 环境下,将备份归档包含在备份全库的命令里,
会经常导致报错 RMAN-08137: WARNING: archived log not deleted, needed for standby or upstream capture process。
为避免此报错,你应该将备份归档放在单独的命令里。我还是创建一个全局脚本:
create global script dg_standby_full
{
backup database plus archivelog;
delete noprompt archivelog all completed before 'sysdate-1';
delete noprompt obsolete;
}
另外一个有用的技巧是,如果可能,使用共享文件系统进行备份。这样你在两台服务器上都可以访问备份文件。
这样,当你需要恢复时,你不需要从另一台服务器上复制文件了。但如果使用共享文件系统的话,你的归档备份虽然有两份,
却都放在一个文件系统里,如果硬盘出现故障,两份备份都会丢失。
一、前言:
网络上关于dataguard的配置文章很多,但是很多打着oracle11g的文章实际都是只能在9 10 上运行,比如FAL_CLIENT在11g中已经废弃,但是现在网络上的文章都是没有标注这一点。而且对于具体含义语焉不详对于新手只能知其然而不知其所以然。这篇文章我就想让像我这样的人对于dataguard配置不仅仅知道怎么配置,还要知道为什么需要这样配置,这样的效果才是最好的。
这篇文章不仅仅是记录如何配置,还介绍了为什么是这样,以及注意要点,我希望这个文章可以作为进行dataguard配置的一个参考手册。
二、前提
1.主库是归档模式:
如果我们不清楚为什么是归档模式,那我们就应该也不会清楚dataguard是用来做什么的。透过很多修饰的官方语言,我们需要明确DG(dataguard简称,后同)实际上的作用就是用来高可用。而实现原理就是从主库获取数据到从库,在主库发生异常的时候,从库接管主库,完成身份的变化。可以一个主库,最多9个从库。同时分为逻辑standby和物理standby这里我们讨论的是物理standby.
一旦创建并配置成 standby 后,dg 负责传输 primary数据库 redo data 到 standby 数据库,standby 数据库通过应用接收到的 redo data 保持与 primary 数据库的事务一致。
这下清楚了吧,需要保证主从库一致,需要传输archive log和redo log到从库,如果不是归档模式无法保证主从库的数据一致。
2.从库只需要安装数据库软件,数据从主库传输后完成。
3.很多人说11g有了active dataguard(ADG),逻辑standby 实际上已经没什么用处了。
4.主从库硬件最好一致。oracle数据库版本需要一致。
(1)内存检查项:
# grep MemTotal /proc/meminfo
交换分区检查项:如果内存在1-2G,swap是1.5倍;2-16G,1倍;超过16G,设置为16G即可。
# grep SwapTotal /proc/meminfo
查看共享内存大小:
# df -h /dev/shm
(2)查看系统处理器架构,与oracle安装包一致
# uname -m
(3)空间空间 /tmp必须大于1G
# df -h /tmp
5.配置环境数据库用户必须有sysdba权限
6.后面的环境:主库 192.168.215.101 数据库实例名:orcl db_unique_name:orcl
从库 192.168.215.102 数据库实例名:orcl db_unique_name:orcldg
三、配置
1.判断DG是否已经安装:
select * from v$option where parameter = 'Oracle Data Guard';
如果是true表示已经安装可以配置,否则需要安装相应组件。
2.设置主库为强制记录日志。
默认情况下数据库操作会记录redo log,但是在一些特定的情况下可以使用nologging来不生成redo信息
(1)表的批量INSERT(通过/*+APPEND */提示使用“直接路径插入“。或采用SQL*Loader直接路径加载)。表数据不生成redo,但是
所有索引修改会生成redo,但是所有索引修改会生成redo(尽管表不生成日志,但这个表上的索引却会生成redo!)。
(2)LOB操作(对大对象的更新不必生成日志)。
(3)通过CREATE TABLE AS SELECT创建表
(4)各种ALTER TABLE操作,如MOVE和SPLIT
(5)在一些表迁移和表空间迁移中,可以使用alter table a nologging;或者alter tablespace snk nologging;在操作完成后再修改回logging状态。
这里需要多说一句,如果你使用nologging导入大批量数据,以后对这些数据的修改会在redo或者archive log中,但是基准的数据是没有的,所以一旦介质损坏是无法完全恢复的,必须在使用nologging完成切换回logging后,做一次全备或者0级备份。
(1)强制记录日志:sql>alter database force logging;
(2)检查状态(YEs为强制):sql>select name,force_logging from v$database;
(3)如果需要在主库添加或者删除数据文件时,这些文件也会在备份添加或删除,使用如下:
sql>alter system set standy_file_management='AUTO';
默认此参数是manual手工方式 sql>show parameter standby
3.创建standby log files(备用日志文件)
从库使用standby log files来保存从主库接收到的重做日志。既然主要是从库在使用,那为什么需要在主库上也建立
standby log files?原因主要由两个:一是主库可能转换为备库,而备库是需要有standby log files的 二是如果主库
建立了standby log files那备库会自动建立。
建立standby如要注意以下几点:
<1>standby log files的大小和redo log files一样。
查询redo log files文件大小(默认50M,3个):select group#,bytes/1024/1024 as M from v$log
<2>一般而言, standbyredo 日志文件组数要比 primary 数据库的 online redo 日志文件组数至少多一个。
推荐 standbyredo 日志组数量基于 primary 数据库的线程数(这里的线程数可以理解为 rac 结构中的 rac
节点数)。
有一个推荐的公式可以做参考:(每线程的日志组数+1)*最大线程数
假设现在节点是1个,则=(3+1)*1=4
如果是双节点 则=(3+1)*2=8
这里我们创建4个standby logfile:
另:不建议组号group#紧挨着redo,因为后续redo有可能调整,这里我们从建立从11到14的standby logfile
1
2
3
4
5
6
7
8
# cd $ORACLE_BASE/oradata/orcl/
# mkdir dg
# chown oracle:dba dg
sql> alter database add standby logfile group 11 '/opt/oracle/oradata/orcl/dg/standby11.log' size 50M;
sql> alter database add standby logfile group 12 '/opt/oracle/oradata/orcl/dg/standby12.log' size 50M;
sql> alter database add standby logfile group 13 '/opt/oracle/oradata/orcl/dg/standby13.log' size 50M;
sql> alter database add standby logfile group 14 '/opt/oracle/oradata/orcl/dg/standby14.log' size 50M;
4.密码文件和控制文件的创建传输
(1)一般数据库默认就有密码文件,存放在$ORACLE_HOME/dbs/orapwSID 这里为orapworcl
如果没有sql>orapwd file=$ORACLE_HOME/dbs/orapworcl password=oracle
(2)检查REMOTE_LOGIN_PASSWORDFILE值是否为 EXCLUSIVE
sql>show parameter REMOTE_LOGIN_PASSWORDFILE
如果值不是EXCLUSIVE,则:alter system set remote_login_passwordfile=exclusive scope=spfile;
(3)密码文件需要scp到从库
# scp orapworcl oracle@192.168.215.102:/opt/oracle/11.2/dbs 提示输入yes
(4)控制文件:
11g的控制文件一共两份,内容一样,一份在$ORACLE_BASE/oradata/orcl/control01.ctl
一份在/opt/oracle/flash_recovery_area/orcl/control02.ctl
生成standby控制文件:
1
2
3
4
sql>shutdown immediate
sql>startup mount
sql>alter database create standby controlfile as '/tmp/standby_control01.ctl';
sql>startup open;
然后在备库建立对应的目录,并授权
mkdir orcl--- chown oracle:oinstall(或dba) orcl
scp control01.ctl oracle@192.168.215.102:/opt/oracle/oradata/orcl
scp control02.ctl oracle@192.168.215.102:/opt/oracle/flash_recovery_area/orcl/
5.db_name和db_unique_name
默认db_name和db_unique_name和实例名是一致的,这里是orcl
需要注意在DG中主库和从库的db_unique_name是不能一致的,需要区分开的。
这里我们设置主库的db_unique_name为orcl,从库为orcldg
sql>show parameter db_unique_name
设置:alter system set db_unique_name=orcl scope=spfile;
--注意虽然默认db_unique_name和db_name是一致的,但是需要显式设置,否则在spfile中没有此参数
6.闪回数据库:
强烈建议开启数据库闪回功能。闪回允许你将数据库还原到以前的某一时间点。当发生故障转移时,这个功能非常有用,
它能让你将老的主库闪回到故障前,然后将其转换为备库。如果没有启用闪回功能,你就必须重建备库,意味着要再复制一次数据文件。
除了这个好处,闪回还能在某些情况下让你避免从备份恢复数据。
(1)快速恢复区(Flash/Fast Recovery Area),默认是配置的,但是需要确认这个区域的磁盘够大,至少300G以上(默认3G)
sql>show parameter db_recovery_file_dest
可以修改位置:sql>alter system set db_recovery_file_dest='新路径';
更改大小:sql>alter system set db_recovery_file_dest_size=400G;
(2)查看是否启用,默认是不开启的
sql>select flashback_on from v$database;
开启:sql>alter database flashback on;
如果你碰到 ORA-01153 报错,那一定是在备库进行此操作。你需要先取消重做日志应用,启用闪回日志,然后重新启用日志应用。
在主库启用闪回日志,不会同步备库也启用。你必须手动在主库和备库上均启用闪回日志。
如果不启用闪回日志,当出现故障转移时,你将需要完全重新开始创建一个备库。
7.SQL*NET设置
(1)配置主库的监听
虽然可以通过netca来进行配置,但是除了这个默认的外,我们还需要一个静态注册SID_LIST_LISTENER,如果没有此从参数而且
dataguard启动顺序不正确,主库会报PING[ARC1]:Heartbeat failed to connect to standby '***'.Error is 12514导致归档无法完成
配置如下
SID_LIST_LISTENER=
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = orcl)
(ORACLE_HOME = /opt/oracle/11.2)
(SID_NAME = orcl)
)
)
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = primaryDB)(PORT = 1521))
)
)
#vi $ORACLE_HOME/network/admin/listener.ora 加入上面的内容
(2)配置tnsnames
#vi $ORACLE_HOME/network/admin/tnsnames.ora
ORCL =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.215.101)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = orcl)
)
)
ORCLDG =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.215.102)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = orcldg)
)
)
(3)传输到备库并修改listener.ora和tnsnames.ora
scp $ORACLE_HOME/network/admin/listener.ora oracle@192.168.215.102:/opt/oracle/11.2/network/admin/
scp $ORACLE_HOME/network/admin/tnsnames.ora oracle@192.168.215.102:/opt/oracle/11.2/network/admin/
--listener.ora:
SID_LIST_LISTENER
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = orcldg)
(ORACLE_HOME = /opt/oracle/11.2)
(SID_NAME = orcl)
)
)
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = standbyDB)(PORT = 1521))
)
)
tnsnames.ora:不需要修改
8.重做日志传输配置
(1)配置归档日志位置:
查询已经设置的归档路径sql:archive log list或者show parameter log_archive_dest_1
sql> alter system set log_archive_dest_1='LOCATION=/opt/oracle/oradata/orcl/archive1 valid_for=(all_logfiles,primary_role) db_unique_name=orcl' scope=spfile;
还可以使用快速恢复区作为归档目录,如LOCATION=use_db_recovery_file_dest
官方文档里说使用 valid_for=(online_logfiles, all_roles),这将导致备库无法归档备用日志文件,因为它们不是在线日志。
但如果使用 all_logfiles 选项,主备库将都能归档在线以及备用日志。
如果你想在备库进行备份,并同时备份归档日志的话,必须使用 all_logfiles。
(2)配置重做日志到备份库:
sql>alter system set log_archive_dest_2='SERVICE=orcldg lgwr sync valid_for=(online_logfile,primary_role)
db_unique_name=orcldg';
(3)要注意STANDBY_ARCHIVE_DEST 参数不需要,已经被官方弃用。设置此参数后启动数据库,只会报 ORA-32004:
obsolete or deprecated parameter(s) specified for RDBMS instance 错。
9.配置FAL_SERVER
这个参数指定当日志传输出现问题时,备库到哪里去找缺少的归档日志。它用在备库接收的到的重做日志间有缺口的时候。
这种情况会发生在日志传输出现中断时,比如你需要对备库进行维护操作。在备库维护期间,没有日志传输过来,这时缺口就出现了。
设置了这个参数,备库就会主动去寻找那些缺少的日志,并要求主库进行传输。
你是主库,就填写:
fal_server=从库
从库上就反过来:
fal_server=主库
注意:FAL_CLIENT在11g中已经废弃,虽然可以配置但是已经不起作用了。
sql>alter system set FAL_SERVER='orcldg';
10.Data Guard 配置里的另外一个库的名字
sql> alter system set log_archive_config = 'dg_config=(orcl,orcldg)';
以上的办法是我们采用alter system的方式在线修改,还有一种比较方便的办法(但是容易出错,所以方便和安全什么时候都不可兼得)
sql>create pfile from spfile;
# 手工修改pfile
sql>create spfile from pfile;
然后用pfile生成spfile 同时传输pfile到从库修改后生成spfile
注意手工增加:
*.log_archive_dest_state_1=enable
*.log_archive_dest_state_2=enable
vi initorcl.ora
orcl.__db_cache_size=180355072
orcl.__java_pool_size=4194304
orcl.__large_pool_size=4194304
orcl.__oracle_base='/opt/oracle'#ORACLE_BASE set from environment
orcl.__pga_aggregate_target=264241152
orcl.__sga_target=494927872
orcl.__shared_io_pool_size=0
orcl.__shared_pool_size=289406976
orcl.__streams_pool_size=8388608
*.audit_file_dest='/opt/oracle/admin/orcl/adump'
*.audit_trail='db'
*.compatible='11.2.0.0.0'
*.control_files='/opt/oracle/oradata/orcl/control01.ctl','/opt/oracle/flash_recovery_area/orcl/control02.ctl'#Restore Controlfile
*.db_block_size=8192
*.db_domain=''
*.db_name='orcl'
*.db_recovery_file_dest='/opt/oracle/flash_recovery_area'
*.db_recovery_file_dest_size=4039114752
*.diagnostic_dest='/opt/oracle'
*.dispatchers='(PROTOCOL=TCP) (SERVICE=orclXDB)'
*.fal_server='orcldg'
*.job_queue_processes=1000
*.log_archive_config='dg_config=(orcl,orcldg)'
*.log_archive_dest_1='LOCATION=/opt/oracle/oradata/orcl/archive1 valid_for=(all_logfiles,primary_role) db_unique_name=orcl'
*.log_archive_dest_2='SERVICE=orcldg lgwr sync valid_for=(online_logfile,primary_role) db_unique_name=orcldg'
*.log_archive_format='orcl_%t_%s_%r.dbf'
*.memory_target=756023296
*.open_cursors=300
*.processes=150
*.remote_login_passwordfile='EXCLUSIVE'
*.standby_file_management='AUTO'
*.undo_tablespace='UNDOTBS1'
scp initorcl.ora oracle@192.168.215.102:/opt/oracle/11.2/dbs/
修改备库的initorcl.ora 修改参数如下:
*.db_name='orcl'
*.db_unique_name='orcldg'
*.fal_server='orcl'
*.log_archive_config='dg_config=(orcldg,orcl)'
*.log_archive_dest_1='LOCATION=/opt/oracle/oradata/orcl/archive1 valid_for=(all_logfiles,primary_role) db_unique_name=orcldg'
*.log_archive_dest_2='SERVICE=orcl lgwr sync valid_for=(online_logfile,primary_role) db_unique_name=orcl'
然后sql>create spfile from pfile;
11.传输主库数据到备库
(1)scp -l 8192 -rp /opt/oracle/oradata/orcl/ oracle@192.168.215.102:/opt/oracle/oradata/
注意目的地不要加orcl 会自动创建目录的
-l是limit限制,这样最大是8192/8=1M速度,是为了解决stalled问题
-rp 循环子目录文件
(2)建立spfile中需要的目录
如/opt/oracle/admin/orcl/adump dpdump pfile
12.启用物理备用数据库
sql>startup nomount
sql>alter database mount standby database;
(1)启动 redo 应用
SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT FROM SESSION;
启动实时应用
SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT FROM SESSION;
这个命令指示备库开始使用备用日志文件进行恢复。它也告诉备库命令完成后回到命令行界面
SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;
此时只是暂时 redo 应用,并不是停止 Standby 数据库,standby 仍会保持接收只不过不会再应用
接收到的归档,直到你再次启动 redo 应用为止
(2)停止standby
正常情况下,首先
SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;
然后再sql>shutdown immediate
当然也可以直接shutdown immediate
(3)备用服务器的管理模式与只读模式
<1>.启动到管理模式
SQL>shutdown immediate;
SQL>startup nomount;
SQL>alter database mount standby database;
SQL>alter database recover managed standby database disconnect from session;
<2>.启动到只读方式
SQL>shutdown immediate;
SQL>startup nomount;
SQL>alter database mount standby database;
SQL>alter database open read only;
<3>如果在管理恢复模式下到只读模式
SQL> recover managed standby database cancel;
SQL> alter database open read only;
这个时候,可以给数据库增加临时数据文件(这个在热备份的时候是没有备份过来的)
如alter tablespace temp add tempfile '/u02/oradata/test/temp01.dbf' size 100M;
<4>.从只读方式到管理恢复方式
SQL> recover managed standby database disconnect from session;
(4)应用物理备库的几点监控
如果上面出了问题或者我们不知道成功了没有,可以用下面的方法检测
<1>确认主备库里的归档目的地配置都是有效的
select DEST_ID, STATUS, DESTINATION, ERROR from V$ARCHIVE_DEST where DEST_ID<=2;
目的地状态status应该显示为 VALID,注意如果上面没有执行redo应用会有一条error信息
<2>确认重做日志是否真的被应用了,在主库执行
select SEQUENCE#, FIRST_TIME, NEXT_TIME, APPLIED, ARCHIVED from V$ARCHIVED_LOG where name = 'JED2' order by FIRST_TIME;
如果归档和日志应用均正常,APPLIED 和 ARCHIVED 列都应该是 YES。(如果没有应用redo,applied应该是NO)
很多教程里都让这个查询以 SEQUENCE# 列排序,但我不推荐。如果以 SEQUENCE# 列排序,当你做了一次故障转移后,序列号会再从1开始,
这时使用这个查询,你将不能在结果最后看到最新的记录。我曾经很奇怪为什么查不到新记录,其实是因为新记录不是出现在最后,
我没看到。所以,这个查询都是以 FIRST_TIME 列排序.
<3>主库上检查是否有重做日志缺口
如果你发现日志没有被应用,那可能是重做日志有了缺口,这种情况下备库无法进行日志应用。但如果你的 FAL_SERVER 参数设置正确,这应该不会有问题
select STATUS, GAP_STATUS from V$ARCHIVE_DEST_STATUS where DEST_ID = 2;
如果一切正常,应该返回 VALID 和 NO GAP .切记启用redo应用才能显示No GAP
<4>在主备库上执行以下查询查看数据库状态
select * from V$DATAGUARD_STATUS order by TIMESTAMP;
<5>检查是否成功:
主库上查看日志传送情况:
sql>select dest_name,status,error from v$archive_dest;
应该log_archive_dest_1和2状态应该是valid
切换几次日志:
sql>alter system switch logfile;
查看日志序号:
sql>select sequence# from v$archived_log;
备库验证:
sql>select sequence#,applied from v$archived_log;
13.dataguard启动关闭顺序
(1)监听
先启从库再起主库
#lsnrctl start
(2)启动
先启从库:
sql>startup nomount
sql>alter database mount standby database;
sql>alter database recover managed standby database using current logfile disconnect from session;
在启主库
sql>startup
(3)关闭:和开启正好相反
先关主库:
sql>shutdown immediate
再关从库:
sql>alter database recover managed standby database cancel;
sql>shutdown immediate;
四、switchover主备切换
DG的主要用途是HA高可用性,既然已经搭建好了主备环境,那现实环境中可能存在以下几种情况。
由于某种原因我们需要切换主备身份,即主备切换(Switchover)
主库故障,需要启用备库为主库,即故障转移(Failover)
客户端实现自动的故障转移-客户端故障转移(Client Failover)
下面就这几种情况以及使用闪回数据库重建库,活动数据卫士(Active Data Guard),进行讨论。
1.查看库所在的保护模式和身份
sql>select protection_mode,protection_level from v$database; --默认是最大性能模式(maximum performance)
sql>select database_role from v$database; --主库是primary备库是physical standby
SQL > alter database set standby database to maximize protection; --最大保护
SQL > alter database set standby database to maximize availability; --最高可用性
SQL > alter database set standby database to maximize performance; --最高性能
这里简要说明下这几种保护模式的区别:
最大保护:这种模式能够确保绝无数据丢失。要实现这一步当然是有代价的,它要求所有的事务在提交前其 redo 不仅
被写入到本地的 online redo log,还要同时提交到 standby 数据库的 standbyredo log,并确认 redo 数据至少在一
个 standby 数据库可用(如果有多个的话),然后才会在 primary 数据库上提交。如果出现了什么故障导致 standby
数据库不可用的话,primary 数据库会被 shutdown。
最高性能:这种模式提供在不影响 primary 数据库性能前提下最高级别的数据保护策略。事务可以随时提交,当前
primary 数据库的 redo 数据也需要至少写入一个 standby 数据库,不过这种写入可以是不同步的。
如果网络条件理想的话, 这种模式能够提供类似最高可用性的数据保护而仅对 primary 数据库有轻微的性能影响。
最高可用性:这种模式提供在不影响 primary 数据库可用前提下最高级别的数据保护策略。 其实现方式与最大保护模式类
似,也是要求所有事务在提交前必须保障 redo 数据至少在一个 standby 数据库可用,不过与之不同的是,如果
出现故障导入无法同时写入 standby 数据库 redo log,primary 数据库并不会 shutdown,而是自动转为最高性能
模式,等 standby 数据库恢复正常之后,它又会再自动转换成最高可用性模式。
2.故障转移配置
现在你已经配好了一个物理备库,你可能想试试主备切换(switchover),甚至故障转移(failover),但你先得确定客户端会跟着切换和转移。
我们需要配置数据库和客户端来支持这些功能。要确定你的客户端能连接到正确的数据库,你要在数据库里配置一个支持故障转移的服务,
并配置客户端的 TNS,让它知道如何在一个 Data Guard 集群里找到主库。
(1)主库创建自动转移服务:
此服务在数据库出现故障时会发送通知给客户端,允许查询语句在故障转移发生后继续运行。
我使用命名 SID_RW 显示这时一个可读写的数据库(主库)。
begin
DBMS_SERVICE.CREATE_SERVICE (
service_name => 'orcl_RW',
network_name => 'orcl_RW',
aq_ha_notifications => TRUE,
failover_method => 'BASIC',
failover_type => 'SELECT',
failover_retries => 30,
failover_delay => 5);
end; /
(2)创建存储过程确保只在主库运行
我们创建一个存储过程来实现此目的,如果当前数据库是主库它就启动此服务,如果是备库就停止。
create or replace procedure cmc_taf_service_proc
is
v_role VARCHAR(30);
begin
select DATABASE_ROLE into v_role from V$DATABASE;
if v_role = 'PRIMARY' then
DBMS_SERVICE.START_SERVICE('orcl_RW');
else
DBMS_SERVICE.STOP_SERVICE('orcl_RW');
end if;
end;
/
(3)创建触发器(2个)来确保服务可以运行
创建两个触发器,让数据库在启动和角色转换时运行此存储过程。注意有的文档说是建立一个,那可能会导致你
在重启你的数据库时,它不会重启故障转移服务
create or replace TRIGGER cmc_taf_service_trg_startup
after startup on database
begin
cmc_taf_service_proc;
end;
/
create or replace TRIGGER cmc_taf_manage_trg_rolechange
after db_role_change on database
begin
cmc_taf_service_proc;
end;
/
(4)启动服务
我们执行一次存储过程,确定服务正在运行,并归档当前日志,让以上更改同步到备库。
SQL> exec cmc_taf_service_proc;
SQL> alter system archive log current;
查看服务信息
SQL> show parameter service_names
(5)客户端配置TNS
服务名存在还不够,你必须配置客户端的 TNS 名去连接它。客户端的 TNS 名应该类似如下:
orcl_RW =
(DESCRIPTION =
(ADDRESS_LIST=
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.215.101)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.215.102)(PORT = 1521))
)
(CONNECT_DATA = (SERVICE_NAME = orcl_RW)
(FAILOVER_MODE=(TYPE=SELECT)(METHOD=BASIC)(RETRIES=30)(DELAY=5))
)
)
当你的客户端使用新 TNS 名后,它们能在主备切换和故障转移操作后找到主库。如果客户端在运行一个查询,
并且没有 DML 是在一个交易中,那在发生切换操作后,只要主备转换和故障转移在超过最大重试次数前完成,
这个查询会继续工作,只是会有延迟。你应该多做几次切换实验,以确定 RETRIES 和 DELAY 参数如何设置合适。
如果有一个正在进行中的交易,当客户端连接到新的主库后,
查询将报错(`ORA-25403: transaction must roll back),并回滚。
3.主备切换switchover
(1)主库确认没有日志缺口
SQL> select STATUS, GAP_STATUS from V$ARCHIVE_DEST_STATUS where DEST_ID = 2;
应该返回 VALID 和 NO GAP。
(2)查询v$tempfile视图确认备库的临时文件和主库一样。
(3)确认所有重做日志都已在备库应用,查询备库
SQL> select NAME, VALUE, DATUM_TIME from V$DATAGUARD_STATS;
不应该返回 transport lag 或 apply lag, finish time 应该为0.
关于V$DATAGUARD_STATS是这样描述的:
该动态性能视图显示出在主库上产生了多少重做日志数据,但是还没有被备库所应用。
所以,通过查询该视图可以基本确定如果万一主库出现崩溃的话,备库上将丢失多少重做日志数据。
我们可以在一套Dataguard环境下的任一备库的实例上从该视图里获取相关信息,
然而,在主库的实例上查询该视图返回的信息都将是空。也就是说,只可以从备库的实例上查询V$DATAGUARD_STATS,
从主库实例上是看不到任何有用信息的。
NAME:
apply lag,该值表示在通过在备库上应用主库传递过来的重做日志与主库同步所延迟的时间。
transport lag,该值表示在单位时间内主库上产生的重做日志还没有传输到备库上,或者主库上产生的重做日志还没有被备库所应用。
apply finish time,该值表示在备库上完成应用重做日志所需要的时间。
estimated startup time,该值表示启动和打开物理备库所需要的时间,该字段不是适用于逻辑备库。
standby has been open,该值表示物理备库自从上次启动以来,是否以OPEN READ ONLY方式打开过?
该参数值如果是Y,现在需要做FAILOVER,那么就需要先将该物理备库shutdown然后以OPEN READ WRITE方式打开。
11g的dataguard可以一边OPEN READ ONLY,一边执行redo apply,也就是11g 的ACTIVE Dataguard。
VALUE:给出各个参数的值。如第1个查询中的,apply finish time值为+00 00:00:00.1,说明该物理备库需要0.1秒的时间来完成应用剩余的重做日志数据。
UNIT:各个参数的时间单元。
TIME_COMPUTED:物理备库上估算各个参数的本地时间。
DATUM_TIME:在物理备库上获取元数据来估算 APPLY LAG 和 TRANSPORT LAG 这两个参数值的本地时间。如果从多次查询中看到该时间值对应的APPLY LAG 和 TRANSPORT LAG 这两个参数值保持不变的话,那么就说明该物理备库已经停止从主库接收到重做数据!该字段是11g中新出现的。
(4)确认主库可以进行角色切换,查询主库
SQL> select SWITCHOVER_STATUS from V$DATABASE;
如果返回 TO STANDBY 或 SESSIONS ACTIVE,那么主库就可以进行切换
(5)切换
<1>切换主库为备库命令为:
如果执行为TO STANDB执行
SQL> alter database commit to switchover to physical standby ;
SQL> shutdown immediate;
SQL> startup mount;
如果为SESSIONS ACTIVE执行
SQL> alter database commit to switchover to physical standby with session shutdown;
SQL> shutdown immediate;
SQL> startup mount;
<2>查询备库是否可以切换为主库,查询备库:
SQL> select SWITCHOVER_STATUS from V$DATABASE;
如果返回 TO PRIMARY 或 SESSIONS ACTIVE,就可以切换。如果返回 SWITCHOVER LATENT 或 SWITCHOVER PENDING,就要去检查告警日志,
看有什么问题,一般是需要应用一些日志。如果是需要应用日志的话,在备库执行如下命令:
SQL> recover standby database using backup controlfile;
完成应用后,会变成 TO PRIMARY 或 SESSIONS ACTIVE状态。
或者alter database recover managed standby database disconnect from session;
alter database recover managed standby database cancel;
切换备库为主库了:
SQL> select SWITCHOVER_STATUS from V$DATABASE;
如果是TO_PRIMARY 执行下面的
sql> alter database commit to switchover to primary;
SQL> alter database open;
如果是SESSIONS ACTIVE,执行下面的:
SQL> alter database commit to switchover to primary with session shutdown;
SQL> alter database open;
备库(现在的备库即101)上启用日志应用:
SQL> alter database recover managed standby database using current logfile disconnect from session;
此时在现在的备库101上执行:
sql>select SWITCHOVER_STATUS,DATABASE_ROLE from V$DATABASE; --not allowed PHYSICAL STANDBY
ora-16014错误,删除standby logfile然后alter database clear logfile清理数据库
从现在102主库上alter system switch logfile手工触发去传输standby logfile
注意的是:如果现在把101在切换回主库,102成从库。按照正常操作,先切换现在的主库102成从库,当操作完成的时候,101的 SWITCHOVER_STATUS就成
to_primary也就是说可以切换成主库了。
现在的主库102上执行:
sql> select SWITCHOVER_STATUS,DATABASE_ROLE from V$DATABASE; --RESOLVABLE GAP PRIMARY
检查alert日志发现ora-00312错误,删除错误的log日志,后状态为TO STANDBY,PRIMARY
sql>startup mount;
sql>alter database clear logfile '*****.LOG';
sql>alter database open
(6)问题
如果主备库的sequence#不同,而且主库切换switch logfile也不能传送到备库,可用下面的办法
手工同步归档日志文件到备库,然后在备库执行
sql>alter database register logfile '/opt/oracle/oradata/orcl/archive1/'
会报错,不需要管,会提示可以注册的已经注册进去了
sql>select sequence#,first_change#,next_change#,applied,activation# from v$archived_log;
检查主备库sequence#,然后主库切换logfile可以看到已经可以同步了
五、failover
一般情况下执行failover都是主库已经game over。故障转移将备库转换为主库,但不把原主库(有故障,无法正常工作)切换为备库。当故障转移发生后,你必须重建主库,或者使用闪回数据库功能将主库回退到故障发生前,然后转换其为备库并启用日志应用。
执行failover有几个前提条件如下
1.执行failover的前提
(1)检查归档文件是否连续
查询待转换 standby 数据库的 V$ARCHIVE_GAP 视图,确认归档文件是否连接:
SQL> SELECT THREAD#, LOW_SEQUENCE#, HIGH_SEQUENCE# FROM V$ARCHIVE_GAP;
未选定行
如果返回的有记录, 按照列出的记录号复制对应的归档文件到待转换的 standby 服务器。 这一步非常重
要,必须确保所有已生成的归档文件均已存在于 standby 服务器,不然可能会数据不一致造成转换时报错。
文件复制之后,通过下列命令将其加入数据字典:
SQL>ALTER DATABASE REGISTER PHYSICAL LOGFILE 'filespec1';
(2)检查归档文件是否完整
分别在 primary/standby 执行下列语句:
SQL> select distinct thread#,max(sequence#) over(partition by thread#) a from v$archived_log;
该语句取得当前数据库各线程已归档文件最大序号,如果 primary 与 standby 最大序号不相同,必须将
多出的序号对应的归档文件复制到待转换的 standby 服务器。 不过既然是 failover, 有可能 primary 数据库此
时已经无法打开,甚至无法访问,那只好听天由命了,但是如果可以到mounted,则可以传输归档日志。
所以应该在primary机器crashed之前做好准备。
加入此时结果是:
THREAD# A
---------- ----------
1 87
从库最大为87,主库也执行,如果也是87则ok,如果不一致需要scp 然后执行register
(3)如果当前备库是处于最大保护(maximum protection)模式,要进行故障转移,必须先修改为最大性能
(maximum performance)模式。修改方法:
SQL> alter database set standby database to maximize performance;
2,。执行切换
(1)在备库停止日志应用:
SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;
(2)结束应用任何日志:
SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE FINISH;
或者:
SQL> alter database recover managed standbydatabase finish force;
FORCE 关键字将会停止当前活动的 RFS 进程,以便立刻执行 failover。
(3)转换备库为主库
SQL> alter database commit to switchover to primary with session shutdown;
SQL> alter database open;
注意这个时候主库已经不在dataguard中了。
3.使用闪回重建数据库
(1)获得原备库转换为主库时的 SCN。查询现主库102:
SQL> SELECT to_char(STANDBY_BECAME_PRIMARY_SCN) from V$DATABASE;
(2)在原主库101上执行:
SQL> SHUTDOWN IMMEDIATE;
SQL> STARTUP MOUNT;
SQL> FLASHBACK DATABASE TO SCN &standby_became_primary_scn;输入之前查询到的SCN号
如果没有开始闪回日志,最后一条命令会报错 ORA-38726: Flashback database logging is not on.,
无法进行闪回。你就需要重新从新主库复制数据,重建原主库为备库。
如果命令成功执行,原主库101就可以使用新主库102的日志进行恢复。将原主库101转换成物理备库,并启动日志应用进程:
SQL> ALTER DATABASE CONVERT TO PHYSICAL STANDBY;
SQL> SHUTDOWN IMMEDIATE;
SQL> STARTUP MOUNT;
SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT FROM SESSION;
4.客户端故障转移
我很喜欢的一个功能是,当主备切换或故障转移发生后,客户端能够自动重连。在你的系统里,做下述实验,看结果如何。
orcl 是主库,orcldg 是备库。客户端使用支持故障转移的 orcl_RW 服务名。
首先,用 SYSTEM 用户和 orcl_RW 服务名在 SQL*Plus 里登录主库:
SQL> connect system@orcl_rw
SQL> select db_unique_name from v$database;
查询应该返回主库名 orcl。然后做一次主备切换,在将备库转换为主库
alter database commit to switchover to primary with session shutdown; 这一步时,主备库均处于 MOUNT 状态。
然后执行查询:
SQL> select db_unique_name from v$database;
这时查询应该挂住,这是因为客户端正在尝试寻找主库,但当前又没有可用的主库。然后继续完成主备切换。
当主备切换完成后,客户端应该会重连并重新执行查询,查询完成后成功返回结果 orcldg,因为现在主库已经切换为 orcldg,
不再是orcl。
另一个很酷的测试方法是,执行一个执行时间非常长的查询,当查询结果返回,屏幕一直滚动时开始主备切换。
你应该会看到屏幕暂停滚动一段时间,当切换完成后,又会继续滚动。
5.活动数据卫士(active dataguard)
活动数据卫士是 11g 的新功能,它允许你的物理备库在应用日志时处于只读打开状态。这明显是一个很有用的功能。
能够允许主库有一个物理备库作为备份,并能在保持备库数据更新的同时读取备库,这是一个很好的功能。
调整备库为“READ ONLY WITH APPLY”状态,这体现的便是Oracle 11g物理Active Data Guard功能中的“Active”真实含义。
在实际工作中,这个功能非常好用,经常用于检查实时数据同步情况。
(1)查看备库openmode
sql>select open_mode from v$database;--MOUNTED
(2)取消备库的自动恢复
sql>alter database recover managed standby database cancel;
sql>alter database open;
sql>select open_mode from v$database; --这时候为READ ONLY
(3)read only下备库恢复
sql>alter database recover managed standby database using current logfile disconnect;
sql>select open_mode from v$database; --这时为READ ONLY WITH APPLY
6.11g standby的一些变化:
(1)standby数据库可以直接执行
startup --就是read only打开数据库
startup mount --就是mount standby数据库
(2)read only的情况下可以执行managed recover standby命令。
SQL>startup
SQL>alter database recover managed standby database disconnect;
7.关于备份的引申
有了 Data Guard,你的 RMAN 备份在主库或者备库都可以执行。但既然你已经配置了物理备库,你应该减轻点主库的负载。
基本上,能在主库执行的标准的备份命令或脚本,也能在备库执行,但也有几个值得注意地方。这些 Oracle 官方文档都有,
我只提几个关键的事情:
你应该使用恢复目录(Recovery Catalog)。这是因为主库需要知道备库已经存在了哪些备份文件。你不需要在恢复目录中
注册备库,恢复目录能认出它是备库。
你不能备份备库的控制文件,所以不要在主库关掉所有的备份,至少需要在主库备份控制文件和参数文件。
备份和恢复可以写一整篇文章,我只是讲下我是如何配置备份的,让你能从这里开始,修改并形成自己的策略。
测试下,确认你能从你当前实现的备份设置中恢复。在运行备份前,你需要配置一些基本的东西。
(1)确认开启控制文件和 spfile 自动备份:
RMAN> CONFIGURE CONTROLFILE AUTOBACKUP ON;
(2)根据你的需要设置备份文件保留策略:
RMAN> CONFIGURE RETENTION POLICY TO RECOVERY WINDOW OF 3 DAYS;
(3)如果一个文件已经有备份,并且检查点 SCN 相同,就不备份:
RMAN> CONFIGURE BACKUP OPTIMIZATION ON;
(4)只在主库的归档日志已经在备库应用(或者配置为已经传输到备份)后才删除:
RMAN> CONFIGURE ARCHIVELOG DELETION POLICY TO APPLIED ON ALL STANDBY;
(5)允许 RMAN 在主备间重新同步:
RMAN> CONFIGURE DB_UNIQUE_NAME P10AC CONNECT IDENTIFIER ‘JED’;
RMAN> CONFIGURE DB_UNIQUE_NAME P11AC CONNECT IDENTIFIER 'JED2';
在主库我仍然备份归档日志。首先,在主备库都备份归档提供了冗余。其次,当发生需要恢复的事件(比如数据文件下线等)后,
我在主库已经有归档了。我需要删除过期的归档,以清理磁盘空间。
在 Data Guard 环境下,不能使用标准的在单机删除归档的命令,两者有一点小区别。因为我们必须使用恢复目录,
我创建了一个全局脚本(global script):
create global script dg_primary_arch
{
backup archivelog all;
delete noprompt archivelog all completed before 'sysdate-.5';
delete noprompt backup of archivelog all completed before 'sysdate-2';
}
在备库我运行标准的全库和归档备份,并删除过期的备份集。在 Data Guard 环境下,将备份归档包含在备份全库的命令里,
会经常导致报错 RMAN-08137: WARNING: archived log not deleted, needed for standby or upstream capture process。
为避免此报错,你应该将备份归档放在单独的命令里。我还是创建一个全局脚本:
create global script dg_standby_full
{
backup database plus archivelog;
delete noprompt archivelog all completed before 'sysdate-1';
delete noprompt obsolete;
}
另外一个有用的技巧是,如果可能,使用共享文件系统进行备份。这样你在两台服务器上都可以访问备份文件。
这样,当你需要恢复时,你不需要从另一台服务器上复制文件了。但如果使用共享文件系统的话,你的归档备份虽然有两份,
却都放在一个文件系统里,如果硬盘出现故障,两份备份都会丢失。