Oracle大表清理truncate .. reuse storage

lhrbest發表於2017-06-26

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::=

De.ion of deallocate_unused_clause.gif follows
Description of the illustration deallocate_unused_clause.gif

(size_clause::=)

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

Symptoms
Cause
Solution
References


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 
<snip>
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群,學習最實用的資料庫技術。

Oracle大表清理truncate .. reuse storage
DBA筆試面試講解
歡迎與我聯絡

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26736162/viewspace-2141248/,如需轉載,請註明出處,否則將追究法律責任。

相關文章