众所周知,如果一个库没有设置为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模式。