日期:2014-05-16 浏览次数:20528 次
我们有一个实时日志表数据量太大了(这个不是分区表),这个表不能中断业务,我们先要在线删除部分数据。有这个是生产库不能中断业务不能使用create table rename 的方法来搞。我就老老实实的使用rowid批删除的方法。
create or replace procedure delete_table_by_condition(table_name varchar2,
condition varchar2) is
type mycursor_type is ref cursor;
mycursor mycursor_type;
--cursor mycursor is
-- SELECT ROWID FROM table_name WHERE condition order by rowid;
type rowid_table_type is table of rowid index by pls_integer;
v_rowid rowid_table_type;
v_sql_getrowid varchar2(400);
v_sql_del_table varchar2(400);
BEGIN
v_sql_getrowid := 'SELECT ROWID FROM ' || table_name || ' WHERE ' ||
condition || ' order by rowid ';
v_sql_del_table := 'delete from ' || table_name || ' WHERE rowid = :1';
dbms_output.put_line(v_sql_getrowid);
open mycursor for v_sql_getrowid;
loop
fetch mycursor bulk collect--------每次处理5000行,也就是每5000行一提交
into v_rowid limit 5000;
exit when v_rowid.count = 0;
forall i in v_rowid.first .. v_rowid.last
execute immediate v_sql_del_table using v_rowid(i);
commit;
end loop;
close mycursor;
END;declare
JOBNAME varchar2(100) := 'JOB_delete_table';
JOB_CNT int;
begin
select count(*) into JOB_CNT from user_scheduler_jobs uj where upper(uj.JOB_NAME) = upper(JOBNAME);
if JOB_CNT >= 1 then
begin dbms_scheduler.drop_job(job_name => JOBNAME); end;
end if;
end;
/
begin
dbms_scheduler.create_job(job_name => 'JOB_delete_table',
job_type => 'PLSQL_BLOCK',
job_action => 'begin delete_table_by_condition(''ACCESSLOG'',''logtime < to_char(trunc(sysdate-1),''''yyyy-mm-dd hh24:mi:ss'''')'');end;',
repeat_interval => 'FREQ=DAILY;BYHOUR=5;byminute=0',
enabled => true);
end;
/
exec DBMS_SCHEDULER.enable('JOB_delete_table');
SELECT table_name,
ROUND (BLOCKS * 8192 / 1024 / 1024 , 2) "total_size(M)",
ROUND (num_rows * AVG_ROW_LEN / 1024 / 1024 , 2) "used_size(M)",
ROUND ( ( (BLOCKS * 8192 / 1024 / 1024 ) - (num_rows * AVG_ROW_LEN / 1024 / 1024 )), 2) "wasted_size(M)",
ROUND (ROUND ( ( (BLOCKS * 8192 / 1024 / 1024 )- (num_rows * AVG_ROW_LEN / 1024 / 1024 )),2)/
ROUND (BLOCKS * 8192 / 1024 / 1024 , 2),2)* 100|| '%' wasted_percent
FROM user_tables
WHERE ROUND (BLOCKS * 8192 / 1024 / 1024 , 2) <> 0
ORDER BY 2 desc;