###################################
DG
###################################
# 这里经测试可以一次性 刷完脚本,但是不建议,操作 生产库 的话有一定
危险性
,建议充分理解后分段刷
# 情况一:RAC + DUPLICATE + 单节点 DG(复杂,需要转换路径)
#
主节点 RAC 主库配置
#修改主节点 hosts 增加一条 dg 的 ip 地址
#vim /etc/hosts /etc/hosts
mv /etc/hosts /etc/hosts.bak
cat > /etc/hosts <<EOF
127.0.0.1 localhost
# Public IP(eth0)
192.168.1.91 rac1
192.168.1.92 rac2
192.168.1.96 dg
# Public Virtual IP(eth0:1)
192.168.1.93 rac1-vip
192.168.1.94 rac2-vip
# Private IP(eth1)
192.168.99.1 rac1-priv
192.168.99.2 rac2-priv
# Single Client Access Name Virtua IP(eth0:2)
192.168.1.95 rac-cluster-scan
EOF
#
建立 rac1 和 dg 的 oracle 对等(
需要 安装介质)
/grid/sshsetup/sshUserSetup.sh -user
oracle -hosts "
rac1 dg" -advanced -exverify -confirm -noPromptPassphrase
#
传送
备库 oracle 软件 环境 (主库上运行,用增加 node 的方法直接传送,以提高效率)
su - oracle -c 'export IGNORE_PREADDNODE_CHECKS=Y && /u01/app/oracle/product/11.2.0/db_1/oui/bin/addNode.sh "CLUSTER_NEW_NODES={
dg}"'
# 修复 主库(清除 RAC 上的 dg 节点信息,可以略过)
# su - oracle -c '$ORACLE_HOME/oui/bin/runInstaller -updateNodeList ORACLE_HOME=$ORACLE_HOME "CLUSTER_NODES={rac1,rac2}"'
#
配置
网络服务名文件(
主库
和
备库
都要配,如果不想改 HOSTS 可以将 HOST 设置为对应的 IP 地址)
cat > /u01/app/oracle/product/11.2.0/db_1/network/admin/tnsnames.ora
<< EOF
primary= (DESCRIPTION= (ADDRESS= (PROTOCOL=TCP) (HOST=
rac1) (PORT=1521))
(CONNECT_DATA= (SERVER=DEDICATED) (SERVICE_NAME=
orcl)))
standby= (DESCRIPTION= (ADDRESS= (PROTOCOL=TCP) (HOST=
dg) (PORT=1521))
(CONNECT_DATA= (SERVER=DEDICATED) (SERVICE_NAME=
orclbak)))
EOF
# 测试 网络服务名
su - oracle -c 'tnsping standby && tnsping primary'
# 查看 CRS 资源和 数据库 状态
# su - grid -c "crs_stat -t"
# su - grid -c "srvctl status database -d
orcl"
#
关闭
主库(
谨慎 如果是生产库,要先停 监听 和 CRS
)
su - grid -c "srvctl stop database -d orcl"
#
更改 主库 配置
su - oracle -c 'sqlplus / as sysdba' << EOF
set linesize 300;
set pagesize 50;
-- 启动数据库至 MOUNT 状态
startup mount;
-- 改变数据库为强制日志模式
alter database force logging;
-- 改变数据库为归档模式
alter database archivelog;
-- 开启数据库至 OPEN 模式(这里只启动了 RAC 的节点一)
alter database open;
-- 查看闪回区路径(如已经设置,则跳过修改。该路径为空默认为控制文件的路径,修改至 +FRA 磁盘组)
-- 修改归档日志及闪回区存放路径(db_recovery_file_dest 与 log_archive_dest 冲突,官方已弃用后者)
-- 官方建议将归档日志写到本地磁盘,如果共享磁盘够大的话尽量放到 ASM 里(设置 size 大小后开启)
-- 如果不启用闪回日志,当出现故障转移时,你需要重建一个新的备库。(强烈建议开启闪回)
show parameter db_recovery;
--
alter system set db_recovery_file_dest_size=2G sid='*';
--
alter system set db_recovery_file_dest='
+FRA
' sid='*';
-- alter database flashback on;
-- 切换联机日志文件
alter system switch logfile;
-- 强制归档当前重做日志
-- alter system archive log current;
-- 增加 standby log file(备库 用 RAM 复制数据时会自动生成)
select * from v\$log;
-- ORACLE 要求 standby redo 要比 primary online redo 日志组多一个,每个 RAC 节点是一个 thread
alter database add
standby logfile thread
1 group
11 size 50M ,group
12 size 50M ,group
13 size 50M;
alter database add
standby logfile thread
2 group
14 size 50M ,group
15 size 50M ,group
16 size 50M;
-- DG 相关配置(
fal_client 11G 已弃用,file_name_convert 经测试只是 RMAN 复制数据用来转换路径,备库设置即可
)
alter system set fal_server=
standby
sid='*';
alter system set standby_file_management=AUTO sid='*';
alter system set log_archive_config='DG_CONFIG=(
orcl
,orclbak)' sid='*';
alter system set log_archive_dest_2='SERVICE=
standby LGWR SYNC AFFIRM VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=
orclbak' sid='*';
-- alter system set log_file_name_convert=('/u01/app/oracle/oradata/orclbak','+DATA/orcl/onlinelog','/u01/app/oracle/oradata/orclbak','+FRA/orcl/onlinelog') sid='*';
-- alter system set db_file_name_convert=('/u01/app/oracle/oradata/orclbak','+DATA/orcl/datafile','/u01/app/oracle/oradata/orclbak','+DATA/orcl/tempfile')
sid='*';
-- 重启远程归档
alter system set log_archive_dest_state_2='defer' sid='*';
alter system set log_archive_dest_state_2='defer' sid='*';
alter system set log_archive_dest_state_2='enable' sid='*';
EOF
# 检测主库状态
-- 检测数据库 实例名称 数据库状态 归档模式 强制日志 闪回
su - oracle -c 'sqlplus / as sysdba' << EOF
set linesize 300;
set pagesize 50;
select inst_id,name,dbid,open_mode,log_mode,force_logging,flashback_on from gv\$database;
--
查看
各种数据文件存放路径
select value from v\$parameter where name like '%spfile%' union select name from v\$datafile union select name from v\$controlfile union select member from v\$logfile union select name from v\$tempfile union select name from v\$archived_log union select name from v\$flashback_database_logfile;
EOF
#
修改
IP
#
修改主机名(重新登录才能看到修改结果)
mv /etc/HOSTNAME /etc/HOSTNAME.bak
hostname dg
hostname > /etc/HOSTNAME
sysctl kernel.hostname=dg
#
修改 hosts
文件
#
DG
节点 修改 hosts 文件 及 IP 地址
mv /etc/hosts /etc/hosts.bak
cat > /etc/hosts <<EOF
127.0.0.1 localhost
# Public IP(eth0)
192.168.1.91 rac1
192.168.1.96 dg
EOF
#用户环境变量
echo '
export TMP=/tmp
export TMPDIR=$TMP
export ORACLE_TERM=xterm
export THREADS_FLAG=native
export ORACLE_SID=dg
export ORACLE_UNQNAME=orclbak
export ORACLE_BASE=/u01/app/oracle
export ORACLE_HOME=$ORACLE_BASE/product/11.2.0/db_1
export PATH=/usr/sbin:$PATH:$ORACLE_HOME/bin
export LD_LIBRARY_PATH=$ORACLE_HOME/lib:/lib:/usr/lib
export CLASSPATH=$ORACLE_HOME/JRE:$ORACLE_HOME/jlib:$ORACLE_HOME/rdbms/jlib:$ORACLE_HOME/network/jlib
export LANG=zh_CN.UTF-8
export NLS_DATE_FORMAT="yyyy-mm-dd HH24:MI:SS"
export NLS_LANG="SIMPLIFIED CHINESE_CHINA.AL32UTF8"
alias rsqlplus="rlwrap sqlplus / as sysdba"
alias rrman="rlwrap rman target /"
' > /home/oracle/.bash_profile
#
配置 静态监听
cat > /u01/app/oracle/product/11.2.0/db_1/network/admin/listener.ora<< EOF
SID_LIST_LISTENER= (SID_LIST= (SID_DESC=
(GLOBAL_DBNAME=
orclbak
)
(ORACLE_HOME=/u01/app/oracle/product/11.2.0/db_1)
(SID_NAME=
dg
)))
LISTENER= (DESCRIPTION= (ADDRESS= (PROTOCOL=TCP) (HOST=dg) (PORT=1521))))
EOF
# 启动 监听
su - oracle -c '
lsnrctl start'
# | stop | reload | status'
#
配置 网络服务名文件(
主库 和
备库 都要配,如果不想改 HOSTS 可以将 HOST 设置为对应的 IP 地址)
cat > /u01/app/oracle/product/11.2.0/db_1/network/admin/tnsnames.ora
<< EOF
primary=
(DESCRIPTION=
(ADDRESS=
(PROTOCOL=TCP) (HOST=
rac1
)
(PORT=1521)
)
(CONNECT_DATA= (SERVER=DEDICATED)
(SERVICE_NAME=orcl)
)
)
standby=
(DESCRIPTION=
(ADDRESS= (PROTOCOL=TCP) (HOST=dg) (PORT=1521))
(CONNECT_DATA= (SERVER=DEDICATED)
(SERVICE_NAME=orclbak)
)
)
EOF
# 测试 网络服务名
su - oracle -c
'
tnsping
standby
&&
tnsping primary
'
#
清空 ORACLE 软件的配置文件
rm -rf /u01/app/oracle/product/11.2.0/db_1/dbs/*
rm -rf /u01/app/oracle/product/11.2.0/db_1/dbs/*
#
创建 密码文件(密码必须和主库相同,有说 11G 以后密码文件不能手动创建,要从主库复制,暂未遇见)
su - oracle -c 'orapwd file=/u01/app/oracle/product/11.2.0/db_1/dbs/orapw
dg password=
sys force=y'
#
创建 备库 数据存放文件夹
su - oracle -c 'mkdir -p /u01/app/oracle/oradata/orclbak'
#
创建 备库 spfile (如果只设置db_name,db_unique_name 和 service_names 会跟随 db_name。如果设置了 db_name 又显式设置了 db_unique_name,那么 service_names 会跟随 db_unique_name,DG 要求主库与备库的 db_unique_name 必须不同)
cat
> /u01/app/oracle/product/11.2.0/db_1/dbs/initdg.ora <<EOF
*.compatible='11.2.0.4.0'
*.db_name='
orcl'
*.DB_UNIQUE_NAME='
orclbak'
*.remote_login_passwordfile='EXCLUSIVE'
*.cluster_database=false
*.FAL_SERVER='
primary
'
*.standby_file_management='AUTO'
*.log_archive_config='DG_CONFIG=(
orcl,orclbak
)'
*.log_archive_dest_2='SERVICE=
primary LGWR SYNC AFFIRM VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=
orcl'
*.log_file_name_convert=('+DATA/orcl/onlinelog','/u01/app/oracle/oradata/orclbak','+FRA/orcl/onlinelog','/u01/app/oracle/oradata/orclbak')
*.db_file_name_convert=('+DATA/orcl/datafile','/u01/app/oracle/oradata/orclbak'
,'
+DATA/orcl/tempfile
','/u01/app/oracle/oradata/orclbak'
)
EOF
#
修复 备库(去除 RAC 信息,改为单机 ORACLE 软件,仅需要修改一次)
su - oracle -c 'make -f /u01/app/oracle/product/11.2.0/db_1/rdbms/lib/ins_rdbms.mk ops_off && make -f /u01/app/oracle/product/11.2.0/db_1/rdbms/lib/ins_rdbms.mk install'
# 启动 备库至 NOMOUNT 状态
su - oracle -c 'sqlplus / as sysdba' << EOF
startup nomount pfile='/u01/app/oracle/product/11.2.0/db_1/dbs/initdg.ora';
startup nomount pfile='/u01/app/oracle/product/11.2.0/db_1/dbs/initdg.ora';
EOF
# 复制 数据
#这里我们使用 duplicate database 在不停库状态下直接将数据复制到备库中,11g以前的版本在 RMAN 执行复制命令dupilicate时,必须在备库上存在有备份文件,即主库上备份完成后将文件拷到备库相同目录下,
但是在 11G 里一切都变的简单,只需要在复制命令后加上 FROM ACTIVE DATABASE 参数即可。如果你的主备库路径相同,需要在 DUPLICATE 命令后加上 nofilenamecheck 参数,否则会报错。
su - oracle -c 'rlwrap rman target sys/sys@primary1 auxiliary sys/sys@standby' << EOF
duplicate target database for standby from active database;
EOF
# 如果 RMAN 中途失败或异常终止,备库需要 关闭并重新启动 到 nomount 状态,不要在 RMAN 里重启数据库,会连主库也一并重启。
# 检测 状态(红色是关键参数,主库 和 备库 要仔细对照,手动 sqlplus 里刷命令请去掉转义字符 \)
su - oracle -c 'sqlplus / as sysdba' << EOF
set linesize 300;
set pagesize 50;
-- alter system switch logfile;
-- 查询 (节点 数据库名 scn号 保护模式 库角色 强制归档 闪回 打开状态 故障切换状态)
select inst_id,name,dbid,
current_scn,protection_mode,database_role,force_logging,flashback_on,open_mode,switchover_status from gv\$database;
-- 查询 远程归档是否成功
select DESTINATION,
STATUS,
ERROR
from V\$ARCHIVE_DEST where DEST_ID<=2;
-- select process,client_process,sequence#,status from v$managed_standby;
-- 查询 redo log 是否一致 及 是否被应用
select THREAD#,
SEQUENCE#,ARCHIVED,
APPLIED,DELETED,STATUS from v\$archived_log;
-- 查询
各种数据文件存放路径
-- select value from v\$parameter where name like '%spfile%' union select name from v\$datafile union select name from v\$controlfile union select member from v\$logfile union select name from v\$tempfile union select name from v\$archived_log union select name from v\$flashback_database_logfile;
EOF
#这里对 DG 的
switchover_status 状态做一个详细的说明(先将主库转为备库,然后再将备库转为主库。)
#这里由于环境不同,或者 RAC 多节点情况下 可能会存在很多造成 redo log 不一致或其他未知的状态,比如主库的切换状态一直是 session active 或者 备库的切换状态一直是 not allowed,这里不用担心,先将主库转换为备库试试,可能转换完主库,备库的状态就变成可以转换的状态了。这里 session active 其实也是一种故障现象,问题一般是主库的 log 无法写到远程备库或写入很慢,一般是网络不良或 tnsnames 不通,或者 RAC 节点二没有备库地址或无法联通备库,主库的 dest_2 参数错误等等。。。
# 主库:(OPEN_MODE 默认是 READ WRITE 状态,转换后 RAC 节点二自动关闭)
# ① switchover_status 为
TO_STANDBY
就可以直接将 主库 转换为 物理备库 的状态
# alter database commit to switchover to physical standby;
# startup nomount
;
# alter database mount standby database;
# alter database recover managed standby database disconnect from session;
# ② switchover_status 为 SESSIONS ACTIVE 则要先关闭会话然后转换为备库
# alter database commit to switchover to physical standby with session shutdown;
# startup nomount;
# alter database mount standby database;
# alter database recover managed standby database disconnect from session;
#
备库:(OPEN_MODE 默认是
MOUNTED 状态,转换之后必须重启,否则有权限问题)
# ① switchover_status 为 TO_PRIMARY 切换的标记已经被接收到,并且应用了所有数据,可以直接转换
# alter database commit to switchover to primary;
# shutdown immediate;
# startup;
# ②
switchover_status 为 SESSION ACTIVE 则要先关闭会话然后转换为主库
# alter database commit to switchover to primary with session shutdown;
# shutdown immediate;
# startup;
# ③
switchover_status 为 NOT ALLOWED 切换标记还没收到,此时不能
执行转换。
# 主库 其他常见状态:(都需要解决问题后才能切换)
# RESOLVABLE GAP:该状态表明一个或多个备库有重做间隙。这些间隙可以从主库或其他备库中获取缺省redo后自动地修复。
# UNRESOLVABLE GAP:该状态表明一个或多个备库有重做间隙。这些间隙不可以从主库或其他备库中获取缺省redo后自动地修复。
# LOG SWITCH GAP:该状态表明一个或多个备库在最近的一次 log switch 后丢失了 redo。
# FAILED DESTINATION:该状态表明一个或多个备库在错误状态。
# 更改 protection_mode 保护模式(主备切换后,备库自动沿袭主库的保护模式)
# 最大性能 (
默认,无法同步日志时不影响主库)
# ALTER DATABASE SET STANDBY DATABASE TO
MAXIMIZE PERFORMANCE;
#
最大高可用(无法同步日志时自动切换到最大性能,待可同步时再切换到最大保护)
# ALTER DATABASE SET STANDBY DATABASE TO
MAXIMIZE AVAILABILITY;
#
最大保护 (无法同步日志时主库会 shutdown)
# ALTER DATABASE SET STANDBY DATABASE TO
MAXIMIZE PROTECTION;
# DG 的 关闭 和
启动
顺序
# 监听
关主库 再 关备库(开启相反)
# 数据库 关主库 再 关备库(开启相反)
# 备库 启动命令
# alter database mount standby database;
# alter database recover managed standby database using current logfile disconnect from session;
# 以 standby 模式打开(可做查询库,但是主备切换时,备库必须是 MOUNT 状态)
# alter database recover managed standby database cancel;
# alter database open read only;
# alter database recover managed standby database using current logfile disconnect from session;
# 备库 关闭命令
# alter database recover managed standby database cancel;
# shutdown immediate;
# 物理备库 failover(此操作以后,原主库不再属于该 DG 中的一部分,至针对主库失效后操作)
# ALTER DATABASE RECOVER MANAGED STANDBY DATABASE FINISH FORCE;
# ALTER DATABASE COMMIT TO SWITCHOVER TO PRIMARY;
# ALTER DATABASE OPEN;
#至此,本教程暂告一段落 ,祝刷本愉快 ~~