이 글은 Oracle에 대한 관련 지식을 제공하며, 세션 실행 시 잠금 및 SQL 확인과 관련된 문제를 주로 소개합니다. 모두에게 도움이 되기를 바랍니다.
추천 튜토리얼: "Oracle Video Tutorial"
이 글의 테스트 데이터를 위한 데이터베이스 환경: Oracle 11g
왜 세션 실행 중에 sql이라고 하는 것 같나요? 특정 세션의 기록을 얻을 수 없다는 블로그 게시물도 많이 읽었습니다. 인터넷에서 많은 사람들이 sql_id를 v$active_session_history 및 v$ 뷰와 연결하여 특정 세션의 SQL 실행 기록을 쿼리할 수 있다고 말했습니다. sqlarea.실습해본 결과 불가능하다는 것을 확인했습니다.(dba_hist_active_sess_history 테이블을 통해 시도해봐도 작동하지 않습니다.) 일부 sql의 sql_id가 v$active_session_history에 전혀 기록되지 않고 있습니다. : control_management_pack_access 권한이 없는 것으로 확인되었습니다. 그리고 확인해 보니 매개변수 값이 정상이고 매개변수 데이터베이스가 열려 있는 것으로 나타났습니다. Oracle V$ACTIVE_SESSION_HISTORY 쿼리에 데이터가 없습니다. - wazz_s - 블로그를 참조하세요. 박
v$sqlarea 뷰를 통해 sql의 실행기록을 조회할 수 있는데, sql을 실행하는 sessionid를 찾을 수 없다면, 누가 실행했는지 알 수 있으면 좋겠습니다. sql.
테이블을 잠그게 만든 SQL을 쿼리하려면 인터넷에 있는 대부분의 블로그 게시물에서 v$session 뷰를 쿼리하여 해당 prev_sql_addr 필드 값을 얻고 이를 A 값으로 기록한 다음 이를 가르칩니다. A 값을 v$sqlarea 뷰에 있는 주소 필드의 쿼리 조건 값으로 사용하면 해당 SQL 레코드를 쿼리할 수 있습니다. 연습 테스트로 잠금 테이블을 찾는 SQL을 찾을 수 있지만 대부분의 경우 일반적인 프로덕션 환경에서는 얻을 수 없습니다. 이유는 무엇입니까?
이 기사에서는 탐색적 접근 방식을 사용하여 데이터의 정확성을 보장하기 위해 세션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 session1의 세션 ID를 확인합니다
select userenv('sid') from dual;
세션 ID가 2546
3인 것을 확인할 수 있습니다. session1에서 한 행을 잠급니다.
select * from zxy_table where zxy_name='zxy1' for update;
4 session2에서 세션 ID가 2189인지 쿼리합니다.
그런 다음 session2에서 다음과 같이 session2의 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;
You Lock 테이블이 발생한 원인을 알 수 있습니다. Session id는 이전 Session 1인 2546이고, object_id는 110154입니다. 물론 생성 환경에서는 반드시 1개 이상의 레코드를 여러 번 실행해야 합니다. . n번 실행한 후에도 해당 레코드를 볼 수 있습니다. , 이 레코드가 잠금 테이블의 레코드임을 증명하세요
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_sq l_addr 값은 000000012E045E28을 얻은 다음, 얻은 값을 통해 v$sqlarea
select * from v$sqlarea where address='000000012E045E28';
뷰를 쿼리합니다. , 테이블 잠금을 일으킨 문을 볼 수 있는데 많은 블로그 게시물이 이 단계에서 끝나기 때문에 쿼리는 정말 신뢰할 수 있습니까? 대답은 신뢰할 수 없습니다. 다음과 같이 session1로 돌아가서 원하는 대로 SQL을 실행할 수 있습니다.
select * from zxy_table;
그런 다음 session3에서 실행할 수 있습니다.
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 중국어 웹사이트의 기타 관련 기사를 참조하세요!