ITPub博客

首页 > Linux操作系统 > Linux操作系统 > 《Oracle编程艺术》学习笔记(19)-数据库日志模式 .

《Oracle编程艺术》学习笔记(19)-数据库日志模式 .

原创 Linux操作系统 作者:xiaoweisos 时间:2012-07-19 21:15:50 0 删除 编辑
数据库可以有两种LOG模式,ARCHIVELOG模式和NOARCHIVELOG模式。
NOARCHIVELOG模式在线重做日志写满以后不会被归档,因此出现故障后无法恢复。
可以使用select log_mode from v$database语句来查询,或者在sysdba权限下使用archive log list语句来查询当前的LOG模式。
例如:
sys@ORA11GR2> archive log list
Database log mode              Archive Mode
Automatic archival             Enabled
Archive destination            USE_DB_RECOVERY_FILE_DEST
Oldest online log sequence     18
Next log sequence to archive   20
Current log sequence           20

如需更改LOG模式,需要关闭数据库,然后startup mount,然后调用下面的语句修改:
alter database noarchivelog/archivelog
之后alter database open来打开数据库。

更改log_archive_dest_1参数可更改归档日志目录(pfile/spfile中参数db_recovery_file_dest指定的目录将无效),此外10g之后,可以生成多份日志的拷贝到不同位置,因此可以指定多个目录,例如:
alter system set log_archive_dest_1='location=/data/oracle/log1/archive_log';
alter system set log_archive_dest_2='location=/data/oracle/log2/archive_log';
如需恢复到db_recovery_file_dest指定的目录,可以把上述log_archive_dest_n参数设为空('')。

可以通过alter system archive log current;语句强制归档日志;
可以通过select name from v$archived_log;查看归档日志文件路径。

此外,在NOARCHIVELOG模式下,一些操作,例如CREATE TABLE,除了数据字典的修改外,不会生成REDO日志。
使用INSERT /*+ APPEND*/语法的直接路径插入也不生成REDO日志,但是普通的INSERT操作还是会生成REDO日志。

在ARCHIVELOG模式运行下的数据库,无论是直接路径插入还是普通的插入,都会生成REDO日志,但是可以用NOLOGGING的方式进行一些操作。
1)在SQL语句中设置NOLOGGING
例如在CREATE TABLE语句中使用NOLOGGING,
create table t nologging as select * from all_objects;
除了数据字典的修改外,不会生成REDO日志,相对于不使用NOLOGGING,生成日志大大减少。(在我的测试环境上,从6.56M减少到143K)
需要注意,NOLOGGING不能避免所有后续操作生成redo。在上面创建的表T上进行的后续的“正常“操作(如INSERT、UPDATE 和DELETE)还是会生成日志。其他特殊的操作(如使用SQL*Loader的直接路径加载,或使用INSERT /*+ APPEND*/语法的直接路径插入)不生成日志(除非通过alter table t logging;语句,再次启用完全的日志模式)。

2)在段(表格或者索引)上设置NOLOGGING属性
例如alter index xxx nologging/logging;
这样重建这个索引的时候就不会生成重做日志。

在一个ARCHIVELOG模式的数据库,如果使用NOLOGGING得当,可以加快很多操作的速度。但是需要谨慎,操作后,必须尽快为受影响的数据文件建立一个新的基准备份。

Oracle9i Release 2之后,DBA可能把数据库置于FORCE LOGGING模式。在这种情况下,所有操作都会计入日志。
查询SELECT FORCE_LOGGING FROM V$DATABASE 可以查看是否强制为日志模式。
通过下面的操作来修改(不需要重起数据库)
            ALTER DATABASE FORCE LOGGING;
            ALTER TABLESPACE tablespace_name FORCE LOGGING;
取消FORCE LOGGING模式
            ALTER DATABASE NO FORCE LOGGING;
            ALTER TABLESPACE tablespace_name NO FORCE LOGGING;


NOARCHIVELOG模式和ARCHIVELOG模式下REDO日志生成量对比

                     NOARCHIVELOG  ARCHIVELOG  ARCHIVELOG+NOLOGGING
-----------------------------------------------------------------
CREATE TABLE AS       107964       6773704      142592
INSERT               6630644       6628728     6627988
INSERT /*+ APPEND*/    60312       6722784       60088

*如果FORCE_LOGGING=YES,得到的结果同ARCHIVELOG模式下的结果。

在一个NOARCHIVELOG模式数据库下进行试验的结果:

tony@MYTEST2> select log_mode from v$database;

LOG_MODE
------------
NOARCHIVELOG

tony@MYTEST2> create or replace function get_stat_val( p_name in varchar2 ) return number
  2  as
  3    l_val number;
  4  begin
  5    select b.value into l_val
  6      from v$statname a, v$mystat b
  7      where a.statistic# = b.statistic#
  8        and a.name = p_name;
  9    return l_val;
 10  end;
 11  /

Function created.

tony@MYTEST2> variable redo number
tony@MYTEST2> exec :redo := get_stat_val( 'redo size' );

PL/SQL procedure successfully completed.

tony@MYTEST2> create table t as select * from all_objects;

Table created.

tony@MYTEST2> exec dbms_output.put_line((get_stat_val('redo size')-:redo) -
>   || ' bytes of redo generated...');
107964 bytes of redo generated...

PL/SQL procedure successfully completed.

tony@MYTEST2> truncate table t;

Table truncated.

tony@MYTEST2> exec :redo := get_stat_val( 'redo size' );

PL/SQL procedure successfully completed.

tony@MYTEST2> insert into t select * from all_objects;

53878 rows created.

tony@MYTEST2> exec dbms_output.put_line((get_stat_val('redo size')-:redo) -
>   || ' bytes of redo generated...');
6630644 bytes of redo generated...

PL/SQL procedure successfully completed.

tony@MYTEST2> truncate table t;

Table truncated.

tony@MYTEST2> exec :redo := get_stat_val( 'redo size' );

PL/SQL procedure successfully completed.

tony@MYTEST2> insert /*+ APPEND */ into t select * from all_objects;

53878 rows created.

tony@MYTEST2> exec dbms_output.put_line((get_stat_val('redo size')-:redo) -
>   || ' bytes of redo generated...');
60312 bytes of redo generated...

PL/SQL procedure successfully completed.

将数据库改为ARCHIVELOG模式下进行试验的结果:

tony@MYTEST2> select log_mode from v$database

LOG_MODE
------------
ARCHIVELOG

tony@MYTEST2> variable redo number
tony@MYTEST2> exec :redo := get_stat_val( 'redo size' );

PL/SQL procedure successfully completed.

tony@MYTEST2> create table t as select * from all_objects;

Table created.

tony@MYTEST2> exec dbms_output.put_line((get_stat_val('redo size')-:redo) -
> || ' bytes of redo generated...');
6773704 bytes of redo generated...

PL/SQL procedure successfully completed.

tony@MYTEST2> truncate table t;

Table truncated.

tony@MYTEST2> exec :redo := get_stat_val( 'redo size' );

PL/SQL procedure successfully completed.

tony@MYTEST2> insert into t select * from all_objects;

53878 rows created.

tony@MYTEST2> exec dbms_output.put_line((get_stat_val('redo size')-:redo) -
> || ' bytes of redo generated...');
6628728 bytes of redo generated...

PL/SQL procedure successfully completed.

tony@MYTEST2> truncate table t;

Table truncated.

tony@MYTEST2> exec :redo := get_stat_val( 'redo size' );

PL/SQL procedure successfully completed.

tony@MYTEST2> insert /*+ APPEND */ into t select * from all_objects;

53878 rows created.

tony@MYTEST2> exec dbms_output.put_line((get_stat_val('redo size')-:redo) -
> || ' bytes of redo generated...');
6722784 bytes of redo generated...

PL/SQL procedure successfully completed.

tony@MYTEST2> drop table t;

Table dropped.

tony@MYTEST2> exec :redo := get_stat_val( 'redo size' );

PL/SQL procedure successfully completed.

tony@MYTEST2> create table t nologging as select * from all_objects;

Table created.

tony@MYTEST2> exec dbms_output.put_line((get_stat_val('redo size')-:redo) -
> || ' bytes of redo generated...');
142592 bytes of redo generated...

PL/SQL procedure successfully completed.

tony@MYTEST2> exec :redo := get_stat_val( 'redo size' );

PL/SQL procedure successfully completed.

tony@MYTEST2> truncate table t;

Table truncated.

tony@MYTEST2> exec :redo := get_stat_val( 'redo size' );

PL/SQL procedure successfully completed.

tony@MYTEST2> insert into t select * from all_objects;

53878 rows created.

tony@MYTEST2> exec dbms_output.put_line((get_stat_val('redo size')-:redo) -
> || ' bytes of redo generated...');
6627988 bytes of redo generated...

PL/SQL procedure successfully completed.

tony@MYTEST2> truncate table t;

Table truncated.

tony@MYTEST2> exec :redo := get_stat_val( 'redo size' );

PL/SQL procedure successfully completed.

tony@MYTEST2> insert /*+ APPEND */ into t select * from all_objects;

53878 rows created.

tony@MYTEST2> exec dbms_output.put_line((get_stat_val('redo size')-:redo) -
> || ' bytes of redo generated...');
60088 bytes of redo generated...

PL/SQL procedure successfully completed.

来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/11980046/viewspace-736081/,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论

注册时间:2012-03-08

  • 博文量
    39
  • 访问量
    10466