###################################
DG
###################################
# 这里经测试可以一次性 刷完脚本,但是不建议,操作 生产库 的话有一定
危险性
,建议充分理解后分段刷
# 情况一:RAC + DUPLICATE + 单节点 DG(复杂,需要转换路径)
#
主节点RAC 主库配置
#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
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}"'
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'tnspingstandby&&tnsping primary'
# 查看 CRS 资源和 数据库 状态
# su -grid-c "crs_stat -t"
# su - grid -c "srvctl status database -d
orcl"
su -grid-c "srvctl stop database -dorcl"
#
更改主库 配置
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;
-- 修改归档日志及闪回区存放路径(db_recovery_file_dest 与 log_archive_dest 冲突,官方已弃用后者)
-- 官方建议将归档日志写到本地磁盘,如果共享磁盘够大的话尽量放到 ASM 里(设置 size 大小后开启)
-- 如果不启用闪回日志,当出现故障转移时,你需要重建一个新的备库。(强烈建议开启闪回)
show parameter db_recovery;
--
alter system set db_recovery_file_dest_size=2Gsid='*';
--
alter system set db_recovery_file_dest='
+FRA
' sid='*';
--alter database flashback on;
-- 切换联机日志文件
alter system switch logfile;
-- 强制归档当前重做日志
--alter system archive log current;
select * from v\$log;
-- ORACLE 要求 standby redo 要比 primary online redo 日志组多一个,每个 RAC 节点是一个 thread
alter database add
standbylogfile thread
1group
11size 50M,group
12size 50M,group
13size 50M;
alter database add
standbylogfile thread
2group
14size 50M,group
15size 50M,group
16size 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 setlog_archive_dest_2='SERVICE=
standbyLGWR SYNC AFFIRM VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=
orclbak' sid='*';
-- alter system setlog_file_name_convert=('/u01/app/oracle/oradata/orclbak','+DATA/orcl/onlinelog','/u01/app/oracle/oradata/orclbak','+FRA/orcl/onlinelog')sid='*';
-- alter system setdb_file_name_convert=('/u01/app/oracle/oradata/orclbak','+DATA/orcl/datafile','+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\$datafileunionselect name from v\$controlfileunionselect 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
hostnamedg
hostname > /etc/HOSTNAME
sysctl kernel.hostname=dg
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 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'
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
'
su - oracle -c 'orapwd file=/u01/app/oracle/product/11.2.0/db_1/dbs/orapw
dgpassword=
sysforce=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=
primaryLGWR SYNC AFFIRM VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=
orcl'
*.log_file_name_convert=('+DATA/orcl/onlinelog','+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
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 rmantargetsys/sys@primary1auxiliarysys/sys@standby' << EOF
duplicate target database for standby from active database;
EOF
#检测状态(红色是关键参数,主库和备库要仔细对照,手动 sqlplus 里刷命令请去掉转义字符\)
su - oracle -c 'sqlplus / as sysdba' << EOF
set linesize 300;
set pagesize 50;
--altersystemswitchlogfile;
select inst_id,current_scn,protection_mode,database_role,flashback_on,open_mode,switchover_statusfrom 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\$datafileunionselect name from v\$controlfileunionselect 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 参数错误等等。。。
# ① 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切换标记还没收到,此时不能
执行转换。
# 主库 其他常见状态:(都需要解决问题后才能切换)
# LOG SWITCH GAP:该状态表明一个或多个备库在最近的一次 log switch 后丢失了 redo。
# 更改 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;
# 监听
关主库 再 关备库(开启相反)
# 数据库 关主库 再 关备库(开启相反)
# 备库 启动命令
# 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 中的一部分,至针对主库失效后操作)
# ALTERDATABASERECOVERMANAGEDSTANDBYDATABASEFINISHFORCE;
# ALTERDATABASECOMMITTOSWITCHOVERTOPRIMARY;
# ALTERDATABASEOPEN;
#至此,本教程暂告一段落,祝刷本愉快 ~~