ロックされているオブジェクトを調べるのは簡単だど、単純にSELECTされている表などを調べることができないかと思い、色々攻めあぐねた結果、以下のSQLでそれらしい情報を取得できることが判明した。但し、CRUD等どのような操作を行っているかまでは判別できないみたい。(v$sql表と組み合わせてSQL文見れば良いかもだけど、構文解析が大変そう&信頼性がどうなの&処理が重そうなのでやめた)
- - - - - - - - - - - - - - - - - - - - - - - -
select
s.sid --SID
,s.serial# --シリアル番号
,s.username --Oracleログインユーザ名
,o.to_owner --使用してるオブジェクトオーナー
,o.to_name --使用してるオブジェクト名
from v$session s, v$object_dependency o
where s.sql_address = o.from_address
and s.sql_hash_value = o.from_hash
- - - - - - - - - - - - - - - - - - - - - - - -
これは例えば、次の様な状況のときに使用できるんじゃないかな。
僕のライフワークであるMaterialized Viewでのケースを例にしましょうね。
[状況]
・オンライン開局中にMaterialized ViewをTRUNCATEモードでリフレッシュしなければならない。
・リフレッシュ対象のMaterialized Viewに対する他セッションからの読み取り可能性は常にある。
[問題]
・Materialized ViewをTRUNCATEモードでリフレッシュすると、読取一貫性が保証できなくなる。
→他のセッションがMaterialized ViewをSELECTしていた場合でも問答無用でTRUNCATEするからである。これはMaterialized ViewをSELECTしている最中にTRUNCATEモードでのリフレッシュが走ると、TRUNCATEされた時点までのレコードしか読み取らない(しかもエラーにならない)。例えば本来100万件保持するMaterialized Viewなのに、10万件しか読み取らなかったというケースが発生し業務的にありえない状況になる。
[解決方法]
先に紹介したSQLから取得された情報を使用して、Materialized Viewのリフレッシュ処理部品中に、リフレッシュ対象のMaterialized Viewが他セッションから読み取られている場合に、Materialize Viewリフレッシュ処理をWAITする、処理を実装することで回避できる。(とはいいつつもMaterialized ViewをTRUNCATEモードでリフレッシュ中に、他のセッションがSELECTしたら0件が返却されるから、今度は読取セッション側でMaterialized Viewがリフレッシュ中かどうかの調べるロジックが必要になるという罠)
0 件のコメント:
コメントを投稿