SecureFiles在Oracle 11g中是用来替代large object (LOB),原来的LOB仍然存在,只是用SECUREFILE关键字来说明,SECUREFILE关键字以来表示一种新的存储方式,它允许加密,空间压缩和删除重复数据。
初始化参数
SecureFile 功能可用要求COMPATIBLE 参数设为 11.0.0.0.0或者更高.
DB_SECUREFILE 初始化参数控制缺省的数据库关于LOB存储的行为,允许的值包括:
- ALWAYS – 所有在ASSM 表空间的LOB都创建成 SecureFile LOB.在非 ASSM 表空间的LOB创建成 BasicFile LOB除非显示说明为SecureFiles. BasicFile 存储选项被忽略,如果未指明,SecureFile 作为缺省存储选项。
- FORCE – 所有的 LOB被创建成 SecureFile LOB. 如果 LOB 创建在非ASSM表空间, 则会抛出一个错误。 BasicFile 存储选项被忽略,如果未指明,SecureFile 作为缺省存储选项。
- PERMITTED – 缺省值, 当指定SECUREFILE 关键字时,创建为SecureFile LOB ,缺省存储方法是BASICFILE。
- NEVER – 不允许创建成SecureFile LOBs
- IGNORE – 不允许创建成 SecureFile LOB, 如果有因为SecureFile 存储选项的错误都会被忽略。
- 参数是动态的,因此可以在ALTER SYSTEM 命令中使用.
SQL> ALTER SYSTEM SET db_securefile = 'FORCE'; System altered. SQL> ALTER SYSTEM SET db_securefile = 'PERMITTED'; System altered.
下面的例子假设DB_SECUREFILE 初始化参数值为缺省的PERMITTED。
创建SecureFile LOBs
基础
通过为LOB存储指定SECUREFILE关键字来创建 SecureFile LOB。第一个表是传统类型,第二个是SecureFile类型。
create table contracts_basic
(
contract_id number(12),
contract_name varchar2(80),
file_size number,
orig_file blob
)
tablespace users
lob (orig_file)
(
tablespace users
enable storage in row
chunk 4096
pctversion 20
nocache
nologging
);
create table contracts_sec
(
contract_id number(12),
contract_name varchar2(80),
file_size number,
orig_file blob
)
tablespace users
lob (orig_file)
store as securefile
(
tablespace users
enable storage in row
chunk 4096
pctversion 20
nocache
nologging
)
/
使用下面的过程装载数据,假设SECFILE 目录下有一个contract.pdf 文件
SQL> create directory secfile as '/opt/oracle/';
Directory created.
SQL> host ls /opt/oracle/con*.pdf
/opt/oracle/contract.pdf
declare
l_size number;
l_file_ptr bfile;
l_blob blob;
begin
l_file_ptr := bfilename('SECFILE', 'contract.pdf');
dbms_lob.fileopen(l_file_ptr);
l_size := dbms_lob.getlength(l_file_ptr);
for ctr in 1 .. 100 loop
insert into contracts_sec
(
contract_id,
contract_name,
file_size,
orig_file
)
values
(
ctr,
'Contract '||ctr,
null,
empty_blob()
)
returning orig_file into l_blob;
dbms_lob.loadfromfile(l_blob, l_file_ptr, l_size);
end loop;
commit;
dbms_lob.close(l_file_ptr);
end;
/
LOB 删除重复数据
SecureFiles 的DEDUPLICATE选项允许在LOB的表或者分区级删除重复的入口。这个过程允许防止过度重复。而 KEEP_DUPLICATES 选项显示的避免删除重复。可以使用Alter table 语句修改该选项,例如:
SQL> alter table contracts_sec
2 modify lob(orig_file)
3 (deduplicate)
4 /
使用下面的过程可以查看所占用的空间:
declare
l_segment_name varchar2(30);
l_segment_size_blocks number;
l_segment_size_bytes number;
l_used_blocks number;
l_used_bytes number;
l_expired_blocks number;
l_expired_bytes number;
l_unexpired_blocks number;
l_unexpired_bytes number;
begin
select segment_name
into l_segment_name
from dba_lobs
where table_name = 'CONTRACTS_SEC';
dbms_output.put_line('Segment Name=' || l_segment_name);
dbms_space.space_usage(
segment_owner =>USER,
segment_name => l_segment_name,
segment_type => 'LOB',
partition_name => NULL,
segment_size_blocks => l_segment_size_blocks,
segment_size_bytes => l_segment_size_bytes,
used_blocks => l_used_blocks,
used_bytes => l_used_bytes,
expired_blocks => l_expired_blocks,
expired_bytes => l_expired_bytes,
unexpired_blocks => l_unexpired_blocks,
unexpired_bytes => l_unexpired_bytes
);
dbms_output.put_line('segment_size_blocks => '|| l_segment_size_blocks);
dbms_output.put_line('segment_size_bytes => '|| l_segment_size_bytes);
dbms_output.put_line('used_blocks => '|| l_used_blocks);
dbms_output.put_line('used_bytes => '|| l_used_bytes);
dbms_output.put_line('expired_blocks => '|| l_expired_blocks);
dbms_output.put_line('expired_bytes => '|| l_expired_bytes);
dbms_output.put_line('unexpired_blocks => '|| l_unexpired_blocks);
dbms_output.put_line('unexpired_bytes => '|| l_unexpired_bytes);
end;
/
对于keep_duplicates 的LOB:
Segment Name=SYS_LOB0000069919C00004$$
segment_size_blocks => 10272
segment_size_bytes => 84148224
used_blocks => 2101
used_bytes => 17211392
expired_blocks => 5888
expired_bytes => 48234496
unexpired_blocks => 2247
unexpired_bytes => 18407424
对于deduplicate的LOB:
Segment Name=SYS_LOB0000069919C00004$$
segment_size_blocks => 10272
segment_size_bytes => 84148224
used_blocks => 22
used_bytes => 180224
expired_blocks => 3712
expired_bytes => 30408704
unexpired_blocks => 6502
unexpired_bytes => 53264384
主要是比较used_bytes 值,可以看出deduplicate后,LOB所占用空间大大减少。具体能减少多少,还是看重复率。
LOB 压缩
SecureFiles 的 COMPRESS 选项能够在表或者分区级压缩 LOB内容 。压缩程度使用 MEDIUM或者 HIGH 关键字来说明。如果未指明压缩程度,则指MEDIUM。压缩会带来性能上的影响。LOB上的压缩不影响表的影响,反之亦然。下面的例子里说明了压缩后的空间使用情况。
SQL> alter table contracts_sec
modify lob(orig_file)
(keep_duplicates nocompress );
Table altered.
继续使用前面的过程显示空间使用情况:
Segment Name=SYS_LOB0000069919C00004$$
segment_size_blocks => 11296
segment_size_bytes => 92536832
used_blocks => 2101
used_bytes => 17211392
expired_blocks => 1023
expired_bytes => 8380416
unexpired_blocks => 8135
unexpired_bytes => 66641920
SQL> alter table contracts_sec
modify lob(orig_file)
( compress HIGH);
Table altered.
Segment Name=SYS_LOB0000069922C00004$$
segment_size_blocks => 11680
segment_size_bytes => 95682560
used_blocks => 2101
used_bytes => 17211392
expired_blocks => 3840
expired_bytes => 31457280
unexpired_blocks => 5699
unexpired_bytes => 46686208
好像没什么效果,大概可能和我这个PDF文件本身就是压缩有关。
LOB 加密
SecureFile LOB的加密依赖于walle或者Hardware Security Model (HSM)来持有密钥。wallet setup 的安装可参考 Transparent
Data Encryption (TDE) 和 Tablespace
Encryption,。
SecureFiles的 ENCRYPT 选项可以完LOB内容在块级的加密。USING 子句定义了使用哪种加密算法(3DES168, AES128, AES192, or AES256), 缺省是 'AES192'. 对于SecureFile 压缩,NO SALT选项不可用。具体不做详细介绍。
LOB Cache and Logging
Basicfile 和 SecureFile LOBs共享一些基本的 caching 和logging 选项. 常见的caching 选项有:
- CACHE – LOB数据放在 buffer cache.
- CACHE READS - LOB 数据只有当在读的时候才放在buffer cache ,写操作不放。NOCACHE