oracle rac fail,Oracle RAC service Fail Back 问题解析

01fac6460a22031b8af8da5848698a70.png

对于Oracle RAC中的service的fail over 存在这样的疑问,例如 存在一个service 有一个preferred 的instance 和一个available 的instance,当preferred instance失败时service failover到available instance上,当这个preferred instance的实例恢复时该RAC SERVICE是否会fail back 回到preferred instance ,还是原地不动?

对于这个问题 官方文档有明确的说明:

When a service moves to an available instance, Oracle Database does not move the service back to the preferred instance when the preferred instance restarts because:

The service is running on the desired number of instances.

Maintaining the service on the current instance provides a higher level of service availability.

Not moving the service back to the initial preferred instance prevents a second outage.

You can, however, easily automate fail back to the preferred instance by using FAN callouts.

即oracle认为 当这种场景时不应当立刻做fail back 否则可能造成再次outage ,同时目前的情况也基本符合当初用户对该服务定义的需求。

对于有用户确实需要自动fail back回去的可以参考Ilmar Kerm DB blog 《Scipt to automatically move RAC 11gR2 services back to preferred instances》中的脚本:

#!/bin/bash

#

# GI callout script to catch INSTANCE up event from clusterware and relocate services to preferred instance

# Copy or symlink this script to $GRID_HOME/racg/usrco

# Tested on Oracle Linux 5.8 with 11.2.0.3 Oracle Grid Infrastructure and 11.2.0.2 & 11.2.0.3 Oracle Database Enterprise Edition

# 2012 Ilmar Kerm ilmar.kerm@gmail.com

#

LOGFILE=/u02/app/oracle/grid_callout/log.txt

SCRIPTDIR=`dirname $0`

# Determine grid home

if [[ "${SCRIPTDIR:(-11)}" == "/racg/usrco" ]]; then

CRS_HOME=""${SCRIPTDIR:0:$(( ${#SCRIPTDIR} - 11 ))}""

export CRS_HOME

fi

# Only execute script for INSTANCE events

if [ "$1" != "INSTANCE" ]; then

exit 0

fi

STATUS=""

DATABASE=""

INSTANCE=""

# Parse input arguments

args=("$@")

for arg in ${args[@]}; do

if [[ "$arg" == *=* ]]; then

KEY=${arg%=*}

VALUE=${arg#*=}

case "$KEY" in

status)

STATUS="$VALUE"

;;

database)

DATABASE="$VALUE"

;;

instance)

INSTANCE="$VALUE"

;;

esac

fi

done

# If database, status and instance values are not set, then exit

# status must be up

if [[ -z "$DATABASE" || -z "$INSTANCE" || "$STATUS" != "up" ]]; then

exit 0

fi

echo "`date`" >> "$LOGFILE"

echo "[$DATABASE][`hostname`] Instance $INSTANCE up" >> "$LOGFILE"

#

# Read database software home directory from clusterware

#

DBCONFIG=`$CRS_HOME/bin/crsctl status res ora.$DATABASE.db -f | grep "ORACLE_HOME="`

if [ -z "$DBCONFIG" ]; then

exit 0

fi

declare -r "$DBCONFIG"

echo "ORACLE_HOME=$ORACLE_HOME" >> "$LOGFILE"

# Array function

in_array() {

local hay needle=$1

shift

for hay; do

[[ $hay == $needle ]] && return 0

done

return 1

}

#

# Read information about services

#

for service in `$CRS_HOME/bin/crsctl status res | grep -E "ora\.$DATABASE\.(.+)\.svc" | sed -rne "s/NAME=ora\.$DATABASE\.(.+)\.svc//gip"`; do

SERVICECONFIG=`$ORACLE_HOME/bin/srvctl config service -d $DATABASE -s $service`

echo "Service $service" >> "$LOGFILE"

if [[ `echo "$SERVICECONFIG" | grep "Service is enabled" | wc -l` -eq 1 ]]; then

echo " enabled" >> "$LOGFILE"

PREFERRED=( `echo "$SERVICECONFIG" | grep "Preferred instances:" | sed -rne "s/.*\: ([a-zA-Z0-9]+)//p" | tr "," "\n"` )

#

# Check if current instance is preferred for this service

#

if in_array "$INSTANCE" "${PREFERRED[@]}" ; then

echo " preferred" >> "$LOGFILE"

#

# Check if service is already running on current instance

#

SRVSTATUS=`$ORACLE_HOME/bin/srvctl status service -d $DATABASE -s $service`

if [[ "$SRVSTATUS" == *"is not running"* ]]; then

#

# if service is not running, then start it

#

echo " service stopped, starting" >> "$LOGFILE"

$ORACLE_HOME/bin/srvctl start service -d "$DATABASE" -s "$service" >> "$LOGFILE"

else

#

# Service is running, but is it running on preferred instance?

#

RUNNING=( `echo "$SRVSTATUS" | sed -rne "s/.* ([a-zA-Z0-9]+)//p" | tr "," "\n"` )

echo "${RUNNING[@]} = ${PREFERRED[@]}"

if ! in_array "$INSTANCE" "${RUNNING[@]}" ; then

echo " not running on preferred $INSTANCE" >> "$LOGFILE"

#

# Find the first non-preferred running instance

#

CURRENT=""

for inst in "${RUNNING[@]}"; do

if ! in_array "$inst" "${PREFERRED[@]}" ; then

CURRENT="$inst"

break

fi

done

#

# Relocate

#

if [[ -n "$CURRENT" ]]; then

echo " relocate $CURRENT -> $INSTANCE" >> "$LOGFILE"

$ORACLE_HOME/bin/srvctl relocate service -d "$DATABASE" -s "$service" -i "$CURRENT" -t "$INSTANCE" >> "$LOGFILE"

fi

else

#

# Service is already running on preferred instance, no need to do anything

#

echo " running on preferred $INSTANCE" >> "$LOGFILE"

fi

fi

fi

fi

done

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值