众所周知,如果一个库没有设置为force logging,而这个库在归档模式下,对表的插入操作如果采用APPEND模式,并且表设置为nologging则不会为插入的数据产生日志。那么对LOB列的存储也设置为NOLOGGING,会产生什么样的结果?
测试环境:Oracle 9.2.0.1 for Win,非归档模式
create table test1.t1(id int not null, out_row clob)
lob(out_row) store as (disable storage in row nocache nologging);
关闭数据库,备份数据文件users01.dbf
启动数据库,将表中插入数据:
insert into test1.t1 select rownum,rpad('x',5000,'x') from dba_objects where rownum<=100;
select * from test1.t1;
能够正常返回100行数据。
关闭数据库,用备份的文件还原文件users01.dbf,启动数据库时报错:
数据库装载完毕。
ORA-01113: ?? 5 ??????
ORA-01110: ???? 5: 'D:\ORACLE\ORADATA\XJ\USERS01.DBF'
SQL> recover datafile 5;
完成介质恢复。
SQL> alter session set nls_language=american;
Session altered.
SQL> alter database open;
Database altered.
SQL> select count(*) from test1.t1;
COUNT(*)
----------
100
SQL> select * from test1.t1;
ERROR:
ORA-01578: ORACLE data block corrupted (file # 5, block # 61)
ORA-26040: Data block was loaded using the NOLOGGING option
ORA-01110: data file 5: 'D:\ORACLE\ORADATA\XJ\USERS01.DBF'
由此可以看出,在此前的插入操作中,没有对LOB数据产生日志。
我们将test1.t1删除,再重新创建,只是将LOB设置为LOGGING。
SQL> drop table test1.t1;
表已丢弃。
SQL> create table test1.t1 (id number not null,out_row clob)
2 lob (out_row) store as (disable storage in row nocache logging);
重复上步实验过程,发现LOGGING模式下的LOB能够正常恢复。
将数据库设置为归档模式,重复以上测试过程,发现NOLOGGING模式下的LOB仍然不能恢复。
将数据库设置为FORCE LOGGING模式,重复以上测试过程,发现NOLOGGING模式下的LOB能够正常恢复。
经过进一步测试,对LOB字段进行UPDATE也会产生上述实验结果。
在这个测试中使用了一个比较“笨”的办法。观察LOB列是否产生日志,可以观察redo size和分析日志文件进行。在此不在细述。
经过测试,发现IN ROW的LOB列与表中的其他列数据是一致的LOGGING行为。
注意:LOB列如果设置为CACHE,则只能是LOGGING模式。
由此引出一个问题,由于对LOB列设置为NOLOGGING,虽然能够提高数据插入速度,为数据恢复设置了一道难关。需要此种情况下的备份恢复策略,或者将LOB列设置为LOGGING模式。
众所周知,如果一个库没有设置为force logging,而这个库在归档模式下,对表的插入操作如果采用APPEND模式,并且表设置为nologging则不会为插入的数据产生日志!!!
我这边没有9i环境!
10g和你上面的结果有出入
SQL> select * from v$version;
BANNER
——————————————————————————–
Oracle Database 10g Enterprise Edition Release 10.2.0.1.0 – Prod
PL/SQL Release 10.2.0.1.0 – Production
CORE 10.2.0.1.0 Production
TNS for Linux: Version 10.2.0.1.0 – Production
NLSRTL Version 10.2.0.1.0 – Production
SQL> create table t as select * from dba_objects where 1=0;
Table created.
SQL> Select FORCE_LOGGING from V$DATABASE;
FORCE_
——
NO
SQL> archive log list
Database log mode Archive Mode
Automatic archival Enabled
Archive destination USE_DB_RECOVERY_FILE_DEST
Oldest online log sequence 213
Next log sequence to archive 215
SQL> alter table t nologging;
Table altered.
SQL> SELECT VALUE
2 FROM v$mystat, v$statname
3 WHERE v$mystat.statistic# = v$statname.statistic#
4 AND v$statname.NAME = ‘redo size';
VALUE
———-
2088
SQL> insert /*+ append */ into t select * from dba_objects;
49802 rows created.
SQL> SELECT VALUE
2 FROM v$mystat, v$statname
3 WHERE v$mystat.statistic# = v$statname.statistic#
4 AND v$statname.NAME = ‘redo size';
VALUE
———-
59260
[回复]
老熊 回复:
2月 24th, 2010 at 10:11 上午
@stronghearted, 谢谢你的回复,不过我这里说的是:不会为插入的“数据”产生日志,对于其他一些操作,比如空间管理,数据字典的操作,仍然会产生日志的,你这个测试,只有50多K的日志,显然不会是插入的数据产生的。
[回复]
记得以前有eygle有篇文章,去找了一下
http://www.eygle.com/faq/Nologging&append.htm
[回复]