Post on 18-Jul-2015
Meetup! JPOUGat Oracle CloudWorld 2015 Tokyo
#1
/ Koji Shinkubo @kouji_s_0808
ある日、ログイン処理にちょっと変えた。
ログインしたユーザーの情報をちょっと取得するだけのSELECT文で。
何の特徴もない処理のはずだった。。。
確かに、ログイン毎に実行されるSQL文だけど、ディスクI/Oなんか ほとんどない。はずだった。。。
でも、ディスクI/Oがハンパない。しかも書き込みが!
なーんでだ?
では、ヒント①
通常時と異常時のEMのトップアクティビティのイメージ映像をどうぞ。
Commitクラスでグーンと待機してますね
では、ヒント②
上記のトップアクティビティで待機セッションの大きかった待機クラス(Commit)をドリルダウンしたイメージ映像をどうぞ。
はい、出ましたね。"log file sync"大事なので、もう一回。"log file sync"
ところで、"log file sync"って何でしたっけ?
えー。時間ないので、省略します。どうしてもという方は、以前の"特濃JPOUG"のslide shareをご覧ください。
* どうもブラウザーだと一部文字が化けるようなので、ダウンロードしてもらえるとちゃんと見えるらしいです
http://www.slideshare.net/kshinkub/dbts2013-jpoug-logfilesync
でも、"log file sync"で待機していたSQL文が確認できませんね。
本当に、SELECTなの? 実はINSERTとか更新系のSQLをこっそり実行しているんじゃない? とか思ってますよね。
一旦SQL文が分からなかったので、該当モジュールで実行されたSQL文を探ってみます。
今回の謎を再現するための偽データなので、分かりやすく一つSQL文がありまず。限りなく黒に近い容疑者のSQL文(SELECT)ですね。
一応、見てみます?
では、ヒント③
はい。もう、分かりましたね :)
答えは
SequenceオブジェクトのCache属性が
小さすぎる(デフォルトの20)
解説。など。など。
Sequenceオブジェクト
cache属性の値を超えると何が起こる?
enq: SQ - contentionリカーシブコール
リカーシブコールupdate seq$ set increment$=:2 , minvalue=:3 , maxvalue=:4 , cycle#=:5 , order$=:6 , cache=:7 , highwater=:8 , audit$=:9 , flags=:10 where obj#=:1
まとめSequenceのcache属性のデフォルト値は20cache属性を超える場合、Sequenceは新たにcacheする必要があるが、それは1セッションのみが可能(exclusiveなenqueueを取得する)なので、他のセッションはenq: SQ - contentionで待機するさらに、その際、SEQ$へのUpdate文(リカーシブコール)が発行される
なので、cache属性が小さいといろいろと問題になりますよね
Appendix
ちなみに"log file sync"が問題に注目して、チューニングしてみると。
今度は、こうなっちゃいますよ。
Thanks!