Chinaunix首页 | 论坛 | 博客
  • 博客访问: 3693458
  • 博文数量: 715
  • 博客积分: 1860
  • 博客等级: 上尉
  • 技术积分: 7745
  • 用 户 组: 普通用户
  • 注册时间: 2008-04-07 08:51
个人简介

偶尔有空上来看看

文章分类

全部博文(715)

文章存档

2023年(75)

2022年(134)

2021年(238)

2020年(115)

2019年(11)

2018年(9)

2017年(9)

2016年(17)

2015年(7)

2014年(4)

2013年(1)

2012年(11)

2011年(27)

2010年(35)

2009年(11)

2008年(11)

分类: Oracle

2022-09-02 23:14:45

清理数据,需要删除1000万条记录,会产生多少归档日志,是否会撑爆归档空间?

首先看是用什么方法删除
drop table XXX;   可能只有几百K,无需担心

alter table XXX drop partition PPP; 也没多大

delete from XXX where riqi<'2022-03-02';  这个就难说了,粗略的方法是:
1.切换一下归档日志
2.删除一部分,例如1天的(假设数据每日差不多)或者100万条
3.再切换一次归档
4.看此期间的归档文件大小(如果产生多个,需要合计),再等比放大即可。

演示:
创建模拟数据
  1. conn a/a
  2. drop table big;
  3. create table big as select b.*, sysdate riqi from dba_objects b where 1=2;
  4. insert into big select b.*, to_date('2022-08-01','yyyy-mm-dd') riqi from dba_objects b;
  5. insert into big select b.*, to_date('2022-08-02','yyyy-mm-dd') riqi from dba_objects b;
  6. insert into big select b.*, to_date('2022-08-03','yyyy-mm-dd') riqi from dba_objects b;
  7. insert into big select b.*, to_date('2022-08-04','yyyy-mm-dd') riqi from dba_objects b;
  8. insert into big select b.*, to_date('2022-08-05','yyyy-mm-dd') riqi from dba_objects b;
  9. insert into big select b.*, to_date('2022-08-06','yyyy-mm-dd') riqi from dba_objects b;
  10. commit;




记录当前归档日志号,然后删除一部分数据,让oracle自己产生归档
  1. conn /as sysdba
  2. alter system switch logfile;
  3. archive log list;
  4. delete from a.big where riqi=to_date('2022-08-02','yyyy-mm-dd');
  5. commit;
  6. alter system switch logfile;
  7. archive log list;
可见只生成了一个归档(其实就是执行alter system switch logfile 产生出来的),大小是13M,删除7万多条dba_objects 中的记录会产生这么多的归档,如果删除的数据有几百万,那么oracle写满一个redo后,会自动输出到归档日志里,可能看到很多个归档日志,加和即可,然后等比放大就是归档空间的总需求量。

开发人员看到此就可以退出了。

精确计算方法:
  1. set serverout on
  2. declare
  3.   l_redo1 number;
  4.   l_redo2 number;
  5. begin
  6.   select ms.value
  7.     into l_redo1
  8.     from v$statname sn, v$mystat ms
  9.    where sn.STATISTIC# = ms.STATISTIC#
  10.      and lower(sn.name) = 'redo size';
  11.      
  12.   -- YOUR DML/DDL HERE
  13.   execute immediate 'delete from a.big where riqi=to_date(''2022-08-06'',''yyyy-mm-dd'')';
  14.   
  15.   select ms.value
  16.     into l_redo2
  17.     from v$statname sn, v$mystat ms
  18.    where sn.STATISTIC# = ms.STATISTIC#
  19.      and lower(sn.name) = 'redo size';
  20.      
  21.   DBMS_OUTPUT.put_line((l_redo2 - l_redo1) || ' bytes of redo generated');
  22. end;
  23. /

  24. 统计了几天的
  25. -- 11774584 比实际的13M要小一些,应该是归档文件中还记录redo record 和文件头信息,需要占用一部分空间
  26. -- 11711180
  27. -- 11697676
看看归档日志的内容

  1. ALTER SYSTEM DUMP LOGFILE 'FileName'
  2.     SCN MIN MinimumSCN
  3.     SCN MAX MaximumSCN
  4.     TIME MIN MinimumTime
  5.     TIME MAX MaximumTime
  6.     LAYER Layer
  7.     OPCODE Opcode
  8.     DBA MIN FileNumber BlockNumber
  9.     DBA MAX FileNumber BlockNumber
  10.     RBA MIN LogFileSequenceNumber BlockNumber
  11.     RBA MAX LogFileSequenceNumber BlockNumber
  12.     OBJNO ObjectNumber
  13.     XID UndoSegmentNumber UndoSlotNumber UndoSequenceNumber;


  14. 例如:
  15.   ALTER SYSTEM DUMP LOGFILE '/arch/1_4873_1083135550.dbf';
会输出到一个trc文件中,比归档文件要大5倍左右


看看trc文件内容,深入了解archive log 文件包含的信息

头部信息都差不多

接着往下看,输出了文件头信息:数据库ID,库名称,文件大小,thread号,sequence号,scn起止号等


继续往下看

会看到重做记录(REDO RECORD change#1 change #2)信息,本质上,archive log是redo log的副本,记录的是数据库变化,在oracle里被称为redo records,这些recordes由改变向量组成

record产生过程:
1.为undo记录创建改变向量
2.为数据库块创建改变向量
3.合并改变向量,并将构造好的redo记录写入重做日志缓冲区
4.将undo记录插入undo块中
5.真正改变数据库块

详细内容可参考《oracle core》书中第二章描述。

刚才看到生成的归档文件大小是13M,通过redo size统计信息看到的才11M,具体差在哪里呢?
需要了解redo record结构
还有改变向量的结构

可以看到redo block的大小是512或1024字节(select distinct BLOCK_SIZE from v$archived_log;),与传统的块大小8K不一样。头部信息和空闲空间会导致生成的归档文件比redo size大出一些。

继续往下看,会看到执行了delete后,为了恢复,oracle会记录原始的信息col代表字段,第一个53 59 53 是十六进制,转换为字符就是sys,第二个转换一下:

就是dba_objects里的对象名称。
一模一样。

再有个问题:如何减少redo大小?
可考虑的措施如下:
1.消除冗余索引
2.减少更新的列数
3.消除多余的 SELECT FOR UPDATE 语句
4.减少处理的行数
5.消除 COMMIT 语句
6.增加批量大小
7.使用全局临时表
8.使用外部表

参考:
juliandyke.com
阅读(1031) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~