cls_oracle_logs.sh指令碼遭遇TNS-12508錯誤淺析

潇湘隐者發表於2024-04-23

cls_oracle_logs.sh指令碼的輸出日誌中有TNS-12508錯誤,具體如下所示

........................................................................
LSNRCTL> Current Listener is gsp
LSNRCTL> Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=gsp)))
TNS-12508: TNS:listener could not resolve the COMMAND given
LSNRCTL> LSNR_TRC_DIR: /opt/oracle19c/product/19.3.0/db_1/network/trace/
........................................................................

除錯跟蹤發現,指令碼在切割監聽日誌時,執行命令set log_status off/set log_status on時報TNS-12508錯誤,部分指令碼如下所示:

# Function used to cut log files.
f_cutlog(){

# Set name of log file.
LOG_FILE=$1
CUT_FILE=${LOG_FILE}.${TODAY}
FILESIZE=`ls -l $LOG_FILE | awk '{print $5}'`

# Cut the log file if it has not been cut today.
if [ -f $CUT_FILE ]; then
echo "Log Already Cut Today: $CUT_FILE"
elif [ ! -f $LOG_FILE ]; then
echo "Log File Does Not Exist: $LOG_FILE"
elif [ $FILESIZE -eq 0 ]; then
echo "Log File Has Zero Size: $LOG_FILE"
else
# Cut file.
echo "Cutting Log File: $LOG_FILE"
$MV $LOG_FILE $CUT_FILE
$TOUCH $LOG_FILE
fi
}

.....................................
# See if the listener is logging.
if [ -z "$LSNRLOG" ]; then
echo "Listener Logging is OFF. Not rotating the listener log."
# See if the listener log exists.
elif [ ! -r "$LSNRLOG" ]; then
echo "Listener Log Does Not Exist: $LSNRLOG"
# See if the listener log has been cut today.
elif [ -f $LSNRLOG.$TODAY ]; then
echo "Listener Log Already Cut Today: $LSNRLOG.$TODAY"
# Cut the listener log if the previous two conditions were not met.
else

# Disable logging.
$LSNRCTL <<EOF
set current_listener $LSNRNAME
set log_status off
EOF

# Cut the listener log file.
f_cutlog $LSNRLOG

# Enable logging.
$LSNRCTL <<EOF
set current_listener $LSNRNAME
set log_status on
EOF

# Delete old listener logs.
f_deletelog $LSNRLOG $NDAYS

fi
...................................

如下測試所示

LSNRCTL> set current_listener  gsp
Current Listener is gsp
LSNRCTL> set log_status off
Connecting to (DESCRIPTION=(ADDRESS=(PROTOCOL=IPC)(KEY=REGISTER_gsp)))
TNS-12508: TNS:listener could not resolve the COMMAND given

出現這個現象,是因為我們在監聽引數檔案listener.ora中設定了引數ADMIN_RESTRICTIONS_<listener_name>

ADMIN_RESTRICTIONS_GSP = ON

ADMIN_RESTRICTIONS_<listener_name>引數是一個重要的安全選項,在listener.ora檔案中設定ADMIN_RESTRICTIONS_<listener_name>為ON時, 此後所有在執行時對監聽器的修改都將會被阻止,所有對監聽器的修改都必須透過手工修改listener.ora檔案才能順利完成。

Setting ADMIN_RESTRICTIONS_<listener_name> = ON disables the "runtime" modification of parameters in the listener.ora file.
In other words, the listener refuses to accept SET commands that alter its parameters and states that it cannot "resolve the COMMAND given."

指令碼cls_oracle_logs.sh中,暫停監聽器寫入日誌,完成監聽日誌的切換後,然後啟用監聽器寫入日誌。但是由於引數ADMIN_RESTRICTIONS_<listener_name>為ON的話 這裡就會出現異常,那麼我們修改指令碼的邏輯,如果發現引數ADMIN_RESTRICTIONS_<listener_name>啟用為ON的情況下,就將監聽日誌的內容複製到另外一個檔案, 然後將當前的監聽日誌清空,具體程式碼如下所示:

# Function used to cut log files.
f_cutlog(){

# Set name of log file.
LOG_FILE=$1
PAR_ADMIN_RESTRICTIONS=$2
CUT_FILE=${LOG_FILE}.${TODAY}
FILESIZE=`ls -l $LOG_FILE | awk '{print $5}'`

# Cut the log file if it has not been cut today.
if [ -f $CUT_FILE ]; then
echo "Log Already Cut Today: $CUT_FILE"
elif [ ! -f $LOG_FILE ]; then
echo "Log File Does Not Exist: $LOG_FILE"
elif [ $FILESIZE -eq 0 ]; then
echo "Log File Has Zero Size: $LOG_FILE"
else
# Cut file.
if [ [$PAR_ADMIN_RESTRICTIONS == 'ON' ]] || [[ $PAR_ADMIN_RESTRICTIONS == 'on' ]];then
# Cut file.
echo "Cutting Log File: $LOG_FILE"
cat $LOG_FILE > $CUT_FILE
cat /dev/null > $LOG_FILE
else
echo "Cutting Log File: $LOG_FILE"
$MV $LOG_FILE $CUT_FILE
$TOUCH $LOG_FILE
fi
fi
}


......................................................
# See if the listener is logging.
if [ -z "$LSNRLOG" ]; then
echo "Listener Logging is OFF. Not rotating the listener log."
# See if the listener log exists.
elif [ ! -r "$LSNRLOG" ]; then
echo "Listener Log Does Not Exist: $LSNRLOG"
# See if the listener log has been cut today.
elif [ -f $LSNRLOG.$TODAY ]; then
echo "Listener Log Already Cut Today: $LSNRLOG.$TODAY"
# Cut the listener log if the previous two conditions were not met.
else
# 加上head -1 主要是防止出現兩個名字很接近的監聽,例如下面配置,就會得到兩個值
# ADMIN_RESTRICTIONS_gspprod = ON
# ADMIN_RESTRICTIONS_gspprodro = ON
LSN_ADMIN_RESTRICTIONS=`cat $LSNPARAM | grep -i "ADMIN_RESTRICTIONS_$LSNRNAME" | awk '{print $3}' |head -1`

if [[ $LSN_ADMIN_RESTRICTIONS == "ON" ]] || [[ $LSN_ADMIN_RESTRICTIONS == "on" ]];then
f_cutlog $LSNRLOG $LSN_ADMIN_RESTRICTIONS
else
# Disable logging.
$LSNRCTL <<EOF
set current_listener $LSNRNAME
set log_status off
EOF

# Cut the listener log file.
f_cutlog $LSNRLOG $LSN_ADMIN_RESTRICTIONS

# Enable logging.
$LSNRCTL <<EOF
set current_listener $LSNRNAME
set log_status on
EOF

fi

# Delete old listener logs.
f_deletelog $LSNRLOG $NDAYS

fi
......................................................

相關文章