1、什麼是高水線(High Water Mark)?數據庫
Oracle 數據庫在建立一張表時,會爲這張表分配一個段空間(segment),爲了方便理解,把段空間容納數據的上限,稱之爲高水位線(HIGH WATER MARK) HWM ,HWM是一個標記,用來講明表示有多少未使用的塊分配給這個段。
兩個結論:
1.水位線以上表示已經分配但還未使用塊(block),水位先如下愛表示已經分配且已經使用過的塊(包含了正在使用的塊和使用過的且被刪除了數據的空塊)
2.理論上來講,一張表的水位線只會增大不會減少(除非經過特殊的方法重置),即便將表中的數據所有刪除,HWM仍是爲原值。oracle
2、HWM數據庫的操做有以下影響:app
a) 全表掃描一般要讀出直到HWM標記的全部的屬於該表數據庫塊,即便該表中沒有任何數據。spa
b) 即便HWM如下有空閒的數據庫塊,鍵入在插入數據時使用了append關鍵字,HWM也會不斷增大,佔用系統資源,表所佔的實際空間會不斷增大,致使系統出現問題索引
3、高水位線緣由以及解決方法:資源
產生緣由:
1.操做表時使用刪除了大量數據。
2.在插入時使用了/append nologging/語句,append關鍵字會從爲表分配段中的隨機位置插入,水位線會不斷增高。
3.Sql load 時默認使用truncate 自帶了reuse storage參數,致使truncate之後水位線不會下降。同步
解決方法:
1.直接truncate table drop storage
2.創建一張維護表按期move並重建索引或者shrink space。
3.表數據落表時按照日期創建了備份表,保留必定天數數據
4.Rename表名,重建表,重建索引,將數據導入重建表,drop原表,而後rename重建表爲原表
5.使用alter table 表名 shrink space(oracle10新增功能)
6.在線表重定義(功能強大,操做複雜,通常不使用,能夠改變表的結構)
表重建的兩個方法move與shrink的對比:
move是oracle8出現的命令,使用時會建立一塊和原來表空間相同大小的另外一塊表空間,而後進行數據的複製,完成後使用後表替換原表,解決hwm的問題。
缺點:操做時鎖表,索引會失效。
shrink是oracle10新增功能,使用時不會開闢新的表空間,操做分爲兩步,第一步整理數據,第二步下降水位線,進行第一步時,能夠在線進行操做。能夠再業務不繁忙的時候進行第二步操做。
缺點:相比move速度比較緩慢。
shrink的詳細操做步驟:
詳細收縮步驟it
全表收縮
無論分區表仍是非分區表,收縮均可以表級別進行,具體語句以下:
ALTER TABLE owner.table_name ENABLE ROW MOVEMENT;(開啓行移動會使遊標失效,需謹慎)
ALTER TABLE owner.table_name SHRINK SPACE COMPACT CASCADE(第一步整理數據,並不會下降高水位線,能夠在線進行操做);
ALTER TABLE owner.table_name SHRINK SPACE CASCADE(第二步分析重置高水位線,會短暫鎖表須要在業務量小的時候進行操做);io
單個分區收縮
分區表的收縮還能夠分區級別進行,具體語句以下:
ALTER TABLE owner.table_name ENABLE ROW MOVEMENT;
ALTER TABLE owner.table_name MODIFY PARTITION partition_name SHRINK SPACE COMPACT CASCADE;
ALTER TABLE owner.table_name MODIFY PARTITION partition_name SHRINK SPACE CASCADE;
ALTER INDEX owner.index_name MODIFY PARTITION partition_name SHRINK SPACE COMPACT CASCADE;
ALTER INDEX owner.index_name MODIFY PARTITION partition_name SHRINK SPACE CASCADE;table
4、在線表重定義步驟:
一、確認表是否能夠作在線重定義:
BEGIN
DBMS_REDEFINITION.CAN_REDEF_TABLE(
uname => 'OWNER',
tname => 'ORIGTABLENAME',
options_flag => dbms_redefinition.cons_use_pk);
END;
/
--若是有主鍵則是options_flag => DBMS_REDEFINITION.cons_use_pk,若是沒有DBMS_REDEFINITION.cons_use_rowid
二、建立新的中間表TABLENAME_TMP準備重定義 (能夠新增刪除字段、能夠修改表存儲參數、能夠修改成分區表等須要的操做)
注意由於在線重定義過程當中要求列的屬性要相同,所以不可以使用dbms_redefinition完成列類型的調整
--普通表
CREATE TABLE OWNER.TABLENAME_TMP ( ) TABLESPACE XXX;
--分區表
CREATE TABLE OWNER.TABLENAME_TMP ( )
PARTITION BY RANGE (PARTITIONNAME)
(
PARTITION P1 VALUES LESS THAN ('xxx'),
...
PARTITION PMAX VALUES LESS THAN (MAXVALUE)
)
TABLESPACE XXX;
三、開啓並行提升在線重定義速度:
ALTER SESSION FORCE PARALLEL DML PARALLEL 2;
ALTER SESSION FORCE PARALLEL QUERY PARALLEL 2;
四、開始在線重定義:
BEGIN
dbms_redefinition.start_redef_table(
uname => 'OWNER',
orig_table => 'ORIGTABLENAME',
int_table => 'TABLENAME_TMP',
options_flag => dbms_redefinition.cons_use_pk);
END;
/
--若是有主鍵則是options_flag => DBMS_REDEFINITION.cons_use_pk,若是沒有DBMS_REDEFINITION.cons_use_rowid
五、使用COPY_TABLE_DEPENDENTS把原始表的權限、約束、索引等在中間表上建立一份
DECLARE
num_errors PLS_INTEGER;
BEGIN
dbms_redefinition.copy_table_dependents(
uname => 'OWNER',
orig_table => 'ORIGTABLENAME',
int_table => 'TABLENAME_TMP',
copy_indexes => dbms_redefinition.cons_orig_params,
copy_triggers => true,
copy_constraints => true,
copy_privileges => true,
ignore_errors => false,
num_errors => num_errors,
copy_statistics => true);
END;
/
六、假如在線重定義要好久,這期間應用往源表插入數據,中間表並不會有這條數據,使用sync_interim_table包同步在線重定義期間源表全部的DML的數據:
BEGIN
dbms_redefinition.sync_interim_table(
uname => 'OWNER',
orig_table => 'ORIGTABLENAME',
int_table => 'TABLENAME_TMP');
END;
/
七、完成在線重定義:
BEGIN
DBMS_REDEFINITION.FINISH_REDEF_TABLE(
uname => 'OWNER',
orig_table => 'ORIGTABLENAME',
int_table => 'TABLENAME_TMP');
END;
/
九、中間重定義報錯時須要執行如下命令終止重定義:
*BEGIN
*DBMS_REDEFINITION.ABORT_REDEF_TABLE(
*uname => 'OWNER',
*orig_table => 'ORIGTABLENAME',
*int_table => 'TABLENAME_TMP');
*END;
*/
十、肯定數據索引等同步成功後,刪除中間表: drop table OWNER.TABLENAME_TMP;