1.什么是Data Guard(DG)?

备用数据库(Standby Database),从Oracle9i开始也叫做Data Guard,是Oracle推出的一种高可用性(High Available)数据库解决方案,其主要的目标是Oracle数据库层面的数据保护以及容灾方案。主要组成部分为一个在线的生产数据库(或者是RAC集群),我们一般叫做Primary;以及一个在线备用数据库(或者是RAC集群),我们一般叫做Standby。Primary与Standby之间通过日志同步来保证数据的同步和热备,备用节点是是一种随时处在database recovery的状态应用主节点传输过来的日志,并且随时保持active的状态以备随时切换与灾难恢复。从9i开始正式更名为Data Guard,开始支持三种不同的数据保护模式,并可以采用LGWR/LNSn而不仅仅是以往的ARCH对数据进行传送,并增加了一个叫做DMON的后台进程进行监控。支持多大9个standby同事复制。

2.保护模式有哪些分类?

A. maxmize protection,最大保护模式,没有数据丢失,没有数据分歧。LGWR/LNSn将同时传送到备用节点,在主节点事务提交之前,备用节点也必须收到全部日志数据。如果网络不好,没有传送到将会引起严重的性能问题,导致主节点宕机。

B. maxmize availability,最大可用模式,没有数据丢失,允许数据分歧,允许异步传送。正常情况一般运行在该模式下,主节点与被节点由于网络原因不能够通信时候,将自动切换到最大性能模式运行,主节点的操作继续。

C. maxmize performance,最大性能模式。异步传送日志,无数据同步检查,可能丢失数据,但是能够获得主节点的最佳性能。9i的默认模式。

3.物理架构以及功能分布是?

在DG方案中,理论上至少需要两台主机,两套存储。用于搭建逻辑上和物理上完全一致的DB,如果不是接管需要,standby可以比primary配置低一些。与RAC不同的是DG一般只有一个节点是active的,只有当主机发生故障的时候,才考虑切换到备用服务器。备用服务器一般不提供读写操作(因为通常状况下都是recover standby状态,该状态是没有open的)。只有需要的时候才提供只读的报表查询服务,或者档主站点出现故障的时候,经过一定的切换条件,才转变为主数据库,提供正常服务。

4.DG的内部实现原理是?

物理standby其实就是采用的oracle备份恢复的原理实现的,不过是把很多操作封装起来并且做成自动化处理过程而已。可以把standby数据库看成是一个在不断恢复中的数据库,因为他不知道归档日志什么时候结束。因为运行中的primary永远没有结束业务,所以会不断的长生日志,所以standby就会会永远在apply log和waiting for log这两个状态来回切换。因为primary、standby是物理上面两个完全独立的数据库,所以远没有RAC那么复杂,理论上面只要两个库能够相互tnsping通,再加上一些配置就可以了。

从9i开始,既可以传送归档日志,也可以直接传送联机日志,如果是传输的归档日志则有ARCn进程负责,如果是连接日志,Oracle10g以前是由LGWR负责传送,Oracle10g以后是完全由LNSn进程负责传送。日志的接受工作由standby端的RFS进程完成。standby的log apply工作可以手工完成,或者是物理standby的MRP进程完成的,逻辑standby的log apply是有LSP进程完成的。

如果采用联机日志的方式传送,那么建议在standby创建一组备用日志(standby log),并保持与primary的日志组大小一致。如果采用联机日志方法传送,但是不在standby创建standby log的话,联机日志将会自动写到standby的归档日志中,如果在创建standby 控制文件的时候,maxlogfiles参数指定过小的话,会影响到standby log的创建,这种情况下必须重新创建控制文件。

5.决定standby的一些参数是哪些?

db_file_name_convert (primary,standby数据文件的转换目录映射关系,如果目录结构一致就可以省略。)
应用举例:*.db_file_name_convert='/opt/oracle/oradata/dwapp_primary','/opt/oracle/oradata/dwapp_standby'

log_file_name_convert (primary,standby日志文件的转换目录映射关系,如果目录结构一致就可以省略。)
应用举例:*.log_file_name_conver='/opt/oracle/oradata/dwapp_primary','/opt/oracle/oradata/dwapp_standby'

log_archive_dest_n (备用数据库归档的存放路径,primary端和standby端的配置有所不同,这个参数比较重要。)
应用举例(主):*.log_archive_dest_1='location=/oracle/arch/dwapp valid_for=(all_logfiles,all_roles) db_unique_name=dwapp_p'

应用举例(备):*.log_archive_dest_2='service=dwapp_s lgwr sync net_timeout=50 valid_for=(online_logfiles,primary_role) db_unique_name=dwapp_s'

compatible(Oracle兼容版本,standby的版本号必须大于或者等于primary,如果想要来回切换,两者必须一致)
应用举例:compatible=10.2.0.3.0

fal_server(指明自动日志同步的源头库的tnsname) fal_server = dwapp_p
fal_client (指明自动日志同步的目标库的tnsname) fal_client = dwapp_s

standby_file_management(可以自动同步数据文件,在auto模式下,primary创建数据文件的时候,standby也会自动创建,如果设置manual模式,则不会,可以动态修改)
应用举例standby_file_management=auto|manual

db_unique_name(指定数据库的唯一全局名称,每个单独的物理库一个。如primary= dwapp_p,standby=dwapp_s)
db_name(指定数据库全局统称,primary,standby对外界而言都是同一个)

log_archive_config(主备库的tnsname配置列表)
应用举例:log_archive_config='DG_CONFIG(dwapp_p,dwapp_s)'

6.实战完整搭建过程?

A 确认为归档模式

SQL>Startup mount;

SQL> alter database archivelog;

SQL> archive log list;

B确认主库强制写日志

SQL> select force_logging from v$database;

(所有sql语句nologging操作时 也会强制写日志)

C 修改主备数据库的参数文件(主库)

SQL> alter database open;

SQL> create pfile from spfile;

[oracle@sql ~]$ cd /oracle/app/oracle/product/10.2.0/db_1/dbs/

[oracle@sql dbs]$ vim initTEST.ora (将spfile改名为其他)

DB_UNIQUE_NAME=TEST --show parameter DB_UNIQUE_NAME确认主库名称

LOG_ARCHIVE_CONFIG='DG_CONFIG=(DB95,DB96)' --此处为主库网络连接串(tnsnames.ora)

LOG_ARCHIVE_DEST_1='LOCATION=/home/oracle/archive VALID_FOR=(ALL_LOGFILES,ALL_ROLES) DB_UNIQUE_NAME=TEST' --主库的归档日志路径

LOG_ARCHIVE_DEST_2='SERVICE=DB96 LGWR ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=TEST'

FAL_SERVER=DB95 --网络异常恢复后自动将延迟的归档日志传输到备库,此处为主库网络连接串(tnsnames.ora)

FAL_CLIENT=DB96

STANDBY_FILE_MANAGEMENT=AUTO (默认只传递数据,此作用主库把新创建的数据文件也传到备库)

[oracle@sql ~]$ cd /oracle/app/oracle/product/10.2.0/db_1/network/admin/

[oracle@sql admin]$ vim tnsnames.ora

DB95 =

(DESCRIPTION =

(ADDRESS_LIST =

  (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.18.95)(PORT = 1521))

)

(CONNECT_DATA =

  (SID = TEST)

)

)

DB96 =

(DESCRIPTION =

(ADDRESS_LIST =

  (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.18.96)(PORT = 1521))

)

(CONNECT_DATA =

  (SID = TEST)

)

)

[oracle@sql admin]$ vim listener.ora

SID_LIST_LISTENER =

(SID_LIST =

(SID_DESC =

  (GLOBAL_DBNAME = TEST)

  (ORACLE_HOME = /oracle/app/oracle/product/10.2.0/db_1)

  (SID_NAME = TEST)

)

)

LISTENER =

(DESCRIPTION =

(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.18.96)(PORT = 1521))

)

[oracle@sql ~]$ mkdir /home/oracle/archive/

SQL> startup force; (重启数据库)

SQL> show parameter ARCHIVE(查看到刚才配置的值生效了)

D 将主库的pfile 传到备库(将备库的spfile改名)

[oracle@sql dbs]$ vim initTEST.ora (添加下面几行到pfile中)

DB_UNIQUE_NAME=TEST --show parameter DB_UNIQUE_NAME

LOG_ARCHIVE_CONFIG='DG_CONFIG=(DB95,DB96)'

LOG_ARCHIVE_DEST_1='LOCATION=/home/oracle/archive VALID_FOR=(ALL_LOGFILES,ALL_ROLES)

DB_UNIQUE_NAME=TEST'

LOG_ARCHIVE_DEST_2='SERVICE=DB95 LGWR ASYNC VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE)

DB_UNIQUE_NAME=TEST'

FAL_SERVER=DB96

FAL_CLIENT=DB95

STANDBY_FILE_MANAGEMENT=AUTO

修改传输文件和监听文件并在主备上都开启监听

[oracle@sql ~]$ cd /oracle/app/oracle/product/10.2.0/db_1/network/admin/

[oracle@sql admin]$ vim tnsnames.ora

DB95 =

(DESCRIPTION =

(ADDRESS_LIST =

  (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.18.95)(PORT = 1521))

)

(CONNECT_DATA =

  (SID = TEST)

)

)

DB96 =

(DESCRIPTION =

(ADDRESS_LIST =

  (ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.18.96)(PORT = 1521))

)

(CONNECT_DATA =

  (SID = TEST)

)

)

[oracle@sql admin]$ vim listener.ora

SID_LIST_LISTENER =

(SID_LIST =

(SID_DESC =

  (GLOBAL_DBNAME = TEST)

  (ORACLE_HOME = /oracle/app/oracle/product/10.2.0/db_1)

  (SID_NAME = TEST)

)

)

LISTENER =

(DESCRIPTION =

(ADDRESS = (PROTOCOL = TCP)(HOST = 192.168.18.95)(PORT = 1521))

)

[oracle@sql ~]$ sqlplus sys/123456 as sysdba (登录数据库)

SQL> startup nomount ; (开启到nonount状态)

E 确保主备数据库两边的密码文件中的密码一致(保证主备数据库之间通过tns网络连接串能够互相连通对方DB95上本地测试)

[oracle@sql dbs]$ scp orapwTEST 192.168.18.95:$ORACLE_HOME/dbs/ (在主库上)

[oracle@sql ~]$ sqlplus sys/123456@DB96 as sysdba (在备库上成功连接主库)

F 迁移数据库到备库,一下RMAN操作全部在主库上执行

[oracle@sql ~]$ mkdir db_bak

[oracle@sql ~]$rman target /

RMAN> backup full database format='/home/oracle/db_bak/%U' include current controlfile for standby;

传输备份片文件到备库的相同备份目录下

[oracle@sql ~]$mkdir /home/oracle/db_bak

[oracle@sql db_bak]$ scp * 192.168.18.95:/home/oracle/db_bak/

RMAN> connect auxiliary sys/123456@DB95 (95上,一定不要退出上次的RMAN连接)

RMAN> duplicate target database for standby nofilenamecheck;

G在主库上查看进程

SQL> select process from v$managed_standby;

PROCESS


ARCH

ARCH

没有灾备的进程

查看归档错误信息

SQL> select error from v$archive_dest;

SQL> alter system switch logfile; (切换日志组)

SQL> select process from v$managed_standby;

PROCESS


ARCH

ARCH

LNS

(已经有了进程,lns传输进程)

H 在备库查看

SQL> select process from v$managed_standby;

PROCESS


ARCH

ARCH

RFS

RFS

(已经有了进程,rfs接收进程)

备库具有恢复日志进程,需要手动激活此进程

SQL> alter database recover managed standby database disconnect from session;

SQL> select process from v$managed_standby;

PROCESS


ARCH

ARCH

RFS

RFS

MRP0

I 验证

在主库上

SQL> create table t01 as select * from dba_objects;

SQL> commit;

(主库只有切换日志时,备库会同步,但主库日志变化备库会记录到归档日志中)

SQL> alter system switch logfile;

在备库上

SQL> alter database recover managed standby database cancel;

(备库上,只有把恢复日志进程取消,才可以打开数据库)

SQL> alter database open;

SQL> select count(*) from t01;(已经有了)