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> SELECT log_mode FROM v$database;
LOG_MODE
------------
ARCHIVELOG
如果是NOARCHIVELOG模式,则将其修改为ARCHIVELOG模式
SQL> SHUTDOWN IMMEDIATE;
SQL> STARTUP MOUNT;
SQL> ALTER DATABASE ARCHIVELOG;
SQL> ALTER DATABASE OPEN;
2. 启用强制日志
SQL> ALTER DATABASE FORCE LOGGING;
SQL> SELECT name,force_logging FROM v$database;
NAME FOR
--------- ---
HMDG YES
3. 创建密码文件
如果密码文件不存在,则创建一个密码文件,备用服务器使用主服务器的密码文件。Data Guard配置中的每个数据库的所有用户密码必须完全相同。
$ orapwd file=/tmp/orapwHMDG password=hm_201802 entries=20
4. 创建备用重做日志
备用重做日志文件的大小要与当前主数据库的在线重做日志文件大小完全匹配。
确定备用重做日志文件组的数量,建议的数量:(每个线程最大的日志数 + 1) * 最大线程数
SQL> SELECT * FROM v$log;
GROUP# THREAD# SEQUENCE# BYTES BLOCKSIZE MEMBERS ARC
---------- ---------- ---------- ---------- ---------- ---------- ---
STATUS FIRST_CHANGE# FIRST_TIM NEXT_CHANGE# NEXT_TIME
---------------- ------------- --------- ------------ ---------
1 1 40 104857600 512 1 YES
INACTIVE 769491 06-FEB-18 813871 07-FEB-18
2 1 41 104857600 512 1 NO
CURRENT 813871 07-FEB-18 2.8147E+14
3 1 39 104857600 512 1 YES
INACTIVE 742672 06-FEB-18 769491 06-FEB-18
#下面创建8组备用重做日志
SQL> ALTER DATABASE ADD STANDBY LOGFILE GROUP 4 '/u01/app/oracle/oradata/HMDG/redo04.log' SIZE 500M;
SQL> ALTER DATABASE ADD STANDBY LOGFILE GROUP 5 '/u01/app/oracle/oradata/HMDG/redo05.log' SIZE 500M;
SQL> ALTER DATABASE ADD STANDBY LOGFILE GROUP 6 '/u01/app/oracle/oradata/HMDG/redo06.log' SIZE 500M;
SQL> ALTER DATABASE ADD STANDBY LOGFILE GROUP 7 '/u01/app/oracle/oradata/HMDG/redo07.log' SIZE 500M;
SQL> ALTER DATABASE ADD STANDBY LOGFILE GROUP 8 '/u01/app/oracle/oradata/HMDG/redo08.log' SIZE 500M;
SQL> ALTER DATABASE ADD STANDBY LOGFILE GROUP 9 '/u01/app/oracle/oradata/HMDG/redo09.log' SIZE 500M;
SQL> ALTER DATABASE ADD STANDBY LOGFILE GROUP 10 '/u01/app/oracle/oradata/HMDG/redo10.log' SIZE 500M;
SQL> ALTER DATABASE ADD STANDBY LOGFILE GROUP 11 '/u01/app/oracle/oradata/HMDG/redo11.log' SIZE 500M;
#验证
SQL> SELECT GROUP#,THREAD#,SEQUENCE#,ARCHIVED,STATUS FROM V$STANDBY_LOG;
GROUP# THREAD# SEQUENCE# ARC STATUS
---------- ---------- ---------- --- ----------
4 0 0 YES UNASSIGNED
5 0 0 YES UNASSIGNED
6 0 0 YES UNASSIGNED
7 0 0 YES UNASSIGNED
8 0 0 YES UNASSIGNED
9 0 0 YES UNASSIGNED
10 0 0 YES UNASSIGNED
11 0 0 YES UNASSIGNED
8 rows selected.
5. 开启闪回日志
SQL> alter database flashback on;
SQL> select flashback_on from v$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 ~]$ sqlplus system/hm_123456@HMDG
SQL*Plus: Release 11.2.0.4.0 Production on Wed Feb 7 16:07:54 2018
Copyright (c) 1982, 2013, Oracle. All rights reserved.
Connected to:
Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production
With the Partitioning, OLAP, Data Mining and Real Application Testing options
SQL>
9. 主数据库初始化参数设置
检查DB_NAME和DB_UNIQUE_NAME参数设置,在我的例子中,主数据库的DB_NAME和DB_UNIQUE_NAME值都为HMDG。DB_NAME是主备所有节点都使用相同的值,即使用主的DB_NAME值,DB_UNIQUE_NAME必须是全局唯一的值,即每一个节点值都不同
SQL> SHOW PARAMETER DB_NAME
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_name string HMDG
SQL> SHOW PARAMETER DB_UNIQUE_NAME
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_unique_name string HMDG
#设置DB_UNIQUE_NAME参数值
SQL> ALTER SYSTEM SET DB_UNIQUE_NAME=HMDG SCOPE=SPFILE;
确定备库的DB_UNIQUE_NAME之后,接下来首先我们设置LOG_ARCHIVE_CONFIG参数
SQL> ALTER SYSTEM SET LOG_ARCHIVE_CONFIG='DG_CONFIG=(HMDG,HMDG2)' SCOPE=SPFILE;
配置主数据库本地归档日志的位置和远程备用数据重做日志的位置,注意LOG_ARCHIVE_DEST_1为本地的参数设置,LOG_ARCHIVE_DEST_2为远程节点的设置
SQL> ALTER SYSTEM SET LOG_ARCHIVE_DEST_1='LOCATION=/u01/app/oracle/oradata/HMDG VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=HMDG' SCOPE=SPFILE;
SQL> ALTER SYSTEM SET LOG_ARCHIVE_DEST_2='SERVICE=HMDG2 LGWR ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=HMDG2' SCOPE=SPFILE;
设置LOG_ARCHIVE_DEST_STATE_1和LOG_ARCHIVE_DEST_STATE_2的值为ENABLE
SQL> ALTER SYSTEM SET LOG_ARCHIVE_DEST_STATE_1=ENABLE SCOPE=SPFILE;
SQL> ALTER SYSTEM SET LOG_ARCHIVE_DEST_STATE_2=ENABLE SCOPE=SPFILE;
设置LOG_ARCHIVE_FORMAT和LOG_ARCHIVE_MAX_PROCESSES参数为合适的值,并且REMOTE_LOGIN_PASSWORDFILE必须设置为'EXCLUSIVE'
SQL> ALTER SYSTEM SET LOG_ARCHIVE_FORMAT = '%t_%s_%r.arc' SCOPE = SPFILE;
SQL> ALTER SYSTEM SET LOG_ARCHIVE_MAX_PROCESSES = 30 SCOPE = SPFILE;
SQL> ALTER SYSTEM SET REMOTE_LOGIN_PASSWORDFILE = EXCLUSIVE SCOPE = SPFILE;
接下来设置与备用数据库相关的参数值,确保主数据库已经准备好切换为备数据库
SQL> ALTER SYSTEM SET FAL_SERVER=HMDG2 SCOPE = SPFILE;
SQL> ALTER SYSTEM SET FAL_CLIENT=HMDG SCOPE = SPFILE;
SQL> ALTER SYSTEM SET DB_FILE_NAME_CONVERT='HMDG2','HMDG' SCOPE = SPFILE;
SQL> ALTER SYSTEM SET LOG_FILE_NAME_CONVERT='/u01/app/oracle/oradata/HMDG2/','/u01/app/oracle/oradata/HMDG/' SCOPE = SPFILE;
SQL> ALTER SYSTEM SET STANDBY_FILE_MANAGEMENT=AUTO SCOPE = SPFILE;
设置完主数据库初始化参数后,需要重新启动数据库配置才生效
SQL> shutdown immediate
SQL> startup
SQL> show parameter standby_file_management
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
standby_file_management string AUTO
10. 生成一个PFILE参数文件
在设置了主数据库初始化参数之后,我们可以手动生成一个主服务器的PFILE参数文件
SQL> CREATE PFILE FROM SPFILE;
查看$ORACLE_HOME/dbs/目录下生成的initHMDG.ora文件
$ cat initHMDG.ora
HMDG.__db_cache_size=234881024
HMDG.__java_pool_size=33554432
HMDG.__large_pool_size=1962934272
HMDG.__oracle_base='/u01/app/oracle'#ORACLE_BASE set from environment
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/HMDG VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=HMDG'
*.log_archive_dest_2='SERVICE=HMDG2 LGWR ASYNC VALID_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 ~]$ rman target = /
RMAN> BACKUP DATABASE PLUS ARCHIVELOG;
12. 创建备用数据库的控制文件和PFILE文件
创建备用数据库控制文件
SQL> ALTER DATABASE CREATE STANDBY CONTROLFILE AS '/tmp/HMDG2.ctl';
创建备用数据库的PFILE文件
SQL> CREATE PFILE='/tmp/initHMDG2.ora' FROM SPFILE;
备用数据库服务器设置
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. 将控制文件、参数文件和密码文件从主服务器上复制到备用服务器上
#控制文件
$ scp oracle@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
#密码文件
$ scp oracle@hmdb11dg-db1:/tmp/orapwHMDG /u01/app/oracle/product/11.2.0/db_1/dbs/orapwHMDG2
#参数文件
$ scp oracle@hmdb11dg-db1:/tmp/initHMDG2.ora /u01/app/oracle/product/11.2.0/db_1/dbs/
initHMDG2.ora
3. 修改备用数据库初始化参数
修改备用服务器的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/HMDG2 VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=HMDG2'
*.log_archive_dest_2='SERVICE=HMDG LGWR ASYNC VALID_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 / as sysdba
SQL> STARTUP NOMOUNT PFILE='/u01/app/oracle/product/11.2.0/db_1/dbs/initHMDG2.ora';
创建SPFILE文件
SQL> CREATE SPFILE FROM PFILE;
使用RMAN将主数据库复制到备用数据库,以sys用户连接,并使用DUPLICATE复制主库到备库
$ rman TARGET sys/hm_123456@HMDG AUXILIARY sys/hm_123456@HMDG2
使用以下DUPLICATE语句复制主库
DUPLICATE TARGET DATABASE FOR STANDBY FROM ACTIVE DATABASE;
在RMAN复制过程中如果没有产生任何错误,接下来就可以立即开启日志重做应用
SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE;
SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT FROM SESSION;
或者
SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT FROM SESSION;
取消申请恢复命令
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;
在主上强制主数据库上的日志切换器将当前的重做日志组归档
SQL> ALTER SYSTEM SWITCH LOGFILE;
在备上查询日志应用情况
SQL> select sequence#, first_time, applied from v$archived_log order by sequence#;
SEQUENCE# FIRST_TIM APPLIED
---------- --------- ---------
100 08-FEB-18 YES
101 08-FEB-18 YES
102 08-FEB-18 IN-MEMORY
在主上执行日志切换
ALTER SYSTEM SWITCH LOGFILE;
再查看备上日志应用
SQL> select sequence#, first_time, applied from v$archived_log order by sequence#;
SEQUENCE# FIRST_TIM APPLIED
---------- --------- ---------
100 08-FEB-18 YES
101 08-FEB-18 YES
102 08-FEB-18 YES
103 08-FEB-18 IN-MEMORY
主备切换
1. 主数据库
在当前主数据库中查询主备状态
SQL> SELECT SWITCHOVER_STATUS FROM V$DATABASE;
SWITCHOVER_STATUS
--------------------
TO STANDBY
当主数据库的状态为TO STANDBY时,表示可以切换到备用数据库
主上执行
SQL> ALTER DATABASE COMMIT TO SWITCHOVER TO PHYSICAL STANDBY WITH SESSION SHUTDOWN;
SQL> SHUTDOWN IMMEDIATE;
SQL> STARTUP MOUNT;
-- 在备切换为主时,将旧的主启动为备用数据库
SQL> STARTUP NOMOUNT;
SQL> ALTER DATABASE MOUNT STANDBY DATABASE;
SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT FROM SESSION;
2. 备数据库
在备上确定当前切换状态
SQL> SELECT SWITCHOVER_STATUS FROM V$DATABASE;
SWITCHOVER_STATUS
-----------------
TO_PRIMARY
1 row selected
备上执行
SQL> ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY;
-- 确认打开数据库
SQL> ALTER DATABASE OPEN;
-- 或者
SQL> SHUTDOWN IMMEDIATE;
SQL> STARTUP;