summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
Diffstat (limited to 'storage')
-rw-r--r--storage/innobase/CMakeLists.txt4
-rw-r--r--storage/innobase/fil/fil0pagecompress.cc322
-rw-r--r--storage/innobase/handler/ha_innodb.cc55
-rw-r--r--storage/innobase/include/fil0fil.h21
-rw-r--r--storage/innobase/include/fsp0pagecompress.h14
-rw-r--r--storage/innobase/include/fsp0pagecompress.ic3
-rw-r--r--storage/innobase/include/univ.i13
-rw-r--r--storage/innobase/os/os0file.cc17
-rw-r--r--storage/innobase/srv/srv0srv.cc2
-rw-r--r--storage/xtradb/CMakeLists.txt4
-rw-r--r--storage/xtradb/fil/fil0pagecompress.cc322
-rw-r--r--storage/xtradb/handler/ha_innodb.cc55
-rw-r--r--storage/xtradb/include/fil0fil.h21
-rw-r--r--storage/xtradb/include/fsp0pagecompress.h14
-rw-r--r--storage/xtradb/include/fsp0pagecompress.ic3
-rw-r--r--storage/xtradb/include/univ.i13
-rw-r--r--storage/xtradb/os/os0file.cc21
-rw-r--r--storage/xtradb/srv/srv0srv.cc2
18 files changed, 833 insertions, 73 deletions
diff --git a/storage/innobase/CMakeLists.txt b/storage/innobase/CMakeLists.txt
index ced05daee3e..622fff87536 100644
--- a/storage/innobase/CMakeLists.txt
+++ b/storage/innobase/CMakeLists.txt
@@ -20,9 +20,13 @@ INCLUDE(CheckCSourceCompiles)
INCLUDE(CheckCSourceRuns)
INCLUDE(lz4)
INCLUDE(lzo)
+INCLUDE(lzma)
+INCLUDE(bzip2)
MYSQL_CHECK_LZ4()
MYSQL_CHECK_LZO()
+MYSQL_CHECK_LZMA()
+MYSQL_CHECK_BZIP2()
# OS tests
IF(UNIX)
diff --git a/storage/innobase/fil/fil0pagecompress.cc b/storage/innobase/fil/fil0pagecompress.cc
index b717590499b..7980bb1a7bd 100644
--- a/storage/innobase/fil/fil0pagecompress.cc
+++ b/storage/innobase/fil/fil0pagecompress.cc
@@ -68,11 +68,185 @@ static ulint srv_data_read, srv_data_written;
#ifdef HAVE_LZO
#include "lzo/lzo1x.h"
#endif
+#ifdef HAVE_LZMA
+#include "lzma.h"
+#endif
+#ifdef HAVE_BZIP2
+#include "bzlib.h"
+#endif
/* Used for debugging */
//#define UNIV_PAGECOMPRESS_DEBUG 1
/****************************************************************//**
+For page compressed pages decompress the page after actual read
+operation. */
+static
+void
+fil_decompress_page_2(
+/*==================*/
+ byte* page_buf, /*!< out: destination buffer for
+ uncompressed data */
+ byte* buf, /*!< in: source compressed data */
+ ulong len, /*!< in: length of output buffer.*/
+ ulint* write_size) /*!< in/out: Actual payload size of
+ the compressed data. */
+{
+ ulint page_type = mach_read_from_2(buf + FIL_PAGE_TYPE);
+
+ if (page_type != FIL_PAGE_COMPRESSED) {
+ /* It is not a compressed page */
+ return;
+ }
+
+ ulint olen = 0;
+ byte* ptr = buf + FIL_PAGE_DATA;
+ ulint version = mach_read_from_1(buf + FIL_PAGE_VERSION);
+ int err = 0;
+
+ ut_a(version == 1);
+
+ /* Read the original page type, before we compressed the data. */
+ page_type = mach_read_from_2(buf + FIL_PAGE_ORIGINAL_TYPE_V1);
+
+ ulint original_len = mach_read_from_2(buf + FIL_PAGE_ORIGINAL_SIZE_V1);
+
+ if (original_len < UNIV_PAGE_SIZE_MIN - (FIL_PAGE_DATA + 8)
+ || original_len > UNIV_PAGE_SIZE_MAX - FIL_PAGE_DATA
+ || len < original_len + FIL_PAGE_DATA) {
+ fprintf(stderr,
+ "InnoDB: Corruption: We try to uncompress corrupted page\n"
+ "InnoDB: Original len %lu len %lu.\n",
+ original_len, len);
+
+ fflush(stderr);
+ ut_error;
+
+ }
+
+ ulint algorithm = mach_read_from_1(buf + FIL_PAGE_ALGORITHM_V1);
+
+ switch(algorithm) {
+ case PAGE_ZLIB_ALGORITHM: {
+
+ fprintf(stderr, "InnoDB: [Note]: zlib\n");
+
+ err = uncompress(page_buf, &len, ptr, original_len);
+ /* If uncompress fails it means that page is corrupted */
+ if (err != Z_OK) {
+
+ fprintf(stderr,
+ "InnoDB: Corruption: Page is marked as compressed\n"
+ "InnoDB: but uncompress failed with error %d.\n"
+ "InnoDB: size %lu len %lu\n",
+ err, original_len, len);
+
+ fflush(stderr);
+
+ ut_error;
+ }
+
+ break;
+ }
+#ifdef HAVE_LZ4
+ case PAGE_LZ4_ALGORITHM: {
+ fprintf(stderr, "InnoDB: [Note]: lz4\n");
+ err = LZ4_decompress_fast(
+ (const char*) ptr, (char*) (page_buf), original_len);
+
+ if (err < 0) {
+ fprintf(stderr,
+ "InnoDB: Corruption: Page is marked as compressed\n"
+ "InnoDB: but decompression read only %d bytes.\n"
+ "InnoDB: size %lu len %lu\n",
+ err, original_len, len);
+ fflush(stderr);
+
+ ut_error;
+ }
+ break;
+ }
+#endif /* HAVE_LZ4 */
+
+#ifdef HAVE_LZMA
+ case PAGE_LZMA_ALGORITHM: {
+
+ lzma_ret ret;
+ size_t src_pos = 0;
+ size_t dst_pos = 0;
+ uint64_t memlimit = UINT64_MAX;
+
+ fprintf(stderr, "InnoDB: [Note]: lzma\n");
+ ret = lzma_stream_buffer_decode(
+ &memlimit,
+ 0,
+ NULL,
+ ptr,
+ &src_pos,
+ original_len,
+ (page_buf),
+ &dst_pos,
+ len);
+
+
+ if (ret != LZMA_OK || (dst_pos <= 0 || dst_pos > len)) {
+ fprintf(stderr,
+ "InnoDB: Corruption: Page is marked as compressed\n"
+ "InnoDB: but decompression read only %ld bytes.\n"
+ "InnoDB: size %lu len %lu\n",
+ dst_pos, original_len, len);
+ fflush(stderr);
+
+ ut_error;
+ }
+
+ break;
+ }
+#endif /* HAVE_LZMA */
+
+#ifdef HAVE_LZO
+ case PAGE_LZO_ALGORITHM: {
+ fprintf(stderr, "InnoDB: [Note]: lzo \n");
+ err = lzo1x_decompress((const unsigned char *)ptr,
+ original_len,(unsigned char *)(page_buf), &olen, NULL);
+
+ if (err != LZO_E_OK || (olen == 0 || olen > UNIV_PAGE_SIZE)) {
+ fprintf(stderr,
+ "InnoDB: Corruption: Page is marked as compressed\n"
+ "InnoDB: but decompression read only %ld bytes.\n"
+ "InnoDB: size %lu len %lu\n",
+ olen, original_len, len);
+ fflush(stderr);
+
+ ut_error;
+ }
+ break;
+ }
+#endif /* HAVE_LZO */
+
+ default:
+ fprintf(stderr,
+ "InnoDB: Corruption: Page is marked as compressed\n"
+ "InnoDB: but compression algorithm %s\n"
+ "InnoDB: is not known.\n"
+ ,fil_get_compression_alg_name(algorithm));
+
+ fflush(stderr);
+ ut_error;
+ break;
+ }
+
+ /* Leave the header alone */
+ memmove(buf+FIL_PAGE_DATA, page_buf, original_len);
+
+ mach_write_to_2(buf + FIL_PAGE_TYPE, page_type);
+
+ ut_ad(memcmp(buf + FIL_PAGE_LSN + 4,
+ buf + (original_len + FIL_PAGE_DATA)
+ - FIL_PAGE_END_LSN_OLD_CHKSUM + 4, 4) == 0);
+}
+
+/****************************************************************//**
For page compressed pages compress the page before actual write
operation.
@return compressed page to be written*/
@@ -157,6 +331,50 @@ fil_compress_page(
break;
#endif /* HAVE_LZO */
+#ifdef HAVE_LZMA
+ case PAGE_LZMA_ALGORITHM: {
+ size_t out_pos=0;
+
+ err = lzma_easy_buffer_encode(
+ compression_level,
+ LZMA_CHECK_NONE,
+ NULL, /* No custom allocator, use malloc/free */
+ reinterpret_cast<uint8_t*>(buf),
+ len,
+ reinterpret_cast<uint8_t*>(out_buf + header_len),
+ &out_pos,
+ (size_t)&write_size);
+
+ if (err != LZMA_OK || write_size > UNIV_PAGE_SIZE-header_len) {
+ srv_stats.pages_page_compression_error.inc();
+ *out_len = len;
+ return (buf);
+ }
+ break;
+ }
+#endif /* HAVE_LZMA */
+
+#ifdef HAVE_BZIP2
+ case PAGE_BZIP2_ALGORITHM: {
+
+ err = BZ2_bzBuffToBuffCompress(
+ (char *)(out_buf + header_len),
+ (unsigned int *)&write_size,
+ (char *)buf,
+ len,
+ 1,
+ 0,
+ 0);
+
+ if (err != BZ_OK || write_size > UNIV_PAGE_SIZE-header_len) {
+ srv_stats.pages_page_compression_error.inc();
+ *out_len = len;
+ return (buf);
+ }
+ break;
+ }
+#endif /* HAVE_BZIP2 */
+
case PAGE_ZLIB_ALGORITHM:
err = compress2(out_buf+header_len, (ulong*)&write_size, buf, len, level);
@@ -245,10 +463,39 @@ fil_decompress_page(
ulint compression_alg = 0;
byte *in_buf;
ulint olen=0;
+ ulint ptype;
ut_ad(buf);
ut_ad(len);
+ ptype = mach_read_from_2(buf+FIL_PAGE_TYPE);
+
+ /* Do not try to uncompressed pages that are not compressed */
+ if (ptype != FIL_PAGE_PAGE_COMPRESSED && ptype != FIL_PAGE_COMPRESSED) {
+ return;
+ }
+
+ // If no buffer was given, we need to allocate temporal buffer
+ if (page_buf == NULL) {
+#ifdef UNIV_PAGECOMPRESS_DEBUG
+ fprintf(stderr,
+ "InnoDB: Note: FIL: Compression buffer not given, allocating...\n");
+#endif /* UNIV_PAGECOMPRESS_DEBUG */
+ in_buf = static_cast<byte *>(ut_malloc(UNIV_PAGE_SIZE));
+ } else {
+ in_buf = page_buf;
+ }
+
+ if (ptype == FIL_PAGE_COMPRESSED) {
+
+ fil_decompress_page_2(in_buf, buf, len, write_size);
+ // Need to free temporal buffer if no buffer was given
+ if (page_buf == NULL) {
+ ut_free(in_buf);
+ }
+ return;
+ }
+
/* Before actual decompress, make sure that page type is correct */
if (mach_read_from_4(buf+FIL_PAGE_SPACE_OR_CHKSUM) != BUF_NO_CHECKSUM_MAGIC ||
@@ -267,17 +514,6 @@ fil_decompress_page(
/* Get compression algorithm */
compression_alg = mach_read_from_8(buf+FIL_PAGE_FILE_FLUSH_LSN);
- // If no buffer was given, we need to allocate temporal buffer
- if (page_buf == NULL) {
-#ifdef UNIV_PAGECOMPRESS_DEBUG
- fprintf(stderr,
- "InnoDB: Note: FIL: Compression buffer not given, allocating...\n");
-#endif /* UNIV_PAGECOMPRESS_DEBUG */
- in_buf = static_cast<byte *>(ut_malloc(UNIV_PAGE_SIZE));
- } else {
- in_buf = page_buf;
- }
-
/* Get the actual size of compressed page */
actual_size = mach_read_from_2(buf+FIL_PAGE_DATA);
/* Check if payload size is corrupted */
@@ -324,7 +560,7 @@ fil_decompress_page(
#ifdef HAVE_LZ4
case PAGE_LZ4_ALGORITHM:
- err = LZ4_decompress_fast((const char *)buf+FIL_PAGE_DATA+FIL_PAGE_COMPRESSED_SIZE, (char *)in_buf, UNIV_PAGE_SIZE);
+ err = LZ4_decompress_fast((const char *)buf+FIL_PAGE_DATA+FIL_PAGE_COMPRESSED_SIZE, (char *)in_buf, len);
if (err != (int)actual_size) {
fprintf(stderr,
@@ -354,7 +590,67 @@ fil_decompress_page(
ut_error;
}
break;
-#endif
+#endif /* HAVE_LZO */
+#ifdef HAVE_LZMA
+ case PAGE_LZMA_ALGORITHM: {
+
+ lzma_ret ret;
+ size_t src_pos = 0;
+ size_t dst_pos = 0;
+ uint64_t memlimit = UINT64_MAX;
+
+ ret = lzma_stream_buffer_decode(
+ &memlimit,
+ 0,
+ NULL,
+ buf+FIL_PAGE_DATA+FIL_PAGE_COMPRESSED_SIZE,
+ &src_pos,
+ actual_size,
+ in_buf,
+ &dst_pos,
+ len);
+
+
+ if (ret != LZMA_OK || (dst_pos == 0 || dst_pos > UNIV_PAGE_SIZE)) {
+ fprintf(stderr,
+ "InnoDB: Corruption: Page is marked as compressed\n"
+ "InnoDB: but decompression read only %ld bytes.\n"
+ "InnoDB: size %lu len %lu\n",
+ olen, actual_size, len);
+ fflush(stderr);
+
+ ut_error;
+ }
+
+ break;
+ }
+#endif /* HAVE_LZMA */
+#ifdef HAVE_BZIP2
+ case PAGE_BZIP2_ALGORITHM: {
+ unsigned int dst_pos = UNIV_PAGE_SIZE;
+
+ err = BZ2_bzBuffToBuffDecompress(
+ (char *)in_buf,
+ &dst_pos,
+ (char *)(buf+FIL_PAGE_DATA+FIL_PAGE_COMPRESSED_SIZE),
+ actual_size,
+ 1,
+ 0);
+
+ if (err != BZ_OK || (dst_pos == 0 || dst_pos > UNIV_PAGE_SIZE)) {
+ fprintf(stderr,
+ "InnoDB: Corruption: Page is marked as compressed\n"
+ "InnoDB: but decompression read only %du bytes.\n"
+ "InnoDB: size %lu len %lu err %d\n",
+ dst_pos, actual_size, len, err);
+ fflush(stderr);
+
+ ut_error;
+ }
+ break;
+ }
+#endif /* HAVE_BZIP2 */
+
default:
fprintf(stderr,
"InnoDB: Corruption: Page is marked as compressed\n"
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 471c9d1d038..709bca475d7 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -578,6 +578,8 @@ innodb_compression_algorithm_validate(
static ibool innodb_have_lzo=IF_LZO(1, 0);
static ibool innodb_have_lz4=IF_LZ4(1, 0);
+static ibool innodb_have_lzma=IF_LZMA(1, 0);
+static ibool innodb_have_bzip2=IF_BZIP2(1, 0);
static const char innobase_hton_name[]= "InnoDB";
@@ -745,6 +747,10 @@ static SHOW_VAR innodb_status_variables[]= {
(char*) &innodb_have_lz4, SHOW_BOOL},
{"have_lzo",
(char*) &innodb_have_lzo, SHOW_BOOL},
+ {"have_lzma",
+ (char*) &innodb_have_lzma, SHOW_BOOL},
+ {"have_bzip2",
+ (char*) &innodb_have_bzip2, SHOW_BOOL},
{NullS, NullS, SHOW_LONG}
};
@@ -3026,6 +3032,24 @@ innobase_init(
}
#endif
+#ifndef HAVE_LZMA
+ if (innodb_compression_algorithm == PAGE_LZMA_ALGORITHM) {
+ sql_print_error("InnoDB: innodb_compression_algorithm = %lu unsupported.\n"
+ "InnoDB: liblzma is not installed. \n",
+ innodb_compression_algorithm);
+ goto error;
+ }
+#endif
+
+#ifndef HAVE_BZIP2
+ if (innodb_compression_algorithm == PAGE_BZIP2_ALGORITHM) {
+ sql_print_error("InnoDB: innodb_compression_algorithm = %lu unsupported.\n"
+ "InnoDB: libbz2 is not installed. \n",
+ innodb_compression_algorithm);
+ goto error;
+ }
+#endif
+
os_innodb_umask = (ulint) my_umask;
/* First calculate the default path for innodb_data_home_dir etc.,
@@ -17046,7 +17070,7 @@ static MYSQL_SYSVAR_BOOL(use_trim, srv_use_trim,
"Use trim. Default FALSE.",
NULL, NULL, FALSE);
-static const char *page_compression_algorithms[]= { "none", "zlib", "lz4", "lzo", 0 };
+static const char *page_compression_algorithms[]= { "none", "zlib", "lz4", "lzo", "lzma", "bzip2", 0 };
static TYPELIB page_compression_algorithms_typelib=
{
array_elements(page_compression_algorithms) - 1, 0,
@@ -17054,9 +17078,12 @@ static TYPELIB page_compression_algorithms_typelib=
};
static MYSQL_SYSVAR_ENUM(compression_algorithm, innodb_compression_algorithm,
PLUGIN_VAR_OPCMDARG,
- "Compression algorithm used on page compression. One of: none, zlib, lz4, or lzo",
+ "Compression algorithm used on page compression. One of: none, zlib, lz4, lzo, lzma, or bzip2",
innodb_compression_algorithm_validate, NULL,
- IF_LZO(PAGE_LZO_ALGORITHM, IF_LZ4(PAGE_LZ4_ALGORITHM, PAGE_ZLIB_ALGORITHM)),
+ /* We use here the largest number of supported compression method to
+ enable all those methods that are available. Availability of compression
+ method is verified on innodb_compression_algorithm_validate function. */
+ PAGE_ALGORITHM_LAST,
&page_compression_algorithms_typelib);
static MYSQL_SYSVAR_LONG(mtflush_threads, srv_mtflush_threads,
@@ -17804,5 +17831,27 @@ innodb_compression_algorithm_validate(
}
#endif
+#ifndef HAVE_LZMA
+ if (compression_algorithm == PAGE_LZMA_ALGORITHM) {
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
+ HA_ERR_UNSUPPORTED,
+ "InnoDB: innodb_compression_algorithm = %lu unsupported.\n"
+ "InnoDB: liblzma is not installed. \n",
+ compression_algorithm);
+ DBUG_RETURN(1);
+ }
+#endif
+
+#ifndef HAVE_BZIP2
+ if (compression_algorithm == PAGE_BZIP2_ALGORITHM) {
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
+ HA_ERR_UNSUPPORTED,
+ "InnoDB: innodb_compression_algorithm = %lu unsupported.\n"
+ "InnoDB: libbz2 is not installed. \n",
+ compression_algorithm);
+ DBUG_RETURN(1);
+ }
+#endif
+
DBUG_RETURN(0);
}
diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h
index e1f938dbf32..965b1c31e23 100644
--- a/storage/innobase/include/fil0fil.h
+++ b/storage/innobase/include/fil0fil.h
@@ -126,6 +126,24 @@ extern fil_addr_t fil_addr_null;
data file (ibdata*, not *.ibd):
the file has been flushed to disk
at least up to this lsn */
+/** If page type is FIL_PAGE_COMPRESSED then the 8 bytes starting at
+FIL_PAGE_FILE_FLUSH_LSN are broken down as follows: */
+
+/** Control information version format (u8) */
+static const ulint FIL_PAGE_VERSION = FIL_PAGE_FILE_FLUSH_LSN;
+
+/** Compression algorithm (u8) */
+static const ulint FIL_PAGE_ALGORITHM_V1 = FIL_PAGE_VERSION + 1;
+
+/** Original page type (u16) */
+static const ulint FIL_PAGE_ORIGINAL_TYPE_V1 = FIL_PAGE_ALGORITHM_V1 + 1;
+
+/** Original data size in bytes (u16)*/
+static const ulint FIL_PAGE_ORIGINAL_SIZE_V1 = FIL_PAGE_ORIGINAL_TYPE_V1 + 2;
+
+/** Size after compression (u16)*/
+static const ulint FIL_PAGE_COMPRESS_SIZE_V1 = FIL_PAGE_ORIGINAL_SIZE_V1 + 2;
+
#define FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID 34 /*!< starting from 4.1.x this
contains the space id of the page */
#define FIL_PAGE_SPACE_ID FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID
@@ -162,7 +180,8 @@ extern fil_addr_t fil_addr_null;
#define FIL_PAGE_TYPE_BLOB 10 /*!< Uncompressed BLOB page */
#define FIL_PAGE_TYPE_ZBLOB 11 /*!< First compressed BLOB page */
#define FIL_PAGE_TYPE_ZBLOB2 12 /*!< Subsequent compressed BLOB page */
-#define FIL_PAGE_TYPE_LAST FIL_PAGE_TYPE_ZBLOB2
+#define FIL_PAGE_COMPRESSED 13 /*!< Compressed page */
+#define FIL_PAGE_TYPE_LAST FIL_PAGE_COMPRESSED
/*!< Last page type */
/* @} */
diff --git a/storage/innobase/include/fsp0pagecompress.h b/storage/innobase/include/fsp0pagecompress.h
index f2cd38481f6..15212227829 100644
--- a/storage/innobase/include/fsp0pagecompress.h
+++ b/storage/innobase/include/fsp0pagecompress.h
@@ -27,11 +27,15 @@ Created 11/12/2013 Jan Lindström jan.lindstrom@skysql.com
#ifndef fsp0pagecompress_h
#define fsp0pagecompress_h
-#define PAGE_UNCOMPRESSED 0
-#define PAGE_ZLIB_ALGORITHM 1
-#define PAGE_LZ4_ALGORITHM 2
-#define PAGE_LZO_ALGORITHM 3
-#define PAGE_ALGORITHM_LAST PAGE_LZO_ALGORITHM
+/* Supported page compression methods */
+
+#define PAGE_UNCOMPRESSED 0
+#define PAGE_ZLIB_ALGORITHM 1
+#define PAGE_LZ4_ALGORITHM 2
+#define PAGE_LZO_ALGORITHM 3
+#define PAGE_LZMA_ALGORITHM 4
+#define PAGE_BZIP2_ALGORITHM 5
+#define PAGE_ALGORITHM_LAST PAGE_BZIP2_ALGORITHM
/**********************************************************************//**
Reads the page compression level from the first page of a tablespace.
diff --git a/storage/innobase/include/fsp0pagecompress.ic b/storage/innobase/include/fsp0pagecompress.ic
index 65ad90cdfc4..1ba3b7835c9 100644
--- a/storage/innobase/include/fsp0pagecompress.ic
+++ b/storage/innobase/include/fsp0pagecompress.ic
@@ -151,6 +151,9 @@ fil_get_compression_alg_name(
case PAGE_LZO_ALGORITHM:
return ("LZO");
break;
+ case PAGE_LZMA_ALGORITHM:
+ return ("LZMA");
+ break;
default:
return("UNKNOWN");
ut_error;
diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i
index 54815c47419..6c299aadb0f 100644
--- a/storage/innobase/include/univ.i
+++ b/storage/innobase/include/univ.i
@@ -2,6 +2,7 @@
Copyright (c) 1994, 2013, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
+Copyright (c) 2013, 2014 SkySQL Ab.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -343,6 +344,18 @@ typedef enum innodb_file_formats_enum innodb_file_formats_t;
#define IF_LZ4(A,B) B
#endif
+#ifdef HAVE_LZMA
+#define IF_LZMA(A,B) A
+#else
+#define IF_LZMA(A,B) B
+#endif
+
+#ifdef HAVE_BZIP2
+#define IF_BZIP2(A,B) A
+#else
+#define IF_BZIP2(A,B) B
+#endif
+
/** The universal page size of the database */
#define UNIV_PAGE_SIZE ((ulint) srv_page_size)
diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc
index 3a6a05a0c03..52e8ac841f3 100644
--- a/storage/innobase/os/os0file.cc
+++ b/storage/innobase/os/os0file.cc
@@ -2885,9 +2885,8 @@ try_again:
os_mutex_exit(os_file_count_mutex);
if (ret && len == n) {
- if (fil_page_is_compressed((byte *)buf)) {
- fil_decompress_page(NULL, (byte *)buf, len, NULL);
- }
+ fil_decompress_page(NULL, (byte *)buf, len, NULL);
+
return(TRUE);
}
#else /* __WIN__ */
@@ -2900,9 +2899,7 @@ try_again:
ret = os_file_pread(file, buf, n, offset);
if ((ulint) ret == n) {
- if (fil_page_is_compressed((byte *)buf)) {
- fil_decompress_page(NULL, (byte *)buf, n, NULL);
- }
+ fil_decompress_page(NULL, (byte *)buf, n, NULL);
return(TRUE);
}
@@ -5254,9 +5251,7 @@ os_aio_windows_handle(
#endif
if (slot->type == OS_FILE_READ) {
- if (fil_page_is_compressed(slot->buf)) {
- fil_decompress_page(slot->page_buf, slot->buf, slot->len, slot->write_size);
- }
+ fil_decompress_page(slot->page_buf, slot->buf, slot->len, slot->write_size);
} else {
if (slot->page_compress_success && fil_page_is_compressed(slot->page_buf)) {
if (srv_use_trim && os_fallocate_failed == FALSE) {
@@ -5373,9 +5368,7 @@ retry:
#endif
if (slot->type == OS_FILE_READ) {
- if (fil_page_is_compressed(slot->buf)) {
- fil_decompress_page(slot->page_buf, slot->buf, slot->len, slot->write_size);
- }
+ fil_decompress_page(slot->page_buf, slot->buf, slot->len, slot->write_size);
} else {
if (slot->page_compress_success &&
fil_page_is_compressed(slot->page_buf)) {
diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc
index 71edadea9fc..b9cfb3544b9 100644
--- a/storage/innobase/srv/srv0srv.cc
+++ b/storage/innobase/srv/srv0srv.cc
@@ -154,7 +154,7 @@ UNIV_INTERN my_bool srv_use_trim = FALSE;
UNIV_INTERN my_bool srv_use_posix_fallocate = FALSE;
/* If this flag is TRUE, then we disable doublewrite buffer */
UNIV_INTERN my_bool srv_use_atomic_writes = FALSE;
-/* If this flag IS TRUE, then we use lz4 to compress/decompress pages */
+/* If this flag IS TRUE, then we use this algorithm for page compressing the pages */
UNIV_INTERN ulong innodb_compression_algorithm = PAGE_ZLIB_ALGORITHM;
/* Number of threads used for multi-threaded flush */
UNIV_INTERN long srv_mtflush_threads = MTFLUSH_DEFAULT_WORKER;
diff --git a/storage/xtradb/CMakeLists.txt b/storage/xtradb/CMakeLists.txt
index cd2caaed6a1..528c6f87fcc 100644
--- a/storage/xtradb/CMakeLists.txt
+++ b/storage/xtradb/CMakeLists.txt
@@ -20,9 +20,13 @@ INCLUDE(CheckCSourceCompiles)
INCLUDE(CheckCSourceRuns)
INCLUDE(lz4)
INCLUDE(lzo)
+INCLUDE(lzma)
+INCLUDE(bzip2)
MYSQL_CHECK_LZ4()
MYSQL_CHECK_LZO()
+MYSQL_CHECK_LZMA()
+MYSQL_CHECK_BZIP2()
# OS tests
IF(UNIX)
diff --git a/storage/xtradb/fil/fil0pagecompress.cc b/storage/xtradb/fil/fil0pagecompress.cc
index 6ca6491cc4f..4efd6a82efe 100644
--- a/storage/xtradb/fil/fil0pagecompress.cc
+++ b/storage/xtradb/fil/fil0pagecompress.cc
@@ -68,11 +68,185 @@ static ulint srv_data_read, srv_data_written;
#ifdef HAVE_LZO
#include "lzo/lzo1x.h"
#endif
+#ifdef HAVE_LZMA
+#include "lzma.h"
+#endif
+#ifdef HAVE_BZIP2
+#include "bzlib.h"
+#endif
/* Used for debugging */
//#define UNIV_PAGECOMPRESS_DEBUG 1
/****************************************************************//**
+For page compressed pages decompress the page after actual read
+operation. */
+static
+void
+fil_decompress_page_2(
+/*==================*/
+ byte* page_buf, /*!< out: destination buffer for
+ uncompressed data */
+ byte* buf, /*!< in: source compressed data */
+ ulong len, /*!< in: length of output buffer.*/
+ ulint* write_size) /*!< in/out: Actual payload size of
+ the compressed data. */
+{
+ ulint page_type = mach_read_from_2(buf + FIL_PAGE_TYPE);
+
+ if (page_type != FIL_PAGE_COMPRESSED) {
+ /* It is not a compressed page */
+ return;
+ }
+
+ ulint olen = 0;
+ byte* ptr = buf + FIL_PAGE_DATA;
+ ulint version = mach_read_from_1(buf + FIL_PAGE_VERSION);
+ int err = 0;
+
+ ut_a(version == 1);
+
+ /* Read the original page type, before we compressed the data. */
+ page_type = mach_read_from_2(buf + FIL_PAGE_ORIGINAL_TYPE_V1);
+
+ ulint original_len = mach_read_from_2(buf + FIL_PAGE_ORIGINAL_SIZE_V1);
+
+ if (original_len < UNIV_PAGE_SIZE_MIN - (FIL_PAGE_DATA + 8)
+ || original_len > UNIV_PAGE_SIZE_MAX - FIL_PAGE_DATA
+ || len < original_len + FIL_PAGE_DATA) {
+ fprintf(stderr,
+ "InnoDB: Corruption: We try to uncompress corrupted page\n"
+ "InnoDB: Original len %lu len %lu.\n",
+ original_len, len);
+
+ fflush(stderr);
+ ut_error;
+
+ }
+
+ ulint algorithm = mach_read_from_1(buf + FIL_PAGE_ALGORITHM_V1);
+
+ switch(algorithm) {
+ case PAGE_ZLIB_ALGORITHM: {
+
+ fprintf(stderr, "InnoDB: [Note]: zlib\n");
+
+ err = uncompress(page_buf, &len, ptr, original_len);
+ /* If uncompress fails it means that page is corrupted */
+ if (err != Z_OK) {
+
+ fprintf(stderr,
+ "InnoDB: Corruption: Page is marked as compressed\n"
+ "InnoDB: but uncompress failed with error %d.\n"
+ "InnoDB: size %lu len %lu\n",
+ err, original_len, len);
+
+ fflush(stderr);
+
+ ut_error;
+ }
+
+ break;
+ }
+#ifdef HAVE_LZ4
+ case PAGE_LZ4_ALGORITHM: {
+ fprintf(stderr, "InnoDB: [Note]: lz4\n");
+ err = LZ4_decompress_fast(
+ (const char*) ptr, (char*) (page_buf), original_len);
+
+ if (err < 0) {
+ fprintf(stderr,
+ "InnoDB: Corruption: Page is marked as compressed\n"
+ "InnoDB: but decompression read only %d bytes.\n"
+ "InnoDB: size %lu len %lu\n",
+ err, original_len, len);
+ fflush(stderr);
+
+ ut_error;
+ }
+ break;
+ }
+#endif /* HAVE_LZ4 */
+
+#ifdef HAVE_LZMA
+ case PAGE_LZMA_ALGORITHM: {
+
+ lzma_ret ret;
+ size_t src_pos = 0;
+ size_t dst_pos = 0;
+ uint64_t memlimit = UINT64_MAX;
+
+ fprintf(stderr, "InnoDB: [Note]: lzma\n");
+ ret = lzma_stream_buffer_decode(
+ &memlimit,
+ 0,
+ NULL,
+ ptr,
+ &src_pos,
+ original_len,
+ (page_buf),
+ &dst_pos,
+ len);
+
+
+ if (ret != LZMA_OK || (dst_pos <= 0 || dst_pos > len)) {
+ fprintf(stderr,
+ "InnoDB: Corruption: Page is marked as compressed\n"
+ "InnoDB: but decompression read only %ld bytes.\n"
+ "InnoDB: size %lu len %lu\n",
+ dst_pos, original_len, len);
+ fflush(stderr);
+
+ ut_error;
+ }
+
+ break;
+ }
+#endif /* HAVE_LZMA */
+
+#ifdef HAVE_LZO
+ case PAGE_LZO_ALGORITHM: {
+ fprintf(stderr, "InnoDB: [Note]: lzo \n");
+ err = lzo1x_decompress((const unsigned char *)ptr,
+ original_len,(unsigned char *)(page_buf), &olen, NULL);
+
+ if (err != LZO_E_OK || (olen == 0 || olen > UNIV_PAGE_SIZE)) {
+ fprintf(stderr,
+ "InnoDB: Corruption: Page is marked as compressed\n"
+ "InnoDB: but decompression read only %ld bytes.\n"
+ "InnoDB: size %lu len %lu\n",
+ olen, original_len, len);
+ fflush(stderr);
+
+ ut_error;
+ }
+ break;
+ }
+#endif /* HAVE_LZO */
+
+ default:
+ fprintf(stderr,
+ "InnoDB: Corruption: Page is marked as compressed\n"
+ "InnoDB: but compression algorithm %s\n"
+ "InnoDB: is not known.\n"
+ ,fil_get_compression_alg_name(algorithm));
+
+ fflush(stderr);
+ ut_error;
+ break;
+ }
+
+ /* Leave the header alone */
+ memmove(buf+FIL_PAGE_DATA, page_buf, original_len);
+
+ mach_write_to_2(buf + FIL_PAGE_TYPE, page_type);
+
+ ut_ad(memcmp(buf + FIL_PAGE_LSN + 4,
+ buf + (original_len + FIL_PAGE_DATA)
+ - FIL_PAGE_END_LSN_OLD_CHKSUM + 4, 4) == 0);
+}
+
+/****************************************************************//**
For page compressed pages compress the page before actual write
operation.
@return compressed page to be written*/
@@ -157,6 +331,50 @@ fil_compress_page(
break;
#endif /* HAVE_LZO */
+#ifdef HAVE_LZMA
+ case PAGE_LZMA_ALGORITHM: {
+ size_t out_pos=0;
+
+ err = lzma_easy_buffer_encode(
+ compression_level,
+ LZMA_CHECK_NONE,
+ NULL, /* No custom allocator, use malloc/free */
+ reinterpret_cast<uint8_t*>(buf),
+ len,
+ reinterpret_cast<uint8_t*>(out_buf + header_len),
+ &out_pos,
+ (size_t)&write_size);
+
+ if (err != LZMA_OK || write_size > UNIV_PAGE_SIZE-header_len) {
+ srv_stats.pages_page_compression_error.inc();
+ *out_len = len;
+ return (buf);
+ }
+ break;
+ }
+#endif /* HAVE_LZMA */
+
+#ifdef HAVE_BZIP2
+ case PAGE_BZIP2_ALGORITHM: {
+
+ err = BZ2_bzBuffToBuffCompress(
+ (char *)(out_buf + header_len),
+ (unsigned int *)&write_size,
+ (char *)buf,
+ len,
+ 1,
+ 0,
+ 0);
+
+ if (err != BZ_OK || write_size > UNIV_PAGE_SIZE-header_len) {
+ srv_stats.pages_page_compression_error.inc();
+ *out_len = len;
+ return (buf);
+ }
+ break;
+ }
+#endif /* HAVE_BZIP2 */
+
case PAGE_ZLIB_ALGORITHM:
err = compress2(out_buf+header_len, (ulong*)&write_size, buf, len, level);
@@ -244,10 +462,39 @@ fil_decompress_page(
ulint compression_alg = 0;
byte *in_buf;
ulint olen=0;
+ ulint ptype;
ut_ad(buf);
ut_ad(len);
+ ptype = mach_read_from_2(buf+FIL_PAGE_TYPE);
+
+ /* Do not try to uncompressed pages that are not compressed */
+ if (ptype != FIL_PAGE_PAGE_COMPRESSED && ptype != FIL_PAGE_COMPRESSED) {
+ return;
+ }
+
+ // If no buffer was given, we need to allocate temporal buffer
+ if (page_buf == NULL) {
+#ifdef UNIV_PAGECOMPRESS_DEBUG
+ fprintf(stderr,
+ "InnoDB: Note: FIL: Compression buffer not given, allocating...\n");
+#endif /* UNIV_PAGECOMPRESS_DEBUG */
+ in_buf = static_cast<byte *>(ut_malloc(UNIV_PAGE_SIZE));
+ } else {
+ in_buf = page_buf;
+ }
+
+ if (ptype == FIL_PAGE_COMPRESSED) {
+
+ fil_decompress_page_2(in_buf, buf, len, write_size);
+ // Need to free temporal buffer if no buffer was given
+ if (page_buf == NULL) {
+ ut_free(in_buf);
+ }
+ return;
+ }
+
/* Before actual decompress, make sure that page type is correct */
if (mach_read_from_4(buf+FIL_PAGE_SPACE_OR_CHKSUM) != BUF_NO_CHECKSUM_MAGIC ||
@@ -266,17 +513,6 @@ fil_decompress_page(
/* Get compression algorithm */
compression_alg = mach_read_from_8(buf+FIL_PAGE_FILE_FLUSH_LSN);
- // If no buffer was given, we need to allocate temporal buffer
- if (page_buf == NULL) {
-#ifdef UNIV_PAGECOMPRESS_DEBUG
- fprintf(stderr,
- "InnoDB: Note: FIL: Compression buffer not given, allocating...\n");
-#endif /* UNIV_PAGECOMPRESS_DEBUG */
- in_buf = static_cast<byte *>(ut_malloc(UNIV_PAGE_SIZE));
- } else {
- in_buf = page_buf;
- }
-
/* Get the actual size of compressed page */
actual_size = mach_read_from_2(buf+FIL_PAGE_DATA);
/* Check if payload size is corrupted */
@@ -323,7 +559,7 @@ fil_decompress_page(
#ifdef HAVE_LZ4
case PAGE_LZ4_ALGORITHM:
- err = LZ4_decompress_fast((const char *)buf+FIL_PAGE_DATA+FIL_PAGE_COMPRESSED_SIZE, (char *)in_buf, UNIV_PAGE_SIZE);
+ err = LZ4_decompress_fast((const char *)buf+FIL_PAGE_DATA+FIL_PAGE_COMPRESSED_SIZE, (char *)in_buf, len);
if (err != (int)actual_size) {
fprintf(stderr,
@@ -353,7 +589,67 @@ fil_decompress_page(
ut_error;
}
break;
-#endif
+#endif /* HAVE_LZO */
+#ifdef HAVE_LZMA
+ case PAGE_LZMA_ALGORITHM: {
+
+ lzma_ret ret;
+ size_t src_pos = 0;
+ size_t dst_pos = 0;
+ uint64_t memlimit = UINT64_MAX;
+
+ ret = lzma_stream_buffer_decode(
+ &memlimit,
+ 0,
+ NULL,
+ buf+FIL_PAGE_DATA+FIL_PAGE_COMPRESSED_SIZE,
+ &src_pos,
+ actual_size,
+ in_buf,
+ &dst_pos,
+ len);
+
+
+ if (ret != LZMA_OK || (dst_pos == 0 || dst_pos > UNIV_PAGE_SIZE)) {
+ fprintf(stderr,
+ "InnoDB: Corruption: Page is marked as compressed\n"
+ "InnoDB: but decompression read only %ld bytes.\n"
+ "InnoDB: size %lu len %lu\n",
+ olen, actual_size, len);
+ fflush(stderr);
+
+ ut_error;
+ }
+
+ break;
+ }
+#endif /* HAVE_LZMA */
+#ifdef HAVE_BZIP2
+ case PAGE_BZIP2_ALGORITHM: {
+ unsigned int dst_pos = UNIV_PAGE_SIZE;
+
+ err = BZ2_bzBuffToBuffDecompress(
+ (char *)in_buf,
+ &dst_pos,
+ (char *)(buf+FIL_PAGE_DATA+FIL_PAGE_COMPRESSED_SIZE),
+ actual_size,
+ 1,
+ 0);
+
+ if (err != BZ_OK || (dst_pos == 0 || dst_pos > UNIV_PAGE_SIZE)) {
+ fprintf(stderr,
+ "InnoDB: Corruption: Page is marked as compressed\n"
+ "InnoDB: but decompression read only %du bytes.\n"
+ "InnoDB: size %lu len %lu err %d\n",
+ dst_pos, actual_size, len, err);
+ fflush(stderr);
+
+ ut_error;
+ }
+ break;
+ }
+#endif /* HAVE_BZIP2 */
+
default:
fprintf(stderr,
"InnoDB: Corruption: Page is marked as compressed\n"
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index 5d60a6f0f96..6d6e986b83e 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -719,6 +719,8 @@ static MYSQL_THDVAR_BOOL(fake_changes, PLUGIN_VAR_OPCMDARG,
static ibool innodb_have_lzo=IF_LZO(1, 0);
static ibool innodb_have_lz4=IF_LZ4(1, 0);
+static ibool innodb_have_lzma=IF_LZMA(1, 0);
+static ibool innodb_have_bzip2=IF_BZIP2(1, 0);
static SHOW_VAR innodb_status_variables[]= {
{"available_undo_logs",
@@ -939,6 +941,10 @@ static SHOW_VAR innodb_status_variables[]= {
(char*) &innodb_have_lz4, SHOW_BOOL},
{"have_lzo",
(char*) &innodb_have_lzo, SHOW_BOOL},
+ {"have_lzma",
+ (char*) &innodb_have_lzma, SHOW_BOOL},
+ {"have_bzip2",
+ (char*) &innodb_have_bzip2, SHOW_BOOL},
{NullS, NullS, SHOW_LONG}
};
@@ -3411,6 +3417,24 @@ innobase_init(
}
#endif
+#ifndef HAVE_LZMA
+ if (innodb_compression_algorithm == PAGE_LZMA_ALGORITHM) {
+ sql_print_error("InnoDB: innodb_compression_algorithm = %lu unsupported.\n"
+ "InnoDB: liblzma is not installed. \n",
+ innodb_compression_algorithm);
+ goto error;
+ }
+#endif
+
+#ifndef HAVE_BZIP2
+ if (innodb_compression_algorithm == PAGE_BZIP2_ALGORITHM) {
+ sql_print_error("InnoDB: innodb_compression_algorithm = %lu unsupported.\n"
+ "InnoDB: libbz2 is not installed. \n",
+ innodb_compression_algorithm);
+ goto error;
+ }
+#endif
+
os_innodb_umask = (ulint) my_umask;
/* First calculate the default path for innodb_data_home_dir etc.,
@@ -18219,7 +18243,7 @@ static MYSQL_SYSVAR_BOOL(use_trim, srv_use_trim,
"Use trim. Default FALSE.",
NULL, NULL, FALSE);
-static const char *page_compression_algorithms[]= { "none", "zlib", "lz4", "lzo", 0 };
+static const char *page_compression_algorithms[]= { "none", "zlib", "lz4", "lzo", "lzma", "bzip2", 0 };
static TYPELIB page_compression_algorithms_typelib=
{
array_elements(page_compression_algorithms) - 1, 0,
@@ -18227,9 +18251,12 @@ static TYPELIB page_compression_algorithms_typelib=
};
static MYSQL_SYSVAR_ENUM(compression_algorithm, innodb_compression_algorithm,
PLUGIN_VAR_OPCMDARG,
- "Compression algorithm used on page compression. One of: none, zlib, lz4, or lzo",
+ "Compression algorithm used on page compression. One of: none, zlib, lz4, lzo, lzma, or bzip2",
innodb_compression_algorithm_validate, NULL,
- IF_LZO(PAGE_LZO_ALGORITHM, IF_LZ4(PAGE_LZ4_ALGORITHM, PAGE_ZLIB_ALGORITHM)),
+ /* We use here the largest number of supported compression method to
+ enable all those methods that are available. Availability of compression
+ method is verified on innodb_compression_algorithm_validate function. */
+ PAGE_ALGORITHM_LAST,
&page_compression_algorithms_typelib);
static MYSQL_SYSVAR_LONG(mtflush_threads, srv_mtflush_threads,
@@ -19023,6 +19050,28 @@ innodb_compression_algorithm_validate(
}
#endif
+#ifndef HAVE_LZMA
+ if (compression_algorithm == PAGE_LZMA_ALGORITHM) {
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
+ HA_ERR_UNSUPPORTED,
+ "InnoDB: innodb_compression_algorithm = %lu unsupported.\n"
+ "InnoDB: liblzma is not installed. \n",
+ compression_algorithm);
+ DBUG_RETURN(1);
+ }
+#endif
+
+#ifndef HAVE_BZIP2
+ if (compression_algorithm == PAGE_BZIP2_ALGORITHM) {
+ push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
+ HA_ERR_UNSUPPORTED,
+ "InnoDB: innodb_compression_algorithm = %lu unsupported.\n"
+ "InnoDB: libbz2 is not installed. \n",
+ compression_algorithm);
+ DBUG_RETURN(1);
+ }
+#endif
+
DBUG_RETURN(0);
}
diff --git a/storage/xtradb/include/fil0fil.h b/storage/xtradb/include/fil0fil.h
index 45798c882be..7dbb8d6123b 100644
--- a/storage/xtradb/include/fil0fil.h
+++ b/storage/xtradb/include/fil0fil.h
@@ -127,6 +127,24 @@ extern fil_addr_t fil_addr_null;
data file (ibdata*, not *.ibd):
the file has been flushed to disk
at least up to this lsn */
+/** If page type is FIL_PAGE_COMPRESSED then the 8 bytes starting at
+FIL_PAGE_FILE_FLUSH_LSN are broken down as follows: */
+
+/** Control information version format (u8) */
+static const ulint FIL_PAGE_VERSION = FIL_PAGE_FILE_FLUSH_LSN;
+
+/** Compression algorithm (u8) */
+static const ulint FIL_PAGE_ALGORITHM_V1 = FIL_PAGE_VERSION + 1;
+
+/** Original page type (u16) */
+static const ulint FIL_PAGE_ORIGINAL_TYPE_V1 = FIL_PAGE_ALGORITHM_V1 + 1;
+
+/** Original data size in bytes (u16)*/
+static const ulint FIL_PAGE_ORIGINAL_SIZE_V1 = FIL_PAGE_ORIGINAL_TYPE_V1 + 2;
+
+/** Size after compression (u16)*/
+static const ulint FIL_PAGE_COMPRESS_SIZE_V1 = FIL_PAGE_ORIGINAL_SIZE_V1 + 2;
+
#define FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID 34 /*!< starting from 4.1.x this
contains the space id of the page */
#define FIL_PAGE_SPACE_ID FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID
@@ -164,7 +182,8 @@ extern fil_addr_t fil_addr_null;
#define FIL_PAGE_TYPE_BLOB 10 /*!< Uncompressed BLOB page */
#define FIL_PAGE_TYPE_ZBLOB 11 /*!< First compressed BLOB page */
#define FIL_PAGE_TYPE_ZBLOB2 12 /*!< Subsequent compressed BLOB page */
-#define FIL_PAGE_TYPE_LAST FIL_PAGE_TYPE_ZBLOB2
+#define FIL_PAGE_COMPRESSED 13 /*!< Compressed page */
+#define FIL_PAGE_TYPE_LAST FIL_PAGE_COMPRESSED
/*!< Last page type */
/* @} */
diff --git a/storage/xtradb/include/fsp0pagecompress.h b/storage/xtradb/include/fsp0pagecompress.h
index f2cd38481f6..15212227829 100644
--- a/storage/xtradb/include/fsp0pagecompress.h
+++ b/storage/xtradb/include/fsp0pagecompress.h
@@ -27,11 +27,15 @@ Created 11/12/2013 Jan Lindström jan.lindstrom@skysql.com
#ifndef fsp0pagecompress_h
#define fsp0pagecompress_h
-#define PAGE_UNCOMPRESSED 0
-#define PAGE_ZLIB_ALGORITHM 1
-#define PAGE_LZ4_ALGORITHM 2
-#define PAGE_LZO_ALGORITHM 3
-#define PAGE_ALGORITHM_LAST PAGE_LZO_ALGORITHM
+/* Supported page compression methods */
+
+#define PAGE_UNCOMPRESSED 0
+#define PAGE_ZLIB_ALGORITHM 1
+#define PAGE_LZ4_ALGORITHM 2
+#define PAGE_LZO_ALGORITHM 3
+#define PAGE_LZMA_ALGORITHM 4
+#define PAGE_BZIP2_ALGORITHM 5
+#define PAGE_ALGORITHM_LAST PAGE_BZIP2_ALGORITHM
/**********************************************************************//**
Reads the page compression level from the first page of a tablespace.
diff --git a/storage/xtradb/include/fsp0pagecompress.ic b/storage/xtradb/include/fsp0pagecompress.ic
index a72c4a1df90..a2553eeb47b 100644
--- a/storage/xtradb/include/fsp0pagecompress.ic
+++ b/storage/xtradb/include/fsp0pagecompress.ic
@@ -151,6 +151,9 @@ fil_get_compression_alg_name(
case PAGE_LZO_ALGORITHM:
return ("LZO");
break;
+ case PAGE_LZMA_ALGORITHM:
+ return ("LZMA");
+ break;
default:
return("UNKNOWN");
ut_error;
diff --git a/storage/xtradb/include/univ.i b/storage/xtradb/include/univ.i
index ba3de00dd10..2a3a85c219f 100644
--- a/storage/xtradb/include/univ.i
+++ b/storage/xtradb/include/univ.i
@@ -2,6 +2,7 @@
Copyright (c) 1994, 2013, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2008, Google Inc.
+Copyright (c) 2013, 2014 SkySQL Ab.
Portions of this file contain modifications contributed and copyrighted by
Google, Inc. Those modifications are gratefully acknowledged and are described
@@ -358,6 +359,18 @@ typedef enum innodb_file_formats_enum innodb_file_formats_t;
#define IF_LZ4(A,B) B
#endif
+#ifdef HAVE_LZMA
+#define IF_LZMA(A,B) A
+#else
+#define IF_LZMA(A,B) B
+#endif
+
+#ifdef HAVE_BZIP2
+#define IF_BZIP2(A,B) A
+#else
+#define IF_BZIP2(A,B) B
+#endif
+
/** The universal page size of the database */
#define UNIV_PAGE_SIZE ((ulint) srv_page_size)
diff --git a/storage/xtradb/os/os0file.cc b/storage/xtradb/os/os0file.cc
index e7fdb3e37b9..82eee4440f9 100644
--- a/storage/xtradb/os/os0file.cc
+++ b/storage/xtradb/os/os0file.cc
@@ -3081,9 +3081,8 @@ try_again:
os_mutex_exit(os_file_count_mutex);
if (ret && len == n) {
- if (fil_page_is_compressed((byte *)buf)) {
- fil_decompress_page(NULL, (byte *)buf, len, NULL);
- }
+ fil_decompress_page(NULL, (byte *)buf, len, NULL);
+
return(TRUE);
}
#else /* __WIN__ */
@@ -3097,9 +3096,7 @@ try_again:
if ((ulint) ret == n) {
- if (fil_page_is_compressed((byte *)buf)) {
- fil_decompress_page(NULL, (byte *)buf, n, NULL);
- }
+ fil_decompress_page(NULL, (byte *)buf, n, NULL);
return(TRUE);
}
@@ -3201,9 +3198,7 @@ try_again:
if ((ulint) ret == n) {
- if (fil_page_is_compressed((byte *)buf)) {
- fil_decompress_page(NULL, (byte *)buf, n, NULL);
- }
+ fil_decompress_page(NULL, (byte *)buf, n, NULL);
return(TRUE);
}
@@ -5321,9 +5316,7 @@ os_aio_windows_handle(
}
#endif
if (slot->type == OS_FILE_READ) {
- if (fil_page_is_compressed(slot->buf)) {
- fil_decompress_page(slot->page_buf, slot->buf, slot->len, slot->write_size);
- }
+ fil_decompress_page(slot->page_buf, slot->buf, slot->len, slot->write_size);
} else {
if (slot->page_compress_success && fil_page_is_compressed(slot->page_buf)) {
if (srv_use_trim && os_fallocate_failed == FALSE) {
@@ -5439,9 +5432,7 @@ retry:
}
#endif
if (slot->type == OS_FILE_READ) {
- if (fil_page_is_compressed(slot->buf)) {
- fil_decompress_page(slot->page_buf, slot->buf, slot->len, slot->write_size);
- }
+ fil_decompress_page(slot->page_buf, slot->buf, slot->len, slot->write_size);
} else {
if (slot->page_compress_success &&
fil_page_is_compressed(slot->page_buf)) {
diff --git a/storage/xtradb/srv/srv0srv.cc b/storage/xtradb/srv/srv0srv.cc
index 7c1058f536f..8e01ea7402e 100644
--- a/storage/xtradb/srv/srv0srv.cc
+++ b/storage/xtradb/srv/srv0srv.cc
@@ -172,7 +172,7 @@ UNIV_INTERN my_bool srv_use_trim = FALSE;
UNIV_INTERN my_bool srv_use_posix_fallocate = FALSE;
/* If this flag is TRUE, then we disable doublewrite buffer */
UNIV_INTERN my_bool srv_use_atomic_writes = FALSE;
-/* If this flag IS TRUE, then we use lz4 to compress/decompress pages */
+/* If this flag IS TRUE, then we use this algorithm for page compressing the pages */
UNIV_INTERN ulong innodb_compression_algorithm = PAGE_ZLIB_ALGORITHM;
/* Number of threads used for multi-threaded flush */
UNIV_INTERN long srv_mtflush_threads = MTFLUSH_DEFAULT_WORKER;