Oracle Data Guard是由Oracle公司提供的一套高可用性数据库解决方案。Data Guard可以确保企业数据的高可用性,并实现数据保护和灾难恢复。Data Guard提供了一套综合创建、维护、管理和监视一个或多个备用数据库的服务,使得用户能够轻松地应对Oracle生产数据库的灾难发生和数据损坏。Data Guard将维护的备用数据库保持为和主数据库(生产数据库)的数据和事物的一致性,当主数据库意外当机或者不可用时,Data Guard可以将任何一台备用数据库切换为主数据库,从而最大限度的减少数据库服务器当机的时间。
Data Guard原理
利用重做日志实现从生产库(主)到备用数据库的实时备份(备库通过应用主库上的数据变化来保持数据的同步),主备服务器可以互相切换(即将其中一台提升为主服务器)。
Data Guard架构
Primary Database(主数据库): 即一个生产数据库,在Data Guard中其主要角色的作用,是大多数应用程序访问的数据库。
Standby Database(备数据库): Standby数据库是主数据的备份副本,备用数据库可以是物理备用数据库或逻辑备用数据库,即以下两种类型
- Physical standby database: 物理备用数据库(使用Redo Apply技术),主要用于灾难恢复。
- Logical standby database: 逻辑备用数据库(使用sql Apply技术),除了用于灾难恢复外,还可以提供数据查询、分析等服务
Data Guard数据保护模式
Data Guard可以运行以三种不同的模式运行。
Maximum protection(最大保护): 确保主数据库发生故障时不会发生数据丢失。在所有重做数据写入到本地在线重做日志和至少一个备用数据库的备用重做日志之前,不允许事务的提交。如果由于故障不能将主数据库的重做日志写入到至少一个备用数据库的备用重做日志,则主数据库将关闭。
Maximum availability(最高可用性): 提供最高级别的数据保护,而不会影响主数据库的可用性。与最大保护模式一样,在恢复事物所需的重做日志写入本地联机重做日志和至少一个备用数据库的备用重做日志之前,事务不会提交。最大保护模式不同的是,在主数据库发生故障时不会将其重做日志写入备用数据库的重做日志。相反,主数据库以最大的性能模式下运行。
Maximum performance(最高性能): 默认模式。提供最高级别的数据保护,但不影响主数据库的性能。
环境准备
在我的测试环境中,我准备了两台CentOS7.4虚拟机,并同时都安装了Oracle11gR2的11.2.0.4.0企业版的数据库软件,其中只有主服务器创建一个数据库实例,备用服务器仅安装Oracle数据库软件。
主数据库:
OS: CentOS7.4
Hostname: hmdb11dg-db1
Oracle Version: 11.2.0.4.0
Oracle SID: HMDG(使用DBCA工具创建的一个数据库)
备数据库:
OS: CentOS7.4
Hostname: hmdb11dg-db2
Oracle Version: 11.2.0.4.0
Oracle SID: HMDG2
注意: 在开始之前,备用服务上还没有将要与主服务器同步备份的数据库实例
主数据库的设置
1. 启用归档日志
检查主数据是否处于归档日志模式
sql>SELECTlog_modeFROMv$database; LOG_MODE ------------ ARCHIVELOG
如果是NOARCHIVELOG模式,则将其修改为ARCHIVELOG模式
sql>SHUTDOWNIMMEDIATE; sql>STARTUPMOUNT; sql>ALTERDATABASEARCHIVELOG; sql>ALTERDATABASEOPEN;
2. 启用强制日志
sql>ALTERDATABASEFORCELOGGING; sql>SELECTname,force_loggingFROMv$database; NAMEFOR ------------ HMDGYES
3. 创建密码文件
如果密码文件不存在,则创建一个密码文件,备用服务器使用主服务器的密码文件。Data Guard配置中的每个数据库的所有用户密码必须完全相同。
$orapwdfile=/tmp/orapwHMDGpassword=hm_201802entries=20
4. 创建备用重做日志
备用重做日志文件的大小要与当前主数据库的在线重做日志文件大小完全匹配。
确定备用重做日志文件组的数量,建议的数量:(每个线程最大的日志数 + 1) * 最大线程数
sql>SELECT*FROMv$log; GROUP#THREAD#SEQUENCE#BYTESBLOCKSIZEMEMBERSARC --------------------------------------------------------------- STATUSFIRST_CHANGE#FIRST_TIMNEXT_CHANGE#NEXT_TIME ----------------------------------------------------------- 11401048576005121YES INACTIVE76949106-FEB-1881387107-FEB-18 21411048576005121NO CURRENT81387107-FEB-182.8147E+14 31391048576005121YES INACTIVE74267206-FEB-1876949106-FEB-18 #下面创建8组备用重做日志 sql>ALTERDATABASEADDSTANDBYLOGFILEGROUP4'/u01/app/oracle/oradata/HMDG/redo04.log'SIZE500M; sql>ALTERDATABASEADDSTANDBYLOGFILEGROUP5'/u01/app/oracle/oradata/HMDG/redo05.log'SIZE500M; sql>ALTERDATABASEADDSTANDBYLOGFILEGROUP6'/u01/app/oracle/oradata/HMDG/redo06.log'SIZE500M; sql>ALTERDATABASEADDSTANDBYLOGFILEGROUP7'/u01/app/oracle/oradata/HMDG/redo07.log'SIZE500M; sql>ALTERDATABASEADDSTANDBYLOGFILEGROUP8'/u01/app/oracle/oradata/HMDG/redo08.log'SIZE500M; sql>ALTERDATABASEADDSTANDBYLOGFILEGROUP9'/u01/app/oracle/oradata/HMDG/redo09.log'SIZE500M; sql>ALTERDATABASEADDSTANDBYLOGFILEGROUP10'/u01/app/oracle/oradata/HMDG/redo10.log'SIZE500M; sql>ALTERDATABASEADDSTANDBYLOGFILEGROUP11'/u01/app/oracle/oradata/HMDG/redo11.log'SIZE500M; #验证 sql>SELECTGROUP#,THREAD#,SEQUENCE#,ARCHIVED,STATUSFROMV$STANDBY_LOG; GROUP#THREAD#SEQUENCE#ARCSTATUS ------------------------------------------- 400YESUNASSIGNED 500YESUNASSIGNED 600YESUNASSIGNED 700YESUNASSIGNED 800YESUNASSIGNED 900YESUNASSIGNED 1000YESUNASSIGNED 1100YESUNASSIGNED 8rowsselected.
5. 开启闪回日志
sql>alterdatabaseflashbackon; sql>selectflashback_onfromv$database; FLASHBACK_ON ------------------ YES
6. Oracle监听配置
主备数据库必须配置注册静态监听服务(listener.ora配置)
#主数据库 $cat/u01/app/oracle/product/11.2.0/db_1/network/admin/listener.ora LISTENER= (DESCRIPTION_LIST= (DESCRIPTION= (ADDRESS=(PROTOCOL=TCP)(HOST=hmdb11dg-db1)(PORT=1521)) (ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC1521)) ) ) SID_LIST_LISTENER= (SID_LIST= (SID_DESC= (GLOBAL_DBNAME=HMDG.DB) (ORACLE_HOME=/u01/app/oracle/product/11.2.0/db_1) (SID_NAME=HMDG) ) ) ADR_BASE_LISTENER=/u01/app/oracle #备数据库 $cat/u01/app/oracle/product/11.2.0/db_1/network/admin/listener.ora LISTENER= (DESCRIPTION_LIST= (DESCRIPTION= (ADDRESS=(PROTOCOL=TCP)(HOST=hmdb11dg-db2)(PORT=1521)) (ADDRESS=(PROTOCOL=IPC)(KEY=EXTPROC1521)) ) ) SID_LIST_LISTENER= (SID_LIST= (SID_DESC= (GLOBAL_DBNAME=HMDG2.DB) (ORACLE_HOME=/u01/app/oracle/product/11.2.0/db_1) (SID_NAME=HMDG2) ) ) ADR_BASE_LISTENER=/u01/app/oracle
7. 主备数据库TNS别名连接信息配置
修改两台服务器上的$ORACLE_HOME/network/admin/tnsnames.ora配置文件,主备使用相同的配置
HMDG= (DESCRIPTION= (ADDRESS=(PROTOCOL=TCP)(HOST=hmdb11dg-db1)(PORT=1521)) (CONNECT_DATA= (SERVER=DEDICATED) (SERVICE_NAME=HMDG.DB) ) ) HMDG2= (DESCRIPTION= (ADDRESS=(PROTOCOL=TCP)(HOST=hmdb11dg-db2)(PORT=1521)) (CONNECT_DATA= (SERVER=DEDICATED) (SERVICE_NAME=HMDG2.DB) ) )
8. 测试使用TNS别名连接数据库
[oracle@hmdb11dg-db1~]$sqlplussystem/hm_123456@HMDG sql*Plus:Release11.2.0.4.0ProductiononWedFeb716:07:542018 Copyright(c)1982,2013,Oracle.Allrightsreserved. Connectedto: OracleDatabase11gEnterpriseEditionRelease11.2.0.4.0-64bitProduction WiththePartitioning,OLAP,DataMiningandRealApplicationTestingoptions sql>
9. 主数据库初始化参数设置
检查DB_NAME和DB_UNIQUE_NAME参数设置,在我的例子中,主数据库的DB_NAME和DB_UNIQUE_NAME值都为HMDG。DB_NAME是主备所有节点都使用相同的值,即使用主的DB_NAME值,DB_UNIQUE_NAME必须是全局唯一的值,即每一个节点值都不同
sql>SHOWPARAMETERDB_NAME NAMETYPEVALUE ----------------------------------------------------------------------------- db_namestringHMDG sql>SHOWPARAMETERDB_UNIQUE_NAME NAMETYPEVALUE ----------------------------------------------------------------------------- db_unique_namestringHMDG #设置DB_UNIQUE_NAME参数值 sql>ALTERSYSTEMSETDB_UNIQUE_NAME=HMDGSCOPE=SPFILE;
确定备库的DB_UNIQUE_NAME之后,接下来首先我们设置LOG_ARCHIVE_CONFIG参数
sql>ALTERSYSTEMSETLOG_ARCHIVE_CONFIG='DG_CONFIG=(HMDG,HMDG2)'SCOPE=SPFILE;
配置主数据库本地归档日志的位置和远程备用数据重做日志的位置,注意LOG_ARCHIVE_DEST_1为本地的参数设置,LOG_ARCHIVE_DEST_2为远程节点的设置
sql>ALTERSYSTEMSETLOG_ARCHIVE_DEST_1='LOCATION=/u01/app/oracle/oradata/HMDGVALID_FOR=(ALL_LOGFILES,ALL_ROLES)DB_UNIQUE_NAME=HMDG'SCOPE=SPFILE; sql>ALTERSYSTEMSETLOG_ARCHIVE_DEST_2='SERVICE=HMDG2LGWRASYNCVALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE)DB_UNIQUE_NAME=HMDG2'SCOPE=SPFILE;
设置LOG_ARCHIVE_DEST_STATE_1和LOG_ARCHIVE_DEST_STATE_2的值为ENABLE
sql>ALTERSYSTEMSETLOG_ARCHIVE_DEST_STATE_1=ENABLESCOPE=SPFILE; sql>ALTERSYSTEMSETLOG_ARCHIVE_DEST_STATE_2=ENABLESCOPE=SPFILE;
设置LOG_ARCHIVE_FORMAT和LOG_ARCHIVE_MAX_PROCESSES参数为合适的值,并且REMOTE_LOGIN_PASSWORDFILE必须设置为'EXCLUSIVE'
sql>ALTERSYSTEMSETLOG_ARCHIVE_FORMAT='%t_%s_%r.arc'SCOPE=SPFILE; sql>ALTERSYSTEMSETLOG_ARCHIVE_MAX_PROCESSES=30SCOPE=SPFILE; sql>ALTERSYSTEMSETREMOTE_LOGIN_PASSWORDFILE=EXCLUSIVESCOPE=SPFILE;
接下来设置与备用数据库相关的参数值,确保主数据库已经准备好切换为备数据库
sql>ALTERSYSTEMSETFAL_SERVER=HMDG2SCOPE=SPFILE; sql>ALTERSYSTEMSETFAL_CLIENT=HMDGSCOPE=SPFILE; sql>ALTERSYSTEMSETDB_FILE_NAME_CONVERT='HMDG2','HMDG'SCOPE=SPFILE; sql>ALTERSYSTEMSETLOG_FILE_NAME_CONVERT='/u01/app/oracle/oradata/HMDG2/','/u01/app/oracle/oradata/HMDG/'SCOPE=SPFILE; sql>ALTERSYSTEMSETSTANDBY_FILE_MANAGEMENT=AUTOSCOPE=SPFILE;
sql>shutdownimmediate sql>startup sql>showparameterstandby_file_management NAMETYPEVALUE ----------------------------------------------------------------------------- standby_file_managementstringAUTO
在设置了主数据库初始化参数之后,我们可以手动生成一个主服务器的PFILE参数文件
sql>CREATEPFILEFROMSPFILE;
查看$ORACLE_HOME/dbs/目录下生成的initHMDG.ora文件
$catinitHMDG.ora HMDG.__db_cache_size=234881024 HMDG.__java_pool_size=33554432 HMDG.__large_pool_size=1962934272 HMDG.__oracle_base='/u01/app/oracle'#ORACLE_BASEsetfromenvironment HMDG.__pga_aggregate_target=150994944 HMDG.__sga_target=3137339392 HMDG.__shared_io_pool_size=0 HMDG.__shared_pool_size=872415232 HMDG.__streams_pool_size=0 *.audit_file_dest='/u01/app/oracle/admin/HMDG/adump' *.audit_trail='db' *.compatible='11.2.0.4.0' *.control_files='/u01/app/oracle/oradata/HMDG/control01.ctl','/u01/app/oracle/fast_recovery_area/HMDG/control02.ctl' *.db_block_size=8192 *.db_domain='' *.db_file_name_convert='HMDG2','HMDG' *.db_name='HMDG' *.db_recovery_file_dest='/u01/app/oracle/fast_recovery_area' *.db_recovery_file_dest_size=10737418240 *.db_unique_name='HMDG' *.diagnostic_dest='/u01/app/oracle' *.dispatchers='(PROTOCOL=TCP)(SERVICE=HMDGXDB)' *.fal_client='HMDG' *.fal_server='HMDG2' *.log_archive_config='DG_CONFIG=(HMDG,HMDG2)' *.log_archive_dest_1='LOCATION=/u01/app/oracle/oradata/HMDGVALID_FOR=(ALL_LOGFILES,ALL_ROLES)DB_UNIQUE_NAME=HMDG' *.log_archive_dest_2='SERVICE=HMDG2LGWRASYNCVALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE)DB_UNIQUE_NAME=HMDG2' *.log_archive_dest_state_1='ENABLE' *.log_archive_dest_state_2='ENABLE' *.log_archive_format='%t_%s_%r.arc' *.log_archive_max_processes=30 *.log_file_name_convert='/u01/app/oracle/oradata/HMDG2/','/u01/app/oracle/oradata/HMDG/' *.memory_target=3277848576 *.open_cursors=300 *.processes=5000 *.remote_login_passwordfile='EXCLUSIVE' *.sessions=5505 *.standby_file_management='AUTO' *.undo_tablespace='UNDOTBS1'
11. 备份主数据库
为通过手动同步主数据库的原始数据文件创建备份,如果你使用的是RMAN 的DUPLICATE来恢复备用数据库,则不需要执行次步骤。
[oracle@hmdb11dg-db1~]$rmantarget=/ RMAN>BACKUPDATABASEPLUSARCHIVELOG;
sql>ALTERDATABASECREATESTANDBYCONTROLFILEAS'/tmp/HMDG2.ctl';
sql>CREATEPFILE='/tmp/initHMDG2.ora'FROMSPFILE;
备用数据库服务器设置
1. 备用数据库上创建必要的目录
$mkdir/u01/app/oracle/admin $mkdir/u01/app/oracle/admin/HMDG2 $mkdir/u01/app/oracle/admin/HMDG2/{adump,dpdump,pfile,scripts} $mkdir-p/u01/app/oracle/oradata/HMDG2 $mkdir-p/u01/app/oracle/fast_recovery_area/HMDG2
2. 将控制文件、参数文件和密码文件从主服务器上复制到备用服务器上
#控制文件 $scporacle@hmdb11dg-db1:/tmp/HMDG2.ctl/u01/app/oracle/oradata/HMDG2/control01.ctl $cp/u01/app/oracle/oradata/HMDG2/control01.ctl/u01/app/oracle/fast_recovery_area/HMDG2/control02.ctl #密码文件 $scporacle@hmdb11dg-db1:/tmp/orapwHMDG/u01/app/oracle/product/11.2.0/db_1/dbs/orapwHMDG2 #参数文件 $scporacle@hmdb11dg-db1:/tmp/initHMDG2.ora/u01/app/oracle/product/11.2.0/db_1/dbs/ initHMDG2.ora
修改备用服务器的PFILE文件$ORACLE_HOME/dbs/initHMDG.ora
... *.audit_file_dest='/u01/app/oracle/admin/HMDG2/adump' *.control_files='/u01/app/oracle/oradata/HMDG2/control01.ctl','/u01/app/oracle/fast_recovery_area/HMDG2/control02.ctl *.db_name='HMDG' *.db_unique_name='HMDG2' *.db_file_name_convert='HMDG','HMDG2' *.log_archive_config='DG_CONFIG=(HMDG,HMDG2)' *.log_archive_dest_1='LOCATION=/u01/app/oracle/oradata/HMDG2VALID_FOR=(ALL_LOGFILES,ALL_ROLES)DB_UNIQUE_NAME=HMDG2' *.log_archive_dest_2='SERVICE=HMDGLGWRASYNCVALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE)DB_UNIQUE_NAME=HMDG' *.fal_client='HMDG' *.fal_server='HMDG2 *.log_archive_dest_state_1='ENABLE' *.log_archive_dest_state_2='ENABLE' *.log_archive_format='%t_%s_%r.arc' *.log_archive_max_processes=30 *.log_file_name_convert='/u01/app/oracle/oradata/HMDG/','/u01/app/oracle/oradata/HMDG2/' ...
创建备用数据库(DUPLICATE)
使用备库的PFILE文件以NOMOUNT模式启动备用数据库实例
$sqlplus/assysdba sql>STARTUPNOMOUNTPFILE='/u01/app/oracle/product/11.2.0/db_1/dbs/initHMDG2.ora';
创建SPFILE文件
sql>CREATESPFILEFROMPFILE;
使用RMAN将主数据库复制到备用数据库,以sys用户连接,并使用DUPLICATE复制主库到备库
$rmanTARGETsys/hm_123456@HMDGAUXILIARYsys/hm_123456@HMDG2
使用以下DUPLICATE语句复制主库
DUPLICATETARGETDATABASEFORSTANDBYFROMACTIVEDATABASE;
在RMAN复制过程中如果没有产生任何错误,接下来就可以立即开启日志重做应用
sql>ALTERDATABASERECOVERMANAGEDSTANDBYDATABASEUSINGCURRENTLOGFILE; sql>ALTERDATABASERECOVERMANAGEDSTANDBYDATABASEDISCONNECTFROMSESSION; 或者 sql>ALTERDATABASERECOVERMANAGEDSTANDBYDATABASEUSINGCURRENTLOGFILEDISCONNECTFROMSESSION;
取消申请恢复命令
ALTERDATABASERECOVERMANAGEDSTANDBYDATABASECANCEL;
在主上强制主数据库上的日志切换器将当前的重做日志组归档
sql>ALTERSYSTEMSWITCHLOGFILE;
在备上查询日志应用情况
sql>selectsequence#,first_time,appliedfromv$archived_logorderbysequence#; SEQUENCE#FIRST_TIMAPPLIED ---------------------------- 10008-FEB-18YES 10108-FEB-18YES 10208-FEB-18IN-MEMORY
在主上执行日志切换
ALTERSYSTEMSWITCHLOGFILE;
再查看备上日志应用
sql>selectsequence#,appliedfromv$archived_logorderbysequence#; SEQUENCE#FIRST_TIMAPPLIED ---------------------------- 10008-FEB-18YES 10108-FEB-18YES 10208-FEB-18YES 10308-FEB-18IN-MEMORY
主备切换
1. 主数据库
sql>SELECTSWITCHOVER_STATUSFROMV$DATABASE; SWITCHOVER_STATUS -------------------- TOSTANDBY
当主数据库的状态为TO STANDBY时,表示可以切换到备用数据库
主上执行
sql>ALTERDATABASECOMMITTOSWITCHOVERTOPHYSICALSTANDBYWITHSESSIONSHUTDOWN; sql>SHUTDOWNIMMEDIATE; sql>STARTUPMOUNT; --在备切换为主时,将旧的主启动为备用数据库 sql>STARTUPNOMOUNT; sql>ALTERDATABASEMOUNTSTANDBYDATABASE; sql>ALTERDATABASERECOVERMANAGEDSTANDBYDATABASEDISCONNECTFROMSESSION;
2. 备数据库
在备上确定当前切换状态
sql>SELECTSWITCHOVER_STATUSFROMV$DATABASE; SWITCHOVER_STATUS ----------------- TO_PRIMARY 1rowselected
备上执行
sql>ALTERDATABASECOMMITTOSWITCHOVERTOPRIMARY; --确认打开数据库 sql>ALTERDATABASEOPEN; --或者 sql>SHUTDOWNIMMEDIATE; sql>STARTUP;