事象
docker + oracle/PHPUnit実行環境での開発時、dockerfileの更新を行い
imageをbuildしphpunitを動かすとDB接続エラーが発生。
何度かphpunitを実行するとOracleエラーコードが変化する不思議な事象に遭遇した時のお話。
環境情報
開発はdockerコンテナ上に、
・Oracleサーバーを構成し、開発DB環境よりデータをdumpしローカルDB環境へテーブル構造をimportするイメージ
・PHP7環境にphptunitをcomposerでインストールしvolumeしたテストコードを実行するイメージ
のサービス構成となっている。
##変化していくエラーコード
コンテナを立ち上げ、UnitTestを実行すると以下のエラーが順に発生。
`ORA-12528:TNS:リスナー: 該当するインスタンスはすべて、新規接続をブロックしています`
`ORA-12526:TNS:リスナー: 該当するインスタンスはすべて限定モードになっています`
`ORA-12537:TNS:接続がクローズされました。`
`ORA-01017:ユーザー名/ パスワードが無効です。ログオンは拒否されました。`
`ORA-01045: user ユーザ名 lacks CREATE SESSION privilege; logon denied`
環境変数ORACLE_HOME
やORACLE_SID
を再確認し、tnsnames.ora
を見直していく中、
変わり身の早さに負けまいと対処を続け、果てにはshutdown & setup
も行う。
暫くすると……突然エラー解消、UnitTestが成功。
構築環境がカタストロフィではなかったもの、釈然としない。
##原因はOracleのstartup
何度か同様の動作を繰り返していくうちに、
・コンテナの再起動では発生しない、再ビルドで発生する
・時間経過で解消される
↓
「dumpしたテーブル構造のimport処理に時間がかかっているのでは?」
と推測し、コンテナのプロセスをUnitTest実行時にチェックするようにした。
#!/bin/sh -u
# option取得
# * -f オプションで強制的に実行
getopts "f" forceExec
# 起動中のコンテナでimportが走っていないか確認
# 自身のgrep処理は除外
if [[ -n `docker-compose exec (database/image) /bin/bash -c 'ps ax | grep -e "(起動script/α)" -e "(起動script/β)" -e "impdp(import処理)" | grep -v "grep"'` ]]; then
# option check
if [[ ${forceExec} != 'f' ]]; then
echo 'now running database script. please wait a few minutes.'
exit
fi
fi
# unit test
# phpunit は composer.jsonで定義
docker-compose exec (api/image) bash -c 'phpunit (対象directory)'
UnitTest実行のshellにチェックを設けて、チーム内周知で一件落着。
インスタンス環境構築の落とし穴に入りかけた一幕と相成りました。