在ORACLE里用存储过程定期分割表 电脑资料_第1页
在ORACLE里用存储过程定期分割表 电脑资料_第2页
在ORACLE里用存储过程定期分割表 电脑资料_第3页
在ORACLE里用存储过程定期分割表 电脑资料_第4页
在ORACLE里用存储过程定期分割表 电脑资料_第5页
已阅读5页,还剩7页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

在ORACLE里用存储过程定期分割表 电脑资料 Oracle数据库里存放着各种各样的数据,其中有一些数据表会随着时间的推移,越来越大, 一、问题的引出 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 suess!); end if; close c1; close c2; exception WHEN OTHERS THEN times:=times+1; if times - 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,YYYYMM) 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 where t1.session_id=t2.sid order by t2.logon_time; 如果有长期出现的一模一样的列(包括时间),可能是没有释放的锁。 我们要在执行分割日志表的存储过程前,用下面S

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论