暂无图片
暂无图片
1
暂无图片
暂无图片
暂无图片

运维专家系列之:Oracle 11g 高级压缩介绍

3559

1     Intro

在当前的企业环境中,数据量增长越来越快,如何更有效的存储数据,节约开支已经是很多企业所面对的问题。随着oracle 11g的推出,Advance Compress 选件可以帮助客户更加有效的进行数据压缩,减少存储,带宽,memory等等应对数据增长所带来的额外开支。一般情况下,高级压缩可以压缩2-4倍的空间。

压缩始终是非常占用 CPU 的过程,并且需要花费一定时间。通常,如果压缩数据,则数据必须解压缩后才能使用。虽然此要求在数据仓库环境中是可以接受的,但在 OLTP 环境中可能无法接受。11g Advanced Compress9i引入的basic Compress功能要强大得多,可以针对OLTP中传统的DML (Insert,Update)进行压缩,而不像以前只针对direct-path 加载数据。

11g Advanced Compress 并不是对行进行压缩,而是对block进行压缩。由于压缩作为触发事件发生,而不是在插入行时发生,因此在正常的 DML 进程中压缩对性能没有影响。压缩被触发后,对 CPU 的需求肯定会变得很高,但在其他任何时间 CPU 影响都为零,因此压缩也适用于 OLTP 应用程序,这是 Oracle Database 11g中压缩的平衡点。

1.1    Compress algorithm

Oracle是针对block进行压缩,一个叫symbolstructure存放压缩的元数据,当表进行压缩时,在symbol table中重复值将会被消除,只存放第一次加入的值。重复值将会被一个类似link替代,指向到相应的值。Oracle高级压缩具有以下特征,

1.       节约空间,一般情况下可以压缩2-4倍的空间。
2.       Oracle在读取压缩数据时不需要先解压而是直接读取。因此对于read来讲没有性能影响,从某种意义上来讲还会提高性能,因为读取的block少了,减少了IO。
3.       写性能的影响。当数据写入block时不可避免的会带来一定的写影响,但是oracle并不是每次都进行压缩而是批量进行,当block的空间占用到一个阀值时会触发整个block的数据一次性压缩,紧接着数据再次写入,当再次达到这个阀值时,整个block再进行批量压缩。这个过程一直重复直到不能再压缩为止。因此在大多数情况,压缩block上的OLTP事务将得到非压缩的性能。

 

 

压缩块和非压缩块的比较


压缩过程


 

下图是一个真实案例中压缩对性能的影响。


1.2    Deliver Method

l  在线重定义,只对新进数据有效,优点是在线实施。

l  move表,可以对老数据进行压缩,缺点是可能影响业务。

 

2     Compress  

2.1    Table

2.1.1     restriction

l  Basic compression添加字段时不能指定默认值。
l  Basic compression不支持drop 字段。
l  OLTP compression支持drop字段,但设置字段unused 避免长时间的解压和再压缩。
l  OLTP compression添加字段指定默认值时,这个字段必须是not null。
l  不支持大于255字段的表。12c增加到1000
l  Basic file LOB类型不支持,secure file LOB支持。
l  不支持索引组织表
l  不支持hash,hash-list分区表
l  不支持外部表,cluster表

2.1.2     Table Compression Method


 

 

2.1.3     Example

 

CREATETABLE test_comp COMPRESS FOR ALLOPERATIONS as select * from dba_objects where 1=2;
 
SQL> SELECT table_name, compression, compress_for FROMuser_tables where table_n
ame in ('TEST_COMP');
 
TABLE_NAME                    COMPRESS COMPRESS_FOR
------------------------------ -------- ------------
TEST_COMP                     ENABLED  OLTP
 
SQL> set time on
11:52:11 SQL> set timing on
11:52:15 SQL>
11:52:15 SQL> insert into test_comp select * fromdba_objects;
 
已创建72478行。
 
已用时间:  00: 00: 00.47
11:52:18 SQL> commit;
 
提交完成。
 
已用时间:  00: 00: 00.01
 
 
 
-non compress
 
11:52:19 SQL> CREATE TABLE test_non_comp  as select * from dba_objects where 1=2
;
11:53:04 SQL> SELECT table_name, compression, compress_forFROM user_tables wher
e table_name in ('TEST_COMP','TEST_NON_COMP');
 
TABLE_NAME                    COMPRESS COMPRESS_FOR
------------------------------ -------- ------------
TEST_COMP                     ENABLED  OLTP
TEST_NON_COMP                 DISABLED
 
11:53:20 SQL> insert into test_non_comp select * fromdba_objects;
 
已创建72479行。
 
已用时间:  00: 00: 00.40<<<<<<<<<<<<<<<<<<<<<<<<<<时间上比压缩表稍微节约一点点。
 
 
 
12:02:40 SQL> select segment_name,bytes/1024/1024 MB fromdba_segments where seg
ment_name IN ('TEST_NON_COMP');
 
SEGMENT_NAME                MB
-------------------- ----------
TEST_NON_COMP              648
 
 
12:04:38 SQL> ALTER TABLE TEST_NON_COMP MOVE COMPRESS FOR OLTP;
 
12:05:27 SQL> select segment_name,bytes/1024/1024 MB fromdba_segments where seg
ment_name IN ( 'TEST_NON_COMP');
 
SEGMENT_NAME                MB
-------------------- ----------
TEST_NON_COMP              208<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<空间得到了3倍压缩
2.1.4     Estimate Compress ratio
SQL> set serveroutput on
SQL> declare
  2  v_blkcnt_cmp pls_integer;
  3  v_blkcnt_uncmp pls_integer;
  4  v_row_cmp pls_integer;
  5  v_row_uncmp pls_integer;
  6  v_cmp_ratio number;
  7  v_comptype_str varchar2(60);
  8  begin
  9  dbms_compression.get_compression_ratio(
 10  scratchtbsname =>upper('&ScratchTBS'),
 11  ownname => user,
 12  tabname => upper('&TableName'),
 13  partname => NULL,
 14  comptype => dbms_compression.comp_for_query_high,
 15  blkcnt_cmp => v_blkcnt_cmp,
 16  blkcnt_uncmp => v_blkcnt_uncmp,
 17  row_cmp => v_row_cmp,
 18  row_uncmp => v_row_uncmp,
 19  cmp_ratio => v_cmp_ratio,
 20  comptype_str => v_comptype_str,subset_numrows=>&num_rows );
 21  dbms_output.put_line('Estimated CompressionRatio: '||to_char(v_cmp_ratio));
 22  dbms_output.put_line('Blocks used bycompressed sample: '||to_char(v_blkcnt_cmp));
 23  dbms_output.put_line('Blocks used byuncompressed sample: '||to_char(v_blkcnt_uncmp));
 24  end;
 25 
输入 scratchtbs 的值:  users
原值   10: scratchtbsname =>upper('&ScratchTBS'),
新值   10: scratchtbsname => upper('users'),
输入 tablename 的值:  test_non_comp
原值   12: tabname => upper('&TableName'),
新值   12: tabname => upper('test_non_comp'),
输入 num_rows 的值:  5798320
原值   20: comptype_str => v_comptype_str,subset_numrows=>&num_rows );
新值   20: comptype_str => v_comptype_str,subset_numrows=>5798320 );
Compression Advisor self-check validationsuccessful. select count(*) on both
Uncompressedand EHCC Compressed format = 5798320 rows
EstimatedCompression Ratio: 17.5
Blocks used by compressed sample: 4690
Blocks used by uncompressed sample: 82521

 

2.2    Secure File

Secure File11g引入的一个新特性。针对LOB的全新设计,针对存储进行了全新算法,可以进行加密,压缩,和消除重复,大大节约了存储空间,增强了读写的性能。


2.2.1     Enable Secure File deduplication

CREATE TABLE images (

image_id NUMBER,

image BLOB)

LOB(image) STORE AS SECUREFILE

(TABLESPACE lob_tbs DEDUPLICATE);

例如在邮件应用中,10个人接收1M的附件,需要存放10份,也就是10M,而deduplication可以只存放一份1M即可,大大节省了空间,同时可以带来读写的性能提升,因为IO减少了。

create table order_desc
(
       order_id     number(12),
       order_name   varchar2(80),
       file_size       number,
       orig_file       blob
)
lob (orig_file)
store as securefile
(tablespace users deduplicate)
;
 
 
create directory "SecureFile" as'D:\TDDOWNLOAD';
 
 
declare
   v_size      number; 
   v_file         bfile;  
   v_blob      blob;   
begin
   v_file := bfilename('SecureFile', 'order.pdf');
   dbms_lob.fileopen(v_file);
   v_size := dbms_lob.getlength(v_file);
    forct in 1 .. 1000 loop
        insertinto order_desc
       (       
           order_id,
           order_name,
           file_size,  
           orig_file   
       )       
       values  
       (       
           ct,        
           'order '||ct,
            null,       
           empty_blob()
       )       
       returning orig_file into v_blob; 
       dbms_lob.loadfromfile(v_blob, v_file, v_size);
    endloop;
   commit;
   dbms_lob.close(v_file);
end;
/
 
 
------------------------------------------------------------------
create table order_lob
(
       order_id     number(12),
       order_name   varchar2(80),
       file_size       number,
       orig_file       blob
)
lob (orig_file) store as
(
       tablespace users
       enable storage in row
       chunk 4096
);
 
 
declare
   v_size      number; 
   v_file         bfile;  
   v_blob      blob;   
begin
   v_file := bfilename('SecureFile', 'order.pdf');
   dbms_lob.fileopen(v_file);
    v_size := dbms_lob.getlength(v_file);
    forct in 1 .. 1000 loop
       insert into order_lob
       (       
           order_id,
           order_name,
           file_size,  
           orig_file   
       )       
       values  
       (       
           ct,        
           'order '||ct,
           null,       
           empty_blob()
       )       
       returning orig_file into v_blob; 
       dbms_lob.loadfromfile(v_blob, v_file, v_size);
    endloop;
    commit;
   dbms_lob.close(v_file);
end;
/
 
 
SQL> selecttable_name,segment_name,column_name,compression,deduplication from dba_lobswhere table_name in ('ORDER_DESC','ORDER_LOB');
 
TABLE_NAME     SEGMENT_NAME                  COLUMN_NAME     COMPRE DEDUPLICATION
--------------- --------------------------------------------- ------ ---------------
ORDER_LOB      SYS_LOB0000074603C00004$$     ORIG_FILE       NONE   NONE
ORDER_DESC     SYS_LOB0000074612C00004$$     ORIG_FILE       NO     LOB

SQL> SELECT SEGMENT_NAME,BYTES FROMDBA_SEGMENTS WHERE SEGMENT_NAME IN('SYS_LOB0000074603C00004$$','SYS_LOB0000074612C00004$$');
 
SEGMENT_NAME                                                                          BYTES
-------------------------------------------------------------------------------------------
SYS_LOB0000074603C00004$$                                                          92274688
SYS_LOB0000074612C00004$$                                                            1179648

存储空间仅为近1%。

 

2.2.2     Enable SecureFile Compress

 

CREATE TABLE images (

Oracle Advanced Compression Page 7

image_id NUMBER,

image BLOB)

LOB(image)STORE AS SECUREFILE

(TABLESPACE lob_tbs COMPRESS);

 

2.3    Backup Data Compress

Oracle支持对RMANDatapump两种备份方式的压缩。

2.3.1     Data Pump

Datapump的压缩是inline的,exportimport时不需要额外步骤操作,自动进行压缩和解压处理。

expdp hr FULL=y DUMPFILE=dpump_dir:full.dmpCOMPRESS;

 

2.3.2     RMAN Compress

企业数据越来越大,对于备份的存储空间需求也越来越大。RMAN 备份compress10g开始引入,有效的降低了空间成本。RMAN压缩是在备份过程中进行,降低了空间需求,同时在进行恢复时不需要额外的进行解压操作。

RMAN的高级压缩基于ZLIB的工业标准算法,相比10g的压缩速度提高了近40%,压缩率降低了20%左右。下图是一个ERP数据库的RMAN 压缩比较。


Syntax for Fast RMAN compression is as below:
RMAN> CONFIGURE COMPRESSION ALGORITHM‘zlib’;
RMAN compression can be done as shown below:
RMAN> backup as COMPRESSED BACKUPSETdatabase archivelog all;

专家简介:

    马雪峰甲骨文公司资深技术专家,10年以上Oracle数据库运维经验,擅长架构部署,升级迁移,性能优化,熟悉电信/金融/制造行业。多次参与过国内大型数据库的迁移,升级及优化工作。先后供职于IBM/ORACLE等知名外企。

    

 
 


文章转载自西区O记重案实录,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论