作者:李敏,云和恩墨交付工程师。

Oracle Corp最先在11G R2中引入了EHCC(Exadata Hybrid Columnar Compression),早先限制较多,体现的方式是这里的E,指的是exadata一体机上才可以启用这个特性。作为exadata上众多优秀特性里一个重要部分,和smart scan或者说cell offloading对比,虽然EHCC能带来极大的空间压缩,但是EHCC还是需要DBA额外做一些操作,甚至多个场景的评估来决定是否要采用。

EHCC(或者说后来因使用平台更多,在除了exadata之外,在Oracle corp的zfssa、Pillar Axiom、SuperCluster、ODA上都支持了之后改成了叫做HCC)本质上解决的问题是IO问题,也可以说,是为了在CPU及IO间平衡,拿算力换空间,目前看来在大部分场景下,这个交换是非常超值的,几倍、十几倍甚至几十倍的压缩率都很常见,如果这部分数据是冷数据,这个特性看起来是完美的。

但是有些时候不是这样的。本文从HCC的多个方面选出一两个点来简述这个特性给DBA带来的第一个直观感受。

测试环境的DB版本



首先,准备环境

创建表空间,这里选择多个小文件的方式。

CREATESMALLFILETABLESPACEEHCCTBS
DATAFILE
'/ehccfs/ORA19C/ora19pdb1/EHCCTBS_001.DBF'SIZE10485760AUTOEXTENDONNEXT1048576MAXSIZE10737418240,
'/ehccfs/ORA19C/ora19pdb1/EHCCTBS_002.DBF'SIZE10485760AUTOEXTENDONNEXT1048576MAXSIZE10737418240,
'/ehccfs/ORA19C/ora19pdb1/EHCCTBS_003.DBF'SIZE10485760AUTOEXTENDONNEXT1048576MAXSIZE10737418240,
'/ehccfs/ORA19C/ora19pdb1/EHCCTBS_004.DBF'SIZE10485760AUTOEXTENDONNEXT1048576MAXSIZE10737418240
BLOCKSIZE8192
FORCELOGGING
DEFAULTCOLUMNSTORENOCOMPRESSNOINMEMORY
ONLINE
SEGMENTSPACEMANAGEMENTAUTO
EXTENTMANAGEMENTLOCALAUTOALLOCATE;
(左右滑动,查看完整代码,下同)


这里选择NO Compress方式创建表空间,不把压缩作为表空间的属性,而用CREATE TABLE的方式来指定压缩属性。

[ora19c@dm01db06~]$sqlplus/assysdba

SQL*Plus:Release19.0.0.0.0-ProductiononSunMar2410:07:022019
Version19.2.0.0.0

Copyright(c)1982,2018,Oracle.Allrightsreserved.


Connectedto:
OracleDatabase19cEnterpriseEditionRelease19.0.0.0.0-Production
Version19.2.0.0.0

SQL>createuserhridentifiedbywelcome1defaulttablespaceehcctbs;

Usercreated.

SQL>grantdbatohr;

Grantsucceeded.

SQL>createtablehr.big_table_no_ehccasselect*fromdba_objects;

Tablecreated.

为了体现压缩率的差距,我创建了一个360M的未压缩表,来对比8种压缩方式下的压缩率。

[ora19c@dm01db06~]$sqlplushr/welcome1@ora19pdb1

SQL*Plus:Release19.0.0.0.0-ProductiononSunMar2410:07:282019
Version19.2.0.0.0

Copyright(c)1982,2018,Oracle.Allrightsreserved.

LastSuccessfullogintime:SunMar24201909:36:33+08:00

Connectedto:
OracleDatabase19cEnterpriseEditionRelease19.0.0.0.0-Production
Version19.2.0.0.0

SQL>

SQL>insertintoBIG_TABLE_NO_EHCCselect*fromBIG_TABLE_NO_EHCC;

72360rowscreated.

SQL>/

144720rowscreated.

SQL>/

289440rowscreated.

SQL>/

578880rowscreated.

SQL>insertintoBIG_TABLE_NO_EHCCselect*fromBIG_TABLE_NO_EHCC;

1157760rowscreated.

SQL>commit;

SQL>selectcount(*)fromBIG_TABLE_NO_EHCC;

COUNT(*)
----------
2315520

SQL>colOWNERfora15
SQL>colSEGMENT_NAMEfora40
SQL>selectOWNER,SEGMENT_NAME,BYTES/1048576SIZE_MBfromdba_segmentswhereSEGMENT_NAMElike('%EHCC%');

OWNERSEGMENT_NAMESIZE_MB
-----------------------------------------------------------------
HRBIG_TABLE_NO_EHCC360

之后基于这个基础表,创建8个不同HCC压缩方式的表。这里我timing on了,但是只做参考,因为redo是200M的,导致CTAS的时候有一次归档行为,IO受影响,可能有一次的时间受影响。

SQL>createtableEHCC_QUERY_HIGHcompressforqueryhightablespaceehcctbsasselect*frombig_table_no_ehcc;

Tablecreated.

Elapsed:00:00:10.61
SQL>createtableEHCC_QUERY_LOWcompressforquerylowtablespaceehcctbsasselect*frombig_table_no_ehcc;

Tablecreated.

Elapsed:00:00:21.33
SQL>createtableEHCC_ARCHIVE_HIGHcompressforarchivehightablespaceehcctbsasselect*frombig_table_no_ehcc;

Tablecreated.

Elapsed:00:00:38.75
SQL>createtableEHCC_ARCHIVE_LOWcompressforarchivelowtablespaceehcctbsasselect*frombig_table_no_ehcc;

Tablecreated.

Elapsed:00:00:11.07
SQL>createtableEHCC_QUERY_HIGH_LOCKINGcompressforqueryhighrowlevellockingtablespaceehcctbsasselect*frombig_table_no_ehcc;

Tablecreated.

Elapsed:00:00:09.46
SQL>createtableEHCC_QUERY_LOW_LOCKINGcompressforquerylowrowlevellockingtablespaceehcctbsasselect*frombig_table_no_ehcc;

Tablecreated.

Elapsed:00:00:12.35
SQL>createtableEHCC_ARCHIVE_HIGH_LOCKINGcompressforarchivehighrowlevellockingtablespaceehcctbsasselect*frombig_table_no_ehcc;

Tablecreated.

Elapsed:00:00:33.90
SQL>createtableEHCC_ARCHIVE_LOW_LOCKINGcompressforarchivelowrowlevellockingtablespaceehcctbsasselect*frombig_table_no_ehcc;

Tablecreated.

Elapsed:00:00:17.50


然后查看这些不同压缩方式下的对象大小。注意这里的LOCKING,指的是row level locking。



除了第一个基础表之外,每两个相邻对象的压缩区别是row level locking方式的区别。


hr.BIG_TABLE_NO_EHCC这个表是基于PDB的dba_objects来创建的一个28列的表,实话说,这个表做HCC跑分测试并不适合,但是依然能在archive high模式下,达到惊人的360/15=24倍的压缩率。



那么,对未压缩的基础表强制全扫,再对最高压缩的archive high的表做强制全扫的话,哪个快呢?



多次测试,结果出乎意料。16秒跟1秒下的差距,这是没在exadata上的结果,如果集合exadata的cell offloading,可以详见OLAP下,HCC的表现了。

Oracle对自家产品间的协同和优化令人目瞪狗呆。

14336,一级位图块
***2019-03-24T17:14:51.182266+08:00(ORA19PDB1(3))
Startdumpdatablockstsn:6file#:24minblk14336maxblk14336
............................
............................
............................
DumpofSecondLevelBitmapBlock
number:9nfree:1ffree:8pdba:0x06003802
Inc#:0Objd:72974Flag:3
opcode:0

这里提示到:

SecondLevelBitmapblockDBAs
--------------------------------------------------------
DBA1:0x06003801
二级位图块,正好是一级14336的下一个块:

下面是这个二级位图块的信息:

DumpofSecondLevelBitmapBlock
number:9nfree:1ffree:8pdba:0x06003802
Inc#:0Objd:72974Flag:3
opcode:0
xid:
L1Ranges:
--------------------------------------------------------
0x06003800Free:1Inst:1
0x06003840Free:1Inst:1
0x05803400Free:1Inst:1
0x06003880Free:1Inst:1
0x05803480Free:1Inst:1
0x06003900Free:1Inst:1
0x05803500Free:1Inst:1
0x06003980Free:1Inst:1
0x05803580Free:7Inst:1

--------------------------------------------------------
Enddumpdatablockstsn:6file#:24minblk14337maxblk14337

看样子是没什么东西。似乎是表太小没用到。

14338块信息不多。这里看14339块。

block_row_dump:
tab0,row0,@0x30
tl:8016fb:--H-F--Nlb:0x0cc:1
nrid:0x06003804.0
col0:[8004]
Compressionlevel:04(ArchiveHigh)
LengthofCUrow:8004
kdzhrh:------PC-CBLK:0StartSlot:00
NUMP:22
PNUM:00POFF:7774PRID:0x06003804.0
PNUM:01POFF:15790PRID:0x06003805.0
PNUM:02POFF:23806PRID:0x06003806.0
PNUM:03POFF:31822PRID:0x06003807.0
PNUM:04POFF:39838PRID:0x06003808.0
PNUM:05POFF:47854PRID:0x06003809.0
PNUM:06POFF:55870PRID:0x0600380a.0
PNUM:07POFF:63886PRID:0x0600380b.0
PNUM:08POFF:71902PRID:0x0600380c.0
PNUM:09POFF:79918PRID:0x0600380d.0
PNUM:10POFF:87934PRID:0x0600380e.0
PNUM:11POFF:95950PRID:0x0600380f.0
PNUM:12POFF:103966PRID:0x06003810.0
PNUM:13POFF:111982PRID:0x06003811.0
PNUM:14POFF:119998PRID:0x06003812.0
PNUM:15POFF:128014PRID:0x06003813.0
PNUM:16POFF:136030PRID:0x06003814.0
PNUM:17POFF:144046PRID:0x06003815.0
PNUM:18POFF:152062PRID:0x06003816.0
PNUM:19POFF:160078PRID:0x06003817.0
PNUM:20POFF:168094PRID:0x06003818.0
PNUM:21POFF:176110PRID:0x06003819.0
*---------
CUheader:
CUversion:0CUmagicnumber:0x4b445a30
CUchecksum:0xbdbe82d3
CUtotallength:180160
CUflags:NC-U-CRD-OP
ncols:26
nrows:32759
algo:0
CUdecomplength:175939len/valuelength:4332401
rowpiecesperrow:1
numdeletedrows:0
START_CU:

这部分信息较多,我按照个人的理解来说说。

tl: 8016 fb: –H-F–N这里的H是CUhead的意思。fb是flag byte,F是first的意思,P是previous,N是next。此外我没有dump最后一个row piece,按道理来说,最后一个0x06003819块上的fb会显示L的,代表last。(事实上我事后dump了,显示的LP)


nrid: 0x06003804.0这里nrid是next row piece id的意思,这里的数据是nrid: 0x06003804.0,换成10进制是rdba: 0x6003804(100677636) file: 24 ,block : 14340,24号文件14340块。


按照道理来说,14340块上显示的是类似PN,没有H的tag。


Compression level: 04 (Archive High)是HCC压缩格式。


NUMP: 22是代表这个CU里有多少个row piece,这里显示的是22个row piece,而根据这个地址看,一个row piece就是一个block,我理解是代表,这个CU里有22个block。


CU checksum: 0xbdbe82d3是这个CU的校验值。


nrows: 32759,代表这个CU里存了32759行,这是一个非常大的数值。

接下来,我们dump那个第二个CU块,14340块。

Startdumpdatablockstsn:6file#:24minblk14340maxblk14340
..........................
..........................
..........................
block_row_dump:
tab0,row0,@0x1f
tl:8033fb:------PNlb:0x0cc:1
nrid:0x06003805.0
col0:[8021]
Compressionlevel:04(ArchiveHigh)
LengthofCUrow:8021
kdzhrh:---------START_CU:

如上文标识的一样,这是PN。

这里将分别按照insert,update,delete这三个DML来测试在HCC情况下相关的可能的压缩转换情况,ROWID变化情况,锁范围情况来阐述。

在DML场景中,对比两张表,非压缩表和压缩表。压缩表的所有行,都在一个CU的一个块里。

如下是创建的表,有一张普通表,一张archive high的表,以及一张row level locking的archive high表。他们分配的大小是一样的,这不代表在extents内占的空间是一样大,而是因为表初始分配的extents是8个block,每个block是8192 bytes。这个是ASSM的分配规律。

SQL>createtabledml_test_no_ehccasselect*fromdba_objectswhererownum<100;

Tablecreated.

SQL>updatedml_test_no_ehccsetOBJECT_ID=rownum;

99rowsupdated.

SQL>commit;

Commitcomplete.

SQL>createtableDML_TEST_ARCHIVE_HIGHcompressforarchivehightablespaceehcctbsasselect*fromdml_test_no_ehcc;

Tablecreated.

SQL>createtableDML_TEST_ARCHIVE_HIGH_LOCKINGcompressforarchivehighrowlevellockingtablespaceehcctbsasselect*fromdml_test_no_ehcc;

Tablecreated.

colOWNERfora15
colSEGMENT_NAMEfora40

SQL>selects.OWNER,s.SEGMENT_NAME,s.BYTES/1024SIZE_MB,t.COMPRESS_FORfromdba_segmentss,dba_tablestwheres.SEGMENT_NAMElike('DML_TEST_%')ands.owner=t.ownerands.segment_name=t.table_nameorderby2;

OWNERSEGMENT_NAMESIZE_MBCOMPRESS_FOR
---------------------------------------------------------------------------------------------------
SYSDML_TEST_ARCHIVE_HIGH64ARCHIVEHIGH
SYSDML_TEST_ARCHIVE_HIGH_LOCKING64ARCHIVEHIGHROWLEVELLOCKING
SYSDML_TEST_NO_EHCC

接下来,需要证明这两个HCC的表的所有行都在同一个CU里。


这个时候,除去一级和二级位图块,dump每个表的第四个块,就是说DML_TEST_ARCHIVE_HIGH在24号文件的19203块,和DML_TEST_ARCHIVE_HIGH_LOCKING在24号文件的19211块,从dump信息中查看是否所有行在一个CU内。

19203块,信息如下,可以看到fb标识为Head,有F,有L,代表这个CU既是first也是last的CU,并且这个CU里的nrows 是99行。这都跟构造的环境一致。

data_block_dump,dataheaderat0x9b95a07c
===============
tsiz:0x1f80
hsiz:0x1c
pbl:0x9b95a07c
76543210
flag=-0------
ntab=1
nrow=1
frre=-1
fsbo=0x1c
fseo=0x1830
avsp=0x1814
tosp=0x1814
r0_9ir2=0x0
mec_kdbh9ir2=0x0
76543210
shcf_kdbh9ir2=----------
76543210
flag_9ir2=--R-----Archivecompression:Y
fcls_9ir2[0]={}
0x16:pti[0]nrow=1offs=0
0x1a:pri[0]offs=0x1830
block_row_dump:
tab0,row0,@0x1830
tl:1872fb:--H-FL--lb:0x0cc:1
col0:[1866]
Compressionlevel:04(ArchiveHigh)
LengthofCUrow:1866
kdzhrh:---------StartSlot:00
*---------
CUheader:
CUversion:0CUmagicnumber:0x4b445a30
CUchecksum:0x24a713c2
CUtotallength:1854
CUflags:NC-U-CRD-OP
ncols:26
nrows:99
algo:0
CUdecomplength:1715len/valuelength:10614
rowpiecesperrow:1
numdeletedrows:0
START_CU:

同样,另外一个表的19211块也是得到一样的构造信息。

data_block_dump,dataheaderat0x7fda7a65e07c
===============
tsiz:0x1f80
hsiz:0x1c
pbl:0x7fda7a65e07c
76543210
flag=-0------
ntab=1
nrow=1
frre=-1
fsbo=0x1c
fseo=0x17c9
avsp=0x17ad
tosp=0x17ad
r0_9ir2=0x0
mec_kdbh9ir2=0x0
76543210
shcf_kdbh9ir2=----------
76543210
flag_9ir2=--R-----Archivecompression:Y
fcls_9ir2[0]={}
0x16:pti[0]nrow=1offs=0
0x1a:pri[0]offs=0x17c9
block_row_dump:
tab0,row0,@0x17c9
tl:1975fb:--H-FL--lb:0x0cc:1
col0:[1969]
Compressionlevel:04(ArchiveHigh)
LengthofCUrow:1969
kdzhrh:--------LStartSlot:00
numlockbits:8
lockedrows:
*---------
CUheader:
CUversion:0CUmagicnumber:0x4b445a30
CUchecksum:0x24a713c2
CUtotallength:1854
CUflags:NC-U-CRD-OP
ncols:26
nrows:99
algo:0
CUdecomplength:1715len/valuelength:10614
rowpiecesperrow:1
numdeletedrows:0
START_CU:

OLTP下的第一个场景测试,我们暂定为insert测试,这里只针对HCC的表做测试,分别测试append方式和常规插入方式在HCC表及row level locking的HCC表下的表现。

根据文档显示,对已经HCC压缩的表的插入,如果是常规插入,新插入的数据将不会被压缩,只有以append等直接路径的方式插入,才会继续压缩。这里除了需要验证这个事情之外,还需要验证下其他会话的并发插入会不会受影响,如果被阻塞,需要测试row level locking方式的HCC表是否受影响。

SQL>selectdistinct(sid)fromv$mystat;

SID
----------
147

SQL>insertintoDML_TEST_ARCHIVE_HIGHselect*fromDML_TEST_NO_EHCC;

99rowscreated.

SQL>

SQL>selectdistinct(sid)fromv$mystat;

SID
----------
269

SQL>insertintoDML_TEST_ARCHIVE_HIGHselect*fromDML_TEST_NO_EHCC;

99rowscreated.

SQL>

这个测试为了证明没有row level locking属性的HCC表的插入,不会锁定单个CU。

但是,这个测试测下来,有一个问题,就是对于没有使用append方式的插入,如果插入的数据,当前已经压缩的CU可以容下,那么插入的数据是会被压缩的,如果以没有append方式插入的数据,当前CU放置不下,那么在接下来的分配中,超出当前CU的数据是特么的不会被压缩的。

这个又一次出乎意料。

COUNT(*)COMPRESSION_TYPE
-------------------------------------------------------------------------
10COMP_NOCOMPRESS
323126COMP_FOR_ARCHIVE_HIGH

SQL>

OLTP下的第二个场景,我们测试DELETE,这个我也不知道测试什么,我暂且对HCC的表,做两个会话的删除测试。

我测试了两次,如果这个表没有被压缩,我分别在两个会话中,删除object_id=1及2的数据,不提交,是互相不会阻塞的。

但是,如果这个表是HCC压缩,并且没有开启row level locking的话,如果在会话1删除object_id=1的条目,在会话2中删除object_id=2的条目,会话2的删除,是会被会话1阻塞的。


这也侧面验证了,普通HCC表,锁的最小单元是CU,而不是像普通表那样,受影响的是被其他会话已经影响到的行。不过仔细一想,道理似乎是一样的。


那么,我前面铺垫了那么多row level locking的HCC特性这个时候就发挥作用了。这个特性是在12c的HCC中引入了。Oracle corp可能发现对整个CU加锁影响的范围太大了,为了对OLTP友好,引入了row level locking的HCC的特性,虽然这可能带来一点点的压缩损耗,在前文能看到压缩损耗的情况。


接下来,对那张创建好的row level locking的表做不同会话的object_id=1和object_id=2的记录的删除。


可以看到添加了row level locking属性的HCC表的同个CU内的删除是互不影响的。

OLTP中,第三个场景测试,我们将测试update,据前文DELETE测试,可以显然的知道,HCC中不带row level locking的压缩是会被其他update阻塞的。带了的话,如果针对同一个CU内不同记录操作,是不会影响的。如果是同一个CU内的相同记录操作,那会是怎么样呢:)。

UPDATE部分,这里重点测试的是rowid变化情况。

重新生成环境:

SQL>droptableDML_TEST_ARCHIVE_HIGHpurge;

Tabledropped.

SQL>droptableDML_TEST_ARCHIVE_HIGH_LOCKINGpurge;

Tabledropped.

SQL>droptableDML_TEST_NO_EHCCpurge;

Tabledropped.

这次表创建的更小。

SQL>createtabledml_test_no_ehccasselect*fromdba_objectswhererownum<10;

Tablecreated.

SQL>createtableDML_TEST_ARCHIVE_HIGHcompressforarchivehightablespaceehcctbsasselect*fromdml_test_no_ehcc;

Tablecreated.

SQL>createtableDML_TEST_ARCHIVE_HIGH_LOCKINGcompressforarchivehighrowlevellockingtablespaceehcctbsasselect*fromdml_test_no_ehcc;

Tablecreated.

SQL>
SQL>colOWNERfora15
SQL>colSEGMENT_NAMEfora40
SQL>selects.OWNER,s.SEGMENT_NAME,s.BYTES/1024SIZE_MB,t.COMPRESS_FORfromdba_segmentss,dba_tablestwheres.SEGMENT_NAMElike('DML_TEST_%')ands.owner=t.ownerands.segment_name=t.table_nameorderby2;

OWNERSEGMENT_NAMESIZE_MBCOMPRESS_FOR
-----------------------------------------------------------------------------------------------------------------------------------------------------------
HRDML_TEST_ARCHIVE_HIGH64ARCHIVEHIGH
HRDML_TEST_ARCHIVE_HIGH_LOCKING64ARCHIVEHIGHROWLEVELLOCKING
HRDML_TEST_NO_EHCC64

SQL>

查看其中HCC表的rowid及块号分布情况。

SQL>selectrowid,object_name,dbms_rowid.rowid_block_number(rowid)fromDML_TEST_ARCHIVE_HIGH;

ROWIDOBJECT_NAMEDBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)
----------------------------------------------------------------------------------------------
AAAR0vAAWAAAEWLAAAI_FILE#_BLOCK#17803
AAAR0vAAWAAAEWLAABI_OBJ317803
AAAR0vAAWAAAEWLAACI_TS117803
AAAR0vAAWAAAEWLAADI_CON117803
AAAR0vAAWAAAEWLAAEIND$17803
AAAR0vAAWAAAEWLAAFCDEF$17803
AAAR0vAAWAAAEWLAAGC_TS#17803
AAAR0vAAWAAAEWLAAHI_CCOL217803
AAAR0vAAWAAAEWLAAII_PROXY_DATA$17803

9rowsselected.

这里可以通过DBMS_COMPRESSION.GET_COMPRESSION_TYPE来确认某行数据的压缩方式:

SQL>selectDBMS_COMPRESSION.GET_COMPRESSION_TYPE('HR','DML_TEST_ARCHIVE_HIGH','AAAR0vAAWAAAEWLAAA')fromdual;

DBMS_COMPRESSION.GET_COMPRESSION_TYPE('HR','DML_TEST_ARCHIVE_HIGH','AAAR0VAAWAAAEWLAAA')
----------------------------------------------------------------------------------------
16

参考如下:

COMP_NOCOMPRESSCONSTANTNUMBER:=1;
COMP_FOR_OLTPCONSTANTNUMBER:=2;
COMP_FOR_QUERY_HIGHCONSTANTNUMBER:=4;
COMP_FOR_QUERY_LOWCONSTANTNUMBER:=8;
COMP_FOR_ARCHIVE_HIGHCONSTANTNUMBER:=16;
COMP_FOR_ARCHIVE_LOWCONSTANTNUMBER:=32;

COMP_RATIO_MINROWSCONSTANTNUMBER:=1000000;
COMP_RATIO_ALLROWSCONSTANTNUMBER:=-1;

可以得知,16就是创建时候的ARCHIVE_HIGH压缩方式。

之后,对这个表,进行更新操作。

SQL>updateDML_TEST_ARCHIVE_HIGHsetOBJECT_NAME=OBJECT_NAME||'MINOR';

9rowsupdated.


再次查看这个表的rowid及块号:


SQL>selectrowid,object_name,dbms_rowid.rowid_block_number(rowid)fromDML_TEST_ARCHIVE_HIGH;

ROWIDOBJECT_NAMEDBMS_ROWID.ROWID_BLOCK_NUMBER(ROWID)
----------------------------------------------------------------------------------------------
AAAR0vAAWAAAEWOAAAI_FILE#_BLOCK#MINOR17806
AAAR0vAAWAAAEWOAABI_OBJ3MINOR17806
AAAR0vAAWAAAEWOAACI_TS1MINOR17806
AAAR0vAAWAAAEWOAADI_CON1MINOR17806
AAAR0vAAWAAAEWOAAEIND$MINOR17806
AAAR0vAAWAAAEWOAAFCDEF$MINOR17806
AAAR0vAAWAAAEWOAAGC_TS#MINOR17806
AAAR0vAAWAAAEWOAAHI_CCOL2MINOR17806
AAAR0vAAWAAAEWOAAII_PROXY_DATA$MINOR17806

9rowsselected.

可以看到,rowid,block id,都发生了变化,所以证明对CU内的数据更新,这里有解压,移动到别的block更新的操作。

那么更新后的数据还是压缩的吗?显然,不是了。

SQL>selectDBMS_COMPRESSION.GET_COMPRESSION_TYPE('HR','DML_TEST_ARCHIVE_HIGH',rowid)fromDML_TEST_ARCHIVE_HIGH;

DBMS_COMPRESSION.GET_COMPRESSION_TYPE('HR','DML_TEST_ARCHIVE_HIGH',ROWID)
-------------------------------------------------------------------------
1
1
1
1
1
1
1
1
1

9rowsselected.

压缩为1,1代表的是COMP_NOCOMPRESS CONSTANT NUMBER := 1,不压缩。所以,除了insert,update也会带来解压不压缩的情况。在执行update操作时,db会将列压缩的数据,转换为行来操作,并且在操作完成之后,并不会再次压缩。

如果需要重新让这些复苏的数据重新压缩,需要显式的move这些表。

刚才注意到,更新会导致压缩数据的rowid发生变化,那么,能不能不变化?答案是可以的。

隐含参数:



然后我们复现上面的更新操作:


第三部分,上面OLAP及OLTP的这么多测试均是单个场景的测试,那么HCC在实际场景下使用起来跟不带HCC的环境对比起来怎么样?这里想起了swingbench。

swingbench不多介绍。但是有个问题,swingbench的对象是自己程序生成的,不能人工干预创建对象用的参数,除非你逐个去改那些脚本。

其实有个简单的办法,就是创建测试表空间的时候,给表空间加上HCC参数。这里只做query high场景下不带row level locking及带row level locking跟非HCC场景下的压力测试。考虑到客户环境不是会串行的,所以我使用4个会话来测试。测试基准数据量为0.5GB,要测三场。

首先生成三个承载表空间,一个是带了HCC属性,一个是带了HCC的row level locking属性,一个是不带HCC属性。

SQL>CREATESMALLFILETABLESPACESOE_EHCC_TBS
2DATAFILE
3'/ehccfs/ORA19C/ora19pdb1/SOE_EHCC_TBS_001.DBF'SIZE10485760AUTOEXTENDONNEXT1048576MAXSIZE10737418240
4BLOCKSIZE8192
5FORCELOGGING
6DEFAULTCOLUMNSTORECOMPRESSFORqueryHIGHNOINMEMORY
7ONLINE
8SEGMENTSPACEMANAGEMENTAUTO
9EXTENTMANAGEMENTLOCALAUTOALLOCATE;

Tablespacecreated.


SQL>CREATESMALLFILETABLESPACESOE_NO_EHCC_TBS
2DATAFILE
3'/ehccfs/ORA19C/ora19pdb1/SOE_NO_EHCC_TBS_001.DBF'SIZE10485760AUTOEXTENDONNEXT1048576MAXSIZE10737418240
4BLOCKSIZE8192
5FORCELOGGING
6DEFAULTCOLUMNSTORECOMPRESSFORqueryHIGHNOINMEMORY
7ONLINE
8SEGMENTSPACEMANAGEMENTAUTO
9EXTENTMANAGEMENTLOCALAUTOALLOCATE;

Tablespacecreated.

SQL>CREATESMALLFILETABLESPACESOE_EHCC_ROW_LOCKING_TBS
2DATAFILE
3'/ehccfs/ORA19C/ora19pdb1/SOE_EHCC_ROW_LOCKING_TBS_001.DBF'SIZE10485760AUTOEXTENDONNEXT1048576MAXSIZE10737418240
4BLOCKSIZE8192
5FORCELOGGING
6DEFAULTCOLUMNSTORECOMPRESSFORqueryHIGHROWLEVELLOCKINGNOINMEMORY
7ONLINE
8SEGMENTSPACEMANAGEMENTAUTO
9EXTENTMANAGEMENTLOCALAUTOALLOCATE;

Tablespacecreated.

最终能看到生成的数据如下:



待数据生成完成之后,开始swingbench的测试。这里停止了测试。因为在swingbench的默认场景中,有大量的DML操作,而跟我上文测试的结果,随着业务时间的推移,大部分表都会因DML而变成非压缩表。所以DML测试的意义不大。唯一可能有测试意义的就是OLAP了。这个修改swingbench配置此处省略。