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
master(主库) 192.168.110.66 orcl mdb orcl
node01(备库) 192.168.110.88 orcl dg01 orcl
node02(备库) 192.168.110.99 orcl dg02 orcl

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

master机器上编辑环境变量

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=mdb
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

node01机器上编辑环境变量

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=dg01
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

node02机器上编辑环境变量

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=dg02
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

在master机器上执行 dbca 创建数据库

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

要求node01和node02密码文件一致

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

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

master和node01和node02的tnsnames.ora文件一致

master和node01两台机器的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
19
20
21
22
23
24
25
26
27
mdb =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.110.66)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = orcl)(UR=A)
)
)
dg01 =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.110.88)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = orcl)(UR=A)
)
)
dg02 =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.110.99)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = orcl)(UR=A)
)
)

master机器上保存退出后可以复制到node01和node02

1
2
$ scp $ORACLE_HOME/network/admin/tnsnames.ora node01:$ORACLE_HOME/network/admin/tnsnames.ora
$ scp $ORACLE_HOME/network/admin/tnsnames.ora node02:$ORACLE_HOME/network/admin/tnsnames.ora

master的监听文件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

node01的监听文件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

node02的监听文件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.99)(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

master和node01和node02启动监听服务(如果监听已经启动需要先关闭)

1
2
$ lsnrctl stop
$ lsnrctl start

master和node01和node02分别测试连接是否正常连接

master node01 node02 分别测试连接master和node01和node02

1
2
3
4
5
6
7
$ sqlplus /nolog 
SQL> conn sys/oracle@mdb as sysdba
Connected.
SQL> conn sys/oracle@dg01 as sysdba
Connected to an idle instance.
SQL> conn sys/oracle@dg02 as sysdba
Connected to an idle instance.

修改master的参数

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

1
2
3
4
5
6
7
8
9
10
11
12
SQL>  conn / as sysdba
SQL> alter system set db_unique_name='mdb' scope=spfile;
SQL> alter system set log_archive_config='dg_config=(mdb,dg01,dg02)';
SQL> alter system set log_archive_dest_2='service=dg01 async valid_for=(online_logfile,primary_role) db_unique_name=dg01';
SQL> alter system set log_archive_dest_3='service=dg02 async valid_for=(online_logfile,primary_role) db_unique_name=dg02';
SQL> alter system set fal_server=dg01,dg02;
SQL> alter system set fal_client=mdb;
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

master机器上数据库开启强制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;

查看master机器上数据库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

master机器上数据库增加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;

检查master和node01和node02文件夹创建对等目录

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

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

在node01机器上执行建立目录

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

在node02机器上执行建立目录

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

准备node01的initnode01.ora文件

1
2
3
4
master机器上执行(把master生成的pfile拷贝到node01)
$ cd $ORACLE_HOME/dbs
$ scp initorcl.ora node01:/u01/initnode01.ora
$ scp initorcl.ora node02:/u01/initnode02.ora

node01机器上打开文件 /u01/initnode01.ora 修改参数

1
2
3
4
5
6
7
*.fal_client=’dg01’
*.fal_server='mdb,dg02'
*.log_archive_dest_2='service=mdb async valid_for=(online_logfile,primary_role) db_unique_name=mdb'
*.log_archive_dest_3='service=dg02 async valid_for=(online_logfile,primary_role) db_unique_name=dg02'
追加参数
*.db_unique_name='dg01'
*.service_names=orcl;

node02机器上打开文件 /u01/initnode02.ora 修改参数

1
2
3
4
5
6
7
*.fal_client=’dg02’
*.fal_server='mdb,dg01'
*.log_archive_dest_2='service=mdb async valid_for=(online_logfile,primary_role) db_unique_name=mdb'
*.log_archive_dest_3='service=dg01 async valid_for=(online_logfile,primary_role) db_unique_name=dg01'
追加参数
*.db_unique_name='dg02'
*.service_names=orcl;

node01启动数据库到nomount使用initnode01.ora文件

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

node01创建spfile文件

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

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

node02启动数据库到nomount使用initnode02ora文件

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

node02创建spfile文件

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

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

master检查信息

(注意:log_file_name_convert 参数值为 orcl, orcl,如果master和node01的数据库名称不一致,需要修改这个参数,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 mdb
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

master机器上启动rman连接到mdb和dg01数据库执行

1
2
如果复制数据库时,备库的路径和原库一致,就需要加nofilenamecheck,不然会报错
$ rman target sys/oracle@mdb auxiliary sys/oracle@dg01

master在rman执行duplicate命令

1
RMAN> duplicate target database for standby from active database dorecover nofilenamecheck;

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

master机器上启动rman连接到mdb和dg02数据库执行

1
2
如果复制数据库时,备库的路径和原库一致,就需要加nofilenamecheck,不然会报错
$ rman target sys/oracle@mdb auxiliary sys/oracle@dg02

master在rman执行duplicate命令

1
RMAN> duplicate target database for standby from active database dorecover nofilenamecheck;

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

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

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
---------- -------------------- --- ---------------- --------------------
dg01 MOUNTED YES PHYSICAL STANDBY NOT ALLOWED

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

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

Database altered.

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

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
---------- -------------------- --- ---------------- --------------------
dg02 MOUNTED YES PHYSICAL STANDBY NOT ALLOWED

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

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

Database altered.

在node01和node02机器上的数据库的归档目录下查看日志归档文件。

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

1
2
3
SQL> alter system switch logfile;

System altered.

再次node01和node02机器上的数据库的归档目录下查看日志归档文件。
有新文件产生证明日志传过来了。

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

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

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

Dataguard 开关顺序

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