今天给客户演示了虚拟机上的switchover和failover的切换过程。客户关心的重点自然是failover,我们直接关掉虚拟存储的开关来模拟阵列故障。failover步骤如下
1.
select NAME,RESETLOGS_TIME,LOG_MODE,OPEN_MODE,PROTECTION_MODE,REMOTE_ARCHIVE,
DATABASE_ROLE,SWITCHOVER_STATUS,FORCE_LOGGING
from v$database;
2. 停止日志应用
alter database recover managed standby database cancel;
3. 关闭standby日志传输
alter database recover managed standby database finish force;
4. 切换到primary
alter database commit to switchover to primary with session shutdown;
做这一步的时候,若存在gap,则会报ORA-16139 :Switchover: Media recovery required - standby not in limbo 错误。做测试的时候,若先起主库再起备库,且未等待备库相关日志传输完毕,就会出现这个问题。此时需要强制切换
alter database activate physical standby database;
5. 重启数据库到open状态
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
附上单机到单机的linux下dataguard实施过程。
准备环境
PRIMARY: RHEL 4.7 + oracle 10.2.0.4单机+文件系统 主机名:zhbqdb1
STANDBY: RHEL 4.7 + oracle 10.2.0.4单机 + 文件系统 主机名:zhbqdb2
主机上创建一个库名为zhdydb1的数据库,开启归档模式。备机装好数据软件,版本升级到与主机一致
在主机和备机上配好/etc/hosts并创建数据存放路径
# Do not remove thefollowing line, or various programs
#that require network functionality will fail.
127.0.0.1 localhost.localdomain localhost
172.17.42.29 zhbqdb1
172.17.42.30 zhbqdb2
创建存放数据文件和归档的目录
mkdir /u01/flash_recovery_area
mkdir /u01/oradata
chown oracle:oinstall/u01/flash_recovery_area
chown oracle:oinstall/u01/oradata
主机的配置
打开force logging
SQL> alter database force logging;
查看当前数据库是否置于force logging 下:
selectforce_logging from v$database;
创建归档目录
mkdir /u01/flash_recovery_area/ZHDYDB1/arch
mkdir/u01/flash_recovery_area/ZHDYDB2
mkdir/u01/flash_recovery_area/ZHDYDB2/arch
mkdir/u01/flash_recovery_area/ZHDYDB2/archivelog
配置tnsnames
在zhbqdb1上
vi$ORACLE_HOME/network/admin/tnsnames.ora
ZHDYDB1 =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST =zhbqdb1)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = zhdydb1)
)
)
ZHDYDB2 =
(DESCRIPTION =
(ADDRESS_LIST =
(ADDRESS = (PROTOCOL = TCP)(HOST =zhbqdb2)(PORT = 1521))
)
(CONNECT_DATA =
(SERVICE_NAME = zhdydb2)
)
)
添加standby redo log file
这里primary库中有7个重做日志组,对应的,需要创建7+1个standby logfilegroup
ALTER DATABASE ADD STANDBY LOGFILE GROUP 8
('/u01/oradata/ZHDYDB1/onlinelog/sdbylog8a.log', '/u01/flash_recovery_area/ZHDYDB1/onlinelog/sdbylog8a.log') SIZE 100M;
ALTERDATABASE ADD STANDBY LOGFILE GROUP 9
('/u01/oradata/ZHDYDB1/onlinelog/sdbylog9a.log', '/u01/flash_recovery_area/ZHDYDB1/onlinelog/sdbylog9a.log') SIZE 100M;
ALTERDATABASE ADD STANDBY LOGFILE GROUP 10
('/u01/oradata/ZHDYDB1/onlinelog/sdbylog10a.log', '/u01/flash_recovery_area/ZHDYDB1/onlinelog/sdbylog10a.log') SIZE 100M;
ALTERDATABASE ADD STANDBY LOGFILE GROUP 11
('/u01/oradata/ZHDYDB1/onlinelog/sdbylog11a.log', '/u01/flash_recovery_area/ZHDYDB1/onlinelog/sdbylog11a.log') SIZE 100M;
ALTERDATABASE ADD STANDBY LOGFILE GROUP 12
('/u01/oradata/ZHDYDB1/onlinelog/sdbylog12a.log', '/u01/flash_recovery_area/ZHDYDB1/onlinelog/sdbylog12a.log') SIZE 100M;
ALTERDATABASE ADD STANDBY LOGFILE GROUP 13
('/u01/oradata/ZHDYDB1/onlinelog/sdbylog13a.log', '/u01/flash_recovery_area/ZHDYDB1/onlinelog/sdbylog13a.log') SIZE 100M;
ALTERDATABASE ADD STANDBY LOGFILE GROUP 14
('/u01/oradata/ZHDYDB1/onlinelog/sdbylog14a.log', '/u01/flash_recovery_area/ZHDYDB1/onlinelog/sdbylog14a.log') SIZE 100M;
ALTERDATABASE ADD STANDBY LOGFILE GROUP 15
('/u01/oradata/ZHDYDB1/onlinelog/sdbylog15a.log', '/u01/flash_recovery_area/ZHDYDB1/onlinelog/sdbylog15a.log') SIZE 100M;
查看状态
SELECTGROUP#,THREAD#,SEQUENCE#,ARCHIVED,STATUS FROM V$STANDBY_LOG;
columnmember format a50
selectgroup#,member from v$logfile order by group#;
创建密码文件及初始化文件
确定primary和standby中各有一个路径用于rman备份: /bak/dgbak
若primary中不存在密码文件,创建一个
orapwdfile=$ORACLE_HOME/dbs/orapwzhdydb1 password=aaa entries=5
cp$ORACLE_HOME/dbs/orapwzhdydb1 /bak/dgbak
mv/bak/dgbak/orapwzhdydb1 /bak/dgbak/orapwzhdydb2
SQL> create pfile='/bak/dgbak/initzhdydb2.ora' from spfile;
修改初始化参数
alter system setdb_unique_name=zhdydb1 scope=spfile;
alter system setLOG_ARCHIVE_CONFIG='DG_CONFIG=(zhdydb1,zhdydb2)' scope=spfile;
alter system setLOG_ARCHIVE_DEST_1='LOCATION=/u01/flash_recovery_area/ZHDYDB1/archivelog VALID_FOR=(ALL_LOGFILES,ALL_ROLES)DB_UNIQUE_NAME=zhdydb1'
scope=spfile;
alter system setLOG_ARCHIVE_DEST_2='SERVICE=zhdydb2 LGWR SYNC AFFIRM VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE)DB_UNIQUE_NAME=zhdydb2' scope=spfile;
alter system setLOG_ARCHIVE_DEST_STATE_1=ENABLE scope=spfile;
alter system setLOG_ARCHIVE_DEST_STATE_2=ENABLE scope=spfile;
alter system setLOG_ARCHIVE_MAX_PROCESSES=10 scope=spfile;
alter system setlog_archive_format='%t_%s_%r.dbf' scope=spfile;
alter system setSTANDBY_ARCHIVE_DEST='LOCATION=/u01/flash_recovery_area/ZHDYDB1/arch' scope=spfile;
alter system setremote_login_passwordfile='EXCLUSIVE' scope=spfile;
alter system set FAL_SERVER=zhdydb2 scope=spfile;
alter system set FAL_CLIENT=zhdydb1 scope=spfile;
alter system set db_file_name_convert='/u01/oradata/ZHDYDB1/','/u01/oradata/ZHDYDB2/'scope=spfile;
alter system set log_file_name_convert='/u01/flash_recovery_area/ZHDYDB1/','/u01/flash_recovery_area/ZHDYDB2/'scope=spfile;
alter system set STANDBY_FILE_MANAGEMENT=AUTO scope=spfile;
重启到mount 状态后
ALTERDATABASE SET STANDBY DATABASE TO MAXIMIZE AVAILABILITY; --将保护级别升级为最大可用
selectdatabase_role,protection_mode,protection_level,switchover_status fromv$database;
DATABASE_ROLE PROTECTION_MODE PROTECTION_LEVEL SWITCHOVER_STATUS
------------------------------------ -------------------- --------------------
PRIMARY MAXIMUM AVAILABILITY UNPROTECTED TO STANDBY
重启数据库
RMAN备份到/bak/dgbak下并将相关文件传输到standby中
rman target / <<END
crosscheck archivelog all;
run{
backup format '/bak/dgbak/db_%u_%d_%s' database;
}
crosscheck archivelog all;
run{
sql"alter system archive log current";
backupformat '/bak/dgbak/ar_%t_%s_%p' archivelog all;
}
run{
backup as compressed backupset
format='/bak/dgbak/standby.ctl'
tag='standby'
current controlfile for standby reuse;
}
crosscheck archivelog all;
run{
sql"alter system archive log current";
backupformat '/bak/dgbak/ar_%t_%s_%p' archivelog all ;
}
exit
END
-----------------------------------------------------------------------------------------------
cd/bak/dgbak
scp *zhbqdb2:/bak/dgbak
scp$ORACLE_HOME/network/admin/tnsnames.ora zhbqdb2:$ORACLE_HOME/network/admin
备机的配置
创建必要的目录
mkdir /u01/oradata/ZHDYDB2
mkdir /u01/flash_recovery_area/ZHDYDB2
mkdir /u01/oradata/ZHDYDB2/onlinelog
mkdir/u01/flash_recovery_area/ZHDYDB2/onlinelog
mkdir/u01/flash_recovery_area/ZHDYDB2/arch
mkdir/u01/flash_recovery_area/ZHDYDB2/archivelog
mkdir/u01/flash_recovery_area/ZHDYDB1
mkdir/u01/flash_recovery_area/ZHDYDB1/arch
mkdir/u01/flash_recovery_area/ZHDYDB1/archivelog
mkdir -p /opt/app/admin
mkdir -p/opt/app/admin/zhdydb1
cd/opt/app/admin/zhdydb1
mkdir adump bdump cdump dpdump pfile udump
将相关文件移到对应的位置
cd/bak/dgbak/
mv initzhdydb2.ora orapwzhdydb2 $ORACLE_HOME/dbs/
编辑初始化参数
vi$ORACLE_HOME/dbs/initzhdydb2.ora
去掉参数:
*.remote_listener='LISTENERS_ORADB'
*.local_listener='LISTENERS_ORADB'
修改以下参数
*.cluster_database=false
确定此时standby环境变量里的ORACLE_SID为zhdydb2
sqlplus / assysdba
startup nomount
create spfilefrom pfile;
shutdownimmediate
startup nomount
altersystem set LOG_ARCHIVE_CONFIG='DG_CONFIG=(zhdydb1,zhdydb2)' scope=spfile;
altersystem set db_unique_name=zhdydb2 scope=spfile;
altersystem set
LOG_ARCHIVE_DEST_1='LOCATION=/u01/flash_recovery_area/ZHDYDB2/archivelog VALID_FOR=(ALL_LOGFILES,ALL_ROLES)DB_UNIQUE_NAME=zhdydb2'
scope=spfile;
altersystem set
LOG_ARCHIVE_DEST_2='SERVICE=zhdydb1LGWR SYNC AFFIRM VALID_FOR=(ONLINE_LOGFILES,PRIMARY_ROLE) DB_UNIQUE_NAME=zhdydb1'
scope=spfile;
altersystem set
STANDBY_ARCHIVE_DEST='LOCATION=/u01/flash_recovery_area/ZHDYDB2/arch' scope=spfile sid='*';
alter system set db_file_name_convert='/u01/oradata/ZHDYDB2/','/u01/oradata/ZHDYDB1/'scope=spfile;
alter system set log_file_name_convert='/u01/flash_recovery_area/ZHDYDB2/','/u01/flash_recovery_area/ZHDYDB1/'scope=spfile;
altersystem set FAL_SERVER=zhdydb1 scope=spfile;
altersystem set FAL_CLIENT=zhdydb2 scope=spfile;
alter system set STANDBY_FILE_MANAGEMENT=AUTO scope=spfile;
shutdown immediate
克隆数据库
前面已经将zhdydb1中的tnsnames.ora复制到standby中,此时再创建一个到客户端的软连接:
ln -s$ORACLE_HOME/network/admin/tnsnames.ora $MY_CLIENT/network/admin/tnsnames.ora
ls -l$MY_CLIENT/network/admin/
SQL> startup nomount;
rman target sys/aaa@zhdydb1 auxiliary / <<EOF
CONFIGURE CONTROLFILE AUTOBACKUP FORMAT FOR DEVICE TYPE DISK TO'/bak/dgbak/%F';
DUPLICATE TARGET DATABASE FOR STANDBY NOFILENAMECHECK DORECOVER;
EOF
重建standby的redo logfile group
alter database drop standby logfile group 8
/
alter database drop standby logfile group 9
/
alter database drop standby logfile group 10
/
alter database drop standby logfile group 11
/
alter database drop standby logfile group 12
/
alter database drop standby logfile group 13
/
alter database drop standby logfile group 14
/
alter database drop standby logfile group 15
/
ALTER DATABASE ADD STANDBY LOGFILE GROUP 8
('/u01/oradata/ZHDYDB2/onlinelog/sdbylog8a.log', '/u01/flash_recovery_area/ZHDYDB2/onlinelog/sdbylog8a.log') SIZE 100M;
ALTER DATABASE ADD STANDBY LOGFILE GROUP 9
('/u01/oradata/ZHDYDB2/onlinelog/sdbylog9a.log', '/u01/flash_recovery_area/ZHDYDB2/onlinelog/sdbylog9a.log') SIZE 100M;
ALTER DATABASE ADD STANDBY LOGFILE GROUP 10
('/u01/oradata/ZHDYDB2/onlinelog/sdbylog10a.log', '/u01/flash_recovery_area/ZHDYDB2/onlinelog/sdbylog10a.log') SIZE 100M;
ALTER DATABASE ADD STANDBY LOGFILE GROUP 11
('/u01/oradata/ZHDYDB2/onlinelog/sdbylog11a.log', '/u01/flash_recovery_area/ZHDYDB2/onlinelog/sdbylog11a.log') SIZE 100M;
ALTER DATABASE ADD STANDBY LOGFILE GROUP 12
('/u01/oradata/ZHDYDB2/onlinelog/sdbylog12a.log', '/u01/flash_recovery_area/ZHDYDB2/onlinelog/sdbylog12a.log') SIZE 100M;
ALTER DATABASE ADD STANDBY LOGFILE GROUP 13
('/u01/oradata/ZHDYDB2/onlinelog/sdbylog13a.log', '/u01/flash_recovery_area/ZHDYDB2/onlinelog/sdbylog13a.log') SIZE 100M;
ALTER DATABASE ADD STANDBY LOGFILE GROUP 14
('/u01/oradata/ZHDYDB2/onlinelog/sdbylog14a.log', '/u01/flash_recovery_area/ZHDYDB2/onlinelog/sdbylog14a.log') SIZE 100M;
ALTER DATABASE ADD STANDBY LOGFILE GROUP 15
('/u01/oradata/ZHDYDB2/onlinelog/sdbylog15a.log', '/u01/flash_recovery_area/ZHDYDB2/onlinelog/sdbylog15a.log') SIZE 100M;
查看状态
SELECTGROUP#,THREAD#,SEQUENCE#,ARCHIVED,STATUS FROM V$STANDBY_LOG;
columnmember format a50
selectgroup#,member from v$logfile order by group#;
启动standby
添加一个监听,将数据库名zhdydb1和实例名zhdydb2注册到监听中
netca
netmgr
启动监听
重新启动standby数据库
SQL> STARTUP NOMOUNT;
SQL> ALTER DATABASE MOUNT STANDBY DATABASE;
ALTERDATABASE RECOVER MANAGED STANDBY DATABASE [ using current logfile ] DISCONNECT FROMSESSION;
关闭standby
ALTERDATABASE RECOVER MANAGED STANDBY DATABASE CANCEL;
SHUTDOWNIMMEDIATE;
lsnrctl stop
检查dg的同步情况
分别在primary和standby中执行如下sql语句
SELECT THREAD#, MAX(SEQUENCE#) AS"LAST_APPLIED_LOG" FROM V$LOG_HISTORY GROUP BY THREAD#;
查询从Primary接收到的所有归档(Standby 端)
SQL> SELECT REGISTRAR, CREATOR, THREAD#, SEQUENCE#, FIRST_CHANGE#,NEXT_CHANGE# FROM V$ARCHIVED_LOG;
查看alert日志
tail -f$ORACLE_BASE/admin/zhdydb1/bdump/alert_zhdydb1.log
tail -f$ORACLE_BASE/admin/zhdydb1/bdump/alert_zhdydb2.log
GAP处理
1) 查看是否有日志GAP:
SQL> SELECT UNIQUE THREAD#,MAX(SEQUENCE#) OVER(PARTITION BY THREAD#) LAST FROM V$ARCHIVED_LOG;
SQL> SELECTTHREAD#, LOW_SEQUENCE#, HIGH_SEQUENCE# FROM V$ARCHIVE_GAP;
2) 如果有,则拷贝过来
3) 手工的注册这些日志:
SQL> ALTERDATABASE REGISTER LOGFILE '路径';
switchover
主库切成备库:
1. 查询当前的状态:
SQL> selectswitchover_status from v$database;
若状态为sessions active,把连到主库的会话关闭掉。或切换时加上with sessionshutdown子句来断开这些会话
2. 切换到physical standby
SQL> alterdatabase commit to switchover to physical standby with session shutdown;
3. 关闭数据库
SQL> shutdownimmediate
4. 启动数据库
SQL> startupnomount;
SQL> alterdatabase mount standby database;
SQL> alterdatabase recover managed standby database using current logfile disconnect fromsession;
备库切成主库
1. 执行完上面的步骤以后,把原备库切成主库
SQL> alterdatabase commit to switchover to primary;
2. 把数据库启动到open状态
SQL> alterdatabase open;
failover
当primary库遇到故障的时候,此时我们需要做一个failover(故障切换),把备库切到主库顶上应用
步骤如下(在备库中操作):
1. 结束apply进程
SQL> alter database recover managed standby database finish force;
2. 切换成主库
SQL> alter database commit to switchover to primary;
3. 启动到open状态
SQL> alter database open;