首页 | Linux 基础 | 资讯动态 | Linux 应用 | Linux 服务器 | Linux 开发 | Linux 安全 | 专题 | 联盟论坛
  当前位置:主页>Linux 服务器>数据库应用>文章内容
如何在Oracle里用存储过程定期分割表
来源:www.unix5.com 作者:riechelr_hl 发布时间:2007-05-22  
Oracle数据库里存放着各种各样的数据,其中有一些数据表会随着时间的推移,越来越大。如交友聊天的日志、短信收发的日志、生产系统的日志、动态网站发布系统的日志等等。这样的信息又和时间紧密相关,有没有办法让这些日志表能按时间自动分割成历史年月(如 log200308,log200309)的表呢? 请看看我用存储过程定期分割表的方法吧。

  一、问题的引出

  1.初学数据库时只知道用delete来删除表里的数据。但在Oracle数据库里,大量delete记录后,并不能释放表所占用的物理空间,这里面有一个高水位的概念,所以我们不能用delete来分割表。

  2.用重命名(rename)表的方法

  (1) 先建一个和原来日志表(假如是log)数据结构一模一样的新表(如log_new),建约束、索引及指定字段的默认值;

  (2) 重命名表log到log_YYYYMM;

  要注意的问题是OLTP系统可能会因为DML操作阻碍重命名执行成功,出现ORA-00054资源正忙的错误提示,需要试多次才能成功。

  (3) 重命名表log_new到log。

  这样应用程序不用修改(受影响的时间仅几秒钟),日志表就被截断分割了。

  上述步骤可以在Oracle里用存储过程来实现。

  二、用存储过程来分割表

   

  可以看到在重命名表的方法中,步骤(2)是个关键。下面这个rename_table过程会在有锁阻碍的情况下用递归的方式重试100次。

  重命名原始表到目标表的存储过程rename_table:

  create or replace procedure rename_table

  (source_name in varchar2,

  target_name in varchar2,

  times in out number)

  is

  query_str varchar2(4000);

  source_name1 varchar2(64);

  target_name1 varchar2(64);

  cursor c1 is select segment_name from user_segments

  where segment_name=upper(source_name);

  dummy c1%rowtype;

  cursor c2 is select segment_name from user_segments

  where segment_name=upper(target_name);

  dummy2 c2%rowtype;

  begin

  source_name1:=source_name;

  target_name1:=target_name;

  open c1;

  fetch c1 into dummy;

  -- if c1%found then

  -- dbms_output.put_line(source_name1||'exist!');

  -- end if;

  open c2;

  fetch c2 into dummy2;

  -- if c2%notfound then

  -- dbms_output.put_line(target_name1||'not exist!');

  -- end if;

  if c2%notfound and c1%found then

  query_str :='alter table '||source_name1||' rename to '

  ||target_name1;

  execute immediate query_str;

  dbms_output.put_line('rename success!');

  end if;

  close c1;

  close c2;

  exception

  WHEN OTHERS THEN

  times:=times+1;

  if times<100 then

  -- dbms_output.put_line('times:'||times);

  rename_table(source_name1,target_name1,times);

  else

  dbms_output.put_line(SQLERRM);

  dbms_output.put_line('error over 100 times,exit');

  end if;

  end;

  /

  截断分割log表的存储过程log_history:

  create or replace procedure log_history

  is

  query_str varchar2(32767);

  year_month varchar2(8);

  times number;

  begin

  select to_char(sysdate-15,'YYYYMMDD') into year_month from dual;

  times:=0;

  query_str :='create table log_new pctfree 10 pctused 80

  as select * from log where 1=2';

  execute immediate query_str;

  query_str :='alter table log_new add constraints log_'

  ||year_month||'_pk

  primary key (id) tablespace indx nologging pctfree 10';

  execute immediate query_str;

  query_str :='alter table log_his modify logtime default sysdate';

  execute immediate query_str;

  query_str :='create index log_'||year_month||'_logtime on log(logtime)

  tablespace indx nologging pctfree 10';

  execute immediate query_str;

  rename_table('log','log'||year_month,times);

  query_str :='alter table log_new rename to log';

  execute immediate query_str;

  end;

  /

  当然您工作环境的日志表可能和我这个做例子的日志表结构上有所不同,约束条件、索引和默认值都不尽相同。只要稍加修改就可以了。

  三、用户需要有create any table系统权限(不是角色里包含的权限)

  因为在执行存储过程时,由角色赋予的权限会失效, 所以执行log_history的用户一定要有DBA单独赋予的create any table系统权限。

  最后在OS里定时每月一号凌晨0:00分执行log_history,让存储过程定期分割表。

  如果要分割的日志表很多,模仿log_history可以写很多类似的存储过程来分割不同项目里的日志表。然后让OS按月,按周或者不定期的执行这些存储过程, 管理员只要查看日志就可以了。

  四、其它注意事项

  如果应用程序有BUG,可能对在用原始日志表产生长期不能释放的锁,执行log_history重命名会不成功。

  这时DBA可以查看数据字典:

  select object_id,session_id,locked_mode from v$locked_object;

  select t2.username,t2.sid,t2.serial#,t2.logon_time

  from v$locked_object t1,v$session t2


共2页: 上一页 1 [2] 下一页
 
如果您对本文有任何疑问或者建议,请到论坛讨论区发表您的意见: >> 论坛入口
[收藏] [推荐] [评论(0条)] [返回顶部] [打印本页] [关闭窗口]  
  热点文章
·在Linux x86上安装Oracle数据库1
·Linux系统下的Oracle数据库编程
·Linux下免费数据库PostgreSQL开
·如何在你的Linux机器上安装运行O
·Oracle开发应用
·PostgreSQL的热备和恢复
·Heartbeat_2.0.3配置MySQL5.0.18
·编制一个Mysql数据库自动备份脚
·mysql 优化参数(十项)详解设置
·MySQL数据库系统的常规管理介绍
·新手入门--全面介绍MySQL的基础
·让PHP网站运转如飞 MySQL 的优化
  相关文章
·关于MySQL数据库的存储引擎详细
·如何在你的Linux机器上安装运行O
·ORACLE数据库的启动和关闭
·Oracle数据库的备份与恢复
·Oracle数据库的备份及恢复策略研
·MySQL数据库中mysqldump命令使用
·简介Mysql中的临时表使用方法
·MySQL和SQL Server,到底选择谁?
·MySQL数据库引擎快速指导
·Apache2+php4.3.6+MySQL4.0.20+S
·让PHP网站运转如飞 MySQL 的优化
·新手入门--全面介绍MySQL的基础

本站信息源至:互联网络,均为学习,交流所用,如有版权问题,请联系我们.
站长QQ:397422079 E_mail:riechelr_hl@unix5.com
转载本站内容请注明原作者名.谢谢!