private lab. このページをアンテナに追加 RSSフィード

2006-04-10 今日は日記を書くのが遅くなった・・・。

Oracle XEをFedoraCore5(FC5)にインストールする。

はじめに。Oracle XEとは?

Oracle XEは、Oracleの戦略的リリースだと私は考えています。

Oracle XEは、評価・開発目的だけなく、商用利用も可能な無料のOracle 10gのサブセットです。いくつかの制限はあるものの、MySQLPostgreSQLを想定するような開発案件については、Oracle XEの採用を考慮することが可能です。

Oracle XEを採用することで、将来のスケールアップやスケールアウトに対応できますし、何よりも使い慣れたOracle環境を使うことができるメリットが大きいです。

アプリケーション開発において、DBとの接続部分をプラッガブルにするということがよく行われます。たとえば廉価版にはMySQLを使い、高い拡張性を求められた場合にはOracleを使うという具合です。

このような構成を行うときには、DBについて良く理解している人の意見を尊重することが重要です。DB製品はそれぞれの長所を出し、より高速で高機能なクエリを実現するために、各DBには独自のSQL拡張があります。この拡張を使わないようにするとパフォーマンスや生産性が下がります。DBをプラッガブルにする際に陥りがちなのは、最大公約数的なSQL文だけを使うようになってしまい、DBの長所を十分に生かしきることができなくなるという問題です。ところが各DBの長所を十分に生かそうとなると、対応するDBの数だけアダプタの実装を増やさなければいけなくなってしまいます。これは生産性の低下をまねいてしまいます。

Oracle XEは、このような問題に対する救世主です。Oracle XEは無料ですから、廉価版の製品を作る際にはOracle XEを採用すればよいのです。そして、必要に応じてStandardからEnterpriseまでに対応させてあげることができます。プログラムコードは〜Enterprise Editionに特有の拡張を使うことを除けば〜全て共有できます。これはアプリケーション開発者にとっての福音ではないでしょうか。

FC5へのOracle XEのインストール

そんなOracle XEをFC5にインストールして使うことができます。インストールも非常に簡単ですので、今までOracleを使ったことのない方もこれを機会に挑戦してみてはいかがでしょうか。

/etc/init.d/oracle-xeスクリプトに対する不満とプライベートパッチ

/etc/init.d/oracle-xeスクリプトは、デフォルトのままだと微妙に不便です。chkconfigで/etc/rc?.dからエントリを消去するのではなく、oracle-xe enable|disableというコマンドで、自動起動の設定ができるのは良いのですが、enable(すなわち自動起動がONになっている状態)のときでないと手動起動もできないという問題があります。

開発機でOracleを使う場合、システムの起動時のOracle自動起動は必要ではないと思います。実際にアプリケーションをテストする瞬間まで、Oracleインスタンスは起動してくれなくて良いというのがほとんどの場合でしょう。そのようなケースを考えると、自動起動をoffにしながら手動起動ができないデフォルトの/etc/init.d/oracle-xeスクリプトはあまりにも不便なのです。*2

作成した起動スクリプトの仕様は以下の通りです。

  • enable/disableの設定に関係なく、stopが期待通りに動作します。
  • enable/disableの設定に関係なく、restartが期待通りに動作します。
  • enable/disableの設定に関係なく、/etc/init.d/oracle-xe force-restartと入力することで手動起動ができます。

このプライベートパッチを使うと、以下のような運用ができます。

  • oracle-xe自体の自動起動はoffにしておきます。これは/etc/init.d/oracle-xe disableとすることで指定できます。
  • oracleを手動起動するときには、/etc/init.d/oracle-xe force-startを実行します。
  • oracle再起動には、/etc/init.d/oracle-xe restartを実行します。
  • oracleの停止には、/etc/init.d/oracle-xe stopを実行します。

以下に、プライベートパッチをあてた/etc/init.d/oracle-xeスクリプトを掲載します。

#!/bin/bash 
#
#
# chkconfig: 2345 80 05
# description: This is a program that is responsible for taking care of
# configuring the Oracle Database 10g Express Edition and its associated 
# services. 
#
# processname: oracle-xe 
# Red Hat or SuSE config: /etc/sysconfig/oracle-xe
# Debian or Ubuntu config: /etc/default/oracle-xe
#
# change log:
#	svaggu 09/28/05 -  Creation
#	svaggu 11/08/05 -  Source function Library change for SuSE
#	svaggu 11/09/05 -  Password validation is added
#	jlbec  11/22/05 -  Debianization
#	svaggu 12/02/05 -  Errors messages are updated
#	svaggu 12/14/05 -  Anonymous is removed from password message prompt and
#			   changing the password for anonymous user logic is also
#			   removed			    
#	svaggu 12/12/05 -  Password validation is modified
#

# Source fuction library
if [ -f /lib/lsb/init-functions ]
then
	. /lib/lsb/init-functions
elif [ -f /etc/init.d/functions ]
then
	. /etc/init.d/functions
fi

# Set path if path not set (if called from /etc/rc)
case $PATH in
    "") PATH=/bin:/usr/bin:/sbin:/etc
        export PATH ;;
esac

# Save LD_LIBRARY_PATH
SAVE_LLP=$LD_LIBRARY_PATH

RETVAL=0
ORACLE_HOME=/usr/lib/oracle/xe/app/oracle/product/10.2.0/server
ORACLE_OWNER=oracle
ORACLE_SID=XE
LSNR=$ORACLE_HOME/bin/lsnrctl
SQLPLUS=$ORACLE_HOME/bin/sqlplus
SU=/bin/su
export ORACLE_HOME
export ORACLE_SID
export PATH=$ORACLE_HOME/bin:$PATH
LOG="$ORACLE_HOME_LISTNER/listener.log"

export LC_ALL=C

if [ $(id -u) != "0" ]
then
    echo "You must be root to run the configure script.  Login as root and then run the 
configure script."
    exit 1
fi

CONFIG_NAME=oracle-xe
CONFIGURATION="/etc/sysconfig/$CONFIG_NAME"
if [ -f /etc/redhat-release ]
then
    . /etc/init.d/functions

    init_status()
    {
	return 0
    }
    exit_status()
    {
	exit $?
    }
    success_status()
    {
	success
	echo
    }
    failure_status()
    {
	failure $?
	echo
    }

elif [ -f /etc/SuSE-release ]
then
    . /etc/rc.status

    init_status()
    {
	rc_reset
    }
    success_status()
    {
	echo "OK"
	return 0
    }
    failure_status()
    {
	echo "Failed"
	return 1
    }
    exit_status()
    {
	exit $?
    }

else
    if [ -d /etc/default ]
    then
        CONFIGURATION="/etc/default/$CONFIG_NAME"
    fi

    init_status()
    {
        return 0
    }

    success_status()
    {
        echo "OK"
        return 0
    }

    failure_status()
    {
        echo "Failed"
        return 0
    }

    exit_status()
    {
        exit $?
    }
fi

# Source configuration

[ -f "$CONFIGURATION" ] && . "$CONFIGURATION"

init_status

#
# if_fail()
#
# Evaluates return codes.  If 0, prints "OK", if 1, prints "Failed"
# and exits.  If 2, status is "already done" and nothing is printed.
# The rest of the functions in here all honor this convention.
#
if_fail()
{
    RC="$1"
    REASON="$2"
    if [ "$RC" = "0" ]
    then
        return
    elif [ "$RC" = "2" ]
    then
        return
    fi
    failure_status "${REASON}"
    exit 1
}


#
# write_sysconfig()
#
# Writes the system configuration
#
write_sysconfig()
{
	cat >"$CONFIGURATION" <<EOF

#This is a configuration file for automatic starting of the Oracle #Database and listener at system startup.It is generated By running #'/etc/init.d/oracle-xe configure'.Please use that method to modify this #file # ORACLE_DBENABLED:'true' means to load the Database at system boot. ORACLE_DBENABLED=${ORACLE_DBENABLED:-false} # LISTENER_PORT: Database listener LISTENER_PORT=${LISTENER_PORT} # HTTP_PORT : HTTP port for Oracle Application Express HTTP_PORT=${HTTP_PORT} # Configuration : Check whether configure has been done or not CONFIGURE_RUN=${CONFIGURE_RUN} EOF if [ $? != 0 ] then return 1 fi return 0 } # configure_perform() # # Instantantiate listener.ora,tnsnames.ora,and create the database, # sets the password,start the listener,and adds database to inittab # if necessary configure_perform() { sed -i "s/%hostname%/`hostname`/g" $ORACLE_HOME/network/admin/listener.ora sed -i "s/%port%/$LISTENER_PORT/g" $ORACLE_HOME/network/admin/listener.ora /bin/chown oracle:dba $ORACLE_HOME/network/admin/listener.ora sed -i "s/%hostname%/`hostname`/g" $ORACLE_HOME/network/admin/tnsnames.ora sed -i "s/%port%/$LISTENER_PORT/g" $ORACLE_HOME/network/admin/tnsnames.ora /bin/chown oracle:dba $ORACLE_HOME/network/admin/tnsnames.ora sed -i "s/%httpport%/$HTTP_PORT/g" $ORACLE_HOME/config/scripts/postDBCreation.sql /bin/chown oracle:dba $ORACLE_HOME/config/scripts/postDBCreation.sql if test $LISTENER_PORT -ne 1521 then if [ -f /tmp/local_listener ] then cat >/tmp/local_listener$$ <<EOF

########################################### # Registration of instance with listsner ########################################### local_listener="(ADDRESS = (PROTOCOL=TCP) (HOST=%hostname%) (PORT=%port%))" EOF /bin/chmod 664 /tmp/local_listener$$ cat /tmp/local_listener$$ >> $ORACLE_HOME/config/scripts/init.ora else cat >/tmp/local_listener <<EOF

########################################### # Registration of instance with listsner ########################################### local_listener="(ADDRESS = (PROTOCOL=TCP) (HOST=%hostname%) (PORT=%port%))" EOF /bin/chmod 664 /tmp/local_listener cat /tmp/local_listener >> $ORACLE_HOME/config/scripts/init.ora fi if test -f /tmp/local_listener then rm -fr /tmp/local_listener elif test -f /tmp/local_listener$$ then rm -fr /tmp/local_listener$$ fi sed -i "s/%port%/$LISTENER_PORT/g" $ORACLE_HOME/config/scripts/init.ora sed -i "s/%hostname%/`hostname`/g" $ORACLE_HOME/config/scripts/init.ora /bin/chown oracle:dba $ORACLE_HOME/config/scripts/init.ora fi sed -i "s/%httpport%/$HTTP_PORT/g" $ORACLE_HOME/config/scripts/DatabaseHomePage.sh /bin/chown oracle:dba $ORACLE_HOME/config/scripts/DatabaseHomePage.sh sed -i "s/%httpport%/$HTTP_PORT/g" $ORACLE_HOME/config/scripts/readonlinehelp.sh /bin/chown oracle:dba $ORACLE_HOME/config/scripts/readonlinehelp.sh homedir=`echo $HOME` if [ "$homedir" = "/root" ] then homedir=`sh -c "echo ~$USER"` fi if [ -f $homedir/.gnome-desktop/oraclexe-gettingstarteddesktop.desktop ] then /bin/chown oracle:dba $homedir/.gnome-desktop/oraclexe-gettingstarteddesktop.desktop /bin/chmod 664 $homedir/.gnome-desktop/oraclexe-gettingstarteddesktop.desktop fi if [ -f $homedir/Desktop/oraclexe-gettingstarteddesktop.desktop ] then /bin/chown oracle:dba $homedir/Desktop/oraclexe-gettingstarteddesktop.desktop /bin/chmod 664 $homedir/Desktop/oraclexe-gettingstarteddesktop.desktop fi if [ -f $ORACLE_HOME/bin/tnslsnr ] then echo -n "Starting Oracle Net Listener..." $SU -s /bin/bash $ORACLE_OWNER -c "$LSNR start" > /dev/null 2>&1 echo "Done" fi echo -n "Configuring Database..." $SU -s /bin/bash $ORACLE_OWNER -c "$ORACLE_HOME/config/scripts/XE.sh" > /dev/null 2>&1 err=`grep "ORA-44410" $ORACLE_HOME/config/log/*.log` if test "$err" != "" then echo "Database Configuration failed. Look into $ORACLE_HOME/config/log for details" exit 1 fi echo alter user sys identified by \"$ORACLE_PASSWORD\"\; | $SU -s /bin/bash $ORACLE_OWNER -c "$SQLPLUS -s / as sysdba" > /dev/null 2>&1 echo alter user system identified by \"$ORACLE_PASSWORD\"\; | $SU -s /bin/bash $ORACLE_OWNER -c "$SQLPLUS -s / as sysdba" > /dev/null 2>&1 echo "Done" /bin/chmod -R 640 /usr/lib/oracle/xe/oradata/XE /bin/chmod 750 /usr/lib/oracle/xe/oradata/XE rm -fr $ORACLE_HOME/config/seeddb if [ -f /etc/oratab ] then echo "XE:$ORACLE_HOME:N" >> /etc/oratab else echo "XE:$ORACLE_HOME:N" >> /etc/oratab /bin/chown oracle:dba /etc/oratab /bin/chmod 644 /etc/oratab fi echo -n "Starting Oracle Database 10g Express Edition Instance..." pmon=`ps -ef | egrep pmon_$ORACLE_SID'\>' | grep -v grep` if [ "$pmon" = "" ]; then $SU -s /bin/bash $ORACLE_OWNER -c "$SQLPLUS -s /nolog @$ORACLE_HOME/config/scripts/startdb.sql" > /dev/null 2>&1 fi echo "Done" echo "Installation Completed Successfully." return 0 } # #configure_ask() # # Ask configuration questions,setting the variables. # configure_ask() { cat <<EOF

Oracle Database 10g Express Edition Configuration ------------------------------------------------- This will configure on-boot properties of Oracle Database 10g Express Edition. The following questions will determine whether the database should be starting upon system boot, the ports it will use, and the passwords that will be used for database accounts. Press <Enter> to accept the defaults. Ctrl-C will abort. EOF #get the http port value while : do while [ 1 ] do echo -n Specify the HTTP port that will be used for Oracle Application Express [8080]: read LINE if [ -z $LINE ] then LINE=8080 fi port=`netstat -n --tcp --listen | grep :$LINE | awk '{print $4}' | cut -d':' -f2` if [ "$port" = "$LINE" ] then echo Port $port appears to be in use by another application.\ Please specify a different port. else break; fi done case "$LINE" in "") break ;; *[^0-9]*) echo "Invalid http port: $LINE" ;; *) HTTP_PORT=$LINE break ;; esac done #get the listener port value while : do echo while [ 1 ] do echo -n Specify a port that will be used for the database listener [1521]: read LINE if [ -z $LINE ] then LINE=1521 fi echo port=`netstat -n --tcp --listen | grep :$LINE | awk '{print $4}' | cut -d':' -f2` if [ "$port" = "$LINE" ] then echo Port $port appears to be in use by another application.\ Please specify a different port. else break; fi done case "$LINE" in "") break ;; *[^0-9]*) echo "Invalid port: $LINE" >&2 ;; *) if [ "$HTTP_PORT" != "$LINE" ] then LISTENER_PORT=$LINE break else echo Database listener cannot be configured on the same port as Oracle Application Express. fi ;; esac done #get the database password while : do echo -n "Specify a password to be used for database accounts. Note that the same password will be used for SYS and SYSTEM. Oracle recommends the use of different passwords for each database account. This can be done after initial configuration:" while [ 1 ] do /bin/stty -echo > /dev/null 2>&1 temp=`echo $IFS` export IFS="\n" while [ 1 ] do read LINE while [ -z "$LINE" ] do echo echo -n "Password can't be null. Enter password:" read LINE done result=`expr index "$LINE" [\'\"]` if [ $result != 0 ]; then echo echo -n "The password you entered contains invalid characters. Enter password:" else break fi done echo echo -n "Confirm the password:" read LINE1 echo if [ "$LINE" != "$LINE1" ]; then echo echo -n "Passwords do not match. Enter the password:" else break fi done /bin/stty echo > /dev/null 2>&1 ORACLE_PASSWORD=$LINE export IFS=$temp break; done while : do if [ "$ORACLE_DBENABLED" = "true" ] then CUR=y else CUR=n fi echo echo -n "Do you want Oracle Database 10g Express Edition to be started on boot (y/n) [y]:" read LINE if [ -z $LINE ] then ORACLE_DBENABLED=true fi echo case "$LINE" in "") break ;; y|Y) ORACLE_DBENABLED=true break ;; n|N) ORACLE_DBENABLED=false break ;; *) echo "Invalid response: $LINE " >&2 break esac done } configure() { if test -f "$CONFIGURATION" then echo "Oracle Database 10g Express Edition is already configured" exit 1 fi configure_ask configure_perform CONFIGURE_RUN=true write_sysconfig echo To access the Database Home Page go to \"http://127.0.0.1:$HTTP_PORT/apex\" } start() { if [ "$CONFIGURE_RUN" != "true" ] then echo "Oracle Database 10g Express Edition is not configured. You must run '/etc/init.d/oracle-xe configure' as the root user to configure the database." exit 0 fi status=`ps -ef | grep tns | grep oracle` if [ "$status" == "" ] then if [ -f $ORACLE_HOME/bin/tnslsnr ] then echo "Starting Oracle Net Listener." $SU -s /bin/bash $ORACLE_OWNER -c "$LSNR start" > /dev/null 2>&1 fi fi echo "Starting Oracle Database 10g Express Edition Instance." $SU -s /bin/bash $ORACLE_OWNER -c "$SQLPLUS -s /nolog @$ORACLE_HOME/config/scripts/startdb.sql" > /dev/null 2>&1 RETVAL=$? if [ $RETVAL -eq 0 ] then echo else echo Failed to start Oracle Net Listener using $ORACLE_HOME/bin/tnslsnr\ and Oracle Express Database using $ORACLE_HOME/bin/sqlplus. RETVAL=1 fi return $RETVAL } stop() { if [ "$CONFIGURE_RUN" != "true" ] then echo "Oracle Database 10g Express Edition is not configured. You must run '/etc/init.d/oracle-xe configure' as the root user to configure the database." exit 0 fi # Stop Oracle 10g Express Edition Database and Listener echo Shutting down Oracle Database 10g Express Edition Instance. $SU -s /bin/bash $ORACLE_OWNER -c "$SQLPLUS -s /nolog @$ORACLE_HOME/config/scripts/stopdb.sql" > /dev/null 2>&1 echo Stopping Oracle Net Listener. $SU -s /bin/bash $ORACLE_OWNER -c "$LSNR stop" > /dev/null 2>&1 RETVAL=$? echo if [ $RETVAL -eq 0 ] && rm -f /var/lock/subsys/$LSNR then return $RETVAL fi } dostatus() { if test ! -f "$CONFIGURATION" then echo "Oracle Database 10g Express Edition is not configured. You must run '/etc/init.d/oracle-xe configure' as the root user to configure the database." exit 0 elif [ "$CONFIGURE_RUN" != "true" ] then echo "Oracle Database 10g Express Edition is not configured. You must run '/etc/init.d/oracle-xe configure' as the root user to configure the database." exit 0 fi $SU -s /bin/bash $ORACLE_OWNER -c "$LSNR status" RETVAL=$? } # See how we were called case "$1" in start) if test -f "$CONFIGURATION" then if test "$ORACLE_DBENABLED" != "true" -o "$FORCE" != "true" then exit 0 fi else echo "Oracle Database 10g Express Edition is not configured. You must run '/etc/init.d/oracle-xe configure' as the root user to configure the database." exit 0 fi start ;; force-start) FORCE=true start RETVAL=$? ;; configure) configure ;; stop) if test ! -f "$CONFIGURATION" then echo "Oracle Database 10g Express Edition is not configured. You must run '/etc/init.d/oracle-xe configure' as the root user to configure the database." exit 0 fi stop ;; restart|reload|force-reload) FORCE=true stop start RETVAL=$? ;; status) dostatus ;; enable) if test -f "$CONFIGURATION" then ORACLE_DBENABLED=true write_sysconfig else echo "Oracle Database 10g Express Edition is not configured. You must run '/etc/init.d/oracle-xe configure' as the root user to configure the database." exit 0 fi ;; disable) if test -f "$CONFIGURATION" then ORACLE_DBENABLED=false write_sysconfig else echo "Oracle Database 10g Express Edition is not configured. You must run '/etc/init.d/oracle-xe configure' as the root user to configure the database." exit 0 fi ;; *) echo $"Usage: $0 {start|force-start|stop|restart|force-reload|configure|status|enable|disable}" exit 1 esac

*1:この指定を行わないと、configure終了後にoracleインスタンスを停止させることができなくて、パニクルかもしれません。その場合には、/etc/init.d/oracle-xe enable; /etc/init.d/oracle-xe stop; /etc/init.d/oracle-xe disable;の順にコマンドを実行してあげてください。

*2:もちろん/etc/rc?.d/からoracle-xeスクリプトを削除してしまうというのは簡単な解決方法です