Exadata Hybrid Columnar Compression に関する検証 その3

<Exadata Hybrid Columnar Compression に関する検証 その3>
ペンネーム: ベロ

新年明けましておめでとうございます。年末、年始だと何かと慌ただしく
なかなか検証する時間も取れないでいましたが、重い腰を上げて今年も
ガッツリHybrid Columnar Compressionの検証を開始します。

なかなかシブイネタが続きますが、お付き合いのほどよろしくお願いします。

昨年の事なので、経緯をお忘れの読者のために簡単に今までの流れをまとめて
みます。

第1回
Oracle 11gR2よりHybrid Columnar Compressionなる新たなデータ圧縮機能が
追加されています。データ圧縮は現在のデータ量爆発の世界では、ストレージ
コストの削減とともにパフォーマンスに関しても有利にはたらく傾向があり、
主にDWH系システムで注目されている技術です。

「しかし」このHybrid Columnar Compressionという新機能はExadataでしか
サポートされおらず、その有効性を検証することができない

第2回
オラクル社のサポート外のため、Exadataではない通常のOracle 11gR2にて
Hybrid Columnar Compressionを使用可能にする技は自主規制のもと、
検証スタート

各種圧縮形式にて、圧縮率と圧縮にかかる時間を計測。結果、Queryタイプの
圧縮はDWHであっても比較的参照が多いテーブルが適しており、Archiveタイプ
の圧縮は、参照頻度が低い、まさしくアーカイブ的に使用するテーブルが
適していると言えると結論づけました。

また、第3回は、表面的な検証から内部的な検証に移ると宣言しました。

では、早速、Hybrid Columnar Compressionの動作イメージから確認しましょう。

1. Hybrid Columnar CompressionはテーブルをCompression Unit(CU)という単位
    で分割して圧縮します。
2. Compression Unit内のデータはカラムごとに分類して圧縮します
    * これがColumnarと名がつく所以です
3. 圧縮データに対してUpdateが発生すると自動で該当行は、OLTPタイプの圧縮に
    変更されます
    * 2で説明したColumnarと従来の圧縮との合わせ技であることからHybridと名が
    つくようです

ここから先の検証内容ですが、

1. Compression Unitとは何ぞや?
2. Columnarの所以であるカラム単位の圧縮とは?
3. OLTPタイプの圧縮にコンバートするオーバーヘッドやクエリーのパフォーマンスの
    違い(圧縮の有無での違い)など

を実施していきます。今回はCompression Unitとは何ぞや?です。

先ずは、ブロックの中身を覗いてみます。

select segment_name,file_id,block_id,blocks
from dba_extents
where segment_name = 'QUERY_HIGH_COMPRESS_TABLE',
and extent_id=0;

SEGMENT_NAME FILE_ID BLOCK_ID BLOCKS
------------------------------ ---------- ---------- ----------
QUERY_HIGH_COMPRESS_TABLE 6 682898 13

alter system dump datafile 6 block min 682898 block max 682911;

今回は、手始めにQueryタイプのテーブルのExtentID=0を指定してダンプを取得
しています。

上記のダンプファイルよりHybrid Columnar Compressionのブロック構造は
大まかに以下のように形成されていることが分かります。

┌──────────── Compression Unit ─────────────┐
│┌──BLOCK#1 ──┐ ┌──BLOCK#2 ──┐ ┌──Block#3 ──┐      │
││Block header    │ │Block header    │ │Block header    │      │
││CU header       │ │CU piece        │ │CU piece        │      │
││CU piece        │ │                │ │                │      │
││                │ │                │ │                │      │
││                │ │                │ │                │      │
││                │ │                │ │                │      │
││                │ │                │ │                │      │
│└────────┘ └────────┘ └────────┘   ...│
└──────────────────────────────────┘

ここでBlock headerはお決まりのブロックヘッダーなのですが、ダンプのなかに
見慣れないCU headerなるものが存在しています。

-------------------------------------------------------------------------------
QUERY HIGHで圧縮したテーブルのブロックダンプ
-------------------------------------------------------------------------------
tab 0, row 1, @0x28
tl: 2089 fb: --H-F--N lb: 0x0 cc: 1
nrid: 0x018aeaa5.0
col 0: [2077]
Compression level: 02 (Query High)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ ← ①
Length of CU row: 2077
^^^^^^^^^^^^^^^^^^^^^^ ← ②
kdzhrh: ------PC CBLK: 4 Start Slot: 00
NUMP: 04
^^^^^^^^ ← ③
PNUM: 00 POFF: 2027 PRID: 0x018aeaa5.0
PNUM: 01 POFF: 10043 PRID: 0x018aeaa6.0
PNUM: 02 POFF: 18059 PRID: 0x018aeaa7.0
PNUM: 03 POFF: 26075 PRID: 0x018aeaa8.0
CU header:
CU version: 0 CU magic number: 0x4b445a30
CU checksum: 0x7d688bc2
CU total length: 31951
CU flags: NC-U-CRD-OP
ncols: 8
nrows: 2192
algo: 0
CU decomp length: 31623 len/value length: 139549
row pieces per row: 1
num deleted rows: 0
-------------------------------------------------------------------------------

実際のところCompression Unitに関する詳細なドキュメントはOracle社から
提供されていないのですが、要約すると以下にようなことが言えるのでは
ないかと思います。

上記ダンプからはCompression level(①)とそのCompression Unitに含まれる
行数(②)が確認できます。
また、NUMP(多分Number of Pieces)4ブロックをCompression Unitとしてアサイン
していると思われます(③)。今回はQueryタイプなので4ブロック(32KB)であるが
Archiveタイプの場合は26といった大きなCompression Unitをアサインしている
場合がありました。
また、アサインされたPNUM(多分 Piece Number)は物理的なブロックです。

ただ、ダンプからは、Columnarの実体を正確に確認することができませんでした。
しかし、何とかしてColumnarの実体を突き止めるべく検証をしていきたいと
思います。

ということで、Hybrid Columnar Compressionとして新たに登場したCompression
Unitですが、まとめると以下のような動作およびメリットがあると考えられます。

- 圧縮の単位であり、従来のブロック単位ではなく、複数のブロックにまたがった
  単位である
- Query/Archiveなどの圧縮タイプにより、またがるブロック数が変化しているよう
  である
- また、Compression Unit内では、カラム別に圧縮されているようである(きっと)
- このことにより、似たようなデータ(カラム別なので)が大量に(複数ブロック分)
  集まり、圧縮効率を高めるようである

当たり前なのですが、メリットがあればデメリットもあります。
Hybrid Columnar CompressionはCompression Unit単位で圧縮を行うと言いましたが
DMLに対してもCompression Unit単位でロックを取得します。
DWHシステムのように頻繁に更新処理が発生しない場合は問題になりにくいかも
知れませんが、OLTPシステムでは、大きな問題になることは言うまでもありません。
(そもそも、Hybrid Columnar CompressionはDWHシステム向けだとOracle社のWhite
Paperにありますので、OLTP系システムは想定外ですね。。。つまり、Hybrid
Columnar CompressionはWrite-Once Read-Manyのようなシステムに向いていると
考えられます)
ここから、QUERYやARCHIVEといった新しい圧縮に関しては、高い圧縮率とトレード
オフで、同時実行性を犠牲にする必要があると言えます。

では次回からは、さらにCompression UnitやColumnarについて検証を深めて
いきたいと思います。