| From: | Steve Adams |
| Date: | 08-Nov-2001 07:56 |
| Subject: | cumulative logons |
|
|
Yes, this is definitely a concern. In fact, it is one of the "Seven Deadly Sins" that I'm expecting to talk about in my OpenWorld presentation next month. If the other performance problems that you mentioned happen to be library cache latch contention, file open waits, or unduly high CPU usage, then it could be that they will disappear if you solve this problem first. I've seen systems that continually disconnect and then reconnect run 2 to 3 times faster just by fixing this one issue. Of course, the best solution is to avoid using shell scripts in production applications entirely. It's not that they cannot be used well; it's just that they seldom are. Developers are much less prone to make performance mistakes like this when working in C or Perl. However, if you're committed to keeping your shell scripts, a simple approach that allows them to remain virtually unchanged is to define a shell function called sqlplus which will be invoked in preference to the executable in $ORACLE_HOME/bin. That function can use a named pipe to direct its input into a persistent SQL*Plus session, and use spool files to get the output. Here is some code that does most of the job. I've left out much of the error checking and some of the details to make the code easier to read.
sqlplus ()
{
export SQLPLUS_PID # sqlplus process id
typeset lstfile=$TMP/$$.lst # file for lst output
typeset script # script file
typeset userpass=$1 # username/password
shift
# setup SQL*Plus session if necessary
#
[[ -n $SQLPLUS_PID ]] &&
kill -0 $SQLPLUS_PID 2>/dev/null ||
{
# create an SQL*Plus process, to read from a named pipe
# (nolog option is used, so connection failures do not get stuck)
#
[[ -p $TMP/sqlplus.in ]] || mknod $TMP/sqlplus.in p
$ORACLE_HOME/bin/sqlplus -s /nolog < $TMP/sqlplus.in > $TMP/sqlplus.out &
SQLPLUS_PID=$!
# direct file descriptor 3 to the SQL*Plus input
#
exec 3> $TMP/sqlplus.in
# wait for connection to complete
#
echo "connect $userpass" >&3
echo "host touch $TMP/done" >&3
waiter -t10 $SQLPLUS_PID &&
(( $(grep -c '^\(ERROR: \)*ORA-' $TMP/sqlplus.out) == 0 )) ||
{
exec 3> /dev/null
kill $SQLPLUS_PID 2>/dev/null
$PAGER $TMP/sqlplus.out
return 1
}
}
# SQL script may be on command line or standard input
#
(($#)) ||
{
cat > $TMP/$$.sql
set -- $TMP/$$.sql
}
script=${1#@}
shift
# run the script, and wait for completion
#
{
echo "spool $lstfile"
echo "@$script $*"
echo "spool off"
echo "host touch $TMP/done"
} >&3
waiter $SQLPLUS_PID ||
{
exec 3> /dev/null
kill $SQLPLUS_PID 2>/dev/null
$PAGER $lstfile
return 1
}
# return output
#
$PAGER $lstfile
egrep -q "^ORA-00028|^ORA-01012|^ORA-12571|^ORA-03114" $lstfile &&
{
exec 3> /dev/null
kill $SQLPLUS_PID 2>/dev/null
return 1
}
grep -q "^ORA-" $lstfile && return 1 || return 0
}
waiter ()
{
typeset timeout # timeout in seconds
typeset pid # process id being waited for
while getopts :t: option "$@"
do
case $option in
t) timeout="$OPTARG" ;;
esac
done
shift $((OPTIND - 1))
pid=$1
typeset -i ticks=0
until [[ -r $TMP/done ]]
do
# check if process has died
# (after 10 seconds, and every 60 seconds)
#
(( (ticks += 1) % 60 == 10)) &&
[[ $(ps -fp $pid) = *defunct* ]] &&
return 1
# check for timeout
#
[[ -n $timeout ]] && (( ticks > timeout )) && return 1
# sleep for 1 second
#
sleep 1
done
'rm' -f $TMP/done
return 0
}
|
![]() |
Does constant login and logout cause any major performance issues? We are observing that some of our home grown application programs use shell scripts to upload data and they constantly keep connecting to the database, which is keeping the cumulative logons statistic increasing, somewhere around 120 per minute. There are other performance issues which are trying to resolve. In the midst we noticed this. Do we need to be concerned about the same?
|