博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ddl操作是否会产生undo?
阅读量:6457 次
发布时间:2019-06-23

本文共 8628 字,大约阅读时间需要 28 分钟。

ddl是否会产生undo? 这可能是每一个初学Oracle的人都会有的疑问;ddl操作又不能rollback回滚,要什么undo数据呢? 事实是几乎每个ddl操作都会产生undo,我们来探究一下:
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
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
SQL> 
select 
vs.
name
, ms.value
  
2    
from 
v$mystat ms, v$sysstat vs
  
3   
where 
ms.statistic# = vs.statistic#
  
4     
and 
name 
'undo change vector size'
;
NAME                                                                  
VALUE
---------------------------------------------------------------- ----------
undo change vector 
size                                                   
0
 
SQL> 
create 
table 
YOUYUS (t1 
int
);
Table 
created.
 
SQL>   
select 
vs.
name
, ms.value
  
2      
from 
v$mystat ms, v$sysstat vs
  
3     
where 
ms.statistic# = vs.statistic#
  
4       
and 
name 
'undo change vector size'
;
NAME                                                                  
VALUE
---------------------------------------------------------------- ----------
undo change vector 
size                                                
1992
 
/*
create 
table
的ddl语句产生了大约1992 bytes的撤销变化向量*/
 
SQL> 
drop 
table 
YOUYUS;
Table 
dropped.
 
SQL>   
select 
vs.
name
, ms.value
  
2      
from 
v$mystat ms, v$sysstat vs
  
3     
where 
ms.statistic# = vs.statistic#
  
4       
and 
name 
'undo change vector size'
;
NAME                                                                  
VALUE
---------------------------------------------------------------- ----------
undo change vector 
size                                                
4528
 
/* 
drop 
table
语句产生2563 bytes的undo数据,多于
create 
table
;我们可以猜测
create 
table
时Oracle需要向基表中
insert
数据,而
drop 
table
时则需要
delete
/
update
数据,显然后者产生更多的undo*/
 
/*我们尝试创建一个由254个列组成的表*/
 
SQL>     
select 
vs.
name
, ms.value
  
2        
from 
v$mystat ms, v$sysstat vs
  
3       
where 
ms.statistic# = vs.statistic#
  
4         
and 
name 
'undo change vector size'
;
NAME                                                                  
VALUE
---------------------------------------------------------------- ----------
undo change vector 
size                                                   
0
 
create 
table 
YOUYUS (
t1 
int
,
t2 
char
(4) 
default 
'oooo'
,
t3 
char
(4) 
default 
'oooo'
,
t4 
char
(4) 
default 
'oooo'
,
t5 
char
(4) 
default 
'oooo'
,
t6 
char
(4) 
default 
'oooo'
,
t7 
char
(4) 
default 
'oooo'
,
t8 
char
(4) 
default 
'oooo'
,
t9 
char
(4) 
default 
'oooo'
,
............................
t248 
char
(4) 
default 
'oooo'
,
t249 
char
(4) 
default 
'oooo'
,
t250 
char
(4) 
default 
'oooo'
,
t251 
char
(4) 
default 
'oooo'
,
t252 
char
(4) 
default 
'oooo'
,
t253 
char
(4) 
default 
'oooo'
,
t254 
char
(4) 
default 
'oooo'
);
 
SQL>     
select 
vs.
name
, ms.value
  
2        
from 
v$mystat ms, v$sysstat vs
  
3       
where 
ms.statistic# = vs.statistic#
  
4         
and 
name 
'undo change vector size'
;
NAME                                                                  
VALUE
---------------------------------------------------------------- ----------
undo change vector 
size                                               
85832
 
/*产生了83k的undo,ddl所产生的undo量视乎其所要维护数据字典的操作类型和操作量*/
 
SQL> oradebug setmypid;
Statement processed.
 
SQL> oradebug event 10046 trace 
name 
context forever,
level 
1;
Statement processed.
 
SQL> 
drop 
table 
YOUYUS;
Table 
dropped.
 
SQL>     
select 
vs.
name
, ms.value
  
2        
from 
v$mystat ms, v$sysstat vs
  
3       
where 
ms.statistic# = vs.statistic#
  
4         
and 
name 
'undo change vector size'
;
NAME                                                                  
VALUE
---------------------------------------------------------------- ----------
undo change vector 
size                                              
214020
 
/*
drop 
产生了125k的undo*/
 
SQL> oradebug tracefile_name;
/home/maclean/app/maclean/diag/rdbms/prod/PROD/trace/PROD_ora_5433.trc
 
/* 我们来看看
drop 
table 
到底做了哪些递归操作? */
 
[maclean@rh2 ~]$ cat PROD_ora_5433.trc|egrep 
"delete|update"
         
'Need use delete_topo_geometry_layer() to deregister table '
select 
decode(u.type#, 2, u.ext_username, u.
name
), o.
name
,        t.
update
$, t.
insert
$, t.
delete
$, t.enabled,        decode(bitand(t.property, 8192),8192, 1, 0),        decode(bitand(t.property, 65536), 65536, 1, 0),       decode(bitand(t.property, 131072), 131072, 1, 0),       (
select 
o.
name 
from 
obj$ o          
where 
o.obj# = u.spare2 
and 
o.type# =57)  
from 
sys.obj$ o, sys.
user
$ u, sys.
trigger
$ t, sys.obj$ bo 
where 
t.baseobject=bo.obj# 
and 
bo.
name 
= :1 
and 
bo.spare3 = :2  
and 
bo.namespace = 1  
and 
t.obj#=o.obj# 
and 
o.owner#=u.
user
#  
and 
o.type# = 12 
and 
bitand(property,16)=0 
and 
bitand(property,8)=0  
order 
by 
o.obj#
delete 
from 
object_usage 
where 
obj# 
in  
(
select 
a.obj# 
from 
object_usage a, ind$ b 
where  
a.obj# = b.obj# 
and 
b.bo# = :1)
delete 
from 
sys.cache_stats_1$ 
where 
dataobj# = :1
delete 
com$ 
where 
obj#=:1
delete 
from 
hist_head$ 
where 
obj# = :1
delete 
from 
dependency$ 
where 
d_obj#=:1
delete 
from 
source$ 
where 
obj#=:1
delete 
from 
compression$ 
where 
obj#=:1
   
m_stmt:=
'delete from sdo_geor_ddl__table$$ where id=2'
;
   
m_stmt:=
'delete from sdo_geor_ddl__table$$'
;
delete 
from 
sdo_geor_ddl__table$$ 
where 
id=2
delete 
from 
col$ 
where 
obj#=:1
delete 
from 
icol$ 
where 
bo#=:1
delete 
from 
icoldep$ 
where 
obj# 
in 
(
select 
obj# 
from 
ind$ 
where 
bo#=:1)
delete 
from 
jijoin$ 
where 
obj# 
in 
select 
obj# 
from 
jijoin$ 
where 
tab1obj# = :1 
or 
tab2obj# = :1)
delete 
from 
jirefreshsql$ 
where 
iobj# 
in 
select 
iobj# 
from 
jirefreshsql$ 
where 
tobj# = :1)
delete 
from 
ccol$ 
where 
obj#=:1
delete 
from 
ind$ 
where 
bo#=:1
delete 
from 
cdef$ 
where 
obj#=:1
delete 
ecol$ 
where 
tabobj# = :1
delete 
from 
tab$ 
where 
obj#=:1
delete 
from 
idl_ub1$ 
where 
obj#=:1 
and 
part=:2
delete 
from 
idl_char$ 
where 
obj#=:1 
and 
part=:2
delete 
from 
idl_ub2$ 
where 
obj#=:1 
and 
part=:2
delete 
from 
idl_sb4$ 
where 
obj#=:1 
and 
part=:2
delete 
from 
ncomp_dll$ 
where 
obj#=:1 returning dllname 
into 
:2
delete 
from 
idl_ub1$ 
where 
obj#=:1 
and 
part=:2
delete 
from 
idl_char$ 
where 
obj#=:1 
and 
part=:2
delete 
from 
idl_ub2$ 
where 
obj#=:1 
and 
part=:2
delete 
from 
idl_sb4$ 
where 
obj#=:1 
and 
part=:2
delete 
from 
ncomp_dll$ 
where 
obj#=:1 returning dllname 
into 
:2
delete 
from 
idl_ub1$ 
where 
obj#=:1 
and 
part=:2
delete 
from 
idl_char$ 
where 
obj#=:1 
and 
part=:2
delete 
from 
idl_ub2$ 
where 
obj#=:1 
and 
part=:2
delete 
from 
idl_sb4$ 
where 
obj#=:1 
and 
part=:2
delete 
from 
ncomp_dll$ 
where 
obj#=:1 returning dllname 
into 
:2
delete 
from 
col$ 
where 
obj#=:1
delete 
coltype$ 
where 
obj#=:1
delete 
from 
subcoltype$ 
where 
obj#=:1
delete 
ntab$ 
where 
obj#=:1
delete 
lob$ 
where 
obj#=:1
delete 
refcon$ 
where 
obj#=:1
delete 
from 
opqtype$ 
where 
obj#=:1
delete 
from 
cdef$ 
where 
obj#=:1
delete 
from 
objauth$ 
where 
obj#=:1
delete 
from 
obj$ 
where 
obj# = :1
update 
seg$ 
set 
type#=:4,blocks=:5,extents=:6,minexts=:7,maxexts=:8,extsize=:9,extpct=:10,
user
#=:11,iniexts=:12,lists=decode(:13, 65535, 
NULL
, :13),groups=decode(:14, 65535, 
NULL
, :14), cachehint=:15, hwmincr=:16, spare1=DECODE(:17,0,
NULL
,:17),scanhint=:18, bitmapranges=:19 
where 
ts#=:1 
and 
file#=:2 
and 
block#=:3
update 
seg$ 
set 
type#=:4,blocks=:5,extents=:6,minexts=:7,maxexts=:8,extsize=:9,extpct=:10,
user
#=:11,iniexts=:12,lists=decode(:13, 65535, 
NULL
, :13),groups=decode(:14, 65535, 
NULL
, :14), cachehint=:15, hwmincr=:16, spare1=DECODE(:17,0,
NULL
,:17),scanhint=:18, bitmapranges=:19 
where 
ts#=:1 
and 
file#=:2 
and 
block#=:3
delete 
from 
seg$ 
where 
ts#=:1 
and 
file#=:2 
and 
block#=:3
 
/*如果ddl操作执行失败又会如何呢?*/
 
SQL> oradebug setmypid;
Statement processed.
SQL> oradebug event 10046 trace 
name 
context forever,
level 
1;
Statement processed.
 
SQL>     
select 
vs.
name
, ms.value
  
2        
from 
v$mystat ms, v$sysstat vs
  
3       
where 
ms.statistic# = vs.statistic#
  
4         
and 
name 
'undo change vector size'
;
NAME                                                                  
VALUE
---------------------------------------------------------------- ----------
undo change vector 
size                                                   
0
 
SQL> 
drop 
table 
YOUYUS;
drop 
table 
YOUYUS
           
*
ERROR 
at 
line 1:
ORA-00942: 
table 
or 
view 
does 
not 
exist
 
SQL>     
select 
vs.
name
, ms.value
  
2        
from 
v$mystat ms, v$sysstat vs
  
3       
where 
ms.statistic# = vs.statistic#
  
4         
and 
name 
'undo change vector size'
;
NAME                                                                  
VALUE
---------------------------------------------------------------- ----------
undo change vector 
size                                                 
264
/*同样产生了undo,量较少*/
 
 
SQL> oradebug tracefile_name;
/home/maclean/app/maclean/diag/rdbms/prod/PROD/trace/PROD_ora_5494.trc
[maclean@rh2 trace]$ cat PROD_ora_5494.trc|egrep 
"update|insert|delete"
         
'Need use delete_topo_geometry_layer() to deregister table '
   
m_stmt:=
'insert into sdo_geor_ddl__table$$ values (1)'
;
   
m_stmt:=
'insert into sdo_geor_ddl__table$$ values (2)'
;
insert 
into 
sdo_geor_ddl__table$$ 
values 
(2)
   
m_stmt:=
'delete from sdo_geor_ddl__table$$'
;
delete 
from 
sdo_geor_ddl__table$$
 
/*执行少量递归操作后,Oracle发现所要
drop
的对象并不存在,将会
rollback
之前的
"部分"
递归dml操作*/
 
其实我们可以把ddl操作分解为以下步骤:
 
begin
commit
;
--编译ddl
begin
--实现ddl,包括一系列递归的数据字典维护操作及其他操作
commit
;
exception
when 
others 
then
rollback
;
end
;
end
;

ddl操作无需也不允许手动commit或rollback参与,但这并不代表ddl操作不产生undo。

本文转自maclean_007 51CTO博客,原文链接:http://blog.51cto.com/maclean/1277536

转载地址:http://heizo.baihongyu.com/

你可能感兴趣的文章
Android 代码混淆之部分类不混淆的技巧
查看>>
移动前端页面与Chrome的远程真机调试
查看>>
selenium 如何处理table
查看>>
Atitit.数据检索与网络爬虫与数据采集的原理概论
查看>>
Jenkins实现生产环境部署文件的回滚操作(Windows)
查看>>
TCP长连接与短连接的区别
查看>>
iOS10 UI教程视图的生命周期
查看>>
php 设置mssql编码 解决乱码问题 mssql_connect charset Utf8
查看>>
java 代码解压7z(带密码)转载请注明出处,谢谢
查看>>
终端直接执行py文件,不需要python命令
查看>>
Leetcode刷题记录:构建最大数二叉树
查看>>
centos7 redis配置
查看>>
spring3: 表达式5.2 SpEL基础
查看>>
『PyTorch x TensorFlow』第六弹_从最小二乘法看自动求导
查看>>
Git安装遇到的问题fatal: Could not read from remote repository.的解决办法
查看>>
MongoDB在Windows系统下的安装和启动
查看>>
C# 让应用程序只运行一个实例
查看>>
重定向标准流
查看>>
《Node Web开发》((美)David Herron)【摘要 书评 试读】- 京东图书
查看>>
ThinkPHP——重复输出解决办法
查看>>