【实战干货Oracle容灾ADG日常维护

2024年 5月 13日 83.3k 0

说明

最近在搞容灾adg,很多东西不熟悉,吃了不少亏,被师傅骂完后含泪总结本篇文章,干货满满。

本文主要介绍了基于rhel 6.8 x86_64的oracle 11gR2容灾ADG的常规维护操作,包括启停、switchover、failover、点检。

需要注意版本之间的差异,不同版本间的维护操作有所差距,最明显的就是物理备用数据库的可用性区别:

  • Oracle 10g:在Oracle 10g中,物理备用数据库(Physical Standby)在应用redo日志时通常处于关闭或mount状态,这意味着在数据同步过程中,备用数据库不能用于查询或其他操作。简单地讲就是如果10g的备库开启了日志同步,那么备库是mounted状态,此时不能读取数据。

  • Oracle 11g:Oracle 11g引入了增强的Active Data Guard功能,允许物理备用数据库以只读方式打开,同时继续接收并应用主数据库的redo日志。这意味着在数据同步的过程中,备用数据库仍然可以支持查询操作,从而提高了资源的利用率。

1 启动和关闭

ADG的启停需要注意顺序,启动的时候,先启动备库,然后启动主库。关闭时,先关闭主库,再关闭备库。

1.1 关闭

先关闭主库:

shutdown immediate;
lsnrctl stop;

后关闭备库:

alter database recover managed standby database cancel; #关闭实时同步
shutdown immediate;
lsnrctl stop;

为什么先关闭主库后关闭备库呢,稍微想一下就知道:

  • 数据一致性:首先关闭主库可以确保在关闭过程中不会有新的数据更改被写入。这样可以确保在关闭备库时,备库上的数据与主库的数据是一致的。
  • 减少备库负载:在关闭主库之后,备库将不再接收来自主库的日志传输。这可以减少备库的负载,并使其能够更快地关闭。
  • 避免数据丢失:如果先关闭备库,而主库仍然在运行并产生新的数据更改,那么这些更改将无法被传输到备库,可能导致数据丢失。

1.2 启动

先启动备库:

lsnrctl start;
startup nomount;
alter database mount standby database;
alter database open read only;
alter database recover managed standby database using current logfile disconnect from session;

后启动主库:

lsnrctl start;
startup;

先启动备库的原因:

  • 数据一致性:在ADG环境中,备库是主库的一个副本,用于在主库发生故障时接管服务。如果先启动主库,那么主库可能会开始产生新的数据更改。然而,如果备库此时还未启动并准备好接收这些更改,那么可能会导致数据不一致的问题。通过先启动备库,可以确保备库在主库开始产生新的数据更改之前已经准备好,从而保持数据的一致性。
  • 避免主库等待:在ADG环境中,主库和备库之间通常存在日志传输服务。如果先启动主库,主库可能会开始生成和传输日志到备库,但如果备库此时还未启动,那么这些日志将被暂时存储在主库上,直到备库启动并准备好接收它们。这可能会导致主库在等待备库启动的过程中产生额外的I/O负载和延迟。通过先启动备库,可以确保主库在启动后能够立即将日志传输到备库,避免不必要的等待和延迟。
  • 恢复能力:在ADG中,备库的主要作用之一是在主库发生故障时提供数据恢复的能力。如果先启动主库,而备库尚未准备好,那么在主库发生故障时,备库可能无法立即接管服务,从而影响系统的恢复能力。通过先启动备库,可以确保在主库发生故障时,备库已经准备好并可以立即接管服务,从而提高系统的恢复能力。
  • 系统稳定性:在某些ADG配置中,例如最大可用性(Maximum Availability)模式下,如果先启动主库而没有先启动备库,可能会导致一些错误或警告消息出现在主库的alert log中。这可能会影响系统的稳定性。通过遵循先备库后主库的启动顺序,可以避免这些潜在的问题,从而提高系统的稳定性。

ps:上面的启停操作顺序只是理论上的,实际上没那么多讲究,只要日志不删就没关系,启动主库备库谁先启都行,停库直接停。

2 Switchover

正常切换,是指在主数据库和备用数据库都正常运行的情况下,将主备角色进行互换的操作。即,当前的主数据库会变为备用数据库,而当前的备用数据库会升级为主数据库。

2.1 执行切换

1)原主库查看主库的状态,确认是否可以切换:

SQL> select name,open_mode,switchover_status,database_role from v$database;

NAME OPEN_MODE SWITCHOVER_STATUS DATABASE_ROLE
--------- -------------------- -------------------- ----------------
ORCL READ WRITE TO STANDBY PRIMARY

2)将原主库切换至备用模式:

如果SWITCHOVER_STATUS为TO STANDBY说明可以立即转换:

SQL> alter database commit to switchover to physical standby;

如果SWITCHOVER_STATUS为SESSIONS ACTIVE则说明主库还存在会话,需要加上session shutdown断开会话切换:

SQL> alter database commit to switchover to physical standby with session shutdown;

3)查看原备库的状态,确认是否可以切换:

SQL> select name,open_mode,switchover_status,database_role from v$database;

NAME OPEN_MODE SWITCHOVER_STATUS DATABASE_ROLE
--------- -------------------- -------------------- ----------------
ORCL READ ONLY WITH APPLY TO PRIMARY PHYSICAL STANDBY

4)将原备库切换为主库:

  • 如果SWITCHOVER_STATUS为TO PRIMARY,可以直接切换:

SQL> alter database commit to switchover to primary;

  • 如果SWITCHOVER_STATUS为SESSION ACTIVE,需要断开会话切换:

SQL> alter database commit to switchover to primary with session shutdown;

  • 如果SWITCHOVER_STATUS为NOT ALLOWED,那应该是主库还没有执行switchover,请检查主库。

5)启动新主库

备库执行切换主库语句后,新主库此时为MOUNTED状态。

SQL> select name,open_mode,switchover_status,database_role from v$database;

NAME OPEN_MODE SWITCHOVER_STATUS DATABASE_ROLE
--------- -------------------- -------------------- ----------------
ORCL MOUNTED NOT ALLOWED PRIMARY

启动:

SQL> alter database open;

Database altered.

SQL> select name,open_mode,switchover_status,database_role from v$database;

NAME OPEN_MODE SWITCHOVER_STATUS DATABASE_ROLE
--------- -------------------- -------------------- ----------------
ORCL READ WRITE FAILED DESTINATION PRIMARY

6)启动新备库

启动到mount状态,只读模式打开:

SQL> startup mount;
ORACLE instance started.

Total System Global Area 835104768 bytes
Fixed Size 2257840 bytes
Variable Size 536874064 bytes
Database Buffers 289406976 bytes
Redo Buffers 6565888 bytes
Database mounted.
SQL> select name,open_mode,switchover_status,database_role from v$database;

NAME OPEN_MODE SWITCHOVER_STATUS DATABASE_ROLE
--------- -------------------- -------------------- ----------------
ORCL MOUNTED RECOVERY NEEDED PHYSICAL STANDBY

SQL> alter database open read only;

Database altered.

SQL> select name,open_mode,switchover_status,database_role from v$database;

NAME OPEN_MODE SWITCHOVER_STATUS DATABASE_ROLE
--------- -------------------- -------------------- ----------------
ORCL READ ONLY RECOVERY NEEDED PHYSICAL STANDBY

开启日志同步:

SQL> alter database recover managed standby database using current logfile disconnect from session;

Database altered.

SQL> select name,open_mode,switchover_status,database_role from v$database;

NAME OPEN_MODE SWITCHOVER_STATUS DATABASE_ROLE
--------- -------------------- -------------------- ----------------
ORCL READ ONLY WITH APPLY NOT ALLOWED PHYSICAL STANDBY

可以看到此时OPEN_MODE为READ ONLY WITH APPLY。

2.2 切换后检查

1)检查数据库角色

检查v$database视图的database_role字段值。

主库:

SQL> select db_unique_name,open_mode,switchover_status,database_role from v$database;

DB_UNIQUE_NAME OPEN_MODE SWITCHOVER_STATUS DATABASE_ROLE
------------------------------ -------------------- -------------------- ----------------
ORCL READ WRITE TO STANDBY PRIMARY

备库:

SQL> select db_unique_name,open_mode,switchover_status,database_role from v$database;

DB_UNIQUE_NAME OPEN_MODE SWITCHOVER_STATUS DATABASE_ROLE
------------------------------ -------------------- -------------------- ----------------
ORCLADG READ ONLY WITH APPLY NOT ALLOWED PHYSICAL STANDBY

2)查看进程

主库:

主库主要看 LNS 进程,此进程负责将主数据库的重做日志条目传输到备用数据库。

SQL> select process ,status , sequence# from v$managed_standby;

PROCESS STATUS SEQUENCE#
--------- ------------ ----------
ARCH CLOSING 78
ARCH CONNECTED 0
ARCH CONNECTED 0
ARCH CLOSING 78
LNS WRITING 79

备库:

备库主要看 MRP0 进程,此进程负责将接收到的归档日志应用到备用数据库上,以维持与主数据库的同步。MRP进程是ADG中的关键组件,它确保备用数据库的数据与主数据库保持一致。

SQL> select process ,status , sequence# from v$managed_standby;

PROCESS STATUS SEQUENCE#
--------- ------------ ----------
ARCH CLOSING 78
ARCH CONNECTED 0
ARCH CONNECTED 0
ARCH CONNECTED 0
RFS IDLE 0
RFS IDLE 0
RFS IDLE 0
RFS IDLE 79
MRP0 APPLYING_LOG 79

3)检查归档是否一致

主库备库都执行:

SQL> select max(sequence#),thread# from v$archived_log where RESETLOGS_CHANGE# = (SELECT RESETLOGS_CHANGE# FROM V$DATABASE_INCARNATION WHERE STATUS = 'CURRENT') GROUP BY THREAD#;

MAX(SEQUENCE#) THREAD#
-------------- ----------
78 1

3 Failover

灾难性恢复一般表示在主数据库出现故障或无法提供服务时,将备库切换为主库以继续提供服务的过程。这是一个灾难恢复策略,用于确保在主数据库出现问题时,备用数据库可以立即接管服务,从而保持业务的连续性。但是可能会有数据丢失的情况。

对于多备库的情況,其他备库不需要做任何操作。灾难性恢复之后原主库默认不再是ADG配置的一部分,需要对原主库进行故障排查和修复,以便在将来能够重新加入ADG环境作为备库。如果原主库无法修复,可以考虑使用备份或其他方法重新搭建一个备库,并将其加入到ADG环境中。

1)将所有未发送的重做从主数据库刷新到目标备用数据库

如果主数据库可以挂载,则可以将任何未发送的归档和当前重做从主数据库刷新到备用数据库。如果操作成功,即使主数据库未设置为最大保护模式,也可以实现零数据丢失故障切换。

确保Redo Apply在备库上处于active状态,启动主库到mount状态。

如果主数据库不能挂载,请转步骤2。

在主数据库执行以下SQL语句:

SQL> ALTER SYSTEM FLUSH REDO TO 'standby_db_unique_name';

此语句会将所有未发送的重做从主数据库刷新到备用数据库,并等待重做应用到备用数据库。

如果执行成功,跳过步骤2、3、4,执行步骤5。如果语句结束时有出现任何错误,或者由于无法再等待语句完成而必须停止语句,则继续执行步骤2。

2)验证备库是否有缺失的归档

查看是否有gap:

SQL> select * from v$archive_gap;

①如果没有查到结果,说明归档在备库没有缺失,那么数据上基本不会有丢失,即使丢失,也只有redo buffer中未来得及刷出的部分可能会丢失。没有归档缺失,直接进行进行步骤3。

②如果有确缺失的归档:

SQL> SELECT THREAD#, LOW_SEQUENCE#, HIGH_SEQUENCE# FROM V$ARCHIVE_GAP;

THREAD# LOW_SEQUENCE# HIGH_SEQUENCE#
---------- ------------- --------------
1 90 92

缺口包括线程1的序列号为90、91和92的归档重做日志文件。

需要在主库找到相应的归档日志文件,传到备库然后注册这些文件:

SQL> ALTER DATABASE REGISTER PHYSICAL LOGFILE 'xxx.arc';

需要一直重复上述两个步骤,直到没有缺口为止。

最坏的情况就是,如果故障是出现了长时间才发现,gap的归档在主库已经被删除,且主库一时半会儿起不来,那这部分数据可能暂时没办法恢复了,只能先做好切换,后续修复主库后进行数据恢复。

3)关闭日志同步

在备用数据库上执行如下SQL语句,暂停同步:

SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;

在备用数据库上执行如下SQL语句,关闭同步:

SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE FINISH;

FINISH实际上是关闭了MRP0进程,备库停止作为备用数据库,并且不会继续接收或应用归档日志,此时才能切换为主库。

可能会遇到的情况:

  1. 如果该语句完成后没有任何错误,则继续执行步骤4。

  2. 如果有报错(比如步骤2中还存在无法填补的数据缺口),解决好报错后再重复执行以上sql。

  3. 如果报错无法解决,仍然可以通过在备库上执行以下SQL语句来执行failover(但会丢失一些数据):

    SQL> ALTER DATABASE ACTIVATE PHYSICAL STANDBY DATABASE;

    ACTIVATE语句完成后,执行步骤6。

4)查看备库状态

SQL> SELECT SWITCHOVER_STATUS FROM V$DATABASE;

SWITCHOVER_STATUS
-----------------
TO PRIMARY
1 row selected

TO PRIMARY或SESSIONS ACTIVE备库可以切换到主角色。如果是NOT ALLOWED的话,说明你步骤3没有成功,需要重新完成步骤3,或者直接执行步骤6(会有数据丢失)。

5)将物理备库切换为主库

SQL> ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY WITH SESSION SHUTDOWN;

如果上一步查询SWITCHOVER_STATUS列返回的值为TO PRIMARY,则可以在切换语句中省略WITH SESSION SHUTDOWN子句。

6)启动新主库

此时为mounted状态,用alter命令打开新主库:

SQL> ALTER DATABASE OPEN;

新主库启动后最好进行一次全库备份。

7)多备库的环境开启日志同步

如果是有多个备库,还需要在在其他备库上重启日志同步:

SQL> ALTER DATABASE RECOVER MANAGED STANDBY DATABASE USING CURRENT LOGFILE DISCONNECT FROM SESSION;

8)修复挂掉的主库

在故障转移之后,尝试把挂掉的主库进行修复,然后重新加入到adg环境中作为备库。

4 点检

4.1 检查同步状态

1)检查数据库角色

检查v$database视图的database_role字段值。

主库:

SQL> select db_unique_name,open_mode,switchover_status,database_role from v$database;

DB_UNIQUE_NAME OPEN_MODE SWITCHOVER_STATUS DATABASE_ROLE
------------------------------ -------------------- -------------------- ----------------
ORCL READ WRITE TO STANDBY PRIMARY

备库:

SQL> select db_unique_name,open_mode,switchover_status,database_role from v$database;

DB_UNIQUE_NAME OPEN_MODE SWITCHOVER_STATUS DATABASE_ROLE
------------------------------ -------------------- -------------------- ----------------
ORCLADG READ ONLY WITH APPLY NOT ALLOWED PHYSICAL STANDBY

2)查看进程

主库:

主库主要看 LNS 进程,此进程负责将主数据库的重做日志条目传输到备用数据库。

SQL> select process ,status , sequence# from v$managed_standby;

PROCESS STATUS SEQUENCE#
--------- ------------ ----------
ARCH CLOSING 78
ARCH CONNECTED 0
ARCH CONNECTED 0
ARCH CLOSING 78
LNS WRITING 79

备库:

备库主要看 MRP0 进程,此进程负责将接收到的归档日志应用到备用数据库上,以维持与主数据库的同步。MRP进程是ADG中的关键组件,它确保备用数据库的数据与主数据库保持一致。

SQL> select process ,status , sequence# from v$managed_standby;

PROCESS STATUS SEQUENCE#
--------- ------------ ----------
ARCH CLOSING 78
ARCH CONNECTED 0
ARCH CONNECTED 0
ARCH CONNECTED 0
RFS IDLE 0
RFS IDLE 0
RFS IDLE 0
RFS IDLE 79
MRP0 APPLYING_LOG 79

3)检查归档是否一致

主库备库都执行:

SQL> select max(sequence#),thread# from v$archived_log where RESETLOGS_CHANGE# = (SELECT RESETLOGS_CHANGE# FROM V$DATABASE_INCARNATION WHERE STATUS = 'CURRENT') GROUP BY THREAD#;

MAX(SEQUENCE#) THREAD#
-------------- ----------
78 1

4)查看GAP

SQL> select * from v$archive_gap;

no rows selected

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

STATUS GAP_STATUS
--------- ------------------------
VALID NO GAP

GAP产生的原因是,一般是备库已经长时间未与主库同步,等发现的时候,主库的归档日志已经删除,备库无法再次与主库同步,这时候GAP就产生了。

5)查看配置情况

主备库都看一下STATUS是否未VALID:

SQL> col DESTINATION for a50
SQL> select DEST_ID, STATUS, DESTINATION, ERROR from V$ARCHIVE_DEST where DEST_ID
set lines 200
col message for a60
select * from V$DATAGUARD_STATUS order by TIMESTAMP;

相关文章

Oracle如何使用授予和撤销权限的语法和示例
Awesome Project: 探索 MatrixOrigin 云原生分布式数据库
下载丨66页PDF,云和恩墨技术通讯(2024年7月刊)
社区版oceanbase安装
Oracle 导出CSV工具-sqluldr2
ETL数据集成丨快速将MySQL数据迁移至Doris数据库

发布评论