查看: 47350|回复: 64

[精华] Nologging到底何时才能生效?

[复制链接]
论坛徽章:
117
ITPUB元老
日期:2005-02-28 12:57:002012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:20版主7段
日期:2012-05-15 15:24:11ITPUB 11周年纪念徽章
日期:2012-09-28 17:34:42ITPUB 11周年纪念徽章
日期:2012-10-09 18:03:32紫蛋头
日期:2013-03-04 17:00:07优秀写手
日期:2013-12-18 09:29:09
发表于 2004-7-13 22:54 | 显示全部楼层 |阅读模式
最初的问题是这个帖子:

http://www.itpub.net/showthread.php?threadid=239905

请大家仔细看那些测试的例子.

看了Tom的解释,始终觉得牵强.
开始以为可能是bug
经过观察和测试,终于发现了Nologging的秘密
论坛徽章:
117
ITPUB元老
日期:2005-02-28 12:57:002012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:20版主7段
日期:2012-05-15 15:24:11ITPUB 11周年纪念徽章
日期:2012-09-28 17:34:42ITPUB 11周年纪念徽章
日期:2012-10-09 18:03:32紫蛋头
日期:2013-03-04 17:00:07优秀写手
日期:2013-12-18 09:29:09
 楼主| 发表于 2004-7-13 22:57 | 显示全部楼层
我们知道,Nologging只在很少情况下生效
通常,DML操作总是要生成redo的

这个我们不多说.

我们来看一下测试:

1.Nologging跟数据库的运行模式有关

a.数据库运行在非归档模式下:

[php]
SQL> archive log list;
Database log mode              No Archive Mode
Automatic archival             Enabled
Archive destination            /opt/oracle/oradata/hsjf/archive
Oldest online log sequence     155
Current log sequence           157

SQL> @redo
SQL> create table test as select * from dba_objects where 1=0;

Table created.

SQL> select * from redo_size;

     VALUE
----------
     63392

SQL>
SQL> insert into test select * from dba_objects;

10470 rows created.

SQL> select * from redo_size;

     VALUE
----------
   1150988

SQL>
SQL> insert /*+ append */ into test select * from dba_objects;

10470 rows created.

SQL> select * from redo_size;

     VALUE
----------
   1152368

SQL> select (1152368 -1150988) redo_append,(1150988 -63392) redo from dual;

REDO_APPEND       REDO
----------- ----------
       1380    1087596

SQL> drop table test;

Table dropped.

.
[/php]

我们看到在Noarchivelog模式下,对于常规表的insert append只产生少量redo

使用道具 举报

回复
论坛徽章:
117
ITPUB元老
日期:2005-02-28 12:57:002012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:20版主7段
日期:2012-05-15 15:24:11ITPUB 11周年纪念徽章
日期:2012-09-28 17:34:42ITPUB 11周年纪念徽章
日期:2012-10-09 18:03:32紫蛋头
日期:2013-03-04 17:00:07优秀写手
日期:2013-12-18 09:29:09
 楼主| 发表于 2004-7-13 22:58 | 显示全部楼层
b.在归档模式下

[php]
SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup mount
ORACLE instance started.

Total System Global Area  235999908 bytes
Fixed Size                   451236 bytes
Variable Size             201326592 bytes
Database Buffers           33554432 bytes
Redo Buffers                 667648 bytes
Database mounted.

SQL> alter database archivelog;

Database altered.

SQL> alter database open;

Database altered.

SQL> @redo
SQL> create table test as select * from dba_objects where 1=0;

Table created.

SQL> select * from redo_size;

     VALUE
----------
     56288

SQL>
SQL> insert into test select * from dba_objects;

10470 rows created.

SQL> select * from redo_size;

     VALUE
----------
   1143948

SQL>
SQL> insert /*+ append */ into test select * from dba_objects;

10470 rows created.

SQL> select * from redo_size;

     VALUE
----------
   2227712

SQL> select (2227712 -1143948) redo_append,(1143948 -56288) redo from dual;

REDO_APPEND       REDO
----------- ----------
    1083764    1087660

SQL> drop table test;

Table dropped.

[/php]

我们看到在归档模式下,对于常规表的insert append产生和insert同样的redo
此时的insert append实际上并不会有性能提高.
但是此时的append是生效了的

通过Logmnr分析日志得到以下结果:

[php]
SQL> select operation,count(*)
  2  from v$logmnr_contents
  3  group by operation;

OPERATION                          COUNT(*)
-------------------------------- ----------
COMMIT                                   17
DIRECT INSERT                      10470   
INTERNAL                                49
START                                      17
                                                  1

.
[/php]
                                          
我们注意到这里是DIRECT INSERT,而且是10470条记录,也就是每条记录都记录了redo.

使用道具 举报

回复
论坛徽章:
117
ITPUB元老
日期:2005-02-28 12:57:002012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:20版主7段
日期:2012-05-15 15:24:11ITPUB 11周年纪念徽章
日期:2012-09-28 17:34:42ITPUB 11周年纪念徽章
日期:2012-10-09 18:03:32紫蛋头
日期:2013-03-04 17:00:07优秀写手
日期:2013-12-18 09:29:09
 楼主| 发表于 2004-7-13 23:00 | 显示全部楼层
2.对于Nologging的table的处理

a. 在归档模式下:

[php]
SQL> create table test nologging as select * from dba_objects where 1=0;

Table created.

SQL> select * from redo_size;

     VALUE
----------
   2270284

SQL>
SQL> insert into test select * from dba_objects;

10470 rows created.

SQL> select * from redo_size;

     VALUE
----------
   3357644

SQL>
SQL> insert /*+ append */ into test select * from dba_objects;

10470 rows created.

SQL> select * from redo_size;

     VALUE
----------
   3359024

SQL> select (3359024 -3357644) redo_append,(3357644 - 2270284) redo from dual;

REDO_APPEND       REDO
----------- ----------
       1380    1087360

SQL> drop table test;

Table dropped.

[/php]
我们注意到,只有append才能减少redo

使用道具 举报

回复
论坛徽章:
117
ITPUB元老
日期:2005-02-28 12:57:002012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:20版主7段
日期:2012-05-15 15:24:11ITPUB 11周年纪念徽章
日期:2012-09-28 17:34:42ITPUB 11周年纪念徽章
日期:2012-10-09 18:03:32紫蛋头
日期:2013-03-04 17:00:07优秀写手
日期:2013-12-18 09:29:09
 楼主| 发表于 2004-7-13 23:01 | 显示全部楼层
b.在非归档模式下:

[php]

SQL> shutdown immediate
Database closed.
Database dismounted.
ORACLE instance shut down.
SQL> startup mount
ORACLE instance started.

Total System Global Area  235999908 bytes
Fixed Size                   451236 bytes
Variable Size             201326592 bytes
Database Buffers           33554432 bytes
Redo Buffers                 667648 bytes
Database mounted.
SQL> alter database noarchivelog;

Database altered.

SQL> alter database open;

Database altered.

SQL> @redo
SQL> create table test nologging as select * from dba_objects where 1=0;

Table created.

SQL> select * from redo_size;

     VALUE
----------
     56580

SQL>
SQL> insert into test select * from dba_objects;

10470 rows created.

SQL> select * from redo_size;

     VALUE
----------
   1144148

SQL>
SQL> insert /*+ append */ into test select * from dba_objects;

10470 rows created.

SQL> select * from redo_size;

     VALUE
----------
   1145528

SQL> select (1145528 -1144148) redo_append,(1144148 -56580) redo from dual;

REDO_APPEND       REDO
----------- ----------
       1380    1087568

SQL>                                          

[/php]
同样只有append才能减少redo的生成.

这就是通常大家认识的情况.

使用道具 举报

回复
论坛徽章:
117
ITPUB元老
日期:2005-02-28 12:57:002012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:20版主7段
日期:2012-05-15 15:24:11ITPUB 11周年纪念徽章
日期:2012-09-28 17:34:42ITPUB 11周年纪念徽章
日期:2012-10-09 18:03:32紫蛋头
日期:2013-03-04 17:00:07优秀写手
日期:2013-12-18 09:29:09
 楼主| 发表于 2004-7-13 23:08 | 显示全部楼层
biti给出过测试,说明在append模式下不会对数据产生undo

也就是说
在Noarchivelog模式下的append操作将是性能最高的.
等价于对Nologging表的append insert操作

大家可以在你的环境里做个测试,来验证一下这个结果.

使用道具 举报

回复
论坛徽章:
3
数据库板块每日发贴之星
日期:2005-10-19 01:01:30管理团队2006纪念徽章
日期:2006-04-16 22:44:45会员2006贡献徽章
日期:2006-04-17 13:46:34
发表于 2004-7-14 01:28 | 显示全部楼层
最初由 eygle 发布
[B]

在Noarchivelog模式下的append操作将是性能最高的.
等价于对Nologging表的append insert操作

[/B]


谢谢eygle的辛勤劳动,这个应该是正解了

[B]
biti给出过测试,说明在append模式下不会对数据产生undo
[/B]


这个帖子,以前我看过的。我认为append insert下只是undo要比insert下的少,但并不是完全没有undo 产生的。

[php]
SQL> select * from v$version;

BANNER
----------------------------------------------------------------
Oracle9i Enterprise Edition Release 9.2.0.1.0 - Production
PL/SQL Release 9.2.0.1.0 - Production
CORE    9.2.0.1.0       Production
TNS for 32-bit Windows: Version 9.2.0.1.0 - Production
NLSRTL Version 9.2.0.1.0 - Production

SQL> create table test as select * from all_objects where 1=2;

SQL> select usn,writes from v$rollstat;

       USN     WRITES
---------- ----------
         0       6900
         1     101874
         2      23752
         3      50500
         4      51000
         5      49180
         6      35260
         7      23692
         8      23514
         9      22698
        10      34620

已选择11行。

SQL> insert /*+ append */into test select * from all_objects;

已创建28950行。  

SQL> select XIDUSN from v$transaction;

    XIDUSN
----------
         5

SQL> commit;

提交完成。

SQL> select usn,writes from v$rollstat;

       USN     WRITES
---------- ----------
         0       6900
         1     104666
         2      25790
         3      53322
         4      53038
         5      77560
         6      37590
         7      26236
         8      25446
         9      25302
        10      36552      
        
SQL> select 77560-49180 from dual;

77560-49180
-----------
      28380   
      
SQL> insert into test select * from all_objects;

已创建28950行。

SQL> select XIDUSN from v$transaction;

    XIDUSN
----------
         8

SQL> commit;

提交完成。

SQL> select usn,writes from v$rollstat;

       USN     WRITES
---------- ----------
         0       6900
         1     109738
         2      30594
         3      58640
         4      57998
         5      82520
         6      42998
         7      31154
         8     169818
         9      30344
        10      41848

已选择11行。

SQL> select 169818-25446 from dual;

169818-25446
------------
      144372

'
[/php]

使用道具 举报

回复
论坛徽章:
8
授权会员
日期:2005-10-30 17:05:33会员2006贡献徽章
日期:2006-04-17 13:46:34会员2007贡献徽章
日期:2007-09-26 18:42:102011新春纪念徽章
日期:2011-02-18 11:42:49ITPUB 11周年纪念徽章
日期:2012-10-09 18:03:32兰博基尼
日期:2014-01-31 14:56:26优秀写手
日期:2015-01-08 06:00:14优秀写手
日期:2015-02-12 06:00:15
发表于 2004-7-14 09:05 | 显示全部楼层
收藏了。

使用道具 举报

回复
论坛徽章:
86
ITPUB元老
日期:2005-02-28 12:57:002012新春纪念徽章
日期:2012-01-04 11:49:542012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:20咸鸭蛋
日期:2012-05-08 10:27:19版主8段
日期:2012-05-15 15:24:112013年新春福章
日期:2013-02-25 14:51:24
发表于 2004-7-14 09:34 | 显示全部楼层
最初由 糖醋兔子 发布
[B]

谢谢eygle的辛勤劳动,这个应该是正解了



这个帖子,以前我看过的。我认为append insert下只是undo要比insert下的少,但并不是完全没有undo 产生的。

[php]
SQL> select * from v$version;

BANNER
----------------------------------------------------------------
Oracle9i Enterprise Edition Release 9.2.0.1.0 - Production
PL/SQL Release 9.2.0.1.0 - Production
CORE    9.2.0.1.0       Production
TNS for 32-bit Windows: Version 9.2.0.1.0 - Production
NLSRTL Version 9.2.0.1.0 - Production

SQL> create table test as select * from all_objects where 1=2;

SQL> select usn,writes from v$rollstat;

       USN     WRITES
---------- ----------
         0       6900
         1     101874
         2      23752
         3      50500
         4      51000
         5      49180
         6      35260
         7      23692
         8      23514
         9      22698
        10      34620

已选择11行。

SQL> insert /*+ append */into test select * from all_objects;

已创建28950行。  

SQL> select XIDUSN from v$transaction;

    XIDUSN
----------
         5

SQL> commit;

提交完成。

SQL> select usn,writes from v$rollstat;

       USN     WRITES
---------- ----------
         0       6900
         1     104666
         2      25790
         3      53322
         4      53038
         5      77560
         6      37590
         7      26236
         8      25446
         9      25302
        10      36552      
        
SQL> select 77560-49180 from dual;

77560-49180
-----------
      28380   
      
SQL> insert into test select * from all_objects;

已创建28950行。

SQL> select XIDUSN from v$transaction;

    XIDUSN
----------
         8

SQL> commit;

提交完成。

SQL> select usn,writes from v$rollstat;

       USN     WRITES
---------- ----------
         0       6900
         1     109738
         2      30594
         3      58640
         4      57998
         5      82520
         6      42998
         7      31154
         8     169818
         9      30344
        10      41848

已选择11行。

SQL> select 169818-25446 from dual;

169818-25446
------------
      144372

'
[/php] [/B]



即使是 nologging +  direct ,redo 也不是完全不产生,logging +  direct 下 undo 的减少,是大大地减少,减少的是什么?  减少的是 数据的undo ,我是特地说了 数据本身的undo ,就如同 redo的减少也一样,我一直都说是 数据本身的 redo ,这和数据库是否产生  redo 和 undo 是不同的概念,比如空间分配的 redo and  undo ,这就不是数据本身的变化!



不管表是否处于nologging下,direct insert 都不会对数据产生 UNDO

----------  这个说法,不会对数据产生undo 和不会产生undo 是两码事,就好比 nologging  +  direct 不会对数据产生 redo(但依然有其他的redo)  和不会产生 redo 是两码事!

这是我当时的测试数据对比
带索引表,表和索引均是logging状态,测试结果及过程如下

----------------------------常规插入-------direct插入

插入日志生成量----------------8350864--------2364484

插入回滚段生成量--------------2343894--------426838

回滚日志生成量----------------4018204--------76032

回滚本身不存在产生回滚-------------------------------------

请再仔细读一读,参考
http://www.itpub.net/showthread.php?threadid=217094

使用道具 举报

回复
论坛徽章:
117
ITPUB元老
日期:2005-02-28 12:57:002012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:202012新春纪念徽章
日期:2012-02-13 15:13:20版主7段
日期:2012-05-15 15:24:11ITPUB 11周年纪念徽章
日期:2012-09-28 17:34:42ITPUB 11周年纪念徽章
日期:2012-10-09 18:03:32紫蛋头
日期:2013-03-04 17:00:07优秀写手
日期:2013-12-18 09:29:09
 楼主| 发表于 2004-7-14 09:39 | 显示全部楼层
不是我的错

我引用的时候就说:

biti给出过测试,说明在append模式下不会对[B]数据[/B]产生undo[/COLOR]



使用道具 举报

回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

TOP技术积分榜 社区积分榜 徽章 团队 统计 知识索引树 积分竞拍 文本模式 帮助
  ITPUB首页 | ITPUB论坛 | 数据库技术 | 企业信息化 | 开发技术 | 微软技术 | 软件工程与项目管理 | IBM技术园地 | 行业纵向讨论 | IT招聘 | IT文档
  ChinaUnix | ChinaUnix博客 | ChinaUnix论坛
CopyRight 1999-2011 itpub.net All Right Reserved. 北京盛拓优讯信息技术有限公司版权所有 联系我们 
京ICP备09055130号-4  北京市公安局海淀分局网监中心备案编号:11010802021510 广播电视节目制作经营许可证:编号(京)字第1149号
  
快速回复 返回顶部 返回列表