Oracle Databaseから定期情報取得するスクリプトについて
この記事は、 JPOUG Advent Calendar 2022 11日目の記事です。
10日目は wmo6hash さんの記事『Oracle Database Patch Maintenance '22 - wmo6hash::blog』でした。
はじめに
みなさん、スクリプトを使ってOracle Databaseの情報取得されていますか?
パフォーマンスをモニタリングできるツールがあったり、データベースのエディションがEnterprise Editionだとできることも違うかと思います。
このようなことが必要なときは得てして上記に一切当てはまらない環境かと思います。
私が過去にやって学んだことを紹介したいと思います。
※本ブログで公開したスクリプトを利用される際は、必ず十分な動作確認を行なってください。
本スクリプトを利用して不具合が発生した場合でも責任は追いかねます。
結論
スクリプトでsqlplusを用いて情報取得をする場合は以下をテンプレートとして使います。
1度の接続で、SQLを実行し続けるサンプルになります。
シェルスクリプト
- get-dbifo.sh
#/bin/sh LOGFILE="`date '+%Y%m%d_%H%M%S'`.log" ( echo 'connect / as sysdba' while true do echo "@v_session.sql ${LOGFILE}" sleep 60 done ) | sqlplus /nolog exit 0
- v_session.sql
set pages 0 lines 32000 trimo on trims on echo off term off feedback off spool &1 append select count(*) from v$session; spool off
PowerShell
PowerShell版はシェルの焼き直し版になります。
- get-dbifo.ps1
& { echo "conn / as sysdba" echo "set feedback off" for ($i=0; $i -lt 9999; $i++){ echo "@v_session.sql test.log" echo "exec DBMS_LOCK.SLEEP(60)" } } | sqlplus /nolog
v_session.sqlはshell版のものをそのまま使えます。
通常の情報取得だとなぜだめか
私がはじめに作ったのは以下のようなスクリプトでした。シンプルに毎回DBへ接続して情報取得するスクリプトですね。
手軽なスクリプトで作っているため、一般的なプログラミング言語でやるようなコネクションを作って、使い回すというものではありませんね。
- get-dbinfo.sh
#/bin/sh LOGFILE="dbinfo_`date '+%Y%m%d_%H%M%S'`.log" while true do sqlplus / as sysdba @v_session.sql ${LOGFILE} > /dev/null 2>&1 sleep 60 done
- v_session.sql
set pages 0 lines 32000 trimo on trims on echo off term off feedback off spool &1 append select count(*) from v$session; spool off exit
上記で何が問題あるかというと、負荷をかけないと再現しないような障害の調査をしなければいけないときです。
このようなときはデータベースの最大接続上限に張り付くような状態が考えられるため、そもそもDBへ接続できないため情報取得できないなんてことになります。
帰宅前にスクリプト仕掛けて翌朝ログを確認したら、実際に負荷のかかった深夜の情報が取れていなかったなんてとても悲しいですよね。
PowerShell版を作る上での課題など
ブログにする上で、shellだけではと思いPowerShell版を作りましたが、思ったようにうまくいきませんでした。
パイプラインの制限
他の方のブログ(*1)でも記載がありますが、shellでのパイプと動作が違うため以下の改良をしています。
- 無限ループをやめ、必要な分の有限ループにする。
無限ループにすると、スクリプトブロックでの出力が確定しないため、sqlplusでの処理がいつまで経っても始まりません。
- PowerShellのStart-Sleepコマンドレットの代わりにDBMS_LOCK.SLEEPを利用する。
スクリプトブロック内でのSleepはSleepの時間分、SQLの出力を遅くするだけで出力が終わるとSQLが一気に実行されて終わります。リソースの推移なんか見れません。
まとめ
情報収集などは、パフォーマンスをモニタリングできるツール/監視ツールなど行うことがほとんどかと思います。
いざ定期的に情報収集が必要になったら、ぜひお使いになってください。