この記事では、Oracle に関する関連知識を提供し、セッション実行時のロックと SQL のチェックに関する問題を中心に紹介します。一緒に見ていきましょう。皆様のお役に立てれば幸いです。 。
推奨チュートリアル: 「Oracle ビデオ チュートリアル 」
この記事のテスト データのデータベース環境: Oracle 11g
セッション実行中の SQL というのはなぜでしょうか? あるセッションの SQL 実行記録が取得できないようです。ブログ記事もよく読みました。インターネット上では多くの人が書いています。 sql_id がビュー v$active_session_history と v$sqlarea に関連付けられているとします。特定のセッションの SQL 実行記録をクエリできます。 練習後、機能しないことがわかりました (テーブル dba_hist_active_sess_history も機能しません) 、一部の SQL の sql_id が v$active_session_history にまったく記録されていないため、パラメータ control_management_pack_access を変更しようとしましたが、権限がないことがわかりました。パラメータ値が正常であり、パラメータ データベースが開いていることがわかりました。ブログ投稿を参照してください: Oracle V$ACTIVE_SESSION_HISTORY Query No Data - wazz_s - Blog Park
SQL の実行記録をクエリできますv$sqlarea ビューを使用しましたが、SQL を実行したセッション ID が見つかりません。このセッション ID があれば、誰が SQL を実行したかを確認できると便利です。
テーブルをロックする原因となった SQL をクエリしたい場合、インターネット上のほとんどのブログ投稿で、ビュー v$ をクエリして、対応する prev_sql_addr フィールドの値を取得することが説明されています。これは値 A として記録され、値 A をビュー v$sqlarea フィールド アドレスのクエリ条件値として使用すると、対応する SQL レコードをクエリできるようになります。模擬テストとして、ロック テーブルを検索する SQL を見つけることができますが、通常の運用環境ではほとんどの場合、それを取得できないのはなぜですか? 以下の概要を参照してください。
この記事では、探索的アプローチを使用して研究しています。データの正確性を確保するために、3 つのデータベース セッションを開き、それぞれセッション 1、セッション 2、セッション 3 として記録しました。具体的な手順
1 セッションで新しいテスト テーブルとテスト データを作成します。 session1
--新建测试表 create table zxy_table(zxy_id int,zxy_name varchar2(20)); --插入数据 insert into zxy_table(zxy_id,zxy_name) values(1,'zxy1'); insert into zxy_table(zxy_id,zxy_name) values(2,'zxy2'); insert into zxy_table(zxy_id,zxy_name) values(3,'zxy3'); insert into zxy_table(zxy_id,zxy_name) values(4,'zxy4'); commit;
2 のセッション ID を表示します。 session1
select userenv('sid') from dual;
セッション ID が 2546
3 であることがわかります。 session1 では、次のように、更新用の選択を通じてテーブル zxy_table の行をロックします。 :
select * from zxy_table where zxy_name='zxy1' for update;
4 session2 で、セッション ID が 2189 であることをクエリします。
次に、テーブル zxy_table の行を値 zxy_name='zxy1 で更新します。
update zxy_table set zxy_name='zxy1_modify' where zxy_name='zxy1';
次に、以下に示すように、SQL がブロックされていることがわかります:
5 次に、セッション 3 に進みます。ロック テーブルの状況を表示するには
まずテーブル v$locked_object を確認します
select * from v$locked_object;
ロック テーブルの原因となったセッション ID が 2546 であることがわかります。これは前の session1 で、object_id は 110154 です。もちろん、生成環境では、必ず複数のレコードが表示されます。これを数回実行する必要があります。n 回実行した後でも、レコードは表示されます。これは、このレコードがロック テーブルのレコードであることを証明します。
Pass object_id :110154 dba4_objects テーブルをクエリして、詳細なロック テーブル情報をクエリします
select object_name as 被锁的表名称,obj.* from dba_objects obj where object_id='110154';
## sessionid: 2546 ## を通じてビュー v$session
select s.prev_sql_addr, module as 客户端工具名称, s.user# as 数据库账号名, s.osuser as 连接数据库客户端对应的window账号名称, s.machine as 连接数据库客户端对应的计算机名称, s.* from v$session s where sid='2546';# をクエリします。 prev_sql_addr: 000000012E045E28 の値を取得し、ビュー v$sqlarea をクエリします。
select * from v$sqlarea where address='000000012E045E28';
上の図からわかるように、結果は「テーブルをロックするステートメントがありますが、多くのブログ投稿はこのステップで終了しています。このクエリは本当に信頼できますか?」になります。答えは信頼できません。次のように、セッション 1 に戻って SQL を自由に実行できます:
select * from zxy_table;
その後、セッション 3 に移動して
select s.prev_sql_addr, module as 客户端工具名称, s.user# as 数据库账号名, s.osuser as 连接数据库客户端对应的window账号名称, s.machine as 连接数据库客户端对应的计算机名称, s.* from v$session s where sid='2546';
を実行できます。
再看看prev_sql_addr是不是变了,从000000012E045E28变为了00000001FB03CEC0,再通过00000001FB03CEC0查询视图v$sqlarea
select * from v$sqlarea where address='00000001FB03CEC0';
得到的sql_text是select * from zxy_table,你敢说这条sql导致了锁表吗?所有只能说是session1当前执行的sql,而且你很难保证session1执行完锁表的sql: select * from zxy_table where zxy_name='zxy1' for update且在提交前不再执行别的sql,这就是前文提出的问题的答案。
推荐教程:《Oracle视频教程》
以上がOracle ビューのロックとセッション実行 SQL (概要共有)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。