1. 在Reorg之前收集table,index,lod的空间占用信息
在做Reorg之前,为了分析方便一般要先拿到相关tables,indexes,clobs所占用的空间大小数据。在这之前需要先分析一下表,因为DB中表的相关信息未必是最新的。
(1)分析表,以更新DB相关视图,保证其中的信息是最新的,例如:DBA_indexes,Dba_tables,中的信息
set serveroutput on
set time on timing on
spool analyze_tables.log
alter session set nls_date_format='ddmmyyyy hh24:mi:ss';
Declare
V_sql varchar2(2000);
JOB_NAME varchar2(24);
v_tableName varchar2(200);
BEGIN
JOB_NAME:= 'JOB1';
Dbms_output.put_line('gather table infor for ' || JOB_NAME || ' start at: '||sysdate);
For v in
(SELECT TABLE_NAME FROM REORG_TABLES WHERE JOBNAME=JOB_NAME)
LOOP
v_tableName:=v.TABLE_NAME;
-- 1. gather table info
Dbms_output.put_line('analyze table:'||v_tableName || ' start at:'||sysdate);
dbms_stats.gather_table_stats(ownname => 'SHAPE',tabname => v_tableName,estimate_percent => 10,method_opt=> 'for all indexed columns',cascade=>TRUE,granularity=>'ALL');
Dbms_output.put_line('analyze table:'||v_tableName || ' complete at:'||sysdate);
END LOOP;
Dbms_output.put_line('gather info for ' || JOB_NAME || ' complete at:'||sysdate);
EXCEPTION
WHEN OTHERS THEN
RAISE_APPLICATION_ERROR(-20001,SQLCODE||SQLERRM);
END;
/
spool off
(2) 获得相关表的Block used status
SELECT segment_name, segment_type, owner, blocks, bytes/1024/1024 as Mb
FROM dba_segments
WHERE segment_name in (SELECT TABLE_NAME FROM REORG_TABLES WHERE JOBNAME='JOB1')
and owner='SHAPE'
ORDER BY segment_name;
(3)获得相关表的实际占用空间大小
SELECT table_name,num_rows,blocks,empty_blocks, (avg_row_len+3)*num_rows/1024/1024 as Mb
FROM all_tables
WHERE table_name in (SELECT TABLE_NAME FROM REORG_TABLES WHERE JOBNAME='JOB1');
(4)获得表上Index的空间占用信息
SELECT t2.table_name, t1.segment_name, t1.segment_type, t1.blocks, t1.bytes/1024/1024 as Mb
FROM dba_segments t1,
(
SELECT INDEX_NAME, TABLE_NAME FROM dba_indexes where table_name in (SELECT TABLE_NAME FROM REORG_TABLES WHERE JOBNAME='JOB1')
) t2
WHERE t1.segment_name = t2.INDEX_NAME
AND t1.owner='SHAPE'
ORDER BY t2.table_name, t1.segment_name;
(5)获得表中的相关clob数据的空间占用信息
set time on timing on
spool shape_info_1.log
select ul.table_name, ul.column_name, ul.segment_name, se.segment_type,
se.owner,se.blocks,se.bytes/1024/1024 as Mb, ul.chunk from dba_lobs ul ,dba_segments se
where ul.segment_name=se.segment_name
and ul.table_name in('CONFIRMATION_ACKS', 'PDF_STORE_IN', 'SHARK_ACTIVITY_LOG', 'MDIS_BATCH_LOG')
and se.OWNER='SHAPE'
order by ul.table_name;
spool off
2. 完成Reorg Job
Declare
V_sql varchar2(2000);
JOB_NAME varchar2(24);
v_tableName varchar2(200);
BEGIN
JOB_NAME:= 'JOB1';
Dbms_output.put_line('reorg for ' || JOB_NAME || ' start at: '||sysdate);
For v in
(SELECT TABLE_NAME FROM REORG_TABLES WHERE JOBNAME=JOB_NAME)
LOOP
v_tableName:=v.TABLE_NAME;
-- 1. reorg table
Dbms_output.put_line('reorg table:'||v_tableName || ' start at:'||sysdate);
V_sql:='Alter table ' || v_tableName || ' move parallel 4';
Execute immediate v_sql;
Dbms_output.put_line('reorg table:'||v_tableName || ' complete at:'||sysdate);
-- 2. reorg clob
Dbms_output.put_line('reorg clobs start at:'||sysdate);
For c in
(SELECT COLUMN_NAME FROM DBA_TAB_COLS WHERE TABLE_NAME=v_tableName AND DATA_TYPE='CLOB' AND OWNER='SHAPE')
LOOP
Dbms_output.put_line('reorg clob:'||c.COLUMN_NAME || ' start at:'||sysdate);
V_sql:='Alter table ' || v_tableName || ' move lob (' || c.COLUMN_NAME || ') store as (tablespace SHAPE_DATA) parallel 4';
Execute immediate v_sql;
Dbms_output.put_line('reorg clob:'||c.COLUMN_NAME || ' complete at:'||sysdate);
END LOOP;
Dbms_output.put_line('reorg clobs complete at:'||sysdate);
END LOOP;
Dbms_output.put_line('reorg for ' || JOB_NAME || ' complete at:'||sysdate);
EXCEPTION
WHEN OTHERS THEN
RAISE_APPLICATION_ERROR(-20001,SQLCODE||SQLERRM);
END;
3. rebuld index。
由于在实际的测试中,当把Rebuild index和reorg放在一起时,rebuild index常常会失败,所以写了独立的script用来rebuild index。
set time on timing on
spool shape_rebuild_indexes.log
alter session set nls_date_format='ddmmyyyy hh24:mi:ss';
Declare
V_sql varchar2(2000);
JOB_NAME varchar2(24);
v_tableName varchar2(200);
BEGIN
JOB_NAME:='JOB1';
Dbms_output.put_line('REBUILD_INDEX_JOB for ' || JOB_NAME || ' start at: '||sysdate);
For v in
(SELECT TABLE_NAME FROM REORG_TABLES WHERE JOBNAME=JOB_NAME)
LOOP
v_tableName:=v.TABLE_NAME;
-- 1. rebuild indexes
Dbms_output.put_line('rebuild indexes start at:'||sysdate);
For x in
(SELECT INDEX_NAME FROM DBA_INDEXES WHERE TABLE_NAME=v_tableName AND INDEX_TYPE='NORMAL' AND OWNER='SHAPE')
LOOP
Dbms_output.put_line('rebuild index:'||x.index_name || ' start at:'||sysdate);
V_sql:='ALTER INDEX '||x.index_name||' nologging';
Execute immediate v_sql;
V_sql:='ALTER INDEX '||x.index_name||' parallel 4';
Execute immediate v_sql;
V_sql:='ALTER INDEX '||x.index_name||' rebuild online';
Execute immediate v_sql;
V_sql:='ALTER INDEX '||x.index_name||' logging';
Execute immediate v_sql;
V_sql:='ALTER INDEX '||x.index_name||' noparallel';
Execute immediate v_sql;
Dbms_output.put_line('rebuild index:'||x.index_name || ' complete at:'||sysdate);
End LOOP;
Dbms_output.put_line('rebuild indexes complete at:'||sysdate);
-- 2. analyze table
Dbms_output.put_line('analyze table:'||v_tableName || ' start at:'||sysdate);
dbms_stats.gather_table_stats(ownname => 'SHAPE',tabname => v_tableName,estimate_percent => 10,method_opt=> 'for all indexed columns',cascade=>TRUE,granularity=>'ALL');
Dbms_output.put_line('analyze table:'||v_tableName || ' complete at:'||sysdate);
END LOOP;
Dbms_output.put_line('REBUILD_INDEX_JOB for ' || JOB_NAME || ' complete at:'||sysdate);
EXCEPTION
WHEN OTHERS THEN
RAISE_APPLICATION_ERROR(-20002,SQLCODE||SQLERRM);
END;
/
spool off
4. 按照1中的步骤,重新分析表并拿到相关空间占用信息。
注意:无论Reorg成功或者失败,都要检查一下是不是所有的Index都VALID的。
select * from user_indexes where status != 'VALID';