OS환경 : Oracle Linux 6.8 (64bit)
DB 환경 : Oracle Database 11.2.0.4
방법 : 오라클 11g DB 재기동시 sql_id 는 남아있을까? (v$sql)
sql 수행 시 만들어진 sql_id는 v$sql 등의 뷰에서 확인할 수있음
DB가 재기동 되었을 경우에는 남아있는지 여부를 확인하는 테스트
테스트 데이터 생성
1
2
3
4
|
SQL> conn / as sysdba
SQL> create table sql_table as select * from dba_objects;
Table created.
|
sql 수행(5회 실행)
1
2
3
4
5
6
7
8
9
|
SQL> select * from sql_table where rownum <= 1;
OWNER OBJECT_NAME SUBOBJECT_NAME
------------------------------ -----------------------------------------------------------------------------------------------------------------
OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE CREATED LAST_DDL_ TIMESTAMP STATUS T G S NAMESPACE EDITION_NAME
---------- -------------- ------------------- --------- --------- ------------------- ------- - - - ---------- ------------------------------
SYS ICOL$ (null)
20 2 TABLE 15-OCT-19 15-OCT-19 2019-10-15:09:16:39 VALID N N N 1 (null)
|
해당 sql의 sql_id 확인
1
2
3
4
5
6
7
|
SQL> select sql_id, sql_text from v$sql where sql_text like '%sql_table%';
SQL_ID SQL_TEXT
------------- -----------------------------------------------------------------------
7hwwnkrrgtcus select * from sql_table where rownum <= 1
gm1zs82v6put9 select sql_id, sql_text from v$sql where sql_text like '%sql_table%'
|
sql_id가 7hwwnkrrgtcus 인것을 확인할 수 있음
db 재기동
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL>startup
ORACLE instance started.
Total System Global Area 2137886720 bytes
Fixed Size 2254952 bytes
Variable Size 1442842520 bytes
Database Buffers 687865856 bytes
Redo Buffers 4923392 bytes
Database mounted.
Database opened.
|
해당 sql의 sql_id로 조회
1
2
3
|
SQL> select sql_id, sql_text from v$sql where sql_id = '7hwwnkrrgtcus';
no rows selected
|
v$sql에서는 찾아볼수없음 (v$sqlarea 도 마찬가지로 no rows)
DBA_HIST_SQL_PLAN 뷰에서 조회
1
2
3
|
SQL> select sql_id from DBA_HIST_SQL_PLAN where sql_id = '7hwwnkrrgtcus';
no rows selected
|
찾아볼수없음
처음 sql 재수행
1
2
3
4
5
6
7
8
9
|
SQL> select * from sql_table where rownum <= 1;
OWNER OBJECT_NAME SUBOBJECT_NAME
------------------------------ -----------------------------------------------------------------------------------------------------------------
OBJECT_ID DATA_OBJECT_ID OBJECT_TYPE CREATED LAST_DDL_ TIMESTAMP STATUS T G S NAMESPACE EDITION_NAME
---------- -------------- ------------------- --------- --------- ------------------- ------- - - - ---------- ------------------------------
SYS ICOL$ (null)
20 2 TABLE 15-OCT-19 15-OCT-19 2019-10-15:09:16:39 VALID N N N 1 (null)
|
해당 sql의 sql_id로 조회
1
2
3
4
5
|
SQL> select sql_id, sql_text from v$sql where sql_id = '7hwwnkrrgtcus';
SQL_ID SQL_TEXT
------------- -----------------------------------------------------------------------
7hwwnkrrgtcus select * from sql_table where rownum <= 1
|
재기동시 v$sql에 sql_id로 검색시 바로 나오진 않지만
해당 쿼리를 재수행하면 해당 sql에 대해 동일한 sql_id가 부여되어서 v$sql에서 조회가 가능함
추가 테스트
v$sql 의 count 확인 후 재기동 후 v$sql 의 count 확인
재기동 전 v$sql, v$sqlarea 의 count 확인
1
2
3
4
5
6
7
8
9
10
11
|
SQL> select count(*) from v$sql;
COUNT(*)
----------
573
SQL> select count(*) from v$sqlarea;
COUNT(*)
----------
569
|
db 재기동
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
|
SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL>startup
ORACLE instance started.
Total System Global Area 2137886720 bytes
Fixed Size 2254952 bytes
Variable Size 1442842520 bytes
Database Buffers 687865856 bytes
Redo Buffers 4923392 bytes
Database mounted.
Database opened.
|
재기동 후 v$sql, v$sqlarea 의 count 확인
1
2
3
4
5
6
7
8
9
10
11
|
SQL> select count(*) from v$sql;
COUNT(*)
----------
318
SQL> select count(*) from v$sqlarea;
COUNT(*)
----------
313
|
재기동 이후에도 약 300개 정도의 데이터가 있음
파싱한 유저 확인
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
SQL>
select d.username, count(*) from v$sql v, dba_users d
where v.parsing_user_id = d.user_id
group by d.username
USERNAME COUNT(*)
------------------------------ ----------
SYS 318
SQL>
select d.username, count(*) from v$sqlarea v, dba_users d
where v.parsing_user_id = d.user_id
group by d.username
USERNAME COUNT(*)
------------------------------ ----------
SYS 313
|
모두 SYS 임
DB가 기동되면서 또는 운영되면서 시스템 내부적으로 실행되는 쿼리들임
결론
sql_id는 sql 이 들어왔을 때 오라클 내부 해쉬함수에 의해 만들어진 값임
재기동시 v$sql에 sql_id로 검색시 바로 나오진 않지만
해당 쿼리를 재수행하면 해당 해쉬 함수에 의해 동일한 sql_id가 부여되어서 v$sql에서 조회가 가능함
메모리에(v$sql 등) 있는 sql 커서정보는 장시간 재호출이 없거나 데이터베이스가 재기동될 때 사라짐
원문
Actually, since 10g the full story goes like this:
Oracle hashes the library cache object name with MD5, producing a 128 bit hash value
Oracle takes last 64 bits of the MD5 hash and this will be the SQL_ID (but it’s shown in base-32 for brevity rather than in hex or as a regular number)
Oracle takes last 32 bits of the MD5 hash and this will be the hash value (as seen in v$sql.hash_value)
https://tanelpoder.com/2009/02/22/sql_id-is-just-a-fancy-representation-of-hash-value/
'ORACLE > Admin' 카테고리의 다른 글
crsctl start crs wait 옵션 (0) | 2020.08.23 |
---|---|
오라클 11g R2 ADRCI 를 이용한 IPS(Incident Packaging Service) 가이드 (0) | 2020.08.16 |
오라클 11g R2 tfa(ahf) SQL 성능 진단 자동 수집 가이드(SRDC) (0) | 2020.08.12 |
오라클 19c RDA(Remote Diagnostic Agent) 사용 가이드 (0) | 2020.08.09 |
오라클 일반 테이블과 blob 테이블 생성, 데이터 삭제 후 datapump 테스트 (0) | 2020.08.01 |