[zt] Truncate操作做了什么

本文详细解析了Oracle数据库中的Truncate操作原理,包括数据字典更新、Extent重新分配及Segment Header的变化等内容,并探讨了不同Oracle版本中Truncate操作的性能优化措施。
         Oracle的Truncate操作只是改了一下数据字典上的一部份信息, 另外将重新分配一个Extent, 并获得一个新的Data Object ID, 并修改Segment Header中的信息, 在数据文件中的数据部份没有作什么修改, 象以前的DOS下删除文件一样, 有undel工具可以将文件找回来, 主要是因为磁盘中存放文件的部份没有修改. 因此对于Truncate操作如果我们知道以前的Data Object ID, 然后在数据文件中是可以重新找回数据的.
SQL> SELECT OBJECT_ID,DATA_OBJECT_ID FROM USER_OBJECTS
2 WHERE OBJECT_NAME='T_INDEX';

OBJECT_ID DATA_OBJECT_ID
---------- --------------
8880 8880

SQL> SELECT EXTENT_ID,FILE_ID,BLOCK_ID FROM DBA_EXTENTS
2 WHERE WNER='FLOU' AND SEGMENT_NAME='T_INDEX';

EXTENT_ID FILE_ID BLOCK_ID
---------- ---------- ----------
0 1 15786

SQL> TRUNCATE TABLE T_INDEX;

Table truncated.

SQL> SELECT OBJECT_ID,DATA_OBJECT_ID FROM USER_OBJECTS
2 WHERE OBJECT_NAME='T_INDEX';

OBJECT_ID DATA_OBJECT_ID
---------- --------------
8880 8884

SQL> SELECT EXTENT_ID,FILE_ID,BLOCK_ID FROM DBA_EXTENTS
2 WHERE WNER='FLOU' AND SEGMENT_NAME='T_INDEX';

EXTENT_ID FILE_ID BLOCK_ID
---------- ---------- ----------
0 1 15786

这里面的Segment Header为什么没有变呢? 这是因为根据Extent分配的规则来算时, 又分到了这个位置.


rchsh 发表于:2006.03.03 09:22 ::分类: ( 数据库 ) ::阅读:(215次) :: 评论 (2) :: 引用 (0)
re: 转贴 [回复]

这里面的Segment Header为什么没有变呢? 这是因为根据Extent分配的规则来算时, 又分到了这个位置.
那这样说高水位是还有的?

Posted by: greatfinish | March 2, 2006 01:08 AM
你可以自已做实验, 如果在这个Segment的前面有空的Extent的话, 在分配时就会分配前面的可用块(LMT), 如果是TRUNCATE ... REUSE STORAGE的话, Segment Header的位置是不会变的.

Posted by: anysql | March 2, 2006 08:00 AM
anysql ,你说truncate 只是修改了数据字典的信息,重新给segment 分配了新的extend,并没有修改数据文件的内容,那你的意思就是说truncate 之后表的内容还在数据文件里面吗?也就是说虽然表被truncate 了,但是他的内容还在数据文件里面,只不过他原来所占的空间被标志为空闲的,可以被其他的对象重新使用,原来表的内容还是存在的,所以说可以重新恢复的,我的理解对吗?

Posted by: rchsh | March 3, 2006 09:32 AM
只有一点, 如果truncate了之后放出来的空间被其他对象重用了, 这时才是真的不能恢复了, 不过truncate操作后不能保证能全部恢复, 因为segment header会占用一个块, 如果刚好分在有数据的块上, 这个块是要格式化的. 如果指定了多个free list group, 则每一个flg又会占用一个块的.

 

 

------------------------------------------------------------------------------------------------------- 

 

 

我们都知道truncate操作会做什么:移动HWM,释放extent,重新生成data_object_id。truncate之所以比比delete快,是因为它根本不需要删除数据。但是在实际中我们经常碰到truncate很慢的情况,实际上它比我们想象的要复杂。

1.在truncate之前,CKPT必须搜索整个buffer cache,把这个object的dirty buffer全部写回磁盘(这个操作在10g有了改进,我们后面再说)。在这个过程中,系统很可能会出现DBWR的等待事件,如果dirty buffer对应的redo还没有被写入,也有可能会出现LGWR的等待事件,比如log file sync。有人说truncate之前要做一次checkpoint,并不是特别确切。

When a truncate is issued, the checkpoint process does a complete scan (till 9204) of the buffer cache.  All of the dirty buffers of the object in the buffer cache are written down to disk.  All of the clean buffers are are invalidated.

2.是否使用了reuse storage,因为需要释放空间,尤其对于字典管理的表空间。很可能会出现Waits on ST enqueue的等待事件。

3.Waits on “RO enqueue” or “CI enqueue”

The RO enqueue known as “Multiple object resue” enqueue, is used to synchronise operations
between foreground process and a background process such as DBWR or CKPT.
It is typically used when you are dropping objects or truncating tables.

When a truncate/drop is issued,

1.the foreground first acquires the “RO” enqueue in exclusive mode,
2.then cross instance calls (or one call if it is a single object) are issued
(the “CI” enqueue is acquired for cross instance call)
3.The CKPT processes on each of instances requests the DBWR to write
the dirty buffers to the disk and invalidate all the clean buffers.
4. After DBWR finishes writing, the foreground process releases the RO
enqueue.

In effect this enqueue serializes the truncate/drop operations given concurrently.

前面说过,9i在truncate之前需要扫描整个SGA找到这个object的dirty buffer,但是10g作了改进:

In Oracle 10g, a new feature was introduced in order to improve performance of operations such as drop, truncate, shrink object. This feature uses ‘object queues’ in the buffer cache infrastructure which points to a list of buffers owned by an object. In 9i, we might scan the entire buffer cache to see which buffers belong to the object is getting truncated and write its dirty buffers to disk. On environments with huge buffer caches, buffer invalidation will take long time. In 10g, the buffer invalidation process only looks at the ‘object queues’ and writes out the dirty buffers to disk. Since ‘object queues’ are short, truncate/drop/shrink operations are very fast in 10g.

这个新特性用参数 “_db_fast_obj_truncate” 来控制,这个新特性有已知的bug,必要时可以关闭

 

http://feitianie.itpub.net/post/8010/56843

http://www.hellodba.net/2009/01/truncate.html 

 

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/35489/viewspace-591892/,如需转载,请注明出处,否则将追究法律责任。

转载于:http://blog.itpub.net/35489/viewspace-591892/

MySQL中rk_ns_temp1_bs 和rk_ns_bz_dz_tmp 都是千万级的大表,请帮我优化以下SQL,写成可以复用的存储过程: -- 更新 UPDATE rk_ns_temp1_bs t1 JOIN rk_ns_bz_dz_tmp t2 ON t1.ZJHM = t2.ZJHM SET t1.sfnshj = '疑似' WHERE t1.sfnshj <> '是' -- 排除已经是“是”的记录 AND t2.HJDZ_SSXQDM_BZ = '440115000000'; -- 地址临时表中户籍地址为“南沙区” -- 是否有效 -- 户籍表状态正常 是 状态注销 否 UPDATE rk_ns_temp1_bs t1 JOIN b_rk_stjh_hjrk_new t2 ON t1.ZJHM = t2.GMSFHM SET t1.zt = CASE WHEN t2.zt = '1' THEN '正常' WHEN t2.zt = '0' THEN '异常' ELSE t1.zt -- 其他状态保持不变 END where t1.sjly = '户籍表'; -- 非户籍表状态正常 是 状态注销 否 -- 先和已经有状态的数据比对,插入非户籍同身份证的状态数据 insert into rk_ns_temp1_bs select ZJLXDM,ZJHM,XM,'非户籍表','否', CASE WHEN t1.zt = '1' THEN '正常' WHEN t1.zt = '0' THEN '异常' else null END from b_rk_stjh_fhjrk_new t1 join rk_ns_temp1_bs t2; on t1.ZJHM = t2.ZJHM and t2.zt is not null; -- 更新非户籍身份状态 UPDATE rk_ns_temp1_bs t1 JOIN b_rk_stjh_fhjrk_new t2 ON t1.ZJHM = t2.ZJHM SET t1.zt = CASE WHEN t2.zt = '1' THEN '正常' WHEN t2.zt = '0' THEN '异常' ELSE t1.zt -- 其他状态保持不变 END where t1.sjly = '非户籍表'; -- 来穗人员表状态正常 是 状态注销 否 -- 先和已经有状态的数据比对,插入来穗同身份证的状态数据 -- 来穗建索引 CREATE INDEX idx_ls_zjhm ON VIEW_T_LDRY_ALL(zjhm); -- insert into rk_ns_temp1_bs select '01',ZJHM,XM,'来穗人员业务表','否', CASE WHEN t1.SFZX = '1' THEN '正常' WHEN t1.SFZX = '0' THEN '异常' else null END from VIEW_T_LDRY_ALL t1 join rk_ns_temp1_bs t2; on t1.ZJHM = t2.ZJHM and t2.zt is not null; -- 更新来穗身份状态 UPDATE rk_ns_temp1_bs t1 JOIN VIEW_T_LDRY_ALL t2 ON t1.ZJHM = t2.ZJHM SET t1.zt = CASE WHEN t2.SFZX = '0' THEN '正常' WHEN t2.SFZX = '1' THEN '异常' ELSE t1.zt -- 其他状态保持不变 END where t1.sjly = '来穗人员业务表';
03-08
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值