Oracle12c Windows 多实例ADG
Oracle DG英文全称Oracle Data Guard,DG提供全面的服务包括:创建、维护、管理、以及监控standby数据库,确保数据安全。DG用途是构建企业数据高可用应用环境。ADG实际是实现自动切换主备的意思,这里关于A暂时不做配置。
[toc]
1. 环境介绍
1.1 安装环境
在主机1上安装数据库软件,并建监听和实例,在主机2上安装数据库软件,并建监听,可以不建实例。
项目 | 主机1(主库) | 主机2(备库) |
---|---|---|
操作系统 | Windows server 2016 | Windows server 2016 |
主机名称 | db31 | db32 |
IP地址 | 172.16.103.31 | 172.16.103.32 |
Oracle版本 | Oracle 12.2.0.1 | Oracle 12.2.0.1 |
BASE | D:\app\Administrator\virtual | D:\app\Administrator\virtual |
SID | orcl1,orcl2 | orcl1,orcl2 |
db_unique_name | db31_orcl1,db31_orcl2 | db32_orcl1,db32_orcl2 |
1.2 多实例启动问题
1.2.1 现象
先部署orcl1实例,在部署orcl2实例。部署后orcl2能正常shutdown/startup,而orcl1在shutdown之后startup不能正常启动,提示没有pfile配置文件。官方解决办法需要指定pfile(Oracle多实例启动)。但是如果只是为了启动实例,后面的ADG同样还是配置不下去的,后面还有很多报错依旧。
1.2.2 分析
在分析日志报错以及日志文件,最多的显示是“指定文件不存在、或无法识别、或无权限访问”。请牢记这个错误提示就是windows下文件权限导致的。
如当前的环境,orcl1不能直接启动需指定pfile,但明明指定路径下是有spfile文件,它为什么非要去读pfile文件呢?问题就在于我们orcl1的spfile的权限不正常。打开spfile的属性安全设置会发现,只有orcl2实例在权限,没有orcl1的权限。
1.2.3 解决办法
通过上面的分析,我们只有把属于orcl1实例的spfile文件的权限修改为everyone修改权限即可。当然其他属于orcl1实例的文件也需要修改。这里还需要把PWDorcl1.ORA文件权限修改正确。
如何修改window文件权限,这里不阐述。
1.3 如何切换实例
切换实例在linux下是修改环境配置文件。在window下直接使用实例名即可。如:
// 登入orc1
sqlplus sys/123456@orc1 as sysdba
// 登入orc2
sqlplus sys/123456@orc2 as sysdba
2. 监听配置
多实例也好,单实例也罢,监听文件只需要一份。在配置时需要注意区分开来。用做ADG的lis和tns,有多少个实例就配置多组,但文件只要一份。
2.1 listener.ora(主端)
# listener.ora Network Configuration File: D:\app\Administrator\virtual\product\12.2.0\dbhome_1\network\admin\listener.ora
# Generated by Oracle configuration tools.
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME = CLRExtProc)
(ORACLE_HOME = D:\app\Administrator\virtual\product\12.2.0\dbhome_1)
(PROGRAM = extproc)
(ENVS = "EXTPROC_DLLS=ONLY:D:\app\Administrator\virtual\product\12.2.0\dbhome_1\bin\oraclr12.dll")
)
(SID_DESC =
(GLOBAL_DBNAME = orcl1)
(ORACLE_HOME = D:\app\Administrator\virtual\product\12.2.0\dbhome_1)
(SID_NAME = orcl1)
(ENVS = "EXTPROC_DLLS=ONLY:D:\app\Administrator\virtual\product\12.2.0\dbhome_1\bin\oraclr12.dll")
)
(SID_DESC =
(GLOBAL_DBNAME = orcl2)
(ORACLE_HOME = D:\app\Administrator\virtual\product\12.2.0\dbhome_1)
(SID_NAME = orcl2)
(ENVS = "EXTPROC_DLLS=ONLY:D:\app\Administrator\virtual\product\12.2.0\dbhome_1\bin\oraclr12.dll")
)
)
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 172.16.103.31)(PORT = 1521))
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
)
)
2.2 listener.ora(备端)
# listener.ora Network Configuration File: D:\app\Administrator\virtual\product\12.2.0\dbhome_1\network\admin\listener.ora
# Generated by Oracle configuration tools.
SID_LIST_LISTENER =
(SID_LIST =
(SID_DESC =
(SID_NAME = CLRExtProc)
(ORACLE_HOME = D:\app\Administrator\virtual\product\12.2.0\dbhome_1)
(PROGRAM = extproc)
(ENVS = "EXTPROC_DLLS=ONLY:D:\app\Administrator\virtual\product\12.2.0\dbhome_1\bin\oraclr12.dll")
)
(SID_DESC =
(GLOBAL_DBNAME = orcl1)
(ORACLE_HOME = D:\app\Administrator\virtual\product\12.2.0\dbhome_1)
(SID_NAME = orcl1)
(ENVS = "EXTPROC_DLLS=ONLY:D:\app\Administrator\virtual\product\12.2.0\dbhome_1\bin\oraclr12.dll")
)
(SID_DESC =
(GLOBAL_DBNAME = orcl2)
(ORACLE_HOME = D:\app\Administrator\virtual\product\12.2.0\dbhome_1)
(SID_NAME = orcl2)
(ENVS = "EXTPROC_DLLS=ONLY:D:\app\Administrator\virtual\product\12.2.0\dbhome_1\bin\oraclr12.dll")
)
)
LISTENER =
(DESCRIPTION_LIST =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 172.16.103.32)(PORT = 1521))
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
)
)
2.3 tnsnames.ora(主端)
# tnsnames.ora Network Configuration File: D:\app\Administrator\virtual\product\12.2.0\dbhome_1\network\admin\tnsnames.ora
# Generated by Oracle configuration tools.
LISTENER_orcl1 =
(ADDRESS = (PROTOCOL = TCP)(HOST = 172.16.103.31)(PORT = 1521))
LISTENER_orcl2 =
(ADDRESS = (PROTOCOL = TCP)(HOST = 172.16.103.31)(PORT = 1521))
ORACLR_CONNECTION_DATA =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
)
(CONNECT_DATA =
(SID = CLRExtProc)
(PRESENTATION = RO)
)
)
orcl1 =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 172.16.103.31)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = orcl1)
)
)
orcl2 =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 172.16.103.31)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = orcl2)
)
)
orcl1_db31 =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 172.16.103.31)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = orcl1)
)
)
orcl1_db32 =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 172.16.103.32)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = orcl1)
)
)
orcl2_db31 =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 172.16.103.31)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = orcl2)
)
)
orcl2_db32 =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 172.16.103.32)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = orcl2)
)
)
2.4 tnsnames.ora(备端)
# tnsnames.ora Network Configuration File: D:\app\Administrator\virtual\product\12.2.0\dbhome_1\network\admin\tnsnames.ora
# Generated by Oracle configuration tools.
LISTENER_ORACLE12 =
(ADDRESS = (PROTOCOL = TCP)(HOST = 172.16.103.32)(PORT = 1521))
LISTENER_ORCL =
(ADDRESS = (PROTOCOL = TCP)(HOST = 172.16.103.32)(PORT = 1521))
ORACLR_CONNECTION_DATA =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = IPC)(KEY = EXTPROC1521))
)
(CONNECT_DATA =
(SID = CLRExtProc)
(PRESENTATION = RO)
)
)
ORCL1 =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 172.16.103.32)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = orcl1)
)
)
ORCL2 =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 172.16.103.32)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = orcl2)
)
)
orcl1_db31 =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 172.16.103.31)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = orcl1)
)
)
orcl1_db32 =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 172.16.103.32)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = orcl1)
)
)
orcl2_db31 =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 172.16.103.31)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = orcl2)
)
)
orcl2_db32 =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = 172.16.103.32)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = orcl2)
)
)
2.5 重启监听
lsnrctl stop
lsnrctl start
3. 实例orcl1
3.1 归档/闪回/强档
# 登录(主端)
sqlplus sys/123456@orcl1 as sysdba
SQL> select instance_name,status from v$instance;
SQL> show pdbs //确定容器数据库
# 查看归档/闪回/强档(主端)
SQL> archive log list;
SQL> select flashback_on from v$database;
SQL> select force_logging from v$database;
SQL> show parameter db_recovery_file_dest;
# 开启强档/归档/闪回(主端)
SQL> alter database force logging;
SQL> alter system set db_recovery_file_dest='D:\app\Administrator\virtual\fast_recovery_area';
SQL> alter system set db_recovery_file_dest_size='40G';
// 此设置会变为临时设置
// 正确的做法是收到添加pfile文件里
// *.db_recovery_file_dest='D:\app\Administrator\virtual\fast_recovery_area'
// *.db_recovery_file_dest_size=42949672960
SQL> shutdown immediate;
SQL> startup pfile=D:\app\Administrator\virtual\product\12.2.0\dbhome_1\database\initorcl1.ora mount;
SQL> alter database archivelog;
SQL> alter database flashback on;
SQL> alter database open;
SQL> alter pluggable database all open; //开启容器数据库
3.2 standby日志
SQL> SELECT GROUP#,ARCHIVED,STATUS,BYTES/1024/1024 FROM V$LOG;
SQL> SELECT GROUP#,MEMBER FROM V$LOGFILE;
SQL>
ALTER DATABASE ADD STANDBY LOGFILE GROUP 11 'D:\APP\ADMINISTRATOR\VIRTUAL\ORADATA\ORCL1\redo11_stb01_log' size 200M;
ALTER DATABASE ADD STANDBY LOGFILE GROUP 12 'D:\APP\ADMINISTRATOR\VIRTUAL\ORADATA\ORCL1\redo12_stb02_log' size 200M;
ALTER DATABASE ADD STANDBY LOGFILE GROUP 13 'D:\APP\ADMINISTRATOR\VIRTUAL\ORADATA\ORCL1\redo13_stb03_log' size 200M;
ALTER DATABASE ADD STANDBY LOGFILE GROUP 14 'D:\APP\ADMINISTRATOR\VIRTUAL\ORADATA\ORCL1\redo14_stb04_log' size 200M;
3.3 pfile文件/pwd密码
# pfile调试
SQL> set line 1000;
SQL> select instance_name,status from v$instance;
SQL> show parameter spfile;
SQL> show parameter name;
SQL> select open_mode from v$database;
SQL> select decode(count(*),1,'spfile','pfile') from v$spparameter where rownum=1 and isspecified ='TRUE';
# 创建pfile
// 如1.2所说,多实例启动指定pfile文件。这里只需修改pfile文件
## 主站配置(在末尾添加)
*.db_unique_name='orcl1_db31'
*.fal_server='orcl1_db32'
*.log_archive_config='dg_config=(orcl1_db31,orcl1_db32)'
*.log_archive_dest_1='location=use_db_recovery_file_dest valid_for=(all_logfiles, all_roles) db_unique_name=orcl1_db31'
*.log_archive_dest_2='service=orcl1_db32 lgwr async valid_for=(online_logfile,primary_role) db_unique_name=orcl1_db32'
*.log_archive_dest_state_1=ENABLE
*.log_archive_dest_state_2=ENABLE
*.standby_file_management='AUTO'
*.db_file_name_convert='D:\app\Administrator\virtual\oradata\ORCL1','D:\app\Administrator\virtual\oradata\ORCL1'
*.log_file_name_convert='D:\app\Administrator\virtual\oradata\ORCL1','D:\app\Administrator\virtual\oradata\ORCL1'
## 备站配置(在末尾添加)
*.db_unique_name='orcl1_db32'
*.fal_server='orcl1_db31'
*.log_archive_config='dg_config=(orcl1_db31,orcl1_db32)'
*.log_archive_dest_1='location=use_db_recovery_file_dest valid_for=(all_logfiles, all_roles) db_unique_name=orcl1_db32'
*.log_archive_dest_2='service=orcl1_db31 lgwr async valid_for=(online_logfile,primary_role) db_unique_name=orcl1_db31'
*.log_archive_dest_state_1=ENABLE
*.log_archive_dest_state_2=ENABLE
*.standby_file_management='AUTO'
*.db_file_name_convert='D:\app\Administrator\virtual\oradata\ORCL1','D:\app\Administrator\virtual\oradata\ORCL1'
*.log_file_name_convert='D:\app\Administrator\virtual\oradata\ORCL1','D:\app\Administrator\virtual\oradata\ORCL1'
# 生成spfile(主端)
SQL> shutdown immediate;
SQL> create spfile from pfile;
SQL> startup;
SQL> alter pluggable database all open;
# 生成spfile(备端)
SQL> shutdown immediate;
SQL> create spfile from pfile;
SQL> startup nomount;
# 将密码文件拷贝到备端(注意文件权限)
D:\app\Administrator\virtual\product\12.2.0\dbhome_1\database\PWDorcl.ORA
3.4 RMAN复制开启同步
# cmd下执行RMAN复制(备端)
rman target sys/123456@orcl1_db31 auxiliary sys/123456@orcl1_db32
# RMAN下执行复制
RMAN> duplicate target database for standby from active database nofilenamecheck;
# SQL下开启同步
SQL> alter database recover managed standby database using current logfile disconnect from session;
## 取消同步
SQL> alter database recover managed standby database cancel;
# 备端打开数据库
SQL> select status from v$instance;
SQL> alter database open;
SQL> alter pluggable database all open;
# 备库开闪回
SQL> select flashback_on from v$database;
alter database flashback on;
# SQL下开启同步
SQL> alter database recover managed standby database using current logfile disconnect from session;
3.5 DG验证
# 主备库状态
SQL> select switchover_status,database_role from v$database;
# 主备库归档序号
SQL>
select thread#, max(sequence#) "Last Standby Seq Applied"
from v$archived_log val, v$database vdb
where val.resetlogs_change# = vdb.resetlogs_change#
and val.applied in ('YES','IN-MEMORY')
group by thread# order by 1;
# 备库DG进程
SQL> select process,client_process,sequence#,status from v$managed_standby;
# 备库模式
SQL> select database_role,protection_mode,protection_level,open_mode from v$database;
# 主库创建表
create table test as select * from dba_objects where rownum < 101;
# 备库查询
select count(*) from test; ## 结果为100表示实时同步成功
# 主库删除
drop table test purge;
4. 实例orcl2
3.1 归档/闪回/强档
# 登录(主端)
sqlplus sys/123456@orcl2 as sysdba
SQL> select instance_name,status from v$instance;
SQL> show pdbs
# 查看归档/闪回/强档(主端)
SQL> archive log list;
SQL> select flashback_on from v$database;
SQL> select force_logging from v$database;
SQL> show parameter db_recovery_file_dest;
# 开启强档/归档/闪回(主端)
SQL> alter database force logging;
SQL> alter system set db_recovery_file_dest='D:\app\Administrator\virtual\fast_recovery_area';
SQL> alter system set db_recovery_file_dest_size='40G';
SQL> shutdown immediate;
SQL> startup mount;
SQL> alter database archivelog;
SQL> alter database flashback on;
SQL> alter database open;
SQL> alter pluggable database all open;
3.2 standby
SQL> SELECT GROUP#,ARCHIVED,STATUS,BYTES/1024/1024 FROM V$LOG;
SQL> SELECT GROUP#,MEMBER FROM V$LOGFILE;
SQL>
ALTER DATABASE ADD STANDBY LOGFILE GROUP 11 'D:\APP\ADMINISTRATOR\VIRTUAL\ORADATA\ORCL2\redo11_stb01_log' size 200M;
ALTER DATABASE ADD STANDBY LOGFILE GROUP 12 'D:\APP\ADMINISTRATOR\VIRTUAL\ORADATA\ORCL2\redo12_stb02_log' size 200M;
ALTER DATABASE ADD STANDBY LOGFILE GROUP 13 'D:\APP\ADMINISTRATOR\VIRTUAL\ORADATA\ORCL2\redo13_stb03_log' size 200M;
ALTER DATABASE ADD STANDBY LOGFILE GROUP 14 'D:\APP\ADMINISTRATOR\VIRTUAL\ORADATA\ORCL2\redo14_stb04_log' size 200M;
3.3 pfile/spfile/密码
# pfile调试
SQL> set line 1000;
SQL> select instance_name,status from v$instance;
SQL> show parameter spfile;
SQL> show parameter name;
SQL> select open_mode from v$database;
SQL> select decode(count(*),1,'spfile','pfile') from v$spparameter where rownum=1 and isspecified ='TRUE';
SQL> startup pfile='D:\app\Administrator\virtual\product\12.2.0\dbhome_1\database\INITORACLE12.ORA'
SQL> SELECT NAME, VALUE, DISPLAY_VALUE FROM V$PARAMETER WHERE NAME ='spfile';
# 创建pfile
SQL> create pfile from spfile;
# 将pfile文件和密码文件拷贝到备端
D:\app\Administrator\virtual\product\12.2.0\dbhome_1\database\INITORCL.ORA
D:\app\Administrator\virtual\product\12.2.0\dbhome_1\database\PWDorcl.ORA
# 修改pfile文件,在INITORCL.ora末尾追加下面内容
## 主站配置
*.db_unique_name='orcl2_db31'
*.fal_server='orcl2_db32'
*.log_archive_config='dg_config=(orcl2_db31,orcl2_db32)'
*.log_archive_dest_1='location=use_db_recovery_file_dest valid_for=(all_logfiles, all_roles) db_unique_name=orcl2_db31'
*.log_archive_dest_2='service=orcl2_db32 lgwr async valid_for=(online_logfile,primary_role) db_unique_name=orcl2_db32'
*.log_archive_dest_state_1=ENABLE
*.log_archive_dest_state_2=ENABLE
*.standby_file_management='AUTO'
*.db_file_name_convert='D:\app\Administrator\virtual\oradata\orcl2','D:\app\Administrator\virtual\oradata\orcl2'
*.log_file_name_convert='D:\app\Administrator\virtual\oradata\orcl2','D:\app\Administrator\virtual\oradata\orcl2'
## 备站配置
*.db_unique_name='orcl2_db32'
*.fal_server='orcl2_db31'
*.log_archive_config='dg_config=(orcl2_db31,orcl2_db32)'
*.log_archive_dest_1='location=use_db_recovery_file_dest valid_for=(all_logfiles, all_roles) db_unique_name=orcl2_db32'
*.log_archive_dest_2='service=orcl2_db31 lgwr async valid_for=(online_logfile,primary_role) db_unique_name=orcl2_db31'
*.log_archive_dest_state_1=ENABLE
*.log_archive_dest_state_2=ENABLE
*.standby_file_management='AUTO'
*.db_file_name_convert='D:\app\Administrator\virtual\oradata\orcl2','D:\app\Administrator\virtual\oradata\orcl2'
*.log_file_name_convert='D:\app\Administrator\virtual\oradata\orcl2','D:\app\Administrator\virtual\oradata\orcl2'
# 生成spfile(主端)
SQL> shutdown immediate;
SQL> create spfile from pfile;
SQL> startup;
SQL> alter pluggable database all open;
# 生成spfile(备端)
SQL> shutdown immediate;
SQL> create spfile from pfile;
SQL> startup nomount;
# 将密码文件拷贝到备端(注意文件权限)
D:\app\Administrator\virtual\product\12.2.0\dbhome_1\database\PWDorc2.ORA
3.4 RMAN复制开启同步
# cmd下执行RMAN复制(备端)
rman target sys/123456@orcl2_db31 auxiliary sys/123456@orcl2_db32
# RMAN下执行复制
RMAN> duplicate target database for standby from active database nofilenamecheck;
# SQL下开启同步
SQL> alter database recover managed standby database using current logfile disconnect from session;
## 取消同步
SQL> alter database recover managed standby database cancel;
# 备端打开数据库
SQL> select status from v$instance;
SQL> alter database open;
SQL> alter pluggable database all open;
# 备库开闪回
SQL> select flashback_on from v$database;
alter database flashback on;
# SQL下开启同步
SQL> alter database recover managed standby database using current logfile disconnect from session;
3.5 DG验证
# 主备库状态
SQL> select switchover_status,database_role from v$database;
# 主备库归档序号
SQL>
select thread#, max(sequence#) "Last Standby Seq Applied"
from v$archived_log val, v$database vdb
where val.resetlogs_change# = vdb.resetlogs_change#
and val.applied in ('YES','IN-MEMORY')
group by thread# order by 1;
# 归档应用
SQL> SELECT SEQUENCE#, FIRST_TIME, NEXT_TIME,APPLIED,DELETED FROM V$ARCHIVED_LOG WHERE DELETED='NO' ORDER BY SEQUENCE#;
# 备库DG进程
SQL> select process,client_process,sequence#,status from v$managed_standby;
# 备库模式
SQL> select database_role,protection_mode,protection_level,open_mode from v$database;
# 主库创建表
create table test as select * from dba_objects where rownum < 101;
# 备库查询
select count(*) from test; ## 结果为100表示实时同步成功
# 主库删除
drop table test purge;
5 手动断开DG
# 关闭同步
SQL> alter database recover managed standby database cancel;
# 强制停止redo apply
SQL> alter database recover managed standby database finish force;
# 查看备库状态
SQL> select switchover_status,database_role from v$database;
SWITCHOVER_STATUS DATABASE_ROLE
---------------------------------------- --------------------------------
SESSIONS ACTIVE PHYSICAL STANDBY
# 切换为primary
SQL> alter database commit to switchover to primary with session shutdown;
# 打开数据库
SQL> alter database open;
# 验证数据库模式
SQL> select database_role,protection_mode,protection_level,open_mode from v$database;
DATABASE_ROLE PROTECTION_MODE PROTECTION_LEVEL OPEN_MODE
----------------- --------------------- --------------------- ---------------
PHYSICAL STANDBY MAXIMUM PERFORMANCE MAXIMUM PERFORMANCE READ WRITE