append+nologging关于redo和undo的问题

append+nologging 不会对数据本生生成redo。这点大家都可以理解。但是会生成undo吗?
答案是,对于数据本身也不会。

可是既然不生成undo,那么如何保证数据的一致性,并且为何经过验证仍然可以flashback query or flashback table?
答:只需要将新分配的块重新标记为 可用 即可,所以并不需要undo数据。

那么是否就真的一点undo和redo数据都不生成呢?
答:否,对于数据本生不会生成redo和undo数据,但是对于譬如分配extents,造成的对于数据字典的修改,这些会生成少量的redo和undo。

标签: 暂无标签
kevin.zhang

写了 32 篇文章,拥有财富 308,被 10 人关注

转播转播 分享分享 分享淘帖
回复

使用道具

P4 | 发表于 2010-11-17 20:27:34
只需要将新分配的块重新标记为 可用 即可该如何理解?
回复

使用道具

P4 | 发表于 2010-11-18 09:20:19
本帖最后由 kevin.zhang 于 2010-11-18 09:42 编辑
chenyu 发表于 2010-11-17 20:27
只需要将新分配的块重新标记为 可用 即可该如何理解?


数据库的块结构中,有很多标志位。其中一个标志位标志着这个块是否属于某一个segment。

如果这个标志位标志为可用,就代表不属于任何一个segment,所以可以被分配。如果标志为不可用,就代表已经属于某一个segment了,不允许再被分配给其它segment。

所以,在flashback的时候,因为这些块在append+nolloging之前肯定不属于任何一个segment肯定是标记为可用的,所以上面并不存在任何有效数据。所以flashback时只需要重新将这些块标记为可用即可。所以append+nologging不需要构造这些块的undo块。
回复

使用道具

P4 | 发表于 2010-11-18 20:47:04
我的理解即使是append+nolloging模式,那插入的数据也数属于某一张表的吧,既然属于某一张表,哪么他就应该属于这个段呀
create table scott.testsegment(id number,name varchar2(20)) nologging storage(INITIAL 1 NEXT 1 MINEXTENTS 1 MAXEXTENTS 65536 PCTINCREASE 0);

select owner,segment_name,segment_type,tablespace_name,header_block,bytes/1024/1024 "size(M)",blocks,extents from dba_segments where owner='SCOTT'and segment_name='TESTSEGMENT';
OWNER      SEGMENT_NAME    SEGMENT_TYPE       TABLESPACE HEADER_BLOCK    size(M)     BLOCKS    EXTENTS
---------- --------------- ------------------ ---------- ------------ ---------- ---------- ----------
SCOTT      TESTSEGMENT     TABLE              USERS              1985      .0625          8          1


begin
  for i in 1..10000 loop
    insert /*+ append */ into scott.testsegment values(i,'abc'||i);
  end loop;
  commit;
end;
/

SQL> select owner,segment_name,segment_type,tablespace_name,header_block,bytes/1024/1024 "size(M)",blocks,extents from dba_segments where owner='SCOTT'and segment_name='TESTSEGMENT';

OWNER      SEGMENT_NAME    SEGMENT_TYPE       TABLESPACE HEADER_BLOCK    size(M)     BLOCKS    EXTENTS
---------- --------------- ------------------ ---------- ------------ ---------- ---------- ----------
SCOTT      TESTSEGMENT     TABLE              USERS              1985        .25         32          4

新增加的24个block是属于testsegment表段的,append+nologging增加的数据如果数据增加完成后不备份,那么如果数据库cash则这部分数据是恢复不了的
回复

使用道具

P4 | 发表于 2010-11-18 21:23:17
对的,如果cash,你用以前的备份往后跑日志,是没法恢复append+nologging的数据,因为没有生成对应的redo。
但是这里讨论的是不生成undo的情况。就是,为何在没有undo,仍然能保证一致性,并且可以flashback。就是因为上文所说的哪些。
回复

使用道具

P4 | 发表于 2010-11-18 22:32:43
SQL> select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;

TO_CHAR(SYSDATE,'YY
-------------------
2010-11-18 21:50:37

SQL> begin
  for i in 1..1000 loop
    insert /*+ append */ into scott.testsegment values(i,'abc'||i);
  end loop;
  commit;
end;
/
  2    3    4    5    6    7
PL/SQL procedure successfully completed.

SQL> select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;

TO_CHAR(SYSDATE,'YY
-------------------
2010-11-18 21:51:06

SQL> begin
  for i in 1..1000 loop
    insert /*+ append */ into scott.testsegment values(i,'abc'||i);
  end loop;
  commit;
end;
/
  2    3    4    5    6    7
PL/SQL procedure successfully completed.

SQL> select to_char(sysdate,'yyyy-mm-dd hh24:mi:ss') from dual;

TO_CHAR(SYSDATE,'YY
-------------------
2010-11-18 21:51:19


SQL> flashback database to timestamp to_timestamp('2010-11-18 21:51:06','yyyy-mm-dd hh24:mi:ss');

Flashback complete.

SQL> alter database open resetlogs;

Database altered.

SQL> select count(*) from testsegment;

  COUNT(*)
----------
      1000

从上面的例子来看,flashback确实能够还原appind+logging的数据,我发现日志中有这样的记录
flashback database to timestamp to_timestamp('2010-11-18 21:51:06','yyyy-mm-dd hh24:mi:ss')
Thu Nov 18 22:05:05 2010
Flashback Restore Start
Flashback Restore Complete
Flashback Media Recovery Start  //这里开始闪回恢复,redo log中没有记录,那么是不是闪回日志中记录了呢?
parallel recovery started with 2 processes
Thu Nov 18 22:05:05 2010
Recovery of Online Redo Log: Thread 1 Group 1 Seq 55 Reading mem 0
  Mem# 0 errs 0: /u01/app/oracle/oradata/PROD/disk1/redo01.log
  Mem# 1 errs 0: /u01/app/oracle/oradata/PROD/disk2/redo01.log
Thu Nov 18 22:05:06 2010
Incomplete Recovery applied until change 541057   //不完全恢复到SCN号
Flashback Media Recovery Complete
Completed: flashback database to timestamp to_timestamp('2010-11-18 21:51:06','yyyy-mm-dd hh24:mi:ss')
Thu Nov 18 22:05:16 2010
alter database open resetlogs
Thu Nov 18 22:05:24 2010
RESETLOGS after incomplete recovery UNTIL CHANGE 541057
Resetting resetlogs activation ID 144092061 (0x896ab9d)

回复

使用道具

P4 | 发表于 2010-11-19 09:06:12
本帖最后由 kevin.zhang 于 2010-11-19 09:07 编辑

老陈,我的意思是,append+nologging不会对数据生成redo和undo。但是这没关系,因为闪回append+nologging不需要redo,不需要undo,也不需要闪回日志。
1不需要redo这点可以理解。
2不需要undo是为什么呢?这点首先要了解undo的作用。undo是为了在修改块后保存原本块上的数据以供回滚或者一致性读。可是append+nologging都是在新分配的块上,上面原先也没有数据,所以也不需要生成undo。但是,append+nologging以后,如果又有常规insert等操作在这些块上进行了修改,那时自然需要生成undo。
3不需要闪回日志。这点很好证明。flashback query 与flashback query本来就是依靠undo而不是闪回日志,所以就算闪回数据库没打开仍然可以对表进行闪回。你可以不用flashback database而用flashback table或flashback query进行尝试。
回复

使用道具

P4 | 发表于 2010-11-22 16:20:30
本帖最后由 Quasimodo 于 2010-11-22 16:22 编辑
kevin.zhang 发表于 2010-11-19 09:06
老陈,我的意思是,append+nologging不会对数据生成redo和undo。但是这没关系,因为闪回append+nologging不 ...

kevin.zhang的描述我不是很明白,"因为闪回append+nologging不需要redo,不需要undo,也不需要闪回日志",这里的闪回是指的flashback database,flashback query还是flashback table?
nologging+append做flashback database操作是比较危险的操作,有可能产生逻辑坏块。
而且flashback database真的不需要redo吗?

下面是我做的flashback database操作,结果产生了逻辑坏块
SYS>l
  1  flashback database to timestamp to_timestamp('2010-11-22 16:05:40',
  2* 'yyyy-mm-dd hh24:mi:ss')
SYS>/

Flashback complete.

SYS>alter database open read only;

Database altered.

SYS>conn scott/oracle
Connected.
SCOTT>select count(*) from test;
select count(*) from test
                     *
ERROR at line 1:
ORA-01578: ORACLE data block corrupted (file # 4, block # 1164)
ORA-01110: data file 4: '/u01/oracle/oradata/PROD/users01.dbf'
ORA-26040: Data block was loaded using the NOLOGGING option

评分

参与人数 1金币 +50 收起 理由
guo + 50 升级为注册会员

查看全部评分

回复

使用道具

P4 | 发表于 2010-11-22 21:28:42
flashback database依赖的是flashback log,必须打开数据库的flashback功能才能使用;
flashback query是使用Undo来实现的
flashback table其实是使用了存储空间实现的,被删除的表并没有真正删除,而是被移动到类似回收站的一个空间里,这个空间和普通对象共用表空间的存储区域
都是flashback但是实现的技术确差别很大,但是flashback database应该不会导致坏快的产生,除非在ORACLE生成flashback log前数据块已经corrupted。
回复

使用道具

P4 | 发表于 2010-11-25 16:39:17
都看晕了!
回复

使用道具

您需要登录后才可以回帖 登录 | 加入社区

本版积分规则

意见
反馈