茫茫網海中的冷日 - 對這文章發表回應
茫茫網海中的冷日
         
茫茫網海中的冷日
發生過的事,不可能遺忘,只是想不起來而已!
 恭喜您是本站第 1675129 位訪客!  登入  | 註冊
主選單

Google 自訂搜尋

Goole 廣告

隨機相片
IMG_G9_00013.jpg

授權條款

使用者登入
使用者名稱:

密碼:


忘了密碼?

現在就註冊!

對這文章發表回應

發表限制: 非會員 可以發表

發表者: 冷日 發表時間: 2019/4/12 7:21:18

表擴展失敗(ORA-01653)後的空間管理問題【THE SPACE MANAGEMENT PROBLEM OF THE TABLE EXTEND FAILD 】

    這兩天在公司做ORACLE10G的DATAGUARD測試的時候,發現表擴展報錯後,後續的一些空間問題。
    測試環境中,建了一個500M的TABLESPACE命名為TEST。
    導入一張表(TEST_ALL)有280多萬的數據,然後建立了有建立了一個同樣結構的表TEST1,進行批量插入操作。
   
SQL> insert into test1 select * from test_all;

ORA-01653: unable to extend table TEST.TEST1 by 1024 in tablespace TEST
  
   這是個較為常見的錯誤,就是TABLESPACE沒有空間了。以下為ORACLE給出的錯誤解釋和解決方法。

// *Cause: Cannot shrink the segment because it is not in auto segment space
//       managed tablespace or it is not a data, index or lob segment.
// *Action: Check the tablespace and segment type and reissue the statement

 
   因為我的表空間沒有設置自動增長,所以會有錯誤報出。但是接下來的問題就很有意思了。我們發現雖然插入操作失敗,但是其所佔的空間並沒有自動收回!我的測試環境中,TEST1表一直佔用184M左右的表空間。並且無論我發ROLLBACK,COMMIT,關閉當前SESSION甚至重新啟動數據庫,這個TEST1表一直會佔用著184M的表空間!
   我只能手工TRUNCATE TABLE或者MOVE的方法來消減這張表佔用的空間。
   有意思的是,當我利用ORACLE10G的新方法來試圖回縮所佔用的空間時,ORACLE報錯並且錯的讓我「找不到北」。如下:
  
SQL> alter table test1 shrink space cascade;

alter table test1 shrink space cascade

ORA-10635: Invalid segment or tablespace type
  
   這個10635錯誤也是一個比較典型的錯誤,ORACLE給出的官方解釋:
  
// *Cause: Cannot shrink the segment because it is not in auto segment space
//         managed tablespace or it is not a data, index or lob segment.
// *Action: Check the tablespace and segment type and reissue the statement

    
    當時我以為自己沒有使用ORACLE的ASSM,但是經過確認自己建表空間的SQL,發現我使用的是ASSM的,但還是害怕有問題,對另外一張TEST_ALL的表進行操作,結果正常。
  
  
SQL> alter table test.test_all shrink space cascade;

Table altered

Executed in 10.859 seconds
   
      看上去ORACLE報的這個錯誤也「驢唇不對馬嘴」了。讓我已經久已不用的MOVE命令關鍵時刻還是有點作用的。
      這佔用的表空間只是會造成空間的浪費嗎,還是有其他副作用的。我先後做了兩個COUNT的SQL,其顯示的執行結果比較清楚的說明了這個問題。
    第一個COUNT的SQL是沒有執行TRUNCATE TABLE命令前的,如下


SQL> select count(*) from test1;

  COUNT(*)
----------
         0


Execution Plan
----------------------------------------------------------
Plan hash value: 3896847026

--------------------------------------------------------------------
| Id  | Operation          | Name  | Rows  | Cost (%CPU)| Time     |
--------------------------------------------------------------------
|   0 | SELECT STATEMENT   |       |     1 |  5135   (1)| 00:01:02 |
|   1 |  SORT AGGREGATE    |       |     1 |            |          |
|   2 |   TABLE ACCESS FULL| TEST1 |     1 |  5135   (1)| 00:01:02 |
--------------------------------------------------------------------

Note
-----
   - dynamic sampling used for this statement


Statistics
----------------------------------------------------------
          6  recursive calls
          2  db block gets
      
23641  consistent gets
          0  physical reads
        228  redo size
        410  bytes sent via SQL*Net to client
        385  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed

      第二個COUNT的SQL是在執行MOVE TABLE後來完成的

SQL> select /*truncate*/count(*) from test1;

  COUNT(*)
----------
         0


Execution Plan
----------------------------------------------------------
Plan hash value: 3896847026

--------------------------------------------------------------------
| Id  | Operation          | Name  | Rows  | Cost (%CPU)| Time     |
--------------------------------------------------------------------
|   0 | SELECT STATEMENT   |       |     1 |     2   (0)| 00:00:01 |
|   1 |  SORT AGGREGATE    |       |     1 |            |          |
|   2 |   TABLE ACCESS FULL| TEST1 |     1 |     2   (0)| 00:00:01 |
--------------------------------------------------------------------

Note
-----
   - dynamic sampling used for this statement


Statistics
----------------------------------------------------------
          1  recursive calls
          0  db block gets
          
4  consistent gets
          0  physical reads
          0  redo size
        410  bytes sent via SQL*Net to client
        385  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed


      第二句要明顯好於第一句。性能上還有有差別的。即TEST1表的HWM是上升的。
      接下來另外一個問題就出現了:如果我可以繼續插入的話,空間佔用會持續增加嗎即HWM會持續增加嗎?如果是的話,這樣導致的性能問題就大了。然後我正常插入了32000條數據,空間佔用沒有變化。為了防止是因為空間限製造成空間佔用不增加,我調大了表空間到600M,結果相同。即空間佔用仍為184M。還好,ORACLE沒有犯錯誤。現在比較兩種情況。
    情況一:在不回縮空間佔用的情況下,執行COUNT(*)
  

SQL> SELECT /*320000*/ COUNT(*) FROM TEST1 WHERE OWNER='SYS';

  COUNT(*)
----------
    140216


Execution Plan
----------------------------------------------------------
Plan hash value: 3896847026

----------------------------------------------------------------------------
| Id  | Operation          | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |       |     1 |    17 |  5144   (1)| 00:01:02 |
|   1 |  SORT AGGREGATE    |       |     1 |    17 |            |          |
|*  2 |   TABLE ACCESS FULL| TEST1 |   158K|  
2628K|  5144   (1)| 00:01:02 |
----------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter("OWNER"='SYS')

Note
-----
   - dynamic sampling used for this statement


Statistics
----------------------------------------------------------
           6  recursive calls
          1  db block gets
       23639  consistent gets
          0  physical reads
         176  redo size

        413  bytes sent via SQL*Net to client
        385  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed
   
      第二種情況,先進行空間收縮,然後進行COUNT查詢。這次使用SHRINK操作,ORACLE沒有報錯。回縮後,TEST1表空間佔用31.8M
  

SQL> SELECT /*shrinked*/ count(*) from test1 where owner='SYS';

  COUNT(*)
----------
    140216


Execution Plan
----------------------------------------------------------
Plan hash value: 3896847026

----------------------------------------------------------------------------
| Id  | Operation          | Name  | Rows  | Bytes | Cost (%CPU)| Time     |
----------------------------------------------------------------------------
|   0 | SELECT STATEMENT   |       |     1 |    17 |   890   (2)| 00:00:11 |
|   1 |  SORT AGGREGATE    |       |     1 |    17 |            |          |
|*  2 |   TABLE ACCESS FULL| TEST1 |   137K|  
2288K|   890   (2)| 00:00:11 |
----------------------------------------------------------------------------

Predicate Information (identified by operation id):
---------------------------------------------------

   2 - filter("OWNER"='SYS')

Note
-----
   - dynamic sampling used for this statement


Statistics
----------------------------------------------------------
          0  recursive calls
          0  db block gets
       4008  consistent gets
          0  physical reads
           0  redo size

        413  bytes sent via SQL*Net to client
        385  bytes received via SQL*Net from client
          2  SQL*Net roundtrips to/from client
          0  sorts (memory)
          0  sorts (disk)
          1  rows processed


      不難發現性能上,第二句還是有非常大的優勢的。
  
      綜上所述
      如果我們在操作(INSERT)某個表,因為空間擴張失敗後,需要認真執行空間的回縮處理。雖然在我們看來,失敗了回滾即可。但是其HWM卻上去後就沒有下來。也許這是ORACLE在並發處理情況下要求快速相應的一種策略。但是也會留下性能憂患的伏筆。週期性的執行空間管理還是非常非常有必要的。
      但是對於ORACLE的SHRINK操作,只有對批量INSERT某個空表而造成空間擴展失敗後的表進行回縮時報ORA-10635錯來看,這應該是個BUG。(因為如果直接對某個空表或有原表中有些數據然後進行INSERT操作造成空間擴展失敗的表執行SHRINK操作都沒有問題)
  
    要多想些,再多想些 -:)

    --------------------系統環境
    OS: REDHAT AS4 U5
    ORACLE:10.2.0.1
   
    歡迎指正。
   
   

原文出處: 表扩展失败(ORA-01653)后的空间管理问题【THE SPACE MANAGEMENT PROBLEM OF THE TABLE EXTEND FAILD 】-Be the miracle!-51CTO博客
內容圖示
url email imgsrc image code quote
樣本
bold italic underline linethrough   












 [詳情...]
validation picture

注意事項:
預覽不需輸入認證碼,僅真正發送文章時才會檢查驗證碼。
認證碼有效期10分鐘,若輸入資料超過10分鐘,請您備份內容後,重新整理本頁並貼回您的內容,再輸入驗證碼送出。

選項

Powered by XOOPS 2.0 © 2001-2008 The XOOPS Project|