MySQL5.7 InnoDB Page Compression

yzs87發表於2017-12-10

1、介紹

mysql5.7中,innodb頁結構增加了一個型別FIL_PAGE_COMPRESSED,用來完成Transparent page compression 特性

2、說明

1)壓縮內容包括:除去FIL_PAGE_DATA外所有資料,包括tail
2)壓縮後的內容+FIL_PAGE_DATA會以block_size對齊,並將空洞清0。意味著將16K壓縮到9K,也需要12KB的資料,因此將block_size設小點,這樣的場景將受益,可以
   減少空間浪費。
3)FIL_PAGE_VERSION內容存1;FIL_PAGE_ALGORITHM_V1指哪個壓縮演算法:ZLIB、LZ4
   FIL_PAGE_ORIGINAL_TYPE_V1:原始頁型別;
   FIL_PAGE_ORIGINAL_SIZE_V1:原始頁需要壓縮的內容大小
   FIL_PAGE_COMPRESS_SIZE_V1:內容壓縮後大小
4)目前支援2種壓縮演算法:zlib和lz4,可以方便擴充套件新的演算法
5)壓縮只是在持久化磁碟的時候壓縮,記憶體中的頁仍然是原始的樣子

3、用法

表定義:
可以透過CREATE TABLE、ALTER TABLE來定義壓縮表:
  create table t1(i int,b blob) compression='zlib';
也可以選擇compression='lz4'來指定lz4壓縮演算法,注意compression屬性的ALTER是立即生效,在做完ALTER COMPRESSION屬性操作後,需要做一次表的rebuild,例如optimize table操作,才能對已有的資料做punch hole。compression屬性儲存在frm檔案中,以2個位元組儲存字串長度,隨後儲存compression屬性定義字串,這也是一個作業系統降級的風險點。

4、程式碼分析

點選(此處)摺疊或開啟

  1. static
  2. byte*
  3. os_file_compress_page(
  4.     Compression    compression,
  5.     ulint        block_size,//檔案系統block大小。通常4K
  6.     byte*        src,//需要壓縮頁的指標
  7.     ulint        src_len,//頁大小
  8.     byte*        dst,//壓縮後,存入目標
  9.     ulint*        dst_len)//壓縮記憶體長度
  10. {
  11.     ulint        len = 0;
  12.     ulint        compression_level = page_zip_level;
  13.     ulint        page_type = mach_read_from_2(src + FIL_PAGE_TYPE);

  14.     //如果要節省空間,頁大小至少是檔案系統block的2倍。壓縮的頁不包括R-tree頁
  15.     if (page_type == FIL_PAGE_RTREE
  16.      || block_size == ULINT_UNDEFINED
  17.      || compression.m_type == Compression::NONE
  18.      || src_len < block_size * 2) {

  19.         *dst_len = src_len;

  20.         return(src);
  21.     }

  22.     /* Must compress to <= N-1 FS blocks. */
  23.     ulint        out_len = src_len - (FIL_PAGE_DATA + block_size);

  24.     /* This is the original data page size - the page header. */
  25.     ulint        content_len = src_len - FIL_PAGE_DATA;

  26.     /* Only compress the data + trailer, leave the header alone */

  27.     switch (compression.m_type) {
  28.     case Compression::NONE:
  29.         ut_error;

  30.     case Compression::ZLIB: {

  31.         uLongf    zlen = static_cast<uLongf>(out_len);

  32.         if (compress2(
  33.             dst + FIL_PAGE_DATA,
  34.             &zlen,
  35.             src + FIL_PAGE_DATA,
  36.             static_cast<uLong>(content_len),
  37.             static_cast<int>(compression_level)) != Z_OK) {

  38.             *dst_len = src_len;

  39.             return(src);
  40.         }

  41.         len = static_cast<ulint>(zlen);

  42.         break;
  43.     }

  44.     case Compression::LZ4:

  45.         len = LZ4_compress_default(
  46.             reinterpret_cast<char*>(src) + FIL_PAGE_DATA,
  47.             reinterpret_cast<char*>(dst) + FIL_PAGE_DATA,
  48.             static_cast<int>(content_len),
  49.             static_cast<int>(out_len));

  50.         if (len == 0 || len >= out_len) {

  51.             *dst_len = src_len;

  52.             return(src);
  53.         }

  54.         break;

  55.     default:
  56.         *dst_len = src_len;
  57.         return(src);
  58.     }

  59.     /* Copy the header as is. */
  60.     memmove(dst, src, FIL_PAGE_DATA);

  61.     /* Add compression control information. Required for decompressing. */
  62.     mach_write_to_2(dst + FIL_PAGE_TYPE, FIL_PAGE_COMPRESSED);

  63.     mach_write_to_1(dst + FIL_PAGE_VERSION, 1);

  64.     mach_write_to_1(dst + FIL_PAGE_ALGORITHM_V1, compression.m_type);

  65.     mach_write_to_2(dst + FIL_PAGE_ORIGINAL_TYPE_V1, page_type);

  66.     mach_write_to_2(dst + FIL_PAGE_ORIGINAL_SIZE_V1, content_len);

  67.     mach_write_to_2(dst + FIL_PAGE_COMPRESS_SIZE_V1, len);

  68.     /* Round to the next full block size */

  69.     len += FIL_PAGE_DATA;

  70.     *dst_len = ut_calc_align(len, block_size);

  71.     /* Clear out the unused portion of the page. */
  72.     if (len % block_size) {
  73.         memset(dst + len, 0x0, block_size - (len % block_size));
  74.     }

  75.     return(dst);
  76. }

5、參考




來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31493717/viewspace-2148515/,如需轉載,請註明出處,否則將追究法律責任。

相關文章