程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 數據庫知識 >> Oracle數據庫 >> Oracle數據庫基礎 >> Row Movement對系統的影響

Row Movement對系統的影響

編輯:Oracle數據庫基礎
【IT168 技術文檔】 ROW MOVEMENT特性最初是在8i時引入的,其目的是提高分區表的靈活性——允許更新Partition Key。這一特性默認是關閉,只是在使用到一些特殊功能時會要求打開。除了之前提到的更新Partition Key,還有2個要求打開的ROW MOVEMENT的功能就是flushback table和Shrink Segment。所以,只有當使用到以上3個功能特性時,ROW MOVEMENT才會真正起作用。我們如果需要知道ROW MOVEMENT會對系統產生什麼影響,就只要看這3個功能使用時會產生什麼影響。

  Flashback Table

  先看Flashback Table。這一功能能幫助我們及時回滾一些誤操作,防止數據意外丟失。在使用該功能之前,必須先打開ROW MOVEMENT,否則就會拋ORA-08189錯誤。我們看以下例子,可以說明在使用Flashback Table功能時,ROW MOVEMENT產生了什麼作用:

  SQL代碼 

SQL> create table test_move as select * from dba_users;

  Table created.

  SQL> select username, rowid from test_move;

  USERNAME ROWID

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

  DMP AAAwSfAAFAAAVlMAAA

  MYTBC AAAwSfAAFAAAVlMAAB

  CS2 AAAwSfAAFAAAVlMAAC

  TBC AAAwSfAAFAAAVlMAAD

  WOW AAAwSfAAFAAAVlMAAE

  REPO AAAwSfAAFAAAVlMAAF

  ... ...

  SYSTEM AAAwSfAAFAAAVlMAAk

  OUTLN AAAwSfAAFAAAVlMAAl

  38 rows selected.

  SQL> delete from test_move where username = 'MYTBC';

  1 row deleted.

  SQL> commit;

  Commit complete.

  SQL> Flashback table test_move to timestamp(systimestamp - interval '3' minute);

  Flashback table test_move to timestamp(systimestamp - interval '3' minute)

  *

  ERROR at line 1:

  ORA-08189: cannot Flashback the table because row movement is not enabled

  此時,由於ROW MOVEMENT還未打開,命令出錯。繼續完成演示:

  SQL代碼  

SQL> alter table test_move enable row movement;

  Table altered.

  SQL> Flashback table test_move to timestamp(systimestamp - interval '3' minute);

  Flashback complete.

  SQL> select username, rowid from test_move;

  USERNAME ROWID

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

  DMP AAAwSfAAFAAAVlMAAB

  MYTBC AAAwSfAAFAAAVlMAAm

  CS2 AAAwSfAAFAAAVlMAAn

  TBC AAAwSfAAFAAAVlMAAo

  WOW AAAwSfAAFAAAVlMAAp

  REPO AAAwSfAAFAAAVlMAAq

  ... ...

  SYSTEM AAAwSfAAFAAAVlMABJ

  OUTLN AAAwSfAAFAAAVlMABK

  38 rows selected.

  當開啟ROW MOVEMENT後,表被順利的flashback了,數據被找回。此時,再比較flashback前後記錄的ROWID,大多數記錄的物理位置都變化。這個過程的內部操作, 可以通過對Flashback Table做SQL Trace來進一步觀察。通過Trace,我們不難發現,Flashback Table實際是通過Flashback Query將表中數據進行了一次刪除、插入操作,因此ROWID會發生變化。

Shrink Segment

  Shrink Segment能幫助我們壓縮數據段、整理數據碎片、降低高水位,以提高性能、節省空間。它也同樣要求開啟ROW MOVEMENT。

  SQL代碼

SQL> select username, rowid from test_move;

  USERNAME ROWID

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

  DMP AAAwShAAFAAAVlQAAA

  MYTBC AAAwShAAFAAAVlQAAB

  CS2 AAAwShAAFAAAVlQAAC

  TBC AAAwShAAFAAAVlQAAD

  WOW AAAwShAAFAAAVlQAAE

  REPO AAAwShAAFAAAVlQAAF

  ... ...

  SYSTEM AAAwShAAFAAAVlQAAk

  OUTLN AAAwShAAFAAAVlQAAl

  38 rows selected.

  SQL> delete from test_move where username = 'MYTBC';

  1 row deleted.

  SQL> commit;

  Commit complete.

  SQL> alter table test_move disable row movement;

  Table altered.

  SQL> alter table test_move shrink space;

  alter table test_move shrink space

  *

  ERROR at line 1:

  ORA-10636: ROW MOVEMENT is not enabled

  SQL> alter table test_move enable row movement;

  Table altered.

  SQL> alter table test_move shrink space;

  Table altered.

  SQL> select username, rowid from test_move;

  USERNAME ROWID

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

  DMP AAAwShAAFAAAVlMAAA

  CS2 AAAwShAAFAAAVlMAAB

  TBC AAAwShAAFAAAVlMAAC

  WOW AAAwShAAFAAAVlMAAD

  REPO AAAwShAAFAAAVlMAAE

  ... ...

  SYSTEM AAAwShAAFAAAVlMAAj

  OUTLN AAAwShAAFAAAVlMAAk

  37 rows selected.

  SQL>

  同樣,我們可以看到在Shrink後,ROWID也變化了。從對其過程的Trace來看,Shrink對數據的改變不是通過SQL實現的,而是通過更底層的函數來實現的。

  從以上分析來看,在執行上面2種操作操作後,其最大影響就是數據的ROWID會發生變化。因此,他們對我們系統的影響就僅限於那些依賴於ROWID編寫的應用。例如,一個程序需要對大量數據進行處理,為了提高效率和控制進度,我們的代碼會先將需要處理的數據記錄的ROWID取出放入臨時表中,然後再根據ROWID對數據進行分批進行處理。當ROWID被取出後,如果對表進行了上述操作,就可能會導致後依賴ROWID進行的操作發生錯誤。但是,這兩種操作都屬於維護性操作,第一種操作發生的機會非常少,從整體看,我們基本可以忽視這一操作對應用的影響;第二種操作也很少發生,並且可以在應用offline的時間進行操作,因此它的影響也是有限的。

  更新Partition Key

  在更新記錄中的Partition Key時,可能會導致該記錄超出當前所在分區的范圍,需要將其轉移到其他對應分區上,因此要求開啟ROW MOVEMENT。

  SQL代碼

SQL> drop table test_move;

  Table dropped.

  SQL> create table test_move

  2 partition by list (owner)

  3 (partition p1 values ('SYS'),

  4 partition p2 values ('DEMO'),

  5 partition p3 values ('SYSTEM'),

  6 partition def values (default))

  7 as select * from dba_tables;

  Table created.

  SQL> update test_move set owner='SYS' where owner='DEMO' and table_name='T_TEST';

  update test_move set owner='SYS' where owner='DEMO' and table_name='T_TEST'

  *

  ERROR at line 1:

  ORA-14402: updating partition key column would cause a partition change

  SQL> alter table test_move enable row movement;

  Table altered.

  SQL> update test_move set owner='SYS' where owner='DEMO' and table_name='T_TEST';

  1 row updated.

  這一操作產生影響的特殊之處在於這是個DML操作,是和online transaction密切相關。對於這樣一個UPDATE,實際上分為3步:先從原有分區將數據刪除;將原數據轉移到新分區上;更新數據。其影響就在於以下幾個方面:

  一個UPDATE被分解為DELET、INSERT、UPDATE三個操作,增加了性能負擔。其中,DELETE的查詢條件與原UPDATE的查詢條件相同,新的UPDATE的查詢條件是基於INSERT生成的新的ROWID;

  相應的Redo Log、Undo Log會增加;

  如果Update語句還涉及到了Local Index的字段的話,新、舊2個分區上的Local Index都要被更新。

  結論

  目前,ROW Movement真正會其作用(ROWID變化)只是在上述3種情況下,因此,需要分析其對系統會產生多大影響,就要分析上述三種操作在你的系統中出現的頻率、以及是否有應用程序依賴與ROWID實現。對於前面兩種,之前說過,它們發生的概率並不高,我個人認為基本上可以忽略它們對系統的影響。而對於最後一種,需要從應用角度進行分析——Partition Key被更新的頻率有多高?如果可能,最好實施一次等量負載下更細Partition Key的壓力測試,通過對比分區和非分區下其產生的性能統計數據做比較,其帶來的性能負載及Waits量與分區所獲取的查詢性能的提高相比,哪一種方式更有助於系統和應用的性能提高。

  此外,有一點希望不要產生誤解,開啟ROW Movement並不會導致發生Row Migration時修改記錄的Rowid。

  還有一點,Row Movement會和域索引(Domain Index)產生沖突:如果表上定義了域索引,開啟Row Movement就會失敗;反之亦然。

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved