欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Data Guard物理备库的正常切换

程序员文章站 2022-05-08 10:04:13
...

 

Oracle 数据库的Data Guard是实现数据库级别的数据灾备机制。它的原理类似数据库备份恢复过程中应用重做日志部分,不停地在备用节点服务器上应用从主库传过来的归档日志文件。
data guard的备用节点又细分成logical standby和physical standby,分别应用在不同的场景中。
在Oracle 10g的Data Guard环境中,备用节点和主库节点可以互相切换。这个功能的用途包括数据库灾备的验证、数据库硬件维护的无缝切换、因数据库服务器更换导致的数据迁移等等。

在以前我处理的数据迁移工作中,一直数据库的备份和异地恢复来完成。这种方案非常可靠,新环境中数据库配置等都不需要做特别修改。但是,如果新环境出现其他故障(网络故障)时,要再将新环境的数据库迁移回去,就不可能了。新环境数据库启用后,会很快有新数据进来。又再用方式做一次数据迁移,时间上也不允许。如果使用Oracle Data Gauard 来完成这个数据迁移工作,即使后来发现新环境有故障,我们也可以利用data guard的角色互换工作再切换到老环境中。

(miki西游 @mikixiyou 文档,原文链接: http://mikixiyou.iteye.com/blog/1561621 )

这个迁移操作分成两个部分,其一是将老环境的数据库和新环境的数据库配置成data guard模式,备库采用physical standby。其二是将主库切换成备库角色,备库又切换成主库角色。



其一,data guard环境搭建

在主库上修改初始化参数,保护级别采用默认值即最大性能,重做日志传输方式采用ARCH  。这里是做数据迁移,如果是灾备需求,则需要设置成最大可用或最大保护,传输重做日志的方式为LGWR SYNC AFFIRM 。

alter system set log_archive_config='dg_config=(mikidb,mikidg)' scope=memory;
 
alter system set log_archive_dest_2='SERVICE=MIKIDB_STANDBY ARCH ASYNC AFFIRM VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=MIKIDG' scope=memory;

 
主库的tnsnames.ora 文件中需要增加一个tnsname ,即log_archive_dest_2 中指定的mikidb_standby 。

mikidb_STANDBY =

   (DESCRIPTION =

     (ADDRESS_LIST =

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

     )

     (CONNECT_DATA =

       (SID = mikidb)

     )

   )

 

 

在备库上修改初始化参数,设置db_unique_name ,fal_client 和fal_server 。

如下:

*.db_unique_name='mikidg'

*.fal_client='mikidb_standby'

*.fal_server='mikidb_primary'

fal 用于探测主库和备库之间归档日志文件的间隔,称之为fetch archive log 。

另外,归档路径也做一个简单设置,用于保存从主库上传输过来的归档日志文件。

*.log_archive_config='dg_config=(mikidb,mikidg)'

*.log_archive_dest_1='LOCATION=+VG1/ valid_for=(all_logfiles,all_roles) db_unique_name=mikidg'

备库的tnsnames.ora 文件中需要增加两个tnsname ,即fal_client 和fal_server 的值,分别是mikidb_standby 和mikidb_primary 。

mikidb_STANDBY =

   (DESCRIPTION =

     (ADDRESS_LIST =

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

     )

     (CONNECT_DATA =

       (SID = mikidb)

     )

   )

mikidb_primary =

   (DESCRIPTION =

     (ADDRESS_LIST =

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

     )

     (CONNECT_DATA =

       (SID = mikidb)

     )

   )

 

在主备库的初始化参数都设置好以后,我们在备库上恢复主库的备份,恢复使用控制文件需要主库特别生成,专门用于data guard 的备库应用。

在rman 下执行backup current controlfile for standby ‘/tmp/ctl.standby’; 就可以。

恢复的数据文件备份集就使用已有的最新的备份集。

登录RMAN 管理工具界面,执行恢复操作。

rman target /

 

restore controlfile from '/tmp/ctl.standby';

sql ‘alter database mount’;

catalog start with ‘/backup/’;

restore database;

recover database;

 

恢复到出错后,退出。

再登录sqlplus  界面,启用备库重做日志不间断应用模式。

alter database recover managed standby database disconnect from session;

通常,主库新生成的数据就会源源不断地通过归档日志文件传输过来,达到了数据迁移的目的。


其二,主库和备库的角色互换

1 、关闭所有主库上的客户端连接,准备主库角色切换

2 、在主库上,将其切换成备库角色

SQL> alter database commit to switchover to physical standby;

Database altered.

SQL> shutdown immediate

ORA-01507: database not mounted

ORACLE instance shut down.

以备用模式启用原主库

 

SQL> startup nomount;

ORACLE instance started.

SQL> alter database mount standby database;

SQL> select name,open_mode,PROTECTION_MODE,DATABASE_ROLE from v$database;

SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT FROM SESSION;

 

3 、在备库上,切换成主库模式。

SQL> alter database commit to switchover to primary;

SQL> shutdown immediate;

ORA-01507: database not mounted

ORACLE instance shut down.

SQL> startup

SQL> alter system switch logfile;

System altered.

 

再将初始化参数按照第一部分做一些修改,就实现了新环境和老环境的对调。如果新环境出现了问题,咱们再切换一次,就让应用再次使用老环境了。即使新环境又新生成了数据,那么老环境也因为是data guard 的物理备库模式,也同步过去了新数据。

总而言之,这将是一个更加靠谱的数据库迁移方案。

但,我想,它还有是有缺陷的。有哪些缺陷呢?

 

 

附参考命令

 

 

-- Make sure that nobody accesses the primary database anymore
sqlplus@master> SHUTDOWN IMMEDIATE
sqlplus@master> STARTUP [RESTRICT]

-- Prepare the SwitchOver
sqlplus@master> ALTER DATABASE COMMIT TO SWITCHOVER TO STANDBY WITH SESSION SHUTDOWN;
sqlplus@standby> ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY;

-- Do it
sqlplus@master> SHUTDOWN IMMEDIATE
sqlplus@master> STARTUP MOUNT
sqlplus@master> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE DISCONNECT;
sqlplus@standby> ALTER DATABASE OPEN

 

 

sqlplus@standby> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE FINISH;
sqlplus@standby> ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY;

 

 

failover操作过程

备库端:
  如果是最大保护和最大可用性模式,则可以直接在备库端执行failover切换。如果是最大性能模式,为了尽可能减少数据丢失,需要检查主库是否有日志没有传输到备库,手动传输备库进行注册和恢复。注意RAC环境下,归档日志是分线程的。

SYS@dev01dg>select distinct thread#,max(sequence#) over(partition by thread#) a from v$archived_log;

   THREAD#          A
---------- ----------
         1        457

SYS@dev01dg>

[oracle@testdb dev01]$ scp * oracle@192.168.0.8:/u01/archive/dev01dg

  注册归档日志有如下两种方法,较为简单当然是用rman 了,一次注册多个。
RMAN>catalog start with '/u01/archive/dev01';

SYS@dev01dg>alter database register logfile '/u01/archive/dev01dg/arch_e8fe6364_1_712757927_460.dbf';

  apply归档日志也有两种方法。

SYS@dev01dg>alter database recover managed standby database disconnect from session;

Database altered.

SYS@dev01dg>

SYS@dev01dg>recover standby database;
ORA-00279: change 2863819 generated at 03/20/2010 21:58:17 needed for thread 1
ORA-00289: suggestion : /u01/archive/dev01dg/arch_e8fe6364_1_712757927_461.dbf
ORA-00280: change 2863819 for thread 1 is in sequence #461

Specify log: {<RET>=suggested | filename | AUTO | CANCEL}
CANCEL
Media recovery cancelled.
SYS@dev01dg>

  当手动apply完所有日志后,就可以failover切换到primary了。但是要注意的时,由于备库没有收到主库End-Of-REDO的信号,所以直接转换会报错,要求介质恢复。此时需要提交命令告诉备库,日志恢复已经finish 了,需要进行failover切换。注意switchover时千万不要带有finish选项,否则就会变成failover了

SYS@dev01dg> alter database commit to switchover to primary with session shutdown;
alter database commit to switchover to primary with session shutdown
*
ERROR at line 1:
ORA-16139: media recovery required

SYS@dev01dg> select database_role,switchover_status from v$database;

DATABASE_ROLE    SWITCHOVER_STATUS
---------------- --------------------
PHYSICAL STANDBY NOT ALLOWED

SYS@dev01dg>alter database recover managed standby database finish [force];

Database altered.

SYS@dev01dg> select database_role,switchover_status from v$database;

DATABASE_ROLE    SWITCHOVER_STATUS
---------------- --------------------
PHYSICAL STANDBY TO PRIMARY

SYS@dev01dg>alter database commit to switchover to primary with session shutdown;

Database altered.

SYS@dev01dg>alter database open;

Database altered.

SYS@dev01dg> select database_role,switchover_status from v$database;

DATABASE_ROLE    SWITCHOVER_STATUS
---------------- --------------------
PRIMARY           SESSIONS ACTIVE

SYS@dev01dg>

  failover完成后,数据库其实是以resetlogs方式打开的,如果log_archive_format='arch_%d_%t_%r_%s.dbf',可以看到归档日志的文件名会有新的resetlogs ID和sequence number,以此与原有的归档日志进行区分。