Oracle11g DataGuard配置

注意
本文最后更新于 2023-11-24,文中内容可能已过时。

摘要

Oracle Data Guard 是针对企业数据库的最有效和最全面的数据可用性、数据保护和灾难恢复解决方案。它提供管理、监视和自动化软件基础架构来创建和维护一个或多个同步备用数据库,从而保护数据不受故障、灾难、错误和损坏的影响。一台主数据库最多可以配备 9 个备数据库。

主库:192.168.1.67 全局数据库名:orcl 实例名:orcl

备库:192.168.1.69 全局数据库名:orcl 实例名:orcl

操作系统:Centos7 64Bit

oracle 版本:11.2.0.4

https://img.bwcxtech.com/img/20200928170655.jpeg

https://img.bwcxtech.com/img/20200928170704.jpeg

  • 主数据库服务器和备数据库服务器的操作系统版本必须一致。

  • 主数据库服务器和备数据库服务器的数据库版本必须一致。

  • 主数据库服务器和备数据库服务器的安装目录必须一致。

Data Guard有以下几种搭建方式

  • 基于拷贝文件的方式进行搭建(源库可以关闭的情况下);
  • 采用rman备份进行恢复的方式进行搭建(本地空间足够的情况下);
  • 基于rman duplicate在线方式进行搭建(本地空间不足的情况下可以用此方式);
  • 基于dgbroker方式进行dg搭建

本次采用基于拷贝文件的方式进行搭建

以下步骤主库和备库的操作完全相同

1
2
[root@primarydb ~]# su - oracle
[oracle@primarydb ~]$ sqlplus / as sysdba;
1
SQL> shutdown immediate;
1
SQL> startup mount;

更改数据库为归档模式

1
SQL> alter database archivelog;

查询控制文件存放周期

1
SQL> show parameter control_file_record_keep_time;

指定控制文件存放周期

1
SQL> alter system set control_file_record_keep_time=30 scope=both;

查询归档日志文件路径

1
SQL> archive log list;

设置归档日志文件路径

1
[oracle@primarydb ~]# mkdir -p /data/oracle/archivelog
1
SQL> alter system set log_archive_dest_1='location=/data/oracle/archivelog/' scope=both;
1
SQL> alter database open;

启用自动归档

1
SQL> alter system archive log start;

未开启归档模式是无法开启闪回功能的

查看闪回目录

1
SQL> show parameter db_recovery_file_dest

查看闪回目录可用大小

1
SQL> show parameter db_recovery_file_dest_size

修改闪回目录位置:

1
SQL> alter system set db_recovery_file_dest='newpath';

修改闪回目录大小

1
SQL> alter system set db_recovery_file_dest_size=400G;

注:以上可根据实际情况修改,不一定都需要执行。

查看闪回功能是否启用,默认不启用

1
SQL> select flashback_on from v$database;

启用闪回功能:

1
SQL> alter database flashback on;
1
2
3
4
SQL> select flashback_on from v$database;
FLASHBACK_ON
------------------
YES

如果是 true 表示已经安装可以配置,否则需要安装相应组件,此组件只有安装企业版才有。

1
2
3
4
5
6
7
SQL> select * from v$option where parameter = 'Oracle Data Guard';
PARAMETER
----------------------------------------------------------------
VALUE
----------------------------------------------------------------
Oracle Data Guard
TRUE
1
SQL> alter database force logging;
1
2
3
4
SQL> select name,force_logging from v$database;
NAME FOR
--------- ---
ORCL YES
1
SQL> alter system set standby_file_management='AUTO' scope=both;
1
2
3
4
SQL> show parameter standby_file_management
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
standby_file_management string AUTO

建立 standby log要注意以下几点:

a) standby log files 的大小和 redo log files 一样。

查询 redo log files 文件大小(默认 50M,3 个):

1
SQL> select group#,bytes/1024/1024 as M from v$log;

b) 一般而言,standby redo日志文件组数要比 primary 数据库的online redo日志文件组数至少多一个。

有一个推荐的公式可以做参考:(每线程的日志组数+1)*最大线程数

假设现在节点是 1 个,则=(3+1)*1=4

如果是双节点 则=(3+1)*2=8

这里创建 4 个standby logfile:

1
SQL> alter database add standby logfile group 11 '/data/oracle/oradata/orcl/standby11.log' size 50M;
1
SQL> alter database add standby logfile group 12 '/data/oracle/oradata/orcl/standby12.log' size 50M;
1
SQL> alter database add standby logfile group 13 '/data/oracle/oradata/orcl/standby13.log' size 50M;
1
SQL> alter database add standby logfile group 14 '/data/oracle/oradata/orcl/standby14.log' size 50M;

另:不建议组号 group#紧挨着 redo,因为后续 redo 有可能调整,这里建立从 11 到 14 的standby logfile

注:/data/oracle/oradata/orcl/standby14.log可以自定义文件名,但是目录必须存在,文件名必须不存在

以上的配置主库备库要一致。

删除日志组(有问题时才删除,这里不进行删除)

1
SQL> alter database drop standby logfile group 11;
1
SQL> alter database drop standby logfile group 12;
1
SQL> alter database drop standby logfile group 13;
1
SQL> alter database drop standby logfile group 14;

配置参数参考链接

查看db_unique_name

主库:

1
SQL> alter system set db_unique_name=primarydb scope=spfile;
1
SQL> startup force;
1
2
3
4
SQL> show parameter db_unique_name
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_unique_name string PRIMARYDB

备库:

1
SQL> alter system set db_unique_name=standbydb scope=spfile;
1
SQL> startup force;
1
2
3
4
SQL> show parameter db_unique_name
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
db_unique_name string STANDBYDB
1
SQL> alter system set FAL_SERVER='standbydb';

FAL_SERVER参数定义为指向主库或者任意备库的TNS标识符列表,与tnsnames.ora文件中配置相符即可

1
SQL> alter system set log_archive_config = 'dg_config=(primarydb,standbydb)';

LOG_ARCHIVE_CONFIG该参数定义了DG配置中可用的DB_UNIQUE_NAME参数值列表。与目标参数(稍后讨论)DB_UNIQUE_NAME的值结合使用时,DG以它们来实现两个数据库之间连接的安全性检查工作。

1
SQL> alter system set FAL_SERVER='primarydb';
1
SQL> alter system set log_archive_config = 'dg_config=(primarydb,standbydb)';

dataguard(简称DG)有两种传输模式:async(异步)和sync(同步)

注:standbydb为备库的db_unique_name

1
SQL> alter system set log_archive_dest_2='service=standbydb lgwr async affirm valid_for=(online_logfile,primary_role) db_unique_name=standbydb';

注:primarydb为备库的db_unique_name

1
SQL> alter system set log_archive_dest_2='service=primarydb lgwr async affirm valid_for=(online_logfile,primary_role) db_unique_name=primarydb';

a) 关闭主库和备库:shutdown immediate

备库:

1
SQL> shutdown immediate;

主 库:

1
SQL> shutdown immediate;

b) 将主库的密码文件复制到备库(主库操作)

1
[oracle@primarydb ~]$ scp $ORACLE_HOME/dbs/orapworcl oracle@standbydb:$ORACLE_HOME/dbs/

a) 在主库创建 standby 控制文件

1
2
[oracle@primarydb ~]# sqlplus / as sysdba;
SQL> startup mount;
1
SQL> alter database create standby controlfile as '/data/oracle/oradata/orcl/standby_control01.ctl';

b) 从主库将 standby 控制文件复制到备库

1
2
# 先关闭数据库
SQL> shutdown immediate;

执行情况:

1
[root@primarydb ~]# scp /data/oracle/oradata/orcl/standby_control01.ctl oracle@standbydb:/data/oracle/oradata/orcl/control01.ctl
1
[root@primarydb ~]# scp /data/oracle/oradata/orcl/standby_control01.ctl oracle@standbydb:/data/oracle/fast_recovery_area/orcl/control02.ctl

注意:以上操作后,请不要启动数据库,数据库将无法启动。

1
[root@primarydb ~]# vi /data/oracle/product/11.2.0/db_1/network/admin/listener.ora
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# listener.ora Network Configuration File: /data/oracle/product/11.2.0/db_1/network/admin/listener.ora
# Generated by Oracle configuration tools.

SID_LIST_LISTENER=
      (SID_LIST =
       (SID_DESC =
        (GLOBAL_DBNAME = orcl)
        (ORACLE_HOME = /data/oracle/product/11.2.0/db_1)
        (SID_NAME = orcl)
    )
  )

LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.67)(PORT = 1521))
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
    )
  )

ADR_BASE_LISTENER = /data/oracle
1
[root@primarydb admin]# vi /data/oracle/product/11.2.0/db_1/network/admin/tnsnames.ora
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# tnsnames.ora Network Configuration File: /data/oracle/product/11.2.0/db_1/network/admin/tnsnames.ora
# Generated by Oracle configuration tools.

PRIMARYDB =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.67)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = orcl)
    )
  )
STANDBYDB =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.69)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = orcl)
    )
  )
1
[root@standbydb /]# vi /data/oracle/product/11.2.0/db_1/network/admin/listener.ora
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# listener.ora Network Configuration File: /data/oracle/product/11.2.0/db_1/network/admin/listener.ora
# Generated by Oracle configuration tools.

SID_LIST_LISTENER=
      (SID_LIST =
       (SID_DESC =
        (GLOBAL_DBNAME = orcl)
        (ORACLE_HOME = /data/oracle/product/11.2.0/db_1)
        (SID_NAME = orcl)
    )
  )

LISTENER =
  (DESCRIPTION_LIST =
    (DESCRIPTION =
      (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.69)(PORT = 1521))
      (ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
    )
  )

ADR_BASE_LISTENER = /data/oracle
1
[root@standbydb /]# vi /data/oracle/product/11.2.0/db_1/network/admin/tnsnames.ora
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# tnsnames.ora Network Configuration File: /data/oracle/product/11.2.0/db_1/network/admin/tnsnames.ora
# Generated by Oracle configuration tools.

PRIMARYDB =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.67)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = orcl)
    )
  )
STANDBYDB =
  (DESCRIPTION =
    (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.1.69)(PORT = 1521))
    (CONNECT_DATA =
      (SERVER = DEDICATED)
      (SERVICE_NAME = orcl)
    )
  )

a) 先重启备库

1
[root@standbydb /]# lsnrctl reload

b) 后重启主库

1
[root@primarydb /]# lsnrctl reload
1
[root@primarydb /]# scp $ORACLE_BASE/oradata/orcl/*.dbf oracle@standbydb:$ORACLE_BASE/oradata/orcl
1
[root@primarydb /]# scp $ORACLE_BASE/oradata/orcl/*.log oracle@standbydb:$ORACLE_BASE/oradata/orcl
1
2
3
4
5
SQL> startup nomount;
SQL> alter database mount standby database;
sqL> alter database open read only;
# SQL> alter database recover managed standby database cancel;
SQL> alter database recover managed standby database using current logfile disconnect from session;
1
SQL> startup;

确认主备库里的归档目的地配置都是有效的

1
sql> select DEST_ID, STATUS, DESTINATION, ERROR from V$ARCHIVE_DEST where DEST_ID<=2;

目的地状态 status 应该显示为VALID,注意如果上面没有执行 redo 应用会有一条 error 信息 确认重做日志是否真的被应用了,在主库执行

1
sql> select SEQUENCE#, FIRST_TIME, NEXT_TIME, APPLIED, ARCHIVED from V$ARCHIVED_LOG order by FIRST_TIME;

如果归档和日志应用均正常,APPLIEDARCHIVED列都应该是 YES。(如果没有应用 redo,applied 应该是 NO)

主库上检查是否有重做日志缺口

如果你发现日志没有被应用,那可能是重做日志有了缺口,这种情况下备库无法进行日志应用。但如

果你的FAL_SERVER参数设置正确,这应该不会有问题

1
sql> select STATUS, GAP_STATUS from V$ARCHIVE_DEST_STATUS where DEST_ID = 2;

如果一切正常,应该返回VALIDNO GAP.切记启用 redo 应用才能显示No GAP在主备库上执行

以下查询查看数据库状态

1
sql> select * from V$DATAGUARD_STATUS order by TIMESTAMP;  #检查是否成功:

主库上查看日志传送情况:

1
sql> select dest_name,status,error from v$archive_dest;

应该log_archive_dest_1log_archive_dest_2 状态应该是valid

切换几次日志:

1
sql> alter system switch logfile;

查看日志序号:

1
sql> select sequence# from v$archived_log;

备库验证:

1
sql> select sequence#,applied from v$archived_log;

查看日志组状态

1
sql> select group#, archived, status from v$standby_log;

测试同步

1
2
3
4
5
sql> conn tms_user/tms_user1;
sql> create table test1(id number);
sql> insert into test1 values(1);
sql> commit;
sql> select * from test1;
1
2
3
4
SQL> startup nomount;
SQL> alter database mount standby database;
# 启用日志应用
SQL> alter database recover managed standby database disconnect from session;
1
2
3
4
SQL> startup nomount;
SQL> alter database mount standby database;
# 只读方式打开数据库
SQL> alter database open read only;
1
2
3
4
# 取消日志应用
SQL> alter database recover managed standby database cancel;
# 只读方式打开数据库
SQL> alter database open read only;

先启备库再起主库

1
[oracle@standbydb /]# lsnrctl start

先启备库:

1
2
3
4
sql> startup nomount;
sql> alter database mount standby database;
sqL> alter database open read only;
sql> alter database recover managed standby database using current logfile disconnect from session;  #启动实时应用

再启主库

1
sql> startup;

先关主库:

1
sql> shutdown immediate;

再关从库:

1
2
sql> alter database recover managed standby database cancel; #暂停日志应用
sql> shutdown immediate;
  1. 最大保护:这种模式能够确保绝无数据丢失。要实现这一步当然是有代价的,它要求所有的事务在提交前其 redo 不仅被写入到本地的online redo log,还要同时提交到standby 数据库的standbyredo log,并确认 redo 数据至少在一个 standby 数据库可用(如果有多个的话),然后才会在 primary 数据库上提交。如果出现了什么故障导致 standby 数据库不可用的话,primary 数据库会被 shutdown。

  2. 最大性能:这种模式提供在不影响 primary 数据库性能前提下最高级别的数据保护策略。事务可以随时提交,当前 primary 数据库的 redo 数据也需要至少写入一个standby 数据库,不过这种写入可以是不同步的。如果网络条件理想的话,这种模式能够提供类似最高可用性的数据保护而仅对 primary 数据库有轻微的性能影响。

  3. 最高可用性:这种模式提供在不影响 primary 数据库可用前提下最高级别的数据保护策略。其实现方式与最大保护模式类似,也是要求所有事务在提交前必须保障 redo数据至少在一个 standby 数据库可用,不过与之不同的是,如果出现故障导入无法同时写入 standby 数据库 redo log,primary 数据库并不会 shutdown,而是自动转为最高性能 模式,等 standby 数据库恢复正常之后,它又会再自动转换成最高可用性模式。

查看保护模式:

1
SQL> select protection_mode,protection_level from v$database;  # 默认是最大性能模式(maximum performance)

查看身份:

1
SQL> select database_role from v$database;

主库是 primary 备库是physical standby

切换保护模式:

1
2
3
SQL> alter database set standby database to maximize protection;   # 最大保护
SQL> alter database set standby database to maximize availability; # 最高可用性
SQL> alter database set standby database to maximize performance;  # 最大性能

参考链接:

Oracle Database Online Documentation 11g Release 2 (11.2)

相关内容