Oracle11g DataGuard配置(一主一备)

作者声明:本篇文章系本人依照真实部署过程原创,未经许可,谢绝转载。

环境准备

硬件环境:
我们使用VM虚拟机来安装两个Linux虚拟机。
虚拟机安装Oracle Linux 5.6 配置如下:
内存:2G
CPU:1个
磁盘:20G

操作系统:
Red Hat Enterprise Linux Server release 5.6 (Tikanga)

oracle数据库:
oracle 11.0.2.4

主机名 ip地址 db_name db_unique_name service_name
dg1(主库) 192.168.110.66 orcl dgs orcl
dg2(备库) 192.168.110.88 orcl dgt orcl

需要在两台虚拟机上分别安装oracle11g软件,只安装软件,不用建立数据库。我们可以先在一台虚拟机上安装好oracle11g,然后复制出来一份虚拟机,然后修改相关参数变成一台新的数据库服务器。
关于oracle11g数据库安装由于篇幅原因本文略过,本文主要是关于DataGuard配置。

dg1机器上编辑环境变量

oracle用户登录,在oracle用户home目录下编辑环境变量(可根据实际路径填写)
vi .bash_profile

1
2
3
4
5
6
7
8
9
10
export ORACLE_BASE=/u01/app/oracle
export ORACLE_HOME=$ORACLE_BASE/product/11.2.0.4/db_1
export ORACLE_SID=orcl
export ORACLE_UNQNAME=dgs
PATH=$ORACLE_HOME/bin:$PATH:$HOME/bin
LD_LIBARY_PATH=$ORACLE_HOME/lib:$LD_LIBARY_PATH
DISPLAY=192.168.110.1:0.0
export LANG=C
export ORACLE_BASE ORACLE_HOME ORACLE_SID PATH LD_LIBARY_PATH DISPLAY
umask 022

dg2机器上编辑环境变量

oracle用户登录,在oracle用户home目录下编辑环境变量(可根据实际路径填写)
vi .bash_profile

1
2
3
4
5
6
7
8
9
10
export ORACLE_BASE=/u01/app/oracle
export ORACLE_HOME=$ORACLE_BASE/product/11.2.0.4/db_1
export ORACLE_SID=orcl
export ORACLE_UNQNAME=dgt
PATH=$ORACLE_HOME/bin:$PATH:$HOME/bin
LD_LIBARY_PATH=$ORACLE_HOME/lib:$LD_LIBARY_PATH
DISPLAY=192.168.110.1:0.0
export LANG=C
export ORACLE_BASE ORACLE_HOME ORACLE_SID PATH LD_LIBARY_PATH DISPLAY
umask 022

在dg1上执行 dbca 创建数据库

数据库名orcl,数据库sys和system用户密码一样oracle(过程略过)。

要求dg1和dg2密码文件一致

dg1上数据库建立好后,要求dg1和dg2上数据库密码一致,在dg1上执行命令(dg1和dg2数据库名一致可以这样操作,dg1和dg2数据库名不一致则密码文件在dg2上需要改名,密码文件规则orapw+sid)

1
2
$ cd $ORACLE_HOME/dbs
$ scp orapworcl dg2:/u01/app/oracle/product/11.2.0.4/db_1/dbs/orapworcl

dg1和dg2的tnsnames.ora文件一致

dg1和dg2两台机器的tnsnames.ora文件一致,内容如下(注意service_name)
vi $ORACLE_HOME/network/admin/tnsnames.ora

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
dgs =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.110.66)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = orcl)(UR=A)
)
)
dgt =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.110.88)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = orcl)(UR=A)
)
)

dg1的监听文件listener.ora做静态注册

vi $ORACLE_HOME/network/admin/listener.ora

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.110.66)(PORT = 1521))
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
)
)

SID_LIST_LISTENER =(SID_LIST=
(SID_DESC=
(SID_NAME= orcl)
(ORACLE_HOME=/u01/app/oracle/product/11.2.0.4/db_1)
)
(SID_DESC=
(SID_NAME= PLSExtProc)
(ORACLE_HOME=/u01/app/oracle/product/11.2.0.4/db_1)
)
)

ADR_BASE_LISTENER = /u01/app/oracle

dg2的监听文件listener.ora做静态注册

vi $ORACLE_HOME/network/admin/listener.ora

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.110.88)(PORT = 1521))
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
)
)

SID_LIST_LISTENER =(SID_LIST=
(SID_DESC=
(SID_NAME= orcl)
(ORACLE_HOME=/u01/app/oracle/product/11.2.0.4/db_1)
)
(SID_DESC=
(SID_NAME= PLSExtProc)
(ORACLE_HOME=/u01/app/oracle/product/11.2.0.4/db_1)
)
)

ADR_BASE_LISTENER = /u01/app/oracle

dg1和dg2启动监听服务(如果监听已经启动需要先关闭)

1
2
$ lsnrctl stop
$ lsnrctl start

dg1和dg2分别测试连接是否正常连接

dg1 测试连接dgs和dgt

1
2
3
$ sqlplus /nolog 
SQL> conn sys/oracle@dgs as sysdba
SQL> conn sys/oracle@dgt as sysdba

dg2 测试连接dgs和dgt

1
2
3
$ sqlplus /nolog 
SQL> conn sys/oracle@dgs as sysdba
SQL> conn sys/oracle@dgt as sysdba

修改dg1的参数

修改dg1的参数(fal_server=对方 ,fal_client=自己, 值设置的是tns监听的名字,具体见下方)

1
2
3
4
5
6
7
8
9
10
11
SQL>  conn / as sysdba
SQL> alter system set db_unique_name='dgs' scope=spfile;
SQL> alter system set log_archive_config='dg_config=(dgs,dgt)';
SQL> alter system set log_archive_dest_2='service=dgt async valid_for=(online_logfile,primary_role) db_unique_name=dgt';
SQL> alter system set fal_server=dgt;
SQL> alter system set fal_client=dgs;
SQL> alter system set standby_file_management=auto;
SQL> alter system set service_names=orcl;

SQL> create pfile from spfile;
文件生成位置 /u01/app/oracle/product/11.2.0.4/db_1/dbs/initorcl.ora

dg1机器上数据库开启强制logging和归档模式

(归档模式需要数据库mount状态下修改)

1
2
3
4
5
SQL> shutdown immediate
SQL> startup mount
SQL> alter database archivelog;
SQL> alter database open;
SQL> alter database force logging;

查看dg1机器上数据库logfile信息确认logfile大小

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
SQL>  col member for a50;
SQL> select group#,status,type,member from v$logfile order by 1;

GROUP# STATUS TYPE MEMBER
---------- ------- ------- --------------------------------------------------
1 ONLINE /u01/app/oracle/oradata/orcl/redo01.log
2 ONLINE /u01/app/oracle/oradata/orcl/redo02.log
3 ONLINE /u01/app/oracle/oradata/orcl/redo03.log

SQL> select group#,bytes from v$log;

GROUP# BYTES
---------- ----------
1 52428800
2 52428800
3 52428800

dg1机器上数据库增加STANDBY LOGFILE

要求大小和logfile一致,组要求多一组

1
2
3
4
SQL> alter database add standby logfile '/u01/app/oracle/oradata/orcl/sredo01.rdo' size 52428800;
SQL> alter database add standby logfile '/u01/app/oracle/oradata/orcl/sredo02.rdo' size 52428800;
SQL> alter database add standby logfile '/u01/app/oracle/oradata/orcl/sredo03.rdo' size 52428800;
SQL> alter database add standby logfile '/u01/app/oracle/oradata/orcl/sredo04.rdo' size 52428800;

检查dg1和dg2文件夹创建对等目录

要求两边目录一致包含子目录

1
2
3
4
5
6
7
8
9
在dg1和dg2上分别执行 
$ cd $ORACLE_BASE
主要检查目录
admin
checkpoints
diag
fast_recovery_area
flash_recovery_area
oradata

在dg2上执行建立目录

1
2
3
4
5
6
7
8
$ cd $ORACLE_BASE
$ mkdir -p admin/orcl/adump
$ mkdir -p admin/orcl/dpdump
$ mkdir -p admin/orcl/pfile
$ mkdir -p oradata/orcl
$ mkdir -p fast_recovery_area/orcl
$ mkdir -p fast_recovery_area/ORCL
$ mkdir -p flash_recovery_area

准备dg2的initdgt.ora文件

1
2
3
dg1上执行(把dg1生成的pfile拷贝到dg2)
$ cd $ORACLE_HOME/dbs
$ scp initorcl.ora dg2:/u01/initdgt.ora

dg2上打开文件 /u01/initdgt.ora 修改参数

1
2
3
4
5
6
7
8
9
*.fal_client=’dgt’
*.fal_server='dgs'
修改
*.log_archive_dest_2='service=dgt async valid_for=(online_logfile,primary_role) db_unique_name=dgt'
修改为
*.log_archive_dest_3='service=dgs async valid_for=(online_logfile,primary_role) db_unique_name=dgs'
追加参数
*.db_unique_name='dgt'
*.service_names=orcl;

dg2启动数据库到nomount使用initdgt.ora文件

1
2
$ sqlplus / as sysdba
SQL> startup nomount pfile=/u01/initdgt.ora

dg2创建spfile文件

(目的下次启动自动读取spfile启动)

1
SQL> create spfile from pfile='/u01/initdgt.ora';

dg1检查信息

(注意:log_file_name_convert 参数值为 orcl, orcl,如果dg1和dg2的数据库名称不一致,需要修改这个参数,db_file_name_convert同理)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
SQL> show parameter name

NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
cell_offloadgroup_name string
db_file_name_convert string
db_name string orcl
db_unique_name string dgs
global_names boolean FALSE
instance_name string orcl
lock_name_space string
log_file_name_convert string
processor_group_name string
service_names string ORCL

dg1上启动rman连接到两个数据库执行

1
$ rman target sys/oracle@dgs auxiliary sys/oracle@dgt

dg1在rman执行duplicate命令

1
2
如果复制数据库时,备库的路径和原库一致,就需要加nofilenamecheck,不然会报错
RMAN> duplicate target database for standby from active database dorecover nofilenamecheck;

执行后查看信息(没有报错则正常执行,有报错需要排查相关错误后再次执行此命令)

执行成功后dg2下查询数据库状态

1
2
3
4
5
6
7
SQL> set lines 1000 pages 50000
SQL> col db_unique_name for a10
SQL> select db_unique_name ,open_mode,force_logging,database_role,switchover_status from v$database;

DB_UNIQUE_ OPEN_MODE FOR DATABASE_ROLE SWITCHOVER_STATUS
---------- -------------------- --- ---------------- --------------------
dgt MOUNTED YES PHYSICAL STANDBY NOT ALLOWED

dg2下执行命令,开始接收日志文件

1
2
3
SQL> alter database recover managed standby database using current logfile disconnect;

Database altered.

dg2下查看日志归档情况

dg1机器上数据库执行日志切换

1
2
3
SQL> alter system switch logfile;

System altered.

再次dg2下查看日志归档

有新文件产生证明日志传过来了

dg2目前运行在mount状态下,分别执行命令打开数据库

1
2
3
4
5
6
先停止redo应用
SQL> alter database recover managed standby database cancel;
打开dg2数据库
SQL> alter database open;
继续接收redo数据
SQL> alter database recover managed standby database using current logfile disconnect;

以上是Oracle11g DataGuard 一主一备配置的整个过程,我们可以在dg1数据库上某个用户下建立表插入数据,然后在dg2数据库执行查询查看效果(略过)。

Dataguard 开关顺序

关闭:先主后备
启动:先备后主