一、环境介绍
操作系统:RHEL Linux 7.4(64位)
数据库版本:Oracle 11gR2 11.2.0.4 (64位)单实例
存储方式:文件系统
主数据库和备数据库目录一致、SID相同
--主数据库
IP地址:10.172.1.152
hostnme: orcldb
SID:orcl
db_name:orcl
db_unique_name:orcl_pri(唯一区分)
--备数据库
IP地址:10.172.1.144
hostnme: orcldb-dg
SID:orcl
db_name: orcl
db_unique_name:orcl_std(唯一区分)
二、环境准备
数据库安装过程:略...
注意:主库在安装完软件后需要进行DBCA 建库操作,推荐不要启用归档模式,会节省时间;备库端只安装数据库软件不要建库!
查看主数据库db_unique_name,并修改:
show parameter db_unique_name
alter system set db_unique_name='orcl_pri' scope=spfile;
alter system set db_unique_name='orcl_std' scope=spfile;
搭建DG必须开归档模式:
创建归档日志目录并赋权限
mkdir /u02/archivelog
chown oracle:oinstall /u02/archivelog -R
修改主库为归档模式:
SQL> archive log list;
SQL> shutdown immediate
SQL> startup mount
SQL> alter database archivelog;
SQL> alter system set log_archive_dest_1='location=/u02/archivelog';
SQL> alter database open;
三、搭建DataGuard
主库配置:
1、将主数据库改为强制日志模式并开启归档(此步骤只在主库上做)
[oracle@orcl ~]$ sqlplus / as sysdba
查看当前是否强制日志模式:
SYS@orcl> select name,log_mode,force_logging from v$database;
NAME LOG_MODE FOR
--------- ------------ ---
orcl NOARCHIVELOG NO
SYS@orcl> alter database force logging;
Database altered.
SYS@orcl> select name,log_mode,force_logging from v$database;
NAME LOG_MODE FOR
--------- ------------ ---
orcl NOARCHIVELOG YES
2、创建密码文件(此步骤只在主库上做)
注意:两端分别创建自己的密码文件好像有问题,备库的密码文件需要跟主库一致, 否则导致日志传输不到备库,有待验证。我最后是将主库的密码文件直接copy 到备库,重命名后使用。
[oracle@pri ~]$ cd $ORACLE_HOME/dbs
[oracle@pri dbs]$ orapwd file=orapworcl password=OraAdmin_HisDB force=y
这条命令可以手动生成密码文件,force=y 的意思是强制覆盖当前已有的密码文件
将主库的密码文件copy 给备库,并重命名:
[oracle@orcl dbs]$ scp orapworcl 10.172.1.118:$ORACLE_HOME/dbs/orapworcl
3、创建standby控制文件
SQL> alter database create standby controlfile as '/u02/backup/standby.ctl';
4、导出当前数据库参数文件
SQL> create pfile='/u02/backup/init.ora' from spfile;
# /u02/backup/是控制文件路径,只是为了保存init.ora文件,方便查找。
5、编辑init.ora文件,增加下面的内容
在主库创建 pfile 文件并修改 pfile 内容
SQL> create pfile from spfile;
[oracle@orcl dbs]$ cd $ORACLE_HOME/dbs
vi initorcl.ora
#添加一下内容
*.db_unique_name=orcl_pri
*.log_archive_config='dg_config=(orcl_pri,orcl_std)'
*.log_archive_dest_1='location=/u02/archivelog valid_for=(all_logfiles,all_roles) db_unique_name=orcl_pri'
*.log_archive_dest_2='service=orcl_std ASYNC NOAFFIRM valid_for=(online_logfiles,primary_role) db_unique_name=orcl_std'
*.log_archive_dest_state_1=enable
*.log_archive_dest_state_2=enable
*.log_archive_max_processes=30
*.fal_server='orcl_std'
*.fal_client='orcl_pri'
*.log_file_name_convert='/u01/app/oracle/oradata/orcl','/u01/app/oracle/oradata/orcl'
*.db_file_name_convert='/u01/app/oracle/oradata/orcl','/u01/app/oracle/oradata/orcl'
*.log_archive_format='%t_%s_%r.dbf'
*.standby_file_management='auto'
PS:该配置中的路径不是正确的,只是提供一个参考,具体的路径需根据实际情况配置。
6、重启数据库,以修改后的参数文件启动
SQL> shutdown immediate;
#使用新参数文件启动数据库
SQL> startup pfile='/u02/backup/initorcl.ora' nomount;
#创建新的spfile文件
SQL> create spfile from pfile='/u02/backup/initorcl.ora';
#停止服务
SQL> shutdown immediate;
#启动服务
SQL> startup;
7、修改监听文件,添加静态监听
修改listener.ora
监听服务文件路径: /u01/app/oracle/product/11.2.0/dbhome_1/network/admin/listener.ora
主库:
[oracle@orcl ~]$ cd $ORACLE_HOME/network/admin
[oracle@orcl admin]$ vim listener.ora 添加如下内容:
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = orcl_pri)
(ORACLE_HOME = /u01/app/oracle/product/11.2.0/dbhome_1)
(SID_NAME = orcl)
)
)
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = orcl)(PORT = 1521))
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC0))
)
)
ADR_BASE_LISTENER = /u01/app/oracle
使新增加的监听生效:
[oracle@pri admin]$ lsnrctl stop
[oracle@pri admin]$ lsnrctl start
确认新增加的静态监听有效:
主库:
[oracle@pri ~]$ lsnrctl status
编辑网络服务名配置文件tnsnames.ora (主库和备库端都要做)
[oracle@pri admin]$ cd $ORACLE_HOME/network/admin
[oracle@pri admin]$ pwd
/u01/app/oracle/product/11.2.0/dbhome_1/network/admin
[oracle@pri admin]$ ls
listener.ora samples shrept.lst tnsnames.ora
[oracle@pri admin]$ vi tnsnames.ora
ORCL_PRI =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = host-10-172-1-171)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = orcl_pri)
)
)
ORCL_STD =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = host-10-172-1-130)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = orcl_std)
)
)
特别说明一下在备库没有安装数据库的时候/u01/app/oracle/product/11.2.0/dbhome_1/network/admin 目录下没有tnsnames.ora 文件
此时需要手工建创建
保证主库和备库的tnsnames.ora文件中的内容完全相同,可以把修改后的文件直接传给备库。
[oracle@pri admin]$ scp tnsnames.ora 10.172.1.130:$ORACLE_HOME/network/admin
配置完后,确保在任意一端上都能tnsping 通对方:
[oracle@pri admin]$ tnsping orcl_pri
[oracle@std admin]$ tnsping orcl_std
#测试配置是否正确
SQL>sqlplus sys/pwd@orcl as sysdba
8、添加日志组作为standby redolog 日志组
查看当前线程与日志组的对应关系及日志组的大小:
SYS@pri> select thread#,group#,bytes/1024/1024 from v$log;
THREAD# GROUP# BYTES/1024/1024
--------------- ------------- ------------------------
1 1 500
1 2 500
1 3 500
如上,我现在的环境有三组redolog ,每个日志组的大小都是50M ,
所以Standby redo log 组数>=(3+1)*1== 4
所以至少需要创建4 组Standby redo log,大小均为50M
(thread:线程,只有在多实例数据库才有用的参数,例如RAC 环境,单实例不考虑)
SYS@pri> select group#,sequence#,status, bytes/1024/1024 from v$standby_log;
GROUP# MEMBER
---------- --------------------------------------------------
3 /u01/app/oracle/oradata/orcl/redo03.log
2 /u01/app/oracle/oradata/orcl/redo02.log
1 /u01/app/oracle/oradata/orcl/redo01.log
[oracle@pri dbs]$ cd /u01/app/oracle/oradata/orcl
新建4个日志组作为standby redolog 日志组,大小与原来的日志组一致:
alter database add standby logfile group 11 ('/u01/app/oracle/oradata/orcl/redo11_std.log') size 500M;
alter database add standby logfile group 12 ('/u01/app/oracle/oradata/orcl/redo12_std.log') size 500M;
alter database add standby logfile group 13 ('/u01/app/oracle/oradata/orcl/redo13_std.log') size 500M;
alter database add standby logfile group 14 ('/u01/app/oracle/oradata/orcl/redo14_std.log') size 500M;
查看standby 日志组的信息:
SYS@pri> select group#,sequence#,status, bytes/1024/1024 from v$standby_log;
GROUP# SEQUENCE# STATUS BYTES/1024/1024
---------- ------------------ ------------------- ------------------------
11 0 UNASSIGNED 500
12 0 UNASSIGNED 500
13 0 UNASSIGNED 500
14 0 UNASSIGNED 500
备库配置:
1、在备库创建相关的目录(只在备库端做)
因为我们的备库没有创建实例,所以是没有相关的目录的,我们需要参考主库的位置来创建。
将主库oracle目录下的admin,cfgtollogs,diag,flash_recover_area目录拷贝到备用库的相同路径,备库已经有的文件和文件夹直接覆盖掉吧。
归档日志文件存放目录:/u02/archivelog
审计文件目录:/u01/app/oracle/admin/orcl/adump
数据文件目录:/u01/app/oracle/oradata/orcl
闪回归档目录:/u01/app/oracle/fast_recovery_area/orcl
或者直接创建目录
[oracle@pri oracle]$ pwd /u01/app/oracle
[oracle@pri oracle]$ ls
admin checkpoints cfgtoollogs diag
--FRA目录
mkdir -p /u01/app/oracle/fast_recovery_area/orcl
--DATAFILE
mkdir -p /u01/app/oracle/oradata/orcl
--adump
mkdir -p /u01/app/oracle/admin/orcl/adump
--archivelog
mkdir -p /u02/archivelog
2、配置备库监听listener.ora和tnsname.ora
备库:
[oracle@dg ~]$ cd $ORACLE_HOME/network/admin
[oracle@dg admin]$ vim listener.ora
#添加如下内容:
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(GLOBAL_DBNAME = orcl_std)
(ORACLE_HOME = /u01/app/oracle/product/11.2.0/dbhome_1)
(SID_NAME = orcl)
)
)
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = orcl02)(PORT = 1521))
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC0))
)
)
ADR_BASE_LISTENER = /u01/app/oracle
配置tnsname.ora:
在备库没有安装数据库的时候/u01/app/oracle/product/11.2.0/dbhome_1/network/admin 目录下没有tnsnames.ora 文件
此时需要手工建创建(或者直接从主库拷贝):
[oracle@std admin]$ cd $ORACLE_HOME/network/admin
[oracle@std admin]$ pwd
/u01/app/oracle/product/11.2.0/dbhome_1/network/admin
[oracle@std admin]$ vi tnsnames.ora
ORCL_PRI =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = host-10-172-1-171)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = orcl_pri)
)
)
ORCL_STD =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = host-10-172-1-130)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = orcl_std)
)
)
配置完后,确保在任意一端上都能tnsping 通对方:
[oracle@std admin]$ tnsping orcl_pri
[oracle@std admin]$ tnsping orcl_std
3、修改备库参数文件并创建实例
将刚才从主库拷贝过来的init.ora作下面的修改,用下面的内容覆盖主库增加的内容。
#添加一下内容
*.db_unique_name=orcl_std
*.log_archive_config='dg_config=(orcl_pri,orcl_std)'
*.log_archive_dest_1='location=/u02/archivelog valid_for=(all_logfiles,all_roles) db_unique_name=orcl_std'
*.log_archive_dest_2='service=orcl_pri ASYNC NOAFFIRM valid_for=(online_logfiles,primary_role) db_unique_name=orcl_pri'
*.log_archive_dest_state_1=enable
*.log_archive_dest_state_2=enable
*.log_archive_max_processes=30
*.fal_server='orcl_pri'
*.fal_client='orcl_std'
*.log_file_name_convert='/u01/app/oracle/oradata/orcl','/u01/app/oracle/oradata/orcl'
*.db_file_name_convert='/u01/app/oracle/oradata/orcl','/u01/app/oracle/oradata/orcl'
*.log_archive_format='%t_%s_%r.dbf'
*.standby_file_management='auto'
4、使用新参数文件建立备库实例
#备库启动到nomount状态
SQL> startup nomount pfile='/u02/backup/initorcl.ora';
#生成spfile文件,然后重启
SQL> create spfile from pfile='/u02/backup/initorcl.ora';
SQL> shutdown immediate;
SQL> startup nomount;
5、启动备库为nomount,进行 duplicate恢复
#启动备用数据库为挂载备库模式
SQL> startup nomount;
#利用RMAN 在备库上恢复主库(备库端做),开始进行 duplicate
[oracle@ ~]$ rman target sys/Oracle123@orcl_pri auxiliary sys/Oracle123@orcl_std
注意:如果使用的是非catalog,在rman 连接时,加上nocatalog关键字,如:
[oracle@ ~]$ rman target sys/Oracle123@orcl_pri auxiliary sys/Oracle123@orcl_std nocatalog
Recovery Manager: Release 11.2.0.4.0 - Production on Wed Apr 19 18:15:53 2017
Copyright (c) 1982, 2011, Oracle and/or its affiliates. All rights reserved.
connected to target database: ORCL (mounted)
connected to auxiliary database: ORCL (not mounted)
--在执行duplicate的时候,如果源库和目标库目录相同,那么在duplicate 时,需要加上nofilenamecheck,如下:
RMAN> duplicate target database for standby from active database dorecover nofilenamecheck;
这条命令可以直接恢复数据文件,standby控制文件,standby日志组,非常霸道!
......
Finished Duplicate Db at 19-APR-17
RMAN>
恢复数据库结束
开启物理备库的实时redo应用:
SQL> alter database open;
SQL> alter database recover managed standby database using current logfile disconnect from session;
四、后续操作及验证
1、查看当前有哪些日志组及其成员:
SYS@pri> set pagesize 100
SYS@pri> col member for a60
SYS@pri> select group#,member from v$logfile order by group#;
GROUP# MEMBER
------------ ------------------------------------------------------------
1 /u01/app/oracle/oradata/orcl/redo01.log
2 /u01/app/oracle/oradata/orcl/redo02.log
3 /u01/app/oracle/oradata/orcl/redo03.log
4 /u01/app/oracle/oradata/orcl/redo11_stb.log
5 /u01/app/oracle/oradata/orcl/redo12_stb.log
6 /u01/app/oracle/oradata/orcl/redo13_stb.log
7 /u01/app/oracle/oradata/orcl/redo14_stb.log
2、更改主备库配置归档日志删除策略
#主库
CONFIGURE ARCHIVELOG DELETION POLICY TO APPLIED ON STANDBY;
这里有个警告, 解决方法,执行如下命令:
SQL> alter system set "_log_deletion_policy"=ALL scope=spfile sid='*';
#备库
CONFIGURE ARCHIVELOG DELETION POLICY TO NONE;
3、启停相关操作
关闭:先关闭主库,后关闭备库;
开启:先开备库启动备库监听,再开主库启动监听。
DG启动顺序:先standby后primary
#standby操作
SQL> startup nomount;
SQL> alter database mount standby database ;
SQL> alter database recover managed standby database using current logfile disconnect from session; #开启日志实时应用
lsnrctl start
#primary操作
SQL> startup
lsnrctl start
4、验证
主库:
SQL> create table test (x number(10));
Table created.
SQL> insert into test values(10);
1 row created.
SQL> commit;
Commit complete.
SQL> alter system switch logfile;
System altered.
备库:
SQL> desc test;
Name Null? Type
----------------------------------------- -------- ----------------------------
X NUMBER(10)
SQL> select * from test;
X
----------
10
###############################################################
查看DG状态:
SQL> select open_mode,database_role,switchover_status from v$database;
SQL> select name,open_mode,switchover#,database_role,switchover_status,guard_status,db_unique_name from v$database;
查看日志应用情况:
SYS@std> set pagesize 100
SYS@std> select sequence#,applied from v$archived_log order by 1;
SEQUENCE# APPLIED
---------- ---------
8 YES
9 YES
10 YES
如上,如果发现有个NO 的,也是正常的,说明该日志在主库上还没有归档,可以在主库上运行alter system switch logfile; 命令来进行日志切换,再到备库查看日志应用情况。
SQL> select process,status from v$managed_standby;
PROCESS STATUS
--------- ------------
ARCH CONNECTED
ARCH CONNECTED
ARCH CONNECTED
ARCH CLOSING
MRP0 WAIT_FOR_LOG
RFS IDLE
查看应用日志延迟时间:
SQL> select value from v$dataguard_stats where name='apply lag';
查看接收日志延迟时间:
SQL> select value from v$dataguard_stats where name='transport lag';
查看接受日志情况:
SQL> select max(sequence#) from v$archived_log where applied='YES';
查看主库和备库的归档序列号是否一致,结果完全一致,至此, DataGuard 的搭建成功!