分區表部分分區不可用導致統計信息收集失效 – JAVA編程語言程序開發技術文章

一個客戶碰到的具體需求,分區表中有些分區所在的表空間被OFFLINE,tb導致在刪除統計信息時報錯。

 

 

下面通過例子來說明這個問題:

SQL> create table t_part_read (id number)
2 partition by range (id)
3 (partition p1 values less than (10) tablespace ts1,
4 partition p2 values less than (20) tablespace ts2,
5 partition pmax values less than (maxvalue) tablespace users);

Table created.www.aiwalls.com

SQL> insert into t_part_read select rownum from tab;

54 rows created.

SQL> commit;

Commit complete.

SQL> exec dbms_stats.gather_table_stats(user, 'T_PART_READ')

PL/SQL procedure successfully completed.

SQL> alter tablespace ts1 read only;

Tablespace altered.

SQL> exec dbms_stats.gather_table_stats(user, 'T_PART_READ')

PL/SQL procedure successfully completed.

SQL> alter tablespace ts1 offline;

Tablespace altered.

SQL> exec dbms_stats.gather_table_stats(user, 'T_PART_READ')
BEGIN dbms_stats.gather_table_stats(user, 'T_PART_READ'); END;

*
ERROR at line 1:
ORA-00376: file 6 cannot be read at this time
ORA-01110: data file 6: '/u01/app/oracle/oradata/ORCL/datafile/o1_mf_ts1_7w8l5fz1_.dbf'
ORA-06512: at "SYS.DBMS_STATS", line 23829
ORA-06512: at "SYS.DBMS_STATS", line 23880
ORA-06512: at line 1

如果將表空間隻讀,並不會影響到表空間上的表或分區的統計信息的收集,因為收集過程隻是讀取,而收集的結果信息是寫到SYSTEM表空間的。

但是如果分區所在的表空間處於OFFLINE狀態,那麼在統計信息收集的過程中就會報錯。

有一個很簡單的方法可以解決這個問題,就是將被OFFLINE影響的分區的統計信息鎖定,這樣Oracle在收集統計信息時就會跳過鎖定的分區,通過這個辦法就可以避免統計信息收集過程中的報錯:

SQL> exec dbms_stats.lock_partition_stats(user, 'T_PART_READ', 'P1')

PL/SQL procedure successfully completed.

SQL> exec dbms_stats.gather_table_stats(user, 'T_PART_READ')
BEGIN dbms_stats.gather_table_stats(user, 'T_PART_READ'); END;

*
ERROR at line 1:
ORA-00376: file 6 cannot be read at this time
ORA-01110: data file 6: '/u01/app/oracle/oradata/ORCL/datafile/o1_mf_ts1_7w8l5fz1_.dbf'
ORA-06512: at "SYS.DBMS_STATS", line 23829
ORA-06512: at "SYS.DBMS_STATS", line 23880
ORA-06512: at line 1

SQL> exec dbms_stats.gather_table_stats(user, 'T_PART_READ', granularity => 'PARTITION')

PL/SQL procedure successfully completed.

即使鎖定分區後,嘗試收集統計信息仍然報錯,這是因為Oracle默認除瞭要收集分區上的統計信息以外,還要收集表級的統計信息,而這就會造成被OFFLINE影響的分區也要被讀取。

解決方法就是在收集統計信息的時候指定收集的粒度是分區,不收集表上的GLOBAL信息。

發佈留言