OS 환경 : Oracle Linux 8.7 (64bit)
DB 환경 : Oracle Database 19.27.0.0
방법 : 오라클 19c 테이블에 grant시 last_ddl_time이 변경될까?
본문에서는 grant 명령시 테이블의 last_ddl_time이 변경되는지를 확인해봄
테스트
시간 단위까지 정확히 보기 위해 세션 날짜 형식 변경
|
1
2
3
|
SQL> alter session set nls_date_format = 'yyyy-mm-dd hh24:mi:ss';
Session altered.
|
테스트용 테이블 및 데이터 생성
|
1
2
3
4
5
|
SQL>
drop table test_grant_time purge;
create table test_grant_time (id number, val varchar2(10));
insert into test_grant_time values(1, 'AAA');
commit;
|
권한 부여 전 LAST_DDL_TIME 확인
|
1
2
3
4
5
6
7
8
9
10
|
SQL>
set lines 200 pages 1000
col object_name for a20
select object_name, last_ddl_time
from dba_objects
where object_name = 'TEST_GRANT_TIME';
OBJECT_NAME LAST_DDL_TIME
-------------------- -------------------
TEST_GRANT_TIME 2026-04-10 20:42:18
|
2026-04-10 20:42:18임
샘플 sql 수행
|
1
2
3
4
5
6
7
|
SQL>
select id, val from test_grant_time
where id = 1;
ID VAL
---------- ----------
1 AAA
|
해당 sql의 invalidations 확인(무효화 되었는지 여부)
|
1
2
3
4
5
6
7
8
|
SQL>
select sql_id, LOADED_VERSIONS, LOADS, INVALIDATIONS, substr(sql_text,1,30) sql_text from v$sql
where sql_text like '%select id, val from test_grant_time%'
and sql_text not like '%sql_text%';
SQL_ID LOADED_VERSIONS LOADS INVALIDATIONS SQL_TEXT
------------- --------------- ---------- ------------- ------------------------------------------------------------
ccnvccvkd0rm0 1 1 0 select id, val from test_grant
|
몇초 ~ 몇분 대기 후 grant 권한 부여
|
1
2
3
|
SQL> grant select on test_grant_time to public;
Grant succeeded.
|
권한 부여 후 LAST_DDL_TIME 재확인
|
1
2
3
4
5
6
7
8
9
10
|
SQL>
set lines 200 pages 1000
col object_name for a20
select object_name, last_ddl_time
from dba_objects
where object_name = 'TEST_GRANT_TIME';
OBJECT_NAME LAST_DDL_TIME
-------------------- -------------------
TEST_GRANT_TIME 2026-04-10 20:47:19
|
last_ddl_time이 2026-04-10 20:47:19로 변경되었음
샘플 sql 재수행
|
1
2
3
4
5
6
7
|
SQL>
select id, val from test_grant_time
where id = 1;
ID VAL
---------- ----------
1 AAA
|
해당 sql의 invalidations 재확인(무효화 되었는지 여부)
|
1
2
3
4
5
6
7
8
|
SQL>
select sql_id, loaded_versions, loads, invalidations, substr(sql_text,1,30) sql_text from v$sql
where sql_text like '%select id, val from test_grant_time%'
and sql_text not like '%sql_text%';
SQL_ID LOADED_VERSIONS LOADS INVALIDATIONS SQL_TEXT
------------- --------------- ---------- ------------- ------------------------------------------------------------
ccnvccvkd0rm0 1 2 1 select id, val from test_grant
|
last_ddl_time이 변경됨에 따라 sql이 무효화(invalidations) 되었고 새로 로드됨
상세 분석
grant시 10046 트레이스를 수행해 확인해보니 내부적으로 obj$를 업데이트하는 부분이 확인됨
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
|
PARSING IN CURSOR #139937448094744 len=409 dep=1 uid=0 oct=6 lid=0 tim=164939067877 hv=696165170 ad='634d3b98' sqlid='c3utnxsnrx8tk'
update obj$ set obj#=:4, type#=:5,ctime=:6,mtime=:7,stime=:8,status=:9,dataobj#=:10,flags=:11,oid$=:12,spare1=:13,spare2=:14,spare3=:15,signature=:16,spare7=:17,spare8=:18,spare9=:19, dflcollid=decode(:20,0,null,:20),creappid=:21,creverid=:22, modappid=:23,modverid=:24,crepatchid=:25,modpatchid=:26 where owner#=:1 and name=:2 and namespace=:3 and remoteowner is null and linkname is null and subname is null
END OF STMT
PARSE #139937448094744:c=320,e=320,p=0,cr=0,cu=0,mis=1,r=0,dep=1,og=4,plh=0,tim=164939067876
BINDS #139937448094744:
Bind#0
oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
oacflg=00 fl2=1000001 frm=00 csi=00 siz=48 off=0
kxsbbbfp=7f45b9d1f588 bln=22 avl=04 flg=05
value=44808
Bind#1
oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
oacflg=00 fl2=1000001 frm=00 csi=00 siz=0 off=24
kxsbbbfp=7f45b9d1f5a0 bln=22 avl=02 flg=01
value=2
...
Bind#25
oacdty=01 mxl=32(15) mxlc=00 mal=00 scl=00 pre=00
oacflg=10 fl2=0001 frm=01 csi=846 siz=32 off=0
kxsbbbfp=811cf356 bln=32 avl=15 flg=09
value="TEST_GRANT_TIME"
Bind#26
oacdty=02 mxl=22(22) mxlc=00 mal=00 scl=00 pre=00
oacflg=00 fl2=1000001 frm=00 csi=00 siz=24 off=0
kxsbbbfp=7f45b9d1f400 bln=22 avl=02 flg=05
value=1
EXEC #139937448094744:c=1228,e=2020,p=0,cr=2,cu=1,mis=1,r=1,dep=1,og=4,plh=2683643009,tim=164939069983
STAT #139937448094744 id=1 cnt=0 pid=0 pos=1 obj=18 op='UPDATE OBJ$ (cr=2 pr=0 pw=0 str=1 time=79 us)'
STAT #139937448094744 id=2 cnt=1 pid=1 pos=1 obj=37 op='INDEX RANGE SCAN I_OBJ2 (cr=2 pr=0 pw=0 str=1 time=15 us cost=2 size=109 card=1)'
CLOSE #139937448094744:c=0,e=0,dep=1,type=3,tim=164939070052
EXEC #139937448121440:c=26003,e=40518,p=0,cr=81,cu=11,mis=0,r=0,dep=0,og=1,plh=0,tim=164939070179
WAIT #139937448121440: nam='log file sync' ela= 470 buffer#=474 sync scn=14005678 p3=0 obj#=-1 tim=164939070695
WAIT #139937448121440: nam='SQL*Net message to client' ela= 1 driver id=1650815232 #bytes=1 p3=0 obj#=-1 tim=164939070725
WAIT #139937448121440: nam='SQL*Net message from client' ela= 341 driver id=1650815232 #bytes=1 p3=0 obj#=-1 tim=164939071077
CLOSE #139937448121440:c=2,e=2,dep=0,type=0,tim=164939071109
|
바인드 변수를 확인해보니 TEST_GRANT_TIME 테이블 오브젝트값을 업데이트 하는것이었음
이부분에서 mtime이 업데이트 되는데 이게 last_ddl_time이라고 함
실제 sys유저로 접속하여 아래와 같이 수정해보면 last_ddl_time이 변경되는것을 확인할 수 있음
*obj$를 수정하는것을 위험하기 때문에 테스트 환경에서만 테스트해보고 꼭 rollback 하는게 좋음
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
var b1 number;
var b2 varchar2(128);
var b3 number;
var b4 number;
var b5 number;
var b6 varchar2(30);
var b7 varchar2(30);
var b8 varchar2(30);
var b9 number;
var b10 number;
var b11 number;
var b12 varchar2(128);
var b13 number;
var b14 number;
var b15 number;
var b16 varchar2(128);
var b17 number;
var b18 number;
var b19 number;
var b20 number;
var b21 number;
var b22 number;
var b23 number;
var b24 number;
var b25 number;
var b26 number;
exec :b1 := 85;
exec :b2 := 'TEST_GRANT_TIME';
exec :b3 := 1;
exec :b4 := 44808;
exec :b5 := 2;
exec :b6 := '4/11/2026 14:27:20';
exec :b7 := '4/30/2026 14:28:5'; <<<---- b7(mtime)을 4월30일로 지정
exec :b8 := '4/11/2026 14:27:20';
exec :b9 := 1;
exec :b10 := 44808;
exec :b11 := 0;
exec :b12 := null;
exec :b13 := 6;
exec :b14 := 1;
exec :b15 := 85;
exec :b16 := '87FB8B715FCD39F9E5751815B217F1';
exec :b17 := 0;
exec :b18 := 0;
exec :b19 := 0;
exec :b20 := 16382;
exec :b21 := null;
exec :b22 := null;
exec :b23 := null;
exec :b24 := null;
exec :b25 := null;
exec :b26 := null;
update obj$
set obj#=:b4,
type#=:b5,
ctime=TO_DATE(:b6, 'MM/DD/YYYY HH24:MI:SS'),
mtime=TO_DATE(:b7, 'MM/DD/YYYY HH24:MI:SS'),
stime=TO_DATE(:b8, 'MM/DD/YYYY HH24:MI:SS'),
status=:b9,
dataobj#=:b10,
flags=:b11,
oid$=:b12,
spare1=:b13,
spare2=:b14,
spare3=:b15,
signature=:b16,
spare7=:b17,
spare8=:b18,
spare9=:b19,
dflcollid=decode(:b20, 0, null, :b20),
creappid=:b21,
creverid=:b22,
modappid=:b23,
modverid=:b24,
crepatchid=:b25,
modpatchid=:b26
where owner#=:b1
and name=:b2
and namespace=:b3
and remoteowner is null
and linkname is null
and subname is null;
1 row updated.
set lines 200 pages 1000
col object_name for a20
select object_name, to_char(last_ddl_time, 'yyyy/mm/dd hh24:mi:ss') last_ddl_time
from dba_objects
where object_name = 'TEST_GRANT_TIME';
OBJECT_NAME LAST_DDL_TIME
-------------------- -------------------
TEST_GRANT_TIME 2026/04/30 14:28:05 <<<---- 4월 30일로 변경됨
rollback;
|
결론 :
DDL이 아닌 DCL인 grant 명령으로도 테이블의 last_ddl_time이 변경됨(내부적으로 obj$를 업데이트 하는 구문이 수행됨)
이로 인해 해당 테이블을 조회하는 sql들도 무효화 되었고, 이로 인해 플랜이 변경될 가능성도 충분히 존재함
참조 : https://docs.oracle.com/en/database/oracle/oracle-database/19/refrn/ALL_OBJECTS.html#
https://docs.oracle.com/en/database/oracle/oracle-database/19/refrn/ALL_TABLES.html
https://docs.oracle.com/en/database/oracle/oracle-database/19/refrn/V-SQL.html
'ORACLE > Admin' 카테고리의 다른 글
| 오라클 26ai CDB TWO_TASK 환경변수 (0) | 2026.04.11 |
|---|---|
| 오라클 19c 잘못된 dns 주소로 인한 sqlplus 연결 지연 문제 (0) | 2026.04.07 |
| 오라클 19c spfile 파라미터 파일 주석 기능 (0) | 2026.03.16 |
| 오라클 19c RAC 환경 ssl(tls)을 이용한 tns(tcps) 연결 설정 (0) | 2026.02.23 |
| 오라클 26ai 신기능 행간 제약사항 Assertion (0) | 2026.02.13 |
