Oracle 10GData Guard配置
目录
1. 概念介绍... 3
1.1 什么是Data Guard. 3
1.2 物理Standby. 3
1.3 逻辑Standby. 4
1.4 Data Guard保护模式... 4
1.5 Data Guard角色转换... 5
1.6 Data Guard特点... 5
2. 参数详解... 6
2.1 primary相关的参数... 6
2.2 Standby相关的参数... 6
3. 物理Standby. 6
3.1 设定环境... 6
3.2 Primary数据库配置... 7
3.2.1 配置监听器... 7
3.2.2 启动归档模式... 8
3.2.3 启动强制归档... 9
3.2.4 修改初始化参数文件... 9
3.2.5 创建Standby数据库控制文件... 11
3.2.6 创建Standby数据库密码文件... 11
3.2.7 复制数据文件... 11
3.3 Standby数据库配置... 12
3.3.1 配置监听器... 12
3.3.2 创建日志输出目录... 13
3.3.3 创建初始化参数文件... 13
3.3.4 启动Standby数据库到mount状态... 14
3.3.5 测试接收归档文件... 15
3.3.6 启动redo应用... 16
3.4 角色切换... 17
3.4.1 Switchover. 17
3.4.2 Failover. 18
3.5 切换保护模式... 19
4. 逻辑Standby. 20
4.1 逻辑Standby的缺点... 20
4.2 创建物理Standby. 20
4.3 设置Primary数据库... 20
4.4 转换物理Standby为逻辑Standby. 21
4.5 调整逻辑Standby初始化参数... 21
4.6 打开逻辑Standby应用redo. 22
4.7 验证环境... 23
5. Duplicate物理Standby. 23
5.1 设定环境... 23
5.2 创建相关目录... 24
5.3 配置辅助实例初始化参数... 24
5.4 创建辅助实例密码文件... 25
5.5 配置监听服务... 25
5.6 在Primary数据库端检查状态... 26
5.7 在Primary数据库端检查备份... 26
5.8 Rman连接目标库和辅助实例... 27
5.9 修改Primary数据库初始化参数... 27
5.10 验证物理standby数据库... 28
Data Guard是一种数据库级别的HA方案,最主要功能是冗灾、数据保护、故障恢复等。用来构建高可用的企业数据库应用环境。
Data Guard是一个集合,有一个Primary数据库(生产数据库)及一个或多个Standby数据库(备份数据库,最多9个)组成。Primary数据库可以是单实例主数据库,也可以是RAC结构。Standby数据库同样可以是单实例数据库,也可以是RAC结构。
Standby数据库通常分为两类:物理standby和逻辑standby。
物理standby:具体到数据库就是不仅文件的物理结构相同,甚至连块在磁盘上的存储位置都是一模一样的(默认情况下)。物理standby是通过接收并应用primary数据库的redo log以介质恢复的方式(将redo中发生了变化的块复制到standby)实现同步。我们知道物理standby与primary数据库完全一模一样(默认情况下,当然也可以不一样,事无绝对嘛),Data Guard通过redo应用维护物理standby数据库。通常在不应用恢复的时候,可以以read-only模式打开,如果数据库指定了flashback area的话,也可以被临时性的置为read-write模式。
redo应用:redo应用必须实在mount状态下。物理standby通过应用归档文件或直接从standby系统中通过oracle恢复机制应用redo文件。恢复操作属于块对块的应用(不理解?那就理解成块复制,将redo中发生了变化的块复制到standby)。如果正在应用redo,数据库不能被open。
Read-only模式:以read-only模式打开后,你可以在standby数据库执行查询,或者备份等操作(变相减轻primary数据库压力)。此时standby数据库仍然可以继续接收redo数据,不过并不会触发操作,直到数据库恢复redo应用。也就是说read-only模式时不能执行redo应用,redo应用时数据库肯定处于未打开状态。如果需要的话,你可以在两种状态间转换,比如先应用redo,然后read-only,然后切换数据库状态再应用redo,呵呵,人生就是循环,数据库也是一样。
Read-write模式:如果以read-write模式打开,则standby数据库将暂停从primary数据库接收redo数据,并且暂时失去灾难保护的功能。当然,以read-write模式打开也并非一无是处,比如你可能需要临时调试一些数据,但是又不方便在正式库操作,那就可以临时将standby数据库置为read-write模式,操作完之后将数据库闪回到操作前的状态(闪回之后,Data Guard会自动同步,不需要重建standby)。
物理standby特点
灾难恢复及高可用性
物理standby提供了一个健全而且极高效的灾难恢复及高可用性的解决方案。更加易于管理的switchover/failover角色转换及最更短的计划内或计划外停机时间。
数据保护
应用物理standby数据库,Dg能够确保即使面对无法预料的灾害也能够不丢失数据。前面也提到物理standby是基于块对块的复制,因此对象、语句统统无关,primary数据库上有什么,物理standby也会有什么。
分担primary数据库压力
通过将一些备份任务、仅查询的需求转移到物理standby,可以有效节省primary数据库的cpu以及i/o资源。
提升性能
物理standby所使用的redo应用技术使用最底层的恢复机制,这种机制能够绕过sql级代码层,因此效率最高。
逻辑standby:逻辑上与primary数据库相同,结构可以不一致。逻辑standby是将接收到的redo数据转换成sql语句,然后执行sql语句方式应用redo数据。逻辑standby通过sql应用与primary数据库保持一致,也正因如此,逻辑standby可以以read-write模式打开,你可以在任何时候访问逻辑standby数据库。同样有利也有弊,逻辑standby对于某些数据类型以及一些ddl,dml会有操作上的限制。
逻辑standby的特点:
除了上述物理standby中提到的类似灾难恢复,高可用性及数据保护等之外,还有下列一些特点:
有效的利用standby的硬件资源
除灾难恢复外,逻辑standby数据库还可用于其它业务需求。比如通过在standby数据库创建额外的索引、物化视图等提高查询性能并满足特定业务需要。又比如创建新的schema(primary数据库并不存在)然后在这些schema中执行ddl或者dml操作等。
分担primary数据库压力
逻辑standby数据库可以在更新表的时候仍然保持打开状态,此时这些表可同时用于只读访问。这使得逻辑standby数据库能够同时用于数据保护和报表操作,从而将主数据库从那些报表和查询任务中解脱出来,节约宝贵的 CPU和I/O资源。
平滑升级
比如跨版本升级啦,打小补丁啦等等,应该说应用的空间很大,而带来的风险却很小(前提是如果你拥有足够的技术实力。另外虽然物理standby也能够实现一些升级操作,但如果跨平台的话恐怕就力不从心,所以此项就不做为物理standby的特点列出了),我个人认为这是一种值的推荐的在线的滚动的平滑的升级方式。
Data Guard 保护模式(DataGuard Protection Modes)
最大保护(MAXIMIZEPROTECTION):
这种模式能够确保绝无数据丢失。要实现这一步当然是有代价的,它要求所有的事务在提交前其redo不仅被写入到本地的online redo log,还要同时提交到standby数据库的standby redo log,并确认redo数据至少在一个standby数据库可用(如果有多个的话),然后才会在primary数据库上提交。如果出现了什么故障导致standby数据库不可用的话,primary数据库会被shutdown。
最大性能(MAXIMIZEPERFORMANCE):
这种模式提供在不影响primary数据库性能前提下最高级别的数据保护策略。事务可以随时提交,当前primary数据库的redo数据也需要至少写入一个standby数据库,不过这种写入可以是不同步的。这种模式是缺省模式。
最大可用性(MAXIMIZEAVAILABILITY):
这种模式提供在不影响primary数据库可用前提下最高级别的数据保护策略。其实现方式与最大保护模式类似,也是要求所有事务在提交前必须保障redo数据至少在一个standby数据库可用,不过与之不同的是,如果出现故障导入无法同时写入standby数据库redo log,primary数据库并不会shutdown,而是自动转为最高性能模式,等standby数据库恢复正常之后,它又会再自动转换成最高可用性模式。
switchover:Primary数据库和Standby数据库之间的角色切换,如将Primary数据库转换成Standby数据库,将Standby数据库转换成Primary数据库。Switchover可以确保数据不会丢失。
failover:当Primary数据库出现故障并且不能被及时恢复试,就需要通过failover将data guard配置的其中一个Standby数据库转换为新的Primary数据库。在最大保护模式或最高可用性保护模式下,failover也可以保证不会丢数据。
Data Guard的特点如下:
灾难恢复及高可用性。
全面的数据保护。
有效利用系统资源。
有高可用及高性能之间更加灵活的平衡机制。
故障自动检查及解决方案。
集中的易用的管理模式。
自动化的角色转换。
a. DB_NAME,数据库名字,需要保持同一个Data Guard 中所有数据库DB_NAME相同。
b. DB_UNIQUE_NAME,对应数据库的实例名,每一个数据库需要指定一个唯一的名字。
c. LOG_ARCHIVE_CONFIG,该参数通过DG_CONFIG属性罗列同一个Data Guard 中所有DB_UNIQUE_NAME(含primary db 及standby db),以逗号分隔。
d. LOG_ARCHIVE_DEST_n,归档文件的生成路径,location代表本地机上,service指明在另一台机器上。
e. LOG_ARCHIVE_DEST_STATE_n,指定参数值为ENABLE,激活定义的归档日志目录,允许redo 传输服务传输redo数据到指定的路径。
f. REMOTE_LOGIN_PASSWORDFILE,推荐设置参数值为EXCLUSIVE或者SHARED,注意保证相同Data Guard配置中所有db 服务器sys密码相同。
注意:以下参数为standby角色相关的参数,建议在Primary数据库的初始化参数中也进行 设置,这样在role transition后(Primary转为Standby)也能正常运行。
a. FAL_SERVER,备库端的参数,给出Oracle网络服务名,通常为指向主库的连接串。
b. FAL_CLIENT,备库端的参数,给出Oracle网络服务名,通常为指向备库的连接串。
c. DB_FILE_NAME_CONVERT,主数据库和备用数据库的数据文件转换目录对映(如果两数据库的目录结构不一样),如果有多个对映,逐一指明对映关系。格式:*.db_file_name_convert=主数据库数据文件目录,备用数据库数据文件目录。
d. LOG_FILE_NAME_CONVERT,指明主数据库和备用数据库的log文件转换目录对映。格式:*. log_file_name_convert=主数据库log目录,备用数据库目录。
e. STANDBY_FILE_MANAGEMENT,如果primary 数据库数据文件发生修改(如新建,删除等)则按照本参数的设置在standby 中做相应修改。设为AUTO 表示自动管理。设为MANUAL表示需要手工管理。
|
主数据库 |
备份数据库 |
IP地址 |
10.10.10.9 |
10.10.10.10 |
DB_NAME |
orcl1 |
orcl1 |
DB_UNIQUE_NAME |
orcl1 |
orcl2 |
ORACLE_SID |
orcl1 |
orcl2 |
数据库软件安装路径 |
/u01/app/oracle/product/10.2.0/db_1 |
/u01/app/oracle/product/10.2.0/db_1 |
数据文件路径 |
/u01/app/oracle/oradata/orcl1 |
/u01/app/oracle/oradata/orcl2 |
本地归档路径 |
/u01/app/oracle/archivelog/orcl1 |
/u01/app/oracle/archivelog/orcl2 |
日志输出路径 |
/u01/app/oracle/admin/orcl1 |
/u01/app/oracle/admin/orcl2 |
存储体系 |
file system |
file system |
Host name |
primary |
standby |
注意:listener.ora和tnsnames.ora通常在$ORCLE_HOME/network/admin目录下面。
配置监听器其实就是在listener.ora文件里面加一段配置:
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = orcl1)
(ORACLE_HOME = /u01/app/oracle/product/10.2.0/db_1)
(SID_NAME = orcl1)
)
)
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 10.10.10.9)(PORT = 1521))
)
)
然后在tnsnames.ora里面还要加入一段代码:
orcl9 =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 10.10.10.9)(PORT = 1521))
)
(CONNECT_DATA =
(SID = orcl1)
(SERVER = DEDICATED)
)
)
orcl10 =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 10.10.10.10)(PORT = 1521))
)
(CONNECT_DATA =
(SID = orcl2)
(SERVER = DEDICATED)
)
)
最后启动监听器:lsnrctl start
测试一下:
[oracle@primary ~]$ tnsping orcl9
TNS Ping Utility for Linux: Version10.2.0.4.0 - Production on 17-AUG-2011 09:04:22
Copyright (c) 1997, 2007, Oracle. All rights reserved.
Used parameter files:
Used TNSNAMES adapter to resolve the alias
Attempting to contact (DESCRIPTION =(ADDRESS = (PROTOCOL = TCP)(HOST = 10.10.10.9)(PORT = 1521)) (CONNECT_DATA =(SERVER = DEDICATED) (SERVICE_NAME = orcl1)))
OK (10 msec)
[oracle@primary ~]$ tnsping orcl10
TNS Ping Utility for Linux: Version 10.2.0.4.0- Production on 17-AUG-2011 09:04:29
Copyright (c) 1997, 2007, Oracle. All rights reserved.
Used parameter files:
Used TNSNAMES adapter to resolve the alias
Attempting to contact (DESCRIPTION =(ADDRESS = (PROTOCOL = TCP)(HOST = 10.10.10.10)(PORT = 1521)) (CONNECT_DATA =(SERVER = DEDICATED) (SERVICE_NAME = orcl2)))
OK (170 msec)
只要能看见OK就是通过了!
由于Standby数据库还没有建立起来,这里还要测试一下从primary主机连Primary数据库:
sqlplus sys/oracle@orcl9 as sysdba
首先查看是否启用了归档模式:
SQL> archive log list
Database log mode No Archive Mode
Automatic archival Disabled
Archive destination /u01/app/oracle/product/10.2.0/db_1/dbs/arch
Oldest online log sequence 1
Current log sequence
中间我就不再详述了,只列出必要的命令:
SQL> alter system set log_archive_dest_1='location=/u01/app/oracle/archivelog/orcl1';
SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup mount
ORACLE instance started.
Total System Global Area 167772160 bytes
Fixed Size 1266392 bytes
Variable Size 62917928 bytes
Database Buffers 100663296 bytes
Redo Buffers 2924544 bytes
Database mounted.
SQL> alter database archivelog;
Database altered.
SQL> alter database open;
Database altered.
SQL> archive log list
Database log mode Archive Mode
Automatic archival Enabled
Archive destination /u01/app/oracle/archivelog/orcl1
Oldest online log sequence 1
Next log sequence to archive 2
Current log sequence 2
从最后可以看见归档模式已经启用了。
SQL> select force_logging fromv$database;
FOR
---
NO
SQL> alter database force logging;
Database altered.
SQL> select force_logging fromv$database;
FOR
---
YES
这里要修改的参数项比较多,当前使用的是spfile,所以我采用pfile来修改:
SQL> create pfile from spfile;
File created.
我修改后的pfile:
orcl1.__db_cache_size=100663296
orcl1.__java_pool_size=4194304
orcl1.__large_pool_size=4194304
orcl1.__shared_pool_size=54525952
orcl1.__streams_pool_size=0
*.audit_file_dest='/u01/app/oracle/admin/orcl1/adump'
*.background_dump_dest='/u01/app/oracle/admin/orcl1/bdump'
*.compatible='10.2.0.3.0'
*.control_files='/u01/app/oracle/oradata/orcl1/control01.ctl','/u01/app/oracle/oradata/orcl1/control02.ctl','/u01/app/oracle/oradata/orcl1/control03.ctl'
*.core_dump_dest='/u01/app/oracle/admin/orcl1/cdump'
*.db_block_size=8192
*.db_domain=''
*.db_file_multiblock_read_count=16
*.db_name='orcl1'
*.dispatchers='(PROTOCOL=TCP)(SERVICE=orcl1XDB)'
*.job_queue_processes=10
*.log_archive_dest_1='location=/u01/app/oracle/archivelog/orcl1'
*.open_cursors=300
*.pga_aggregate_target=16777216
*.processes=150
*.remote_login_passwordfile='EXCLUSIVE'
*.sga_target=167772160
*.undo_management='AUTO'
*.undo_tablespace='UNDOTBS1'
*.user_dump_dest='/u01/app/oracle/admin/orcl1/udump'
*.db_unique_name='orcl1'
*.log_archive_config='dg_config=(orcl1,orcl2)'
*.log_archive_dest_2='service=orcl10 archvalid_for=(online_logfiles,primary_role) db_unique_name=orcl2'
*.log_archive_dest_state_2='enable'
*.fal_server=orcl10
*.fal_client=orcl9
*.db_file_name_convert='/u01/app/oracle/oradata/orcl2','/u01/app/oracle/oradata/orcl1'
*.log_file_name_convert='/u01/app/oracle/oradata/orcl2','/u01/app/oracle/oradata/orcl1'
*.standby_file_management='auto'
通过pfile重建spfile:
SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> create spfile from pfile;
File created.
SQL> startup
ORACLE instance started.
Total System Global Area 167772160 bytes
Fixed Size 1266392 bytes
Variable Size 62917928 bytes
Database Buffers 100663296 bytes
Redo Buffers 2924544 bytes
Database mounted.
Database opened.
注意:只要是给Standby数据库准备的文件我都是放在/u01/standby目录。
SQL> alter database create standbycontrolfile as '/u01/standby/control01.ctl';
Database altered.
控制文件要3份,可以重复执行上面的命令3次,这里直接复制control01.ctl到3个:
[oracle@primary standby]$ cp control01.ctlcontrol02.ctl
[oracle@primary standby]$ cp control01.ctlcontrol03.ctl
因为在Data Guard中要求Primary数据库和Standby数据库的sys管理员用户的密码一样,这里我就复制Primary数据库的密码文件给Standby数据库:
[oracle@primary standby]
$ cp/u01/app/oracle/product/10.2.0/db_1/dbs/orapworcl1 ./orapworcl2
也可以使用如下命令创建:
[oracle@linux~]$ orapwd file='/u01/standby/orapworcl2' password=oracle entries=10
需要复制的文件包括:
密码文件:前面为Standby数据库准备的密码文件。
控制文件:就是前面给Standby数据库创建的控制文件,而不是Primary数据库的控制文件。
联机重做日志和归档重做日志:可以不复制,因为Primary数据库会自动发送到Standby数据库。
数据库文件:所以数据文件都要复制到Standby数据库
临时表空间:临时表空间可以不复制,因为数据库会自动创建。
这里我就把所以的都复制到Standby数据库,因为Primary数据库和Standby数据库都是采用的文件系统,我使用最简单的冷被份来复制所以的文件。
密码文件放到Standby数据库目录:/u01/app/oracle/product/10.2.0/db_1/dbs
归档日志文件放到Standby数据库目录:/u01/app/oracle/archivelog/orcl2
数据库文件、控制文件、联机重做日志文件、临时表空间放到Standby数据库目录:
/u01/app/oracle/oradata/orcl2
没有的目录就手动创建,注意权限!
注意:冷备份的优点是简单,缺点就是必须shutdown数据库或数据库处于mount状态。
和前面Primary数据库配置监听器一样。
listener.ora:
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = orcl2)
(ORACLE_HOME = /u01/app/oracle/product/10.2.0/db_1)
(SID_NAME = orcl2)
)
)
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 10.10.10.10)(PORT = 1521))
)
)
tnsnames.ora:
orcl9 =
(DESCRIPTION =
(ADDRESS_LIST=
(ADDRESS = (PROTOCOL = TCP)(HOST = 10.10.10.9)(PORT = 1521))
)
(CONNECT_DATA =
(SID = orcl1)
(SERVER = DEDICATED)
)
)
orcl10 =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 10.10.10.10)(PORT = 1521))
)
(CONNECT_DATA =
(SID = orcl2)
(SERVER = DEDICATED)
)
)
启动监听器:lsnrctl start
测试一下:
[oracle@standby admin]$ tnsping orcl9
TNS Ping Utility for Linux: Version10.2.0.4.0 - Production on 17-AUG-2011 09:44:04
Copyright (c) 1997, 2007, Oracle. All rights reserved.
Used parameter files:
Used TNSNAMES adapter to resolve the alias
Attempting to contact (DESCRIPTION =(ADDRESS = (PROTOCOL = TCP)(HOST = 10.10.10.9)(PORT = 1521)) (CONNECT_DATA =(SERVER = DEDICATED) (SERVICE_NAME = orcl1)))
OK (0 msec)
[oracle@standby admin]$ tnsping orcl10
TNS Ping Utility for Linux: Version10.2.0.4.0 - Production on 17-AUG-2011 09:44:08
Copyright (c) 1997, 2007, Oracle. All rights reserved.
Used parameter files:
Used TNSNAMES adapter to resolve the alias
Attempting to contact (DESCRIPTION =(ADDRESS = (PROTOCOL = TCP)(HOST = 10.10.10.10)(PORT = 1521)) (CONNECT_DATA =(SERVER = DEDICATED) (SERVICE_NAME = orcl2)))
OK (0 msec)
只要能看见OK就是通过了!
由于Standby数据库还没有建立起来,这里还要测试一下从standby主机连Primary数据库:
sqlplus sys/oracle@orcl9 as sysdba
[oracle@standby admin]$ cd/u01/app/oracle/admin/
[oracle@standby admin]$ mkdir orcl2
[oracle@standby admin]$ cd orcl2/
[oracle@standby orcl2]$ mkdir adump bdumpcdump udump
Standby数据库的初始化参数文件我使用Primary数据库的参数文件(pfile)来修改,修改后我们的Standby数据库参数文件如下:
orcl2.__db_cache_size=100663296
orcl2.__java_pool_size=4194304
orcl2.__large_pool_size=4194304
orcl2.__shared_pool_size=54525952
orcl2.__streams_pool_size=0
*.audit_file_dest='/u01/app/oracle/admin/orcl2/adump'
*.background_dump_dest='/u01/app/oracle/admin/orcl2/bdump'
*.compatible='10.2.0.3.0'
*.control_files='/u01/app/oracle/oradata/orcl2/control01.ctl','/u01/app/oracle/oradata/orcl2/control02.ctl','/u01/app/oracle/oradata/orcl2/control03.ctl'
*.core_dump_dest='/u01/app/oracle/admin/orcl2/cdump'
*.db_block_size=8192
*.db_domain=''
*.db_file_multiblock_read_count=16
*.db_name='orcl1'
*.dispatchers='(PROTOCOL=TCP)(SERVICE=orcl1XDB)'
*.job_queue_processes=10
*.log_archive_dest_1='location=/u01/app/oracle/archivelog/orcl2'
*.open_cursors=300
*.pga_aggregate_target=16777216
*.processes=150
*.remote_login_passwordfile='EXCLUSIVE'
*.sga_target=167772160
*.undo_management='AUTO'
*.undo_tablespace='UNDOTBS1'
*.user_dump_dest='/u01/app/oracle/admin/orcl2/udump'
*.db_unique_name='orcl2'
*.log_archive_config='dg_config=(orcl1,orcl2)'
*.log_archive_dest_2='service=orcl9 archvalid_for=(online_logfiles,primary_role) db_unique_name=orcl1'
*.log_archive_dest_state_2='enable'
*.fal_server=orcl9
*.fal_client=orcl10
*.db_file_name_convert='/u01/app/oracle/oradata/orcl1','/u01/app/oracle/oradata/orcl2'
*.log_file_name_convert='/u01/app/oracle/oradata/orcl1','/u01/app/oracle/oradata/orcl2'
*.standby_file_management='auto'
把修改好的参数文件放到/u01/app/oracle/product/10.2.0/db_1/dbs目录下面,取名为:initorcl2.ora,通过pfile创建spfile:
SQL> create spfile from pfile;
SQL> startup mount
ORACLE instance started.
Total System Global Area 167772160 bytes
Fixed Size 1266392 bytes
Variable Size 62917928 bytes
Database Buffers 100663296 bytes
Redo Buffers 2924544 bytes
Database mounted.
SQL> show parameter convert
NAME TYPE VALUE
----------------------------------------------- ------------------------------
db_file_name_convert string /u01/app/oracle/oradata/orcl1,
/u01/app/oracle/oradata/orcl2
log_file_name_convert string /u01/app/oracle/oradata/orcl1,
/u01/app/oracle/oradata/orcl2
SQL> select name from v$database;
NAME
---------
ORCL1
SQL> select instance_name fromv$instance;
INSTANCE_NAME
----------------
orcl2
SQL> select name from v$datafile;
NAME
--------------------------------------------------------------------------------
/u01/app/oracle/oradata/orcl2/system01.dbf
/u01/app/oracle/oradata/orcl2/undotbs01.dbf
/u01/app/oracle/oradata/orcl2/sysaux01.dbf
/u01/app/oracle/oradata/orcl2/users01.dbf
Primary数据库端输出:
SQL> select max(sequence#) fromv$archived_log;
MAX(SEQUENCE#)
--------------
SQL> alter system archive log current;
System altered.
SQL> select max(sequence#) fromv$archived_log;
MAX(SEQUENCE#)
--------------
2
Standby数据库端输出:
SQL> select max(sequence#) fromv$archived_log;
MAX(SEQUENCE#)
--------------
2
SQL> select sequence#,name fromv$archived_log;
SEQUENCE#
----------
NAME
--------------------------------------------------------------------------------
2
/u01/app/oracle/archivelog/orcl2/1_2_759394348.dbf
首先在Primary数据库端插入一些数据:
SQL> create table test(id int,valuevarchar2(10));
Table created.
SQL> insert into test values(1,'v1');
1 row created.
SQL> commit;
Commit complete.
SQL> select * from test;
ID VALUE
---------- ----------
1 v1
SQL> alter system archive log current;
System altered.
SQL> select max(sequence#) fromv$archived_log;
MAX(SEQUENCE#)
--------------
3
到Standby数据库端查看是否也存在,Standby数据库应用redo:
SQL> select max(sequence#) fromv$archived_log;
MAX(SEQUENCE#)
--------------
3
SQL> alter database recover managedstandby database disconnect from session;
Database altered.
SQL> alter database recover managedstandby database cancel;
Database altered.
SQL> alter database open;
Database altered.
SQL> select * from test;
ID VALUE
---------- ----------
1 v1
说明:
alter database recover managed standbydatabase disconnect from session;这个命令是接收并自动应用redo。
alter database recover managed standbydatabase cancel;是暂停应用redo,但是还是会继续接收。
在alter database open;数据库之前必须暂停应用redo。
在open状态下应用redo,会自动切换为mount状态:
SQL> alter database recover managedstandby database disconnect from session;
Database altered.
SQL> select status from v$instance;
STATUS
------------
MOUNTED
Primary数据库执行:
SQL> select switchover_status fromv$database;
SWITCHOVER_STATUS
--------------------
TO STANDBY
SQL> alter database commit to switchoverto physical standby;
Database altered.
SQL> shutdown immediate
ORA-01507: database not mounted
ORACLE instance shut down.
SQL> startup mount
ORACLE instance started.
Total System Global Area 167772160 bytes
Fixed Size 1266392 bytes
Variable Size 67112232 bytes
Database Buffers 96468992 bytes
Redo Buffers 2924544 bytes
Database mounted.
说明:
此时Primary数据库的switchover_status列的值应该是TO STANDBY,除了TO STANDBY还有SESSIONSACTIVE,说明当前有人连到数据库中,建议首先查询v$session视图,中止这些会话连接。如果胆大也可以在切换的时候加上with session shutdown子句,自动断开连接在实例中的会话:
SQL> alter database commit to switchoverto physical standby with session shutdown;
Standby数据库执行:
SQL> select switchover_status fromv$database;
SWITCHOVER_STATUS
--------------------
TO PRIMARY
SQL> alter database commit to switchoverto primary;
Database altered.
SQL> shutdown immediate
ORA-01507: database not mounted
ORACLE instance shut down.
SQL> startup
ORACLE instance started.
Total System Global Area 167772160 bytes
Fixed Size 1266392 bytes
Variable Size 62917928 bytes
Database Buffers 100663296 bytes
Redo Buffers 2924544 bytes
Database mounted.
Database opened.
说明:
此时Standby数据库的列值应该是TO PRIMARY,除了TO STANDBY还有SESSIONS ACTIVE,和前面的处理方式一样。另外还有SWITCHOVERPENDING,这说明当前Standby数据库没有启用redo应用,只需执行:
alter database recover managed standbydatabase disconnect from session;
切换完成以后,应该测试一下日志能否正常接收,前面已经讲过了,这里就不再介绍。
注意:failover之后,原Primary数据库不再是该DataGuard配置的一部分。
一般情况下failover都是表示Primary数据库瘫痪,最起码也是起不来了,因此这类型的切换基本上不需要Primary数据库做什么操作。所以下列步骤中如果有提到Primary数据库执行的,知己建议如果Primary数据库还可以用,那就执行一下,即时用不了,也没关系,不影响Standby数据库的切换,只是丢点数据罢了。
查询待转换Standby数据库的归档文件是否连续:
SQL> selectthread#,low_sequence#,high_sequence# from v$archive_gap;
no rows selected
如果有返回记录,安装列出的记录号复制对应的归档文件到Standby数据库。这一步非常重要,不然可能因数据不一致造成转换时报错。
文件复制过来,通过下列命令将其加入数据字典:
Alter database register physical logfile ‘filespec1’;
分别在Primary数据库和Standby数据库执行,检查归档文件是否完整:
SQL> select distinctthread#,max(sequence#) over(partition by thread#) a from v$archived_log;
Primary数据库和Standby数据库看到的序列号应该一样,不一样,就应该将多出的序列号文件复制到Standby数据库。不过既然是failover,那么Primary数据库此时无法打开,丢不丢数据就只好听天由命了。
启动failover:
SQL> alter database recover managedstandby database finish force;
切换物理的Standby数据库为Primary数据库:
SQL> alter database commit to switchoverto primary;
Database altered.
SQL> shutdown immediate
ORA-01109: database not open
Database dismounted.
ORACLE instance shut down.
SQL> startup
ORACLE instance started.
Total System Global Area 167772160 bytes
Fixed Size 1266392 bytes
Variable Size 67112232 bytes
Database Buffers 96468992 bytes
Redo Buffers 2924544 bytes
Database mounted.
Database opened.
注意:这里由于原Primary数据库并没有真正的瘫痪,只要重新创建控制文件,就又可以把原Primary数据库配置为Standby数据库。
SQL> select database_role,db_unique_name,protection_mode,protection_levelfrom v$database;
DATABASE_ROLE DB_UNIQUE_ PROTECTION_MODE PROTECTION_LEVEL
---------------- ------------------------------ --------------------
PHYSICAL STANDBY orcl2 MAXIMUM PERFORMANCE MAXIMUM PERFORMANCE
SQL> alter database set standby databaseto MAXIMIZE PROTECTION;
Database altered.
SQL> selectdatabase_role,db_unique_name,protection_mode,protection_level from v$database;
DATABASE_ROLE DB_UNIQUE_ PROTECTION_MODE PROTECTION_LEVEL
---------------- ------------------------------ --------------------
PHYSICAL STANDBY orcl2 MAXIMUM PROTECTION MAXIMUM PROTECTION
SQL> alter database set standby databaseto MAXIMIZE AVAILABILITY;
Database altered.
SQL> select database_role,db_unique_name,protection_mode,protection_levelfrom v$database;
DATABASE_ROLE DB_UNIQUE_ PROTECTION_MODE PROTECTION_LEVEL
---------------- ------------------------------ --------------------
PHYSICAL STANDBY orcl2 MAXIMUM AVAILABILITY MAXIMUM AVAILABILITY
在使用逻辑Standby时需要注意一下几点:
a. 并非所有的数据类型都能被逻辑Standby支持。
SQL> select * fromdba_logstdby_unsupported;
b. 并非所有的存储类型都能被逻辑Standby支持。
c. 并非所遇的PL/SQL包都能被SQL应用支持。
d. 并非所有的SQL语句都能在逻辑Standby端执行。
e. 并非所有的DML操作都能在逻辑Standby端实现SQL应用。
逻辑Standby是由物理Standby转换过去的,所以第一步就是创建物理Standby。注意,这个转换是单向的,并不能由逻辑Standby转换为物理Standby。这里就使用前面创建的物理Standby来转换为逻辑Standby,设定环境如下:
|
主数据库 |
备份数据库 |
IP地址 |
10.10.10.9 |
10.10.10.10 |
DB_NAME |
orcl1 |
orcl1 |
DB_UNIQUE_NAME |
orcl1 |
orcl2 |
ORACLE_SID |
orcl1 |
orcl2 |
数据库软件安装路径 |
/u01/app/oracle/product/10.2.0/db_1 |
/u01/app/oracle/product/10.2.0/db_1 |
数据文件路径 |
/u01/app/oracle/oradata/orcl1 |
/u01/app/oracle/oradata/orcl2 |
本地归档路径 |
/u01/app/oracle/archivelog/orcl1 |
/u01/app/oracle/archivelog/orcl2 |
日志输出路径 |
/u01/app/oracle/admin/orcl1 |
/u01/app/oracle/admin/orcl2 |
存储体系 |
file system |
file system |
Host name |
primary |
standby |
让Primary数据库生成数据字典,Primary数据库生成数据字典之前,一定要让Standby数据库已经停止redo应用:
SQL> alter database recover managedstandby database cancel;
Database altered.
Primary数据库执行下列过程来生成LogMiner字典信息:
SQL> execute dbms_logstdby.build;
PL/SQL procedure successfully completed.
SQL> show parameter db_name
NAME TYPE VALUE
----------------------------------------------- ------------------------------
db_name string ORCL1
SQL> alter database recover to logicalstandby orcl2;
Database altered.
SQL> shutdown immediate
ORA-01507: database not mounted
ORACLE instance shut down.
SQL> startup mount
ORACLE instance started.
Total System Global Area 167772160 bytes
Fixed Size 1266392 bytes
Variable Size 62917928 bytes
Database Buffers 100663296 bytes
Redo Buffers 2924544 bytes
Database mounted.
SQL> show parameter db_name
NAME TYPE VALUE
----------------------------------------------- ------------------------------
db_name string ORCL2
注意:
不同于物理Standby,逻辑Standby是一个全新的数据库,因此建议设定一个唯一的与Primary数据库不同的数据库名(orcl2)。
修改Primary数据库发送日志参数:
SQL> alter system setlog_archive_dest_2='service=orcl10 lgwr asyncvalid_for=(online_logfiles,primary_role) db_unique_name=orcl2';
在逻辑Standby设置重做日志文件路径,将本地生成的归档文件和Primary数据库发送过来的归档文件分开:
SQL> alter system setlog_archive_dest_1='location=/u01/app/oracle/archivelog/orcl2valid_for=(standby_logfiles,standby_role) db_unique_name=orcl2';
SQL> alter system setlog_archive_dest_3='location=/u01/app/oracle/archivelog/orcl2/localvalid_for=(online_logfiles,all_roles) db_unique_name=orcl2';
SQL>alter database open resetlogs;
Databasealtered.
SQL>alter database start logical standby apply;
Databasealtered.
注意:
取消应用redo:alter database stop logicalstandby apply;
如果要启用实时应用,建议首先创建standby redologs:
SQL>select * from v$logfile
GROUP# STATUS TYPE MEMBER IS_
-------------------- ------- ---------------------------------------- ---
3 ONLINE /u01/app/oracle/oradata/orcl2/redo03.log NO
2 ONLINE /u01/app/oracle/oradata/orcl2/redo02.log NO
1 ONLINE /u01/app/oracle/oradata/orcl2/redo01.log NO
SQL>alter database add standby logfile group 4 '/u01/app/oracle/oradata/orcl2/standby01.dbf'size 50m;
Databasealtered.
SQL>alter database add standby logfile group 5 '/u01/app/oracle/oradata/orcl2/standby02.dbf'size 50m;
Databasealtered.
SQL>alter database add standby logfile group 6 '/u01/app/oracle/oradata/orcl2/standby03.dbf'size 50m;
Databasealtered.
--删除:alter database drop standby logfile group 4;
注意:standby log要和Primary数据库的redo log大小一样。不然会引发错误:No standby redo logfiles of size 102400blocks exist
SQL>select * from v$logfile;
GROUP# STATUS TYPE MEMBER IS_
-------------------- ------- ---------------------------------------- ---
3 ONLINE /u01/app/oracle/oradata/orcl2/redo03.log NO
2 ONLINE /u01/app/oracle/oradata/orcl2/redo02.log NO
1 ONLINE /u01/app/oracle/oradata/orcl2/redo01.log NO
4 STANDBY/u01/app/oracle/oradata/orcl2/standby01. NO
dbf
5 STANDBY/u01/app/oracle/oradata/orcl2/standby02. NO
dbf
6 STANDBY/u01/app/oracle/oradata/orcl2/standby03. NO
dbf
GROUP# STATUS TYPE MEMBER IS_
-------------------- ------- ---------------------------------------- ---
6 rowsselected.
SQL>alter database stop logical standby apply;
Databasealtered.
SQL>alter database start logical standby apply immediate;
Databasealtered.
注意:在Primary数据库上sys用户create table无法应用到备库的。
首先在Primary数据库插入数据:
SQL>select * from test;
ID VALUE
--------------------
1 v1
SQL>insert into test values(2,'v2');
1 rowcreated.
SQL>commit;
Commitcomplete.
SQL>select * from test;
ID VALUE
--------------------
1 v1
2 v2
SQL>alter system switch logfile;
Systemaltered.
然后在逻辑Standby查询:
SQL>select * from test;
ID VALUE
--------------------
1 v1
2 v2
注意:duplicate数据库并不是为了故障切换而设计的,因此没有提供standby数据库的容灾功能,或者说仅能提供有限的容灾。大多数情况下duplicate数据库更适用于做测试服务器。
|
主数据库 |
备份数据库 |
IP地址 |
10.10.10.9 |
10.10.10.10 |
DB_NAME |
orcl1 |
orcl1 |
DB_UNIQUE_NAME |
orcl1 |
orcl2 |
ORACLE_SID |
orcl1 |
orcl2 |
数据库软件安装路径 |
/u01/app/oracle/product/10.2.0/db_1 |
/u01/app/oracle/product/10.2.0/db_1 |
数据文件路径 |
/u01/app/oracle/oradata/orcl1 |
/u01/app/oracle/oradata/orcl2 |
本地归档路径 |
/u01/app/oracle/archivelog/orcl1 |
/u01/app/oracle/archivelog/orcl2 |
日志输出路径 |
/u01/app/oracle/admin/orcl1 |
/u01/app/oracle/admin/orcl2 |
存储体系 |
file system |
file system |
Host name |
primary |
standby |
rman备份路径 |
/u01/app/oracle/rman |
/u01/app/oracle/rman |
[oracle@standby admin]$ mkdir orcl2
[oracle@standby admin]$ cd orcl2/
[oracle@standby orcl2]$ mkdir adump bdumpcdump udump pfile
[oracle@standby oracle]$ mkdir -p /u01/app/oracle/archivelog/orcl2
[oracle@standby oracle]$ mkdir -p /u01/app/oracle/oradata/orcl2
[oracle@standby oracle]$ mkdir -p/u01/app/oracle/rman
orcl2.__db_cache_size=100663296
orcl2.__java_pool_size=4194304
orcl2.__large_pool_size=4194304
orcl2.__shared_pool_size=54525952
orcl2.__streams_pool_size=0
*.audit_file_dest='/u01/app/oracle/admin/orcl2/adump'
*.background_dump_dest='/u01/app/oracle/admin/orcl2/bdump'
*.compatible='10.2.0.3.0'
*.control_files='/u01/app/oracle/oradata/orcl2/control01.ctl','/u01/app/oracle/oradata/orcl2/control02.ctl','/u01/app/oracle/oradata/orcl2/control03.ctl'
*.core_dump_dest='/u01/app/oracle/admin/orcl2/cdump'
*.db_block_size=8192
*.db_domain=''
*.db_file_multiblock_read_count=16
*.db_name='orcl1'
*.dispatchers='(PROTOCOL=TCP)(SERVICE=orcl1XDB)'
*.job_queue_processes=10
*.log_archive_dest_1='location=/u01/app/oracle/archivelog/orcl2valid_for=(all_logfiles,all_roles) db_unique_name=orcl2'
*.open_cursors=300
*.pga_aggregate_target=16777216
*.processes=150
*.remote_login_passwordfile='EXCLUSIVE'
*.sga_target=167772160
*.undo_management='AUTO'
*.undo_tablespace='UNDOTBS1'
*.user_dump_dest='/u01/app/oracle/admin/orcl2/udump'
*.db_unique_name='orcl2'
*.log_archive_config='dg_config=(orcl1,orcl2)'
*.db_file_name_convert='/u01/app/oracle/oradata/orcl1','/u01/app/oracle/oradata/orcl2'
*.log_file_name_convert='/u01/app/oracle/oradata/orcl1','/u01/app/oracle/oradata/orcl2'
*.standby_file_management='auto'
注意:由于standby数据库不准备执行角色切换,所以没有配置fail_*及其他归档目标等相关初始化参数。
通过pfile创建spfile:SQL> create spfilefrom pfile;
然后启动实例到nomount状态:SQL> startup nomount
orapwd file='/u01/app/oracle/product/10.2.0/db_1/dbs/orapworcl2'password=oracle entries=10
注意:这里的配置监听器,我是完全依照前面“物理standby”来配置的,就是在Primary数据库和standby数据库都配置了,这里贴出的只是Primary数据库的配置!
listener.ora和tnsnames.ora通常在$ORCLE_HOME/network/admin目录下面。
配置监听器其实就是在listener.ora文件里面加一段配置:
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = orcl1)
(ORACLE_HOME = /u01/app/oracle/product/10.2.0/db_1)
(SID_NAME = orcl1)
)
)
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 10.10.10.9)(PORT = 1521))
)
)
然后在tnsnames.ora里面还要加入一段代码:
orcl9 =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 10.10.10.9)(PORT = 1521))
)
(CONNECT_DATA =
(SID = orcl1)
(SERVER = DEDICATED)
)
)
orcl10 =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 10.10.10.10)(PORT = 1521))
)
(CONNECT_DATA =
(SID = orcl2)
(SERVER = DEDICATED)
)
)
最后启动监听器:lsnrctl start
SQL> archive log list
Database log mode Archive Mode
Automatic archival Enabled
Archive destination /u01/app/oracle/archivelog/orcl1
Oldest online log sequence 1
Next log sequence to archive 2
Current log sequence 2
SQL> select force_logging fromv$database;
FOR
---
YES
RMAN> list backup of database;
RMAN> backupdatabase plus archivelog format'/u01/app/oracle/rman/%d_%U';
RMAN> backup current controlfile for standby format '/u01/app/oracle/rman/%d_%U';
把备份生成的文件复制到standby数据库下对应目录下面。这里我的数据库还指定了闪回恢复区的,我还把flash_recovery_area里面的所以东西复制到standby数据库才成功的执行完的。
[oracle@standby ~]$ rman targetsys/oracle@orcl9 auxiliary sys/oracle@orcl10
RMAN> duplicate target database forstandby;
orcl1.__db_cache_size=100663296
orcl1.__java_pool_size=4194304
orcl1.__large_pool_size=4194304
orcl1.__shared_pool_size=54525952
orcl1.__streams_pool_size=0
*.audit_file_dest='/u01/app/oracle/admin/orcl1/adump'
*.background_dump_dest='/u01/app/oracle/admin/orcl1/bdump'
*.compatible='10.2.0.3.0'
*.control_files='/u01/app/oracle/oradata/orcl1/control01.ctl','/u01/app/oracle/oradata/orcl1/control02.ctl','/u01/app/oracle/oradata/orcl1/control03.ctl'
*.core_dump_dest='/u01/app/oracle/admin/orcl1/cdump'
*.db_block_size=8192
*.db_domain=''
*.db_file_multiblock_read_count=16
*.db_name='orcl1'
*.dispatchers='(PROTOCOL=TCP)(SERVICE=orcl1XDB)'
*.job_queue_processes=10
*.log_archive_dest_1='location=/u01/app/oracle/archivelog/orcl1'
*.open_cursors=300
*.pga_aggregate_target=16777216
*.processes=150
*.remote_login_passwordfile='EXCLUSIVE'
*.sga_target=167772160
*.undo_management='AUTO'
*.undo_tablespace='UNDOTBS1'
*.user_dump_dest='/u01/app/oracle/admin/orcl1/udump'
*.db_unique_name='orcl1'
*.log_archive_config='dg_config=(orcl1,orcl2)'
*.log_archive_dest_2='service=orcl10 archvalid_for=(online_logfiles,primary_role) db_unique_name=orcl2'
*.log_archive_dest_state_2='enable'
*.standby_file_management='auto'
首先在standby数据库应用redo:
SQL> alter database recover managedstandby database disconnect from session;
Database altered.
然后在Primary数据库切换日志:
SQL> select max(sequence#) fromv$archived_log;
MAX(SEQUENCE#)
--------------
7
SQL> alter system switch logfile;
System altered.
SQL> select max(sequence#) fromv$archived_log;
MAX(SEQUENCE#)
--------------
8
最后在standby数据库查询:
SQL> select max(sequence#) fromv$archived_log;
MAX(SEQUENCE#)
--------------
8