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