目录
[一、删除 ADG 备库的完整流程](#一、删除 ADG 备库的完整流程)
[1.2.查看 DG 配置(用 DGMGRL)](#1.2.查看 DG 配置(用 DGMGRL))
[1.2.1.停止 MRP(日志应用)](#1.2.1.停止 MRP(日志应用))
[1.2.2. 确认归档已应用完毕(无 pending)](#1.2.2. 确认归档已应用完毕(无 pending))
[1.2.3. 关闭备库](#1.2.3. 关闭备库)
[1.3.2.找到指向备库的那个 dest(通常是 log_archive_dest_2 之类)](#1.3.2.找到指向备库的那个 dest(通常是 log_archive_dest_2 之类))
1.3.3.同时确认主库备用服务(fal_server)不再指向备库
[1.4.删除备库实例(prdcdb_adg 主机上操作)](#1.4.删除备库实例(prdcdb_adg 主机上操作))
[1.4.1.方式 A:DBCA 删除(备库主机)](#1.4.1.方式 A:DBCA 删除(备库主机))
[1.4.2.方式 B:手动清理(不想用 DBCA 时)](#1.4.2.方式 B:手动清理(不想用 DBCA 时))
[1.5.1. 清除主库中积压的、原本要发往备库的归档](#1.5.1. 清除主库中积压的、原本要发往备库的归档)
[1.5.2. 验证主库完全脱离 DG](#1.5.2. 验证主库完全脱离 DG)
删除 ADG 备库不能直接用dbca -deleteDatabase,那样会留下 DG 配置残留、影响主库。正确流程是先解绑 Data Guard 关系,再删除备库实例及主库残留归档文件。
一、删除 ADG 备库的完整流程
1.1.确认环境与角色(前提检查)
先在主库和备库分别确认:
select name,db_unique_name,database_role,open_mode,protection_mode from v$database;
主库:

备库:

确认:主库角色 = PRIMARY,备库角色 = PHYSICAL STANDBY。记录下主库、备库的唯一标识db_unique_name。
1.2.查看 DG 配置(用 DGMGRL)
进入DGMGRL命令行是专用于DG管理的命令工具,可以先去工具里边确认当前DG环境是启用了broker还是手动的方式做的故障切换。
dgmgrl /
show configuration;

**注意:**没有 Broker,DG 关系是通过主备库的参数配置(log_archive_dest / fal_server 等) 维系的。删除时重点就是双向解除这些参数关联。
1.2.在备库停止日志应用并关闭
1.2.1.停止 MRP(日志应用)
-- 备库 prdcdb_adg
ALTER DATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;

注意:这里当前环境没有打开日志应用,会提示如下

1.2.2. 确认归档已应用完毕(无 pending)
-- 备库
select sequence#,applied from v$archived_log where applied='NO' and resetlogs_change#=(select resetlogs_change# from v$database);

-- 若有 NO,先应用完再继续,避免主库归档堆积
1.2.3. 关闭备库
SHUTDOWN IMMEDIATE;

1.3.从主库解除对备库的归档目标(主库操作)
这是一个比较关键的步骤,如果不做的话,会导致主库会一直尝试往已删的备库传归档并报错、堆积。
1.3.1.查看当前归档目标配置
SHOW PARAMETER log_archive_dest;

1.3.2.找到指向备库的那个 dest(通常是 log_archive_dest_2 之类)
一般配置的话dest_1表示的是本地归档,dest_2则表示传给备库的归档,也可以db_unique_name进行区分。
1)停用dest_2
ALTER SYSTEM SET LOG_ARCHIVE_DEST_STATE_2='DEFER' SCOPE=BOTH;
注:先 DEFER 而非直接清空,是为了安全------停用后若发现还有问题可以再 enable 回滚。确认无误后再彻底清空。
2)清除dest_2配置
ALTER SYSTEM SET LOG_ARCHIVE_DEST_2='' SCOPE=BOTH;


3)验证dest_2已停用
set line 400;
column dest_name format a30;
column error format a30;
SELECT dest_id, dest_name, status, error, db_unique_name FROM v$archive_dest_status WHERE dest_id IN (1, 2);
期望结果:dest_2 状态应为 DEFERRED(或 INACTIVE),error 为空。如果备库在 tnsnames.ora 中有独立条目,保留或删除均可,不影响主库。
1.3.3.同时确认主库备用服务(fal_server)不再指向备库
SHOW PARAMETER fal_server;

-- 若主库 fal_server 配了备库,改成空或删掉
ALTER SYSTEM SET FAL_SERVER='' SCOPE=BOTH;

1.4.删除备库实例(prdcdb_adg 主机上操作)
1.4.1.方式 A:DBCA 删除(备库主机)
dbca -silent -deleteDatabase \
-sourceDB <ORACLE_SID> \
-sysDBAUserName sys \
-sysDBAPassword <密码>
-- 注意sourceDB 在 DBCA 中实际是用来标识要删除的数据库实例的,它匹配的是实例名(ORACLE_SID / INSTANCE_NAME),也就是 prdcdb
bash
[oracle@prdcdb_adg ~]$ vi /etc/oratab
[oracle@prdcdb_adg ~]$ dbca -silent -deleteDatabase -sourceDB prdcdb_standby -sysDBAUserName sys -sysDBAPassword OraclePrdcdb
[FATAL] [DBT-10201] 无法执行删除数据库(D)操作。
原因: 系统上不存在数据库。
[oracle@prdcdb_adg ~]$
[oracle@prdcdb_adg ~]$
[oracle@prdcdb_adg ~]$
[oracle@prdcdb_adg ~]$ source ~/.bash_profile
[oracle@prdcdb_adg ~]$
[oracle@prdcdb_adg ~]$ vi /etc/oratab
[oracle@prdcdb_adg ~]$
[oracle@prdcdb_adg ~]$ cat /etc/oratab
#
# This file is used by ORACLE utilities. It is created by root.sh
# and updated by either Database Configuration Assistant while creating
# a database or ASM Configuration Assistant while creating ASM instance.
# A colon, ':', is used as the field terminator. A new line terminates
# the entry. Lines beginning with a pound sign, '#', are comments.
#
# Entries are of the form:
# $ORACLE_SID:$ORACLE_HOME:<N|Y>:
#
# The first and second fields are the system identifier and home
# directory of the database respectively. The third field indicates
# to the dbstart utility that the database should , "Y", or should not,
# "N", be brought up at system boot time.
#
# Multiple entries with the same $ORACLE_SID are not allowed.
#
#
# 编辑 /etc/oratab,追加备库条目(SID=prdcdb,home 用 12.2)
# 格式:SID:HOME:Y|N
prdcdb:/u01/app/oracle/product/12.2.0.1/dbhome_1:N
#orcl:/u01/app/oracle/product/19c/dbhome_1:N
[oracle@prdcdb_adg ~]$ cd /u01/app/oracle/product/12.2.0/
[oracle@prdcdb_adg 12.2.0]$ ll
总用量 4
drwxr-xr-x 73 oracle oinstall 4096 9月 23 21:42 dbhome_1
[oracle@prdcdb_adg 12.2.0]$ cd ..
[oracle@prdcdb_adg product]$ ll
总用量 0
drwxr-xr-x 3 oracle oinstall 22 6月 17 14:04 12.2.0
[oracle@prdcdb_adg product]$ vi /etc/oratab
[oracle@prdcdb_adg product]$ dbca -silent -deleteDatabase -sourceDB prdcdb_standby -sysDBAUserName sys -sysDBAPassword OraclePrdcdb
[FATAL] [DBT-05511] 指定的数据库 (prdcdb_standby) 不存在。
操作: 提供现有数据库。
[WARNING] [DBT-11503] 实例 (prdcdb_standby) 未在本地节点上运行。这可能导致部分删除 Oracle 数据库。
原因: 要完全删除 Oracle 数据库实例和数据库文件, 需要本地运行的实例。
操作: 指定本地运行的数据库, 或者在运行数据库实例的节点上执行 DBCA。
[oracle@prdcdb_adg product]$ dbca -silent -deleteDatabase -sourceDB prdcdb -sysDBAUserName sys -sysDBAPassword OraclePrdcdb
正在连接到数据库
4%已完成
9%已完成
14%已完成
19%已完成
23%已完成
28%已完成
47%已完成
正在更新网络配置文件
52%已完成
正在删除实例和数据文件
76%已完成
100%已完成
有关详细信息, 请参阅日志文件 "/u01/app/oracle/cfgtoollogs/dbca/prdcdb0.log"。
[oracle@prdcdb_adg product]$
**注意:**删除过程中出现找不到数据库,排查一下看到/etc/oratab里边没有对应的实例注册信息,这是因为我这个测试环境装过19c的,后边安装的实例信息缺失了。


1.4.2.方式 B:手动清理(不想用 DBCA 时)
删除备库数据文件目录
rm -rf $ORACLE_BASE/oradata/<备库目录>
# 删除参数文件、密码文件
rm -f $ORACLE_HOME/dbs/spfile<备库SID>.ora
rm -f $ORACLE_HOME/dbs/init<备库SID>.ora
rm -f $ORACLE_HOME/dbs/orapw<备库SID>
清理监听器配置(listener.ora / tnsnames.ora 中备库条目,可选)
1.5.清理主库归档并验证
1.5.1. 清除主库中积压的、原本要发往备库的归档
-- 主库
SELECT dest_id, dest_name, status, error FROM v$archive_dest_status;
-- 确认原备库 dest 状态为 DEFER/INACTIVE 或已清空
bash
SQL> set line 400;
SQL> column dest_name format a30;
SQL>
SQL> column error format a30;
SQL>
SQL> select dest_id,dest_name,status,error from v$archive_dest_status;
DEST_ID DEST_NAME STATUS ERROR
---------- ------------------------------ --------- ------------------------------
1 LOG_ARCHIVE_DEST_1 VALID
2 LOG_ARCHIVE_DEST_2 INACTIVE
3 LOG_ARCHIVE_DEST_3 INACTIVE
4 LOG_ARCHIVE_DEST_4 INACTIVE
5 LOG_ARCHIVE_DEST_5 INACTIVE
6 LOG_ARCHIVE_DEST_6 INACTIVE
7 LOG_ARCHIVE_DEST_7 INACTIVE
8 LOG_ARCHIVE_DEST_8 INACTIVE
9 LOG_ARCHIVE_DEST_9 INACTIVE
10 LOG_ARCHIVE_DEST_10 INACTIVE
11 LOG_ARCHIVE_DEST_11 INACTIVE
DEST_ID DEST_NAME STATUS ERROR
---------- ------------------------------ --------- ------------------------------
12 LOG_ARCHIVE_DEST_12 INACTIVE
13 LOG_ARCHIVE_DEST_13 INACTIVE
14 LOG_ARCHIVE_DEST_14 INACTIVE
15 LOG_ARCHIVE_DEST_15 INACTIVE
16 LOG_ARCHIVE_DEST_16 INACTIVE
17 LOG_ARCHIVE_DEST_17 INACTIVE
18 LOG_ARCHIVE_DEST_18 INACTIVE
19 LOG_ARCHIVE_DEST_19 INACTIVE
20 LOG_ARCHIVE_DEST_20 INACTIVE
21 LOG_ARCHIVE_DEST_21 INACTIVE
22 LOG_ARCHIVE_DEST_22 INACTIVE
DEST_ID DEST_NAME STATUS ERROR
---------- ------------------------------ --------- ------------------------------
23 LOG_ARCHIVE_DEST_23 INACTIVE
24 LOG_ARCHIVE_DEST_24 INACTIVE
25 LOG_ARCHIVE_DEST_25 INACTIVE
26 LOG_ARCHIVE_DEST_26 INACTIVE
27 LOG_ARCHIVE_DEST_27 INACTIVE
28 LOG_ARCHIVE_DEST_28 INACTIVE
29 LOG_ARCHIVE_DEST_29 INACTIVE
30 LOG_ARCHIVE_DEST_30 INACTIVE
31 LOG_ARCHIVE_DEST_31 INACTIVE
31 rows selected.
SQL>
1.5.2. 验证主库完全脱离 DG
-- 主库
SELECT database_role, open_mode, protection_mode FROM v$database;
-- 应为 PRIMARY / READ WRITE / MAXIMUM PERFORMANCE
-- 确认归档可正常清理、无 pending
SELECT COUNT(*) FROM v$archived_log WHERE applied = 'NO';
bash
SQL> SELECT database_role, open_mode, protection_mode FROM v$database;
DATABASE_ROLE OPEN_MODE PROTECTION_MODE
---------------- -------------------- --------------------
PRIMARY READ WRITE MAXIMUM PERFORMANCE
SQL>
SQL>
SQL>
SQL> SELECT dest_id, dest_name, status, error, db_unique_name
FROM v$archive_dest_status; 2
DEST_ID DEST_NAME STATUS ERROR DB_UNIQUE_NAME
---------- ------------------------------ --------- ------------------------------ ------------------------------
1 LOG_ARCHIVE_DEST_1 VALID prdcdb
2 LOG_ARCHIVE_DEST_2 INACTIVE NONE
3 LOG_ARCHIVE_DEST_3 INACTIVE NONE
4 LOG_ARCHIVE_DEST_4 INACTIVE NONE
5 LOG_ARCHIVE_DEST_5 INACTIVE NONE
6 LOG_ARCHIVE_DEST_6 INACTIVE NONE
7 LOG_ARCHIVE_DEST_7 INACTIVE NONE
8 LOG_ARCHIVE_DEST_8 INACTIVE NONE
9 LOG_ARCHIVE_DEST_9 INACTIVE NONE
10 LOG_ARCHIVE_DEST_10 INACTIVE NONE
11 LOG_ARCHIVE_DEST_11 INACTIVE NONE
DEST_ID DEST_NAME STATUS ERROR DB_UNIQUE_NAME
---------- ------------------------------ --------- ------------------------------ ------------------------------
12 LOG_ARCHIVE_DEST_12 INACTIVE NONE
13 LOG_ARCHIVE_DEST_13 INACTIVE NONE
14 LOG_ARCHIVE_DEST_14 INACTIVE NONE
15 LOG_ARCHIVE_DEST_15 INACTIVE NONE
16 LOG_ARCHIVE_DEST_16 INACTIVE NONE
17 LOG_ARCHIVE_DEST_17 INACTIVE NONE
18 LOG_ARCHIVE_DEST_18 INACTIVE NONE
19 LOG_ARCHIVE_DEST_19 INACTIVE NONE
20 LOG_ARCHIVE_DEST_20 INACTIVE NONE
21 LOG_ARCHIVE_DEST_21 INACTIVE NONE
22 LOG_ARCHIVE_DEST_22 INACTIVE NONE
DEST_ID DEST_NAME STATUS ERROR DB_UNIQUE_NAME
---------- ------------------------------ --------- ------------------------------ ------------------------------
23 LOG_ARCHIVE_DEST_23 INACTIVE NONE
24 LOG_ARCHIVE_DEST_24 INACTIVE NONE
25 LOG_ARCHIVE_DEST_25 INACTIVE NONE
26 LOG_ARCHIVE_DEST_26 INACTIVE NONE
27 LOG_ARCHIVE_DEST_27 INACTIVE NONE
28 LOG_ARCHIVE_DEST_28 INACTIVE NONE
29 LOG_ARCHIVE_DEST_29 INACTIVE NONE
30 LOG_ARCHIVE_DEST_30 INACTIVE NONE
31 LOG_ARCHIVE_DEST_31 INACTIVE NONE
31 rows selected.
SQL>
SQL>
SQL> SELECT COUNT(*) FROM v$archived_log WHERE applied = 'NO';
COUNT(*)
----------
11
SQL>
注意:这里为啥会有11条记录?这是典型的 "已删除归档的残留记录":
归档文件曾经存在,后来被删掉了(可能你之前 rm 掉,或者 RMAN 删了文件但控制文件里保留了"已删除"标记的记录)。
控制文件出于归档连续性/备份追溯的需要,仍然保留这些记录的骨架(DELETED=YES),所以它们还占着 v$archived_log 的 11 行。
REGISTRAR 是 ARCH 和 FGRD,说明这些记录是归档进程和 FGRD(Foreign/Remote Gap Resolution Daemon,Data Guard 用来解决 gap 的进程) 登记的------FGRD 这个登记者进一步说明它们和 Data Guard 的 gap 追踪有关。

**解决方案:**清掉主库指向已删备库的 DG 配置(推荐,从根上解决)
这 11 条带 FGRD 登记者的记录,源头就是主库还在追踪一个已经不存在的备库的 gap。去主库执行:
bash
SHOW PARAMETER log_archive_dest
SHOW PARAMETER fal_server
SHOW PARAMETER log_archive_config
把指向已删备库的 LOG_ARCHIVE_DEST_n、FAL_SERVER、以及 LOG_ARCHIVE_CONFIG 里多余的 DG_CONFIG 条目清掉:
bash
ALTER SYSTEM SET log_archive_dest_2 = '';
ALTER SYSTEM SET fal_server = '';
-- 如果 DG_CONFIG 里还列着备库DG_CONFIG=(prdcdb)';
ALTER SYSTEM SET log_archive_config='' SCOPE=BOTH;
配置清干净后,FGRD 不再追踪,这些记录会在控制文件老化周期后被回收。
1.6.清除SRL备用日志
SRL 就是 DG 环境清除后遗留的闲置物理文件 ,THREAD#=0 + UNASSIGNED + ARCHIVED=YES 三个字段共同证明它们从未被使用过,对当前主库运行无任何影响。

查看当前的文件信息:

注意:还需要进行rm -rf删除

二、核心验证流程汇总
2.1.主库执行
-- 角色
SELECT database_role, open_mode, protection_mode FROM v$database;
-- 归档目标
SELECT dest_id, dest_name, status, error, db_unique_name FROM v$archive_dest_status;
-- DG 参数残留
SHOW PARAMETER log_archive_config;
SHOW PARAMETER fal_server;
SHOW PARAMETER fal_client;
整体过程:
bash
SQL> set line 400;
SQL> SELECT database_role, open_mode, protection_mode FROM v$database;
DATABASE_ROLE OPEN_MODE PROTECTION_MODE
---------------- -------------------- --------------------
PRIMARY READ WRITE MAXIMUM PERFORMANCE
SQL> SELECT dest_id, dest_name, status, error, db_unique_name FROM v$archive_dest_status;
DEST_ID DEST_NAME STATUS ERROR DB_UNIQUE_NAME
---------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --------- ----------------------------------------------------------------- ------------------------------
1 LOG_ARCHIVE_DEST_1 VALID prdcdb
2 LOG_ARCHIVE_DEST_2 INACTIVE NONE
3 LOG_ARCHIVE_DEST_3 INACTIVE NONE
4 LOG_ARCHIVE_DEST_4 INACTIVE NONE
5 LOG_ARCHIVE_DEST_5 INACTIVE NONE
6 LOG_ARCHIVE_DEST_6 INACTIVE NONE
7 LOG_ARCHIVE_DEST_7 INACTIVE NONE
8 LOG_ARCHIVE_DEST_8 INACTIVE NONE
9 LOG_ARCHIVE_DEST_9 INACTIVE NONE
10 LOG_ARCHIVE_DEST_10 INACTIVE NONE
11 LOG_ARCHIVE_DEST_11 INACTIVE NONE
DEST_ID DEST_NAME STATUS ERROR DB_UNIQUE_NAME
---------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --------- ----------------------------------------------------------------- ------------------------------
12 LOG_ARCHIVE_DEST_12 INACTIVE NONE
13 LOG_ARCHIVE_DEST_13 INACTIVE NONE
14 LOG_ARCHIVE_DEST_14 INACTIVE NONE
15 LOG_ARCHIVE_DEST_15 INACTIVE NONE
16 LOG_ARCHIVE_DEST_16 INACTIVE NONE
17 LOG_ARCHIVE_DEST_17 INACTIVE NONE
18 LOG_ARCHIVE_DEST_18 INACTIVE NONE
19 LOG_ARCHIVE_DEST_19 INACTIVE NONE
20 LOG_ARCHIVE_DEST_20 INACTIVE NONE
21 LOG_ARCHIVE_DEST_21 INACTIVE NONE
22 LOG_ARCHIVE_DEST_22 INACTIVE NONE
DEST_ID DEST_NAME STATUS ERROR DB_UNIQUE_NAME
---------- ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- --------- ----------------------------------------------------------------- ------------------------------
23 LOG_ARCHIVE_DEST_23 INACTIVE NONE
24 LOG_ARCHIVE_DEST_24 INACTIVE NONE
25 LOG_ARCHIVE_DEST_25 INACTIVE NONE
26 LOG_ARCHIVE_DEST_26 INACTIVE NONE
27 LOG_ARCHIVE_DEST_27 INACTIVE NONE
28 LOG_ARCHIVE_DEST_28 INACTIVE NONE
29 LOG_ARCHIVE_DEST_29 INACTIVE NONE
30 LOG_ARCHIVE_DEST_30 INACTIVE NONE
31 LOG_ARCHIVE_DEST_31 INACTIVE NONE
31 rows selected.
SQL> SHOW PARAMETER log_archive_config;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
log_archive_config string DG_CONFIG=(prdcdb)
SQL>
SQL> SHOW PARAMETER fal_server;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
fal_server string
SQL>
SQL> SHOW PARAMETER fal_client;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
fal_client string
SQL>
SQL> ALTER SYSTEM SET log_archive_config='' SCOPE=BOTH;
System altered.
SQL> SHOW PARAMETER log_archive_config;
NAME TYPE VALUE
------------------------------------ ----------- ------------------------------
log_archive_config string
SQL>
2.2.备库主机执行
ps -ef | grep pmon | grep -v grep
cat /etc/oratab
lsnrctl status
