Oracle大表清理truncate .. reuse storage
deallocate_unused_clause
Purpose
Use the deallocate_unused_clause to explicitly deallocate unused space at the end of a database object segment and make the space available for other segments in the tablespace.
You can deallocate unused space using the following statements:
ALTER CLUSTER (see ALTER CLUSTER)
ALTER INDEX: to deallocate unused space from the index, an index partition, or an index subpartition (see ALTER INDEX)
ALTER MATERIALIZED VIEW: to deallocate unused space from the overflow segment of an index-organized materialized view (see ALTER MATERIALIZED VIEW)
ALTER TABLE: to deallocate unused space from the table, a table partition, a table subpartition, the mapping table of an index-organized table, the overflow segment of an index-organized table, or a LOB storage segment (see ALTER TABLE)
Syntax
deallocate_unused_clause::=
Description of the illustration deallocate_unused_clause.gif
Semantics
This section describes the semantics of the deallocate_unused_clause. For additional information, refer to the SQL statement in which you set or reset this clause for a particular database object.
You cannot specify both the deallocate_unused_clause and the allocate_extent_clause in the same statement.
Oracle Database frees only unused space above the high water mark (that is, the point beyond which database blocks have not yet been formatted to receive data). Oracle deallocates unused space beginning from the end of the object and moving toward the beginning of the object to the high water mark.
If an extent is completely contained in the deallocation, then the whole extent is freed for reuse. If an extent is partially contained in the deallocation, then the used part up to the high water mark becomes the extent, and the remaining unused space is freed for reuse.
Oracle credits the amount of the released space to the user quota for the tablespace in which the deallocation occurs.
The exact amount of space freed depends on the values of the INITIAL, MINEXTENTS, and NEXT storage parameters. Please refer to the storage_clause for a description of these parameters.
KEEP integer
Specify the number of bytes above the high water mark that the segment of the database object is to have after deallocation.
If you omit KEEP and the high water mark is above the size of INITIAL and MINEXTENTS, then all unused space above the high water mark is freed. When the high water mark is less than the size of INITIAL or MINEXTENTS, then all unused space above MINEXTENTS is freed.
If you specify KEEP, then the specified amount of space is kept and the remaining space is freed. When the remaining number of extents is less thanMINEXTENTS, then Oracle adjusts MINEXTENTS to the new number of extents. If the initial extent becomes smaller than INITIAL, then Oracle adjusts INITIALto the new size.
In either case, Oracle sets the value of the NEXT storage parameter to the size of the last extent that was deallocated.
最近需要清理一张大表,要求不能影响性能。在MySQL里边我们可以通过借助coreutils以及硬链接的方式来最小化I/O,Oracle也可以通过分批次回收空间来最小化I/O,到底如何,下面我们拭目以待。
一、TRUNCATE TABLE 语法
TRUNCATE TABLE [schema_name.]table_name
[ PRESERVE MATERIALIZED VIEW LOG | PURGE MATERIALIZED VIEW LOG ]
[ DROP STORAGE | REUSE STORAGE ] ;
--下面仅列出reuse storage的说明部分
REUSE STORAGE
Specify REUSE STORAGE to retain the space from the deleted rows allocated to the table. Storage values are not reset to the values when the table was created. This space can subsequently be used only by new data in the table resulting from insert or update operations. This clause leaves storage parameters at their current settings.
This setting is useful as an alternative to deleting all rows of a very large table—when the number of rows is very large, the table entails many thousands of extents, and when data is to be reinserted in the future. TRUNCATE TABLE with REUSE STORAGE performs several orders of magnitude faster than deleting all rows, but has the following drawbacks:
?You cannot roll back a TRUNCATE TABLE statement.
?All cursors are invalidated.
?You cannot flash back to the state of the table before the truncate operation.
This clause is not valid for temporary tables. A session becomes unbound from the temporary table when the table is truncated, so the storage is automatically dropped.
If you have specified more than one free list for the object you are truncating, then the REUSE STORAGE clause also removes any mapping of free lists to instances and resets the high-water mark to the beginning of the first extent.
二、演示truncate table .. reuse storage(11g)
SQL> select * from v$version where rownum=1;
BANNER
--------------------------------------------------------------------------------
Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 64bit Production
SQL> create table tb_reuse as select * from dba_objects;
Table created.
SQL> / --多次执行
37200896 rows created.
SQL> create table tb_noreuse as select * from tb_reuse;
Table created.
SQL> select count(*) from tb_reuse;
COUNT(*)
----------
37200896
SQL> select count(*) from tb_noreuse;
COUNT(*)
----------
37200896
SQL> select segment_name,bytes/1024/1024 from dba_segments where segment_name in('TB_REUSE','TB_NOREUSE');
SEGMENT_NAME BYTES/1024/1024
----------------------------------- ---------------
TB_REUSE 4165 --占用空间接近4GB
TB_NOREUSE 4172
SQL> truncate table tb_noreuse; --直接truncate,速度很快
Table truncated.
Elapsed: 00:00:00.25
SQL> select segment_name,bytes/1024/1024 from dba_segments where segment_name in('TB_REUSE','TB_NOREUSE');
SEGMENT_NAME BYTES/1024/1024
----------------------------------- ---------------
TB_REUSE 4165
TB_NOREUSE .0625 -- 空间已回收
Elapsed: 00:00:00.03
SQL> truncate table tb_reuse reuse storage; --使用reuse storage方式,并无太多性能提升
Table truncated.
Elapsed: 00:00:00.07
SQL> alter table tb_reuse deallocate unused keep 2048; --这里漏掉了指定m,缺省为byte
Table altered.
Elapsed: 00:00:00.36
SQL> select segment_name,bytes/1024/1024 from dba_segments where segment_name in('TB_REUSE','TB_NOREUSE');
SEGMENT_NAME BYTES/1024/1024
----------------------------------- ---------------
TB_REUSE .0625
TB_NOREUSE .0625
Elapsed: 00:00:00.03
三、演示truncate table .. reuse storage(12c)
SQL> select * from v$version where rownum=1;
BANNER CON_ID
-------------------------------------------------------------------------------- ----------
Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production 0
SQL> create table tb_12_use as select * from dba_objects;
Table created.
SQL> insert into tb_12_use select * from tb_12_use;
90903 rows created.
SQL> /
11635584 rows created.
SQL> create table tb_12_nouse as select * from tb_12_use;
Table created.
SQL> select segment_name,bytes/1024/1024 from dba_segments where segment_name in('TB_12_USE','TB_12_NOUSE');
SEGMENT_NAME BYTES/1024/1024
------------------------------ ---------------
TB_12_NOUSE 3074 --使用空间为3GB
TB_12_USE 3072
SQL> select 'Leshami' As author,'http://blog.csdn.net/leshami' as Blog from dual;
AUTHOR BLOG
------- ----------------------------
Leshami http://blog.csdn.net/leshami
SQL> set timing on;
SQL> truncate table TB_12_NOUSE; --使用常规方式truncate
Table truncated.
Elapsed: 00:00:01.73
SQL> truncate table TB_12_USE reuse storage; --使用reuse storage方式,并无太多性能提升
Table truncated.
Elapsed: 00:00:01.10
SQL> alter table TB_12_USE deallocate unused keep 2048m;
Table altered.
Elapsed: 00:00:00.25
SQL> alter table TB_12_USE deallocate unused keep 1m;
Table altered.
Elapsed: 00:00:00.14
SQL> select segment_name,bytes/1024/1024 from dba_segments where segment_name in('TB_12_USE','TB_12_NOUSE');
SEGMENT_NAME BYTES/1024/1024
------------------------------ ---------------
TB_12_NOUSE .0625
TB_12_USE 1.0625
Elapsed: 00:00:00.03
-- 由于前面的测试在非归档模式,因此重启切换到归档模式后再次测试
SQL> archive log list;
Database log mode Archive Mode
Automatic archival Enabled
Archive destination USE_DB_RECOVERY_FILE_DEST
Oldest online log sequence 396
Next log sequence to archive 398
Current log sequence 398
SQL> select count(*) from tb_12_use;
COUNT(*)
----------
23273472
SQL> select count(*) from tb_12_nouse;
COUNT(*)
----------
23273472
SQL> truncate table TB_12_NOUSE;
Table truncated.
Elapsed: 00:00:02.07
SQL> truncate table TB_12_USE reuse storage; --归档后使用reuse storage方式,同样无太多性能提升
--因为truncat属于DDL,本身并不会产生太大arch
Table truncated.
Elapsed: 00:00:00.76
四、小结
a、通过上述测试,当使用reuse storage与普通方式并无明显差异
b、truncate table 是ddl操作,无法回滚
c、尽管无明显性能差异,生产环境大表情况,还是建议使用reuse storage结合deallocate方式
How To Efficiently Drop (or Truncate) A Table With Many Extents (文档 ID 68836.1)
***Checked for relevance on 01-Jul-2016***
How to efficiently drop a table with many extents
PURPOSE
~~~~~~~
This note describes why a user process can consume large amounts of CPU
after dropping a table consisting of many extents, and a potential
workaround to stop the problem occurring. Essentially the CPU is being
used to manipulate the extents i.e. moving used extents (uet$) to free
extents (fet$). In certain circumstances it may be possible to regulate
this CPU activity.
SCOPE & APPLICATION
~~~~~~~~~~~~~~~~~~~
This article is intended to assist DBAs who may need to drop a table
consisting of many extents.
RELATED DOCUMENTS
~~~~~~~~~~~~~~~~~
Note:61997.1 SMON - Temporary Segment Cleanup and Free Space Coalescing
Permanent object cleanup
~~~~~~~~~~~~~~~~~~~~~~~~
If a permanent object (table) is made up of many extents, and the object is
to be dropped, the user process dropping the object will consume large
amounts of CPU - this is an inescapable fact. However, with some forethought
it is possible to mitigate the effects of CPU usage (and hence the knock-on
effect on other users of system resources) thus:
1. Identify, but do NOT drop the table
2. Truncate the table, specifying the REUSE STORAGE clause. This will be
quick as extents are not deallocated; the highwater mark is simply
adjusted to the segment header block.
3. Deallocate unused extents from the table, SPECIFYING THE KEEP CLAUSE.
This is the crux - you can control how many extents are to be deallocated
by specifying how much (in terms of Kb or Mb) of the table is NOT
to be deallocated.
Example:
o. Table BIGTAB is 2Gb in size and consists of 262144 8Kb extents
o. There is little CPU power available, and (from past experience) it is
known that dropping an object of this number of extents can take days
o. The system is quiet at night times (no other users or batch jobs)
In the above example the table could be dropped in 'phases' over the period
of a few nights as follows:
1. Truncate the table, specifying the REUSE STORAGE clause:
SQL> TRUNCATE TABLE BIGTAB REUSE STORAGE;
2. If it takes 3 days (72 hours) to drop the table, spread this out over
6 nights i.e. drop 1/3 Gb per night. This can be achieved in 6 (nightly)
steps as follows:
Night 1:
SQL> ALTER TABLE BIGTAB DEALLOCATE UNUSED KEEP 1707M; (2Gb*5/6)
Night 2:
SQL> ALTER TABLE BIGTAB DEALLOCATE UNUSED KEEP 1365M; (2Gb*4/6)
Night 3:
SQL> ALTER TABLE BIGTAB DEALLOCATE UNUSED KEEP 1024M; (2Gb*3/6)
Night 4:
SQL> ALTER TABLE BIGTAB DEALLOCATE UNUSED KEEP 683M; (2Gb*2/6)
Night 5:
SQL> ALTER TABLE BIGTAB DEALLOCATE UNUSED KEEP 341M; (2Gb*1/6)
Night 6:
SQL> DROP TABLE BIGTAB;
NOTE:
If the table only needed truncating, no drop statement is needed here.
The same method can be applied if LOB segments or indexes are involved.
SQL> ALTER TABLE MODIFY LOB ()
DEALLOCATE UNUSED KEEP M;
SQL> ALTER INDEX DEALLOCATE UNUSED KEEP M;
Caveats
~~~~~~~
o. If you have inadvertently tried to drop the table, this method will
not work. This is because the drop will first convert the segment to
a temporary segment, and only then start cleaning up the now temporary
segment's extents. Thus, if the drop is interrupted, the temporary
segment will now be cleaned up by SMON.
o. This method will only work for table, lob and index segment types.
o. This method will not work for segments bigger than 4gb in size due to
unpublished bug:
1190939 -- ORA-3277 WHEN ISSUING AN ALTER TABLE DEALLOCATE UNUSED > 4G (fixed in 10g and higher)
-------------------------------------------------------------------------------
Oracle Support Services
REFERENCES
NOTE:1667223.1 - Truncate Slow in 11.2.0.3 and Higher
怎么有效的drop 或者truncate 有大量extents的table?
来源于:
How To Efficiently Drop (or Truncate) A Table With Many Extents (文档 ID 68836.1)
目的:
本文描述了为什么一个用户进程在drop 了一个含有大量extents的table之后消耗大量的cpu资源。并给出一个潜在的workaround以阻止该问题的发生。本质来说,CPU被用于对extents的管理(manipulate),比如moving used extents(uet$)到 free extents(fet$).在某种情况中,it may be possible to regulate this CPU activity.
适用范围:
本文协助DBA处理 drop 掉很多extents的表。
相关的文章:
Note:61997.1 SMON - Temporary Segment Cleanup and Free Space Coalescing
永久对象的清理
如果一个永久对象(table)是由 很多extents组成的,并且该object被drop,drop 该object的用户进程将会消耗很多的CPU资源,
这是不可避免的事实(an inescapable fact)。但是,基于一些远见卓识(with some forethought),
可以减轻(mitigate)CPU的使用(and hence the knock-on effect on other users of system resources)
1. Identify, but do NOT drop the table
2.使用 REUSE STORAGE子句来truncate 该表。这样会很快,因为相关的extents不会被释放。高水位线(highwater mark)被简单的调整到segment header block
3. 使用KEEP子句来释放该table中未使用的extents。这是本步骤的关键所在--通过指定table中有多少extent不会被释放,你可以控制有多少extents被释放
举例:
o. Table BIGTAB is 2Gb in size and consists of 262144 8Kb extents
o. There is little CPU power available, and (from past experience) it is known that dropping an object of this number of extents can take days
o. The system is quiet at night times (no other users or batch jobs)
在上面的例子中,table可以分为几个阶段在几个晚上被drop
1. Truncate the table, specifying the REUSE STORAGE clause:
SQL> TRUNCATE TABLE BIGTAB REUSE STORAGE;
2. If it takes 3 days (72 hours) to drop the table, spread this out over 6 nights i.e. drop 1/3 Gb per night. This can be achieved in 6 (nightly) steps as follows:
注意:If the table only needed truncating, no drop statement is needed here.
Night 1:
SQL> ALTER TABLE BIGTAB DEALLOCATE UNUSED KEEP 1707M; (2Gb*5/6)
Night 2:
SQL> ALTER TABLE BIGTAB DEALLOCATE UNUSED KEEP 1365M; (2Gb*4/6)
Night 3:
SQL> ALTER TABLE BIGTAB DEALLOCATE UNUSED KEEP 1024M; (2Gb*3/6)
Night 4:
SQL> ALTER TABLE BIGTAB DEALLOCATE UNUSED KEEP 683M; (2Gb*2/6)
Night 5:
SQL> ALTER TABLE BIGTAB DEALLOCATE UNUSED KEEP 341M; (2Gb*1/6)
Night 6:
SQL> DROP TABLE BIGTAB;
相同的方法也适用于LOB segments和index segment
SQL> ALTER TABLE MODIFY LOB ()
DEALLOCATE UNUSED KEEP M;
SQL> ALTER INDEX DEALLOCATE UNUSED KEEP M;
警告(caveats):
o.如果你无意之间使用了drop 命令,本方法就不适用了。这是因为,drop table 会首先convert segment到一个临时segment,and only then start cleaning up the now temporary segment's extents.Thus, if the drop is interrupted, the temporary segment will now be cleaned up by SMON.
o.This method will only work for table, lob and index segment types.
o.This method will not work for segments bigger than 4gb in size due to unpublished bug:
1190939 -- ORA-3277 WHEN ISSUING AN ALTER TABLE DEALLOCATE UNUSED > 4G (fixed in 10g and higher)
Truncate Slow in 11.2.0.3 and Higher (文档 ID 1667223.1)
In this Document
APPLIES TO:
Oracle Database - Enterprise Edition - Version 11.2.0.3 to 12.1.0.1 [Release 11.2 to 12.1]
Information in this document applies to any platform.
SYMPTOMS
AWR reports following wait events in the TOP 5 Foreground Waits:
Top 5 Timed Foreground Events
~~~~~~~~~~~~~~~~~~~~~~~~~~
Event Waits Time(s) Avg wait (ms) % DB time Wait Class
local write wait 493,380 1,585 3 11.78 User I/O
DFS lock handle 1,200,205 692 1 5.14 Other
enq: RO - fast object reuse 568,667 650 1 4.83 Application
The AWR Dictionary Cache Stats shows the following information:
Cache Get Requests Pct Miss Scan Reqs Pct Miss Mod Reqs Final Usage
dc_objects 12,651,937 1.09 0 163,989 3,924
dc_segments 5,048,565 0.01 0 136,674 4,119
The ASH reports the following statements that had waits listed in Top wait events:
Top SQL with Top Events
~~~~~~~~~~~~~~~~~~~~~~~~~
Sampled #
SQL ID Planhash of Executions % Activity Event % Event Top Row Source % RwSrc SQL Text
7a62909337ud7 2452080186 1761 18.83 local write wait 5.81 DDL STATEMENT 5.81 TRUNCATE TABLE ...
CPU + Wait for CPU 4.47 DDL STATEMENT 3.82
DFS lock handle 2.33 DDL STATEMENT 2.33
6tjfm0rv28q7p 348574753 785 8.43 local write wait 2.49 DDL STATEMENT 2.49 TRUNCATE TABLE ...
CPU + Wait for CPU 1.66 DDL STATEMENT 1.22
DFS lock handle 1.45 DDL STATEMENT 1.45
CAUSE
Issue is caused by
Bug 18251841 TRUNCATE PARTITIONED TABLE SLOWER IN 11G THAN ON 10G
This issue occurs on 11.2.0.3 and higher, and its caused by a regression introduced by the fix for un-published Bug 11856377, which was
included in the 11.2.0.3 patchset.
Another symptom of this bug is the much more frequent access to dc_segments.
SOLUTION
Bug is fixed in 12.1.0.2.
For versions 11.2.0.3, 11.2.0.4 and 12.1.0.1:
Download and apply Patch 18251841 for the appropriate platform/version .
REFERENCES
NOTE:68836.1 - How To Efficiently Drop (or Truncate) A Table With Many Extents
BUG:18251841 - TRUNCATE PARTITIONED TABLE SLOWER IN 11G THAN ON 10G
About Me
...............................................................................................................................
● 本文整理自网络
● 本文在itpub(http://blog.itpub.net/26736162)、博客园(http://www.cnblogs.com/lhrbest)和个人微信公众号(xiaomaimiaolhr)上有同步更新
● 本文itpub地址:http://blog.itpub.net/26736162/abstract/1/
● 本文博客园地址:http://www.cnblogs.com/lhrbest
● 本文pdf版及小麦苗云盘地址:http://blog.itpub.net/26736162/viewspace-1624453/
● 数据库笔试面试题库及解答:http://blog.itpub.net/26736162/viewspace-2134706/
● QQ群:230161599 微信群:私聊
● 联系我请加QQ好友(646634621),注明添加缘由
● 于 2017-06-02 09:00 ~ 2017-06-30 22:00 在魔都完成
● 文章内容来源于小麦苗的学习笔记,部分整理自网络,若有侵权或不当之处还请谅解
● 版权所有,欢迎分享本文,转载请保留出处
...............................................................................................................................
拿起手机使用微信客户端扫描下边的左边图片来关注小麦苗的微信公众号:xiaomaimiaolhr,扫描右边的二维码加入小麦苗的QQ群,学习最实用的数据库技术。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/26736162/viewspace-2141248/,如需转载,请注明出处,否则将追究法律责任。