LOB-part4-storage and parameter

LOB列存储一个locator,这个locator指向实际的LOB value。实际的LOB value是存在在table row(inline)里还是table row之外(out-of-line)主要取决于创建表的时候指定的表的属性。

以下的情况Lob value是out-of-line的情况
创建表的时候显式的指定了DISABLE STORAGE IN ROW这个LOB参数;
如果LOB的大小大于4000字节的时候(严格上说是4000 minus系统控制信息个字节),无论LOB storage的属性是什么样的,LOB value都是out-of-line;即使做完update操作之后的lob的长度小于4000字节,但是这个操作无法改变存储的模式,记录依然保持是out-of-line的。

以下的情况是LOB value为inline
当存储的LOB的row大小小于4000个字节的情况下,并且你在创建表的时候明确的指定了ENABLE STORAGE IN ROW或者采用了默认值,那么这种情况下LOB value是inline模式的。当LOB value为NULL的时候也是inline的。

使用默认的LOB inline storage可以获得比较好的性能,避免了创建维护out-of-line的开销。然而在某些场景下,DISABLE STORAGE IN ROW可能也是一个好的选择,因为在行内存储LOB增加了行的大小,当需要对LOB所在的表的其他字段进行大量的update/select操作的时候、全表扫描的时候后者range scan的时候,这种in row的方式会影响数据库的性能。

Persistent LOBs存在2种,一种是从8i时代开始的BasicFiles LOBs,还有就是新引入的SecureFiles LOBs。从性能的角度上来讲建议将TABLE和LOB INDEX存放在不同的表空间,表是可以进行MOVE之类的操作的,但是LOB INDEX是不能进行ALTER操作的。

创建BasicFiles LOB的语法和参数如下

SQL> create table basicfile_t(id number,description clob)
  2  lob(description) store as basicfile
  3  basicfile_seg (
  4     enable storage in row
  5     chunk 8k
  6     pctversion 5
  7     cache
  8     logging
  9     storage(maxextents 5)
 10     tablespace LOB_TEST
 11     );

Table created.

创建Securefile LOB

SQL> create table securefile_t(id number,description clob)
  2  lob(description) store as securefile
  3  securefile_seg(
  4     enable storage in row
  5     chunk 8k
  6     retention auto
  7     cache logging
  8     storage(maxextents 5)
  9     tablespace LOB_TEST
 10     );

Table created.

对比

SQL> select table_name,tablespace_name from user_tables where table_name in ('BASICFILE_T','SECUREFILE_T');

TABLE_NAME                     TABLESPACE_NAME
------------------------------ --------------------
BASICFILE_T                    TEST_8K
SECUREFILE_T                   TEST_8K

SQL> select table_name,column_name,segment_name,chunk,in_row,pctversion from user_lobs;

TABLE_NAME                     COLUMN_NAME     SEGMENT_NAME                        CHUNK IN_ROW    PCTVERSION
------------------------------ --------------- ------------------------------ ---------- --------- ----------
BASICFILE_T                    DESCRIPTION     BASICFILE_SEG                        8192 YES                5
SECUREFILE_T                   DESCRIPTION     SECUREFILE_SEG                       8192 YES

下面介绍一些创建LOB的一些参数

PCTVERSION参数
PCTVERSION控制着用于实现basicfile LOB数据版本化的已分配LOB空间的百分比(在11gR2中默认值为10%,如果你的应用确实经常修改LOB,那么默认值可能会存在无法满足需求的情况。
当应用需要多次的对BasicFile LOB进行更新并且同时伴随着大量的读取,这个时候可以讲PCTVERSION设置为比默认值更大,这个时候允许oracle使用更多的free page用于控制old version。因为大查询会请求对BasicFiles LOB列的连续读,保留BasicFiles LOB 页的old version就显得非常有用,在这种情况下BasicFiles LOB的存储会正常,因为Oracle数据库不会大量的去重用free pages。
当persistent BasicFiles LOB instance只创建并写入一次,后续主要是只读操作,更新操作很少发生的时候,我们可以考虑将这个PCTVERSION参数设置小一些,比如5%。当然,如果在极端情况下,BasicFiles LOBs只有读操作,这个参数也可以设置为0,意味着没有任何page来支持old version这个功能。如果处理LOB时遇到一个ORA-22924错误,解决方案不是增加undo表空间的大小,也不是增加undo保留时间(UNDO_RETENTION),而是应该使用以下命令:ALTER TABLE tab MODIFY LOB (lobname) ( PCTVERSION n)。
关于这个参数的详细设置,可以参考11gR2手册中RECOMMENDED PCTVERSION SETTING

RETENTION参数
作为PCTVERSION的替代参数,Oracle还有个retention参数,对于BasicFiles LOB,这2个参数都可以使用,但是不能同时使用,而对于SecureFiles LOB,则室友retention参数可以使用。这个参数的设置让LOB列存储LOB数据的old version一段时间,而不再是保存一个百分比。这个参数的产生也主要是用来跟UNDO表空间的UNDO特性来融合的,当LOB列设置了retention这个参数之后,LOB数据的old version的保留时间是通过UNTO_RETENTION来进行控制的。

这个参数也有一些限制说明,比如
1. 对于LOB列Undo SQL是不能的,以为它是不同的数据类型,必须通过在LOB列上设置retention属性来对LOB数据使用Undo SQL;
2. 不能显式的指定retention的数值,LOB version的保留时间是通过undo_retention参数来由数据库来决定的;
3. Retention参数只在Automatic Undo Management(AUM)模式下被支持,所以在LOB列上设置这个参数之前要确定表使用了AUM。对于BasicFiles LOB,要想使LOB retention生效,则需要使用ASSM管理表空间,如果BasicFiles LOB创建在了MSSM模式下,那么这个参数是自动被忽略的。

对于SecureFiles LOBs,retention参数的默认是AUTO模式。

Cache/nocache/logging/nologging
关于cache或者nocache的选择,请参考When to Use CACHE, NOCACHE, and CACHE READS
使用cache选项可以提高LOB列读写的性能,然后也是把双刃剑,这样会造成非LOB页过早的被置换出内存。但是无论开启了logging还是nologging,Oracle的LOBs是不会对LOB data页生成rollback信息的,只会对LOB index页生成rollback信息。

Chunk
一个chunk可以是一个或者多个数据块,在创建含有LOB字段的表的时候可以指定chunk的大小,这个chunk的大小与数据库访问和修改LOB value的数据大小有关。Chunk的一部分用来存储系统相关信息一部分用来存储LOB value。Oracle提供了API来返回用于存储LOB value的chunk的空间,PL/SQL中可以使用DBMS_LOB.GETCHUNKSIZE,使用OCI的话可以使用OCILobGetChunkSize()。
默认情况下chunk size等于表空间块的大小,最大是32K。当chunk size的值被确定了之后就不可以进行修改了,所以这个值的选择对于优化存储和性能需求是很关键的。对于inline LOB的chunk size选择不是很重要,但是对于LOB data是out-of-line的情况下,chunk size的选择就很关键了。因为LOB data会占据多个chunk参数的存储空间,如果lob data比较小但是chunk size设置比较大的话将会浪费大量的空间。Data Size和CHUNK Size诠释了这一点。从性能的角度来说,Oracle建议采用大一点的chunks来提升访问LOBs的效率。
关于INITIAL和NEXT参数的设置和CHUNK的关系,Oracle建议CHUNK <= NEXT;CHUNK <= INITIAL。

此条目发表在LOB分类目录。将固定链接加入收藏夹。

发表评论

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / 更改 )

Twitter picture

You are commenting using your Twitter account. Log Out / 更改 )

Facebook photo

You are commenting using your Facebook account. Log Out / 更改 )

Google+ photo

You are commenting using your Google+ account. Log Out / 更改 )

Connecting to %s