Skip to content

Commit

Permalink
Fixed merge error on InnoDB page compression level handling.
Browse files Browse the repository at this point in the history
Merged page compression feature to XtraDB storage engine.

Added feature where page compression can use lz4 compression
method (innodb_use_lz4, default OFF).
  • Loading branch information
Jan Lindström committed Feb 3, 2014
1 parent febe99e commit 8c5d5bc
Show file tree
Hide file tree
Showing 54 changed files with 5,839 additions and 320 deletions.
1 change: 1 addition & 0 deletions storage/innobase/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -294,6 +294,7 @@ SET(INNOBASE_SOURCES
eval/eval0proc.cc
fil/fil0fil.cc
fil/fil0pagecompress.cc
fil/lz4.c
fsp/fsp0fsp.cc
fut/fut0fut.cc
fut/fut0lst.cc
Expand Down
4 changes: 2 additions & 2 deletions storage/innobase/btr/btr0btr.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1923,7 +1923,7 @@ btr_page_reorganize(
dict_index_t* index, /*!< in: record descriptor */
mtr_t* mtr) /*!< in: mtr */
{
return(btr_page_reorganize_low(FALSE, page_compression_level,
return(btr_page_reorganize_low(FALSE, page_zip_level,
block, index, mtr));
}
#endif /* !UNIV_HOTBACKUP */
Expand All @@ -1942,7 +1942,7 @@ btr_parse_page_reorganize(
buf_block_t* block, /*!< in: page to be reorganized, or NULL */
mtr_t* mtr) /*!< in: mtr or NULL */
{
ulint level = page_compression_level;
ulint level = page_zip_level;

ut_ad(ptr && end_ptr);

Expand Down
4 changes: 2 additions & 2 deletions storage/innobase/btr/btr0cur.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1844,7 +1844,7 @@ btr_cur_update_alloc_zip(
/* Have a local copy of the variables as these can change
dynamically. */
bool log_compressed = page_log_compressed_pages;
ulint compression_level = page_compression_level;
ulint compression_level = page_zip_level;
page_t* page = buf_block_get_frame(block);

ut_a(page_zip == buf_block_get_page_zip(block));
Expand Down Expand Up @@ -4334,7 +4334,7 @@ btr_store_big_rec_extern_fields(
heap = mem_heap_create(250000);
page_zip_set_alloc(&c_stream, heap);

err = deflateInit2(&c_stream, page_compression_level,
err = deflateInit2(&c_stream, page_zip_level,
Z_DEFLATED, 15, 7, Z_DEFAULT_STRATEGY);
ut_a(err == Z_OK);
}
Expand Down
2 changes: 1 addition & 1 deletion storage/innobase/fil/fil0fil.cc
Original file line number Diff line number Diff line change
Expand Up @@ -5303,7 +5303,7 @@ fil_io(
os_offset_t offset;
ibool ignore_nonexistent_pages;
ibool page_compressed = FALSE;
ibool page_compression_level = 0;
ulint page_compression_level = 0;

is_log = type & OS_FILE_LOG;
type = type & ~OS_FILE_LOG;
Expand Down
170 changes: 113 additions & 57 deletions storage/innobase/fil/fil0pagecompress.cc
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (C) 2013 SkySQL Ab. All Rights Reserved.
Copyright (C) 2013, 2014, SkySQL Ab. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Expand Down Expand Up @@ -63,6 +63,7 @@ static ulint srv_data_read, srv_data_written;
#include <linux/falloc.h>
#endif
#include "row0mysql.h"
#include "lz4.h"

/****************************************************************//**
For page compressed pages compress the page before actual write
Expand Down Expand Up @@ -100,7 +101,7 @@ fil_compress_page(
/* If no compression level was provided to this table, use system
default level */
if (level == 0) {
level = srv_compress_zlib_level;
level = page_zip_level;
}

#ifdef UNIV_DEBUG
Expand All @@ -110,60 +111,88 @@ fil_compress_page(
#endif

write_size = UNIV_PAGE_SIZE - header_len;
err = compress2(out_buf+header_len, &write_size, buf, len, level);

if (err != Z_OK) {
/* If error we leave the actual page as it was */
if (srv_use_lz4) {
err = LZ4_compress_limitedOutput((const char *)buf, (char *)out_buf+header_len, len, write_size);
write_size = err;

fprintf(stderr,
"InnoDB: Warning: Compression failed for space %lu name %s len %lu rt %d write %lu\n",
space_id, fil_space_name(space), len, err, write_size);
if (err == 0) {
/* If error we leave the actual page as it was */

fprintf(stderr,
"InnoDB: Warning: Compression failed for space %lu name %s len %lu rt %d write %lu\n",
space_id, fil_space_name(space), len, err, write_size);

*out_len = len;
return (buf);
}
} else {
err = compress2(out_buf+header_len, &write_size, buf, len, level);

if (err != Z_OK) {
/* If error we leave the actual page as it was */

fprintf(stderr,
"InnoDB: Warning: Compression failed for space %lu name %s len %lu rt %d write %lu\n",
space_id, fil_space_name(space), len, err, write_size);

*out_len = len;
return (buf);
}
}

*out_len = len;
return (buf);
/* Set up the page header */
memcpy(out_buf, buf, FIL_PAGE_DATA);
/* Set up the checksum */
mach_write_to_4(out_buf+FIL_PAGE_SPACE_OR_CHKSUM, BUF_NO_CHECKSUM_MAGIC);
/* Set up the correct page type */
mach_write_to_2(out_buf+FIL_PAGE_TYPE, FIL_PAGE_PAGE_COMPRESSED);
/* Set up the flush lsn to be compression algorithm */
if (srv_use_lz4) {
mach_write_to_8(out_buf+FIL_PAGE_FILE_FLUSH_LSN, FIL_PAGE_COMPRESSION_LZ4);
} else {
/* Set up the page header */
memcpy(out_buf, buf, FIL_PAGE_DATA);
/* Set up the checksum */
mach_write_to_4(out_buf+FIL_PAGE_SPACE_OR_CHKSUM, BUF_NO_CHECKSUM_MAGIC);
/* Set up the correct page type */
mach_write_to_2(out_buf+FIL_PAGE_TYPE, FIL_PAGE_PAGE_COMPRESSED);
/* Set up the flush lsn to be compression algorithm */
mach_write_to_8(out_buf+FIL_PAGE_FILE_FLUSH_LSN, FIL_PAGE_COMPRESSION_ZLIB);
/* Set up the actual payload lenght */
mach_write_to_2(out_buf+FIL_PAGE_DATA, write_size);
}
/* Set up the actual payload lenght */
mach_write_to_2(out_buf+FIL_PAGE_DATA, write_size);

#ifdef UNIV_DEBUG
/* Verify */
ut_ad(fil_page_is_compressed(out_buf));
ut_ad(mach_read_from_4(out_buf+FIL_PAGE_SPACE_OR_CHKSUM) == BUF_NO_CHECKSUM_MAGIC);
ut_ad(mach_read_from_2(out_buf+FIL_PAGE_DATA) == write_size);
/* Verify */
ut_ad(fil_page_is_compressed(out_buf));
ut_ad(mach_read_from_4(out_buf+FIL_PAGE_SPACE_OR_CHKSUM) == BUF_NO_CHECKSUM_MAGIC);
ut_ad(mach_read_from_2(out_buf+FIL_PAGE_DATA) == write_size);
if (srv_use_lz4) {
ut_ad(mach_read_from_8(out_buf+FIL_PAGE_FILE_FLUSH_LSN) == FIL_PAGE_COMPRESSION_LZ4);
} else {
ut_ad(mach_read_from_8(out_buf+FIL_PAGE_FILE_FLUSH_LSN) == FIL_PAGE_COMPRESSION_ZLIB);
}
#endif

write_size+=header_len;
/* Actual write needs to be alligned on block size */
if (write_size % OS_FILE_LOG_BLOCK_SIZE) {
write_size = (write_size + (OS_FILE_LOG_BLOCK_SIZE - (write_size % OS_FILE_LOG_BLOCK_SIZE)));
}
write_size+=header_len;
/* Actual write needs to be alligned on block size */
if (write_size % OS_FILE_LOG_BLOCK_SIZE) {
write_size = (write_size + (OS_FILE_LOG_BLOCK_SIZE - (write_size % OS_FILE_LOG_BLOCK_SIZE)));
}

#ifdef UNIV_DEBUG
fprintf(stderr,
"InnoDB: Note: Compression succeeded for space %lu name %s len %lu out_len %lu\n",
space_id, fil_space_name(space), len, write_size);
fprintf(stderr,
"InnoDB: Note: Compression succeeded for space %lu name %s len %lu out_len %lu\n",
space_id, fil_space_name(space), len, write_size);
#endif

#define SECT_SIZE 512
srv_stats.page_compression_saved.add((len - write_size));
if ((len - write_size) > 0) {
srv_stats.page_compression_trim_sect512.add(((len - write_size) / SECT_SIZE));
srv_stats.page_compression_trim_sect4096.add(((len - write_size) / (SECT_SIZE*8)));
}
//srv_stats.page_compressed_trim_op.inc();
srv_stats.pages_page_compressed.inc();
*out_len = write_size;

return(out_buf);
srv_stats.page_compression_saved.add((len - write_size));
if ((len - write_size) > 0) {
srv_stats.page_compression_trim_sect512.add(((len - write_size) / SECT_SIZE));
srv_stats.page_compression_trim_sect4096.add(((len - write_size) / (SECT_SIZE*8)));
}
//srv_stats.page_compressed_trim_op.inc();
srv_stats.pages_page_compressed.inc();
*out_len = write_size;

return(out_buf);

}

/****************************************************************//**
Expand Down Expand Up @@ -203,16 +232,30 @@ fil_decompress_page(
/* Get compression algorithm */
compression_alg = mach_read_from_8(buf+FIL_PAGE_FILE_FLUSH_LSN);

if (compression_alg == FIL_PAGE_COMPRESSION_ZLIB) {
// If no buffer was given, we need to allocate temporal buffer
if (page_buf == NULL) {
in_buf = static_cast<byte *>(ut_malloc(UNIV_PAGE_SIZE));
} else {
in_buf = page_buf;
}
// If no buffer was given, we need to allocate temporal buffer
if (page_buf == NULL) {
#ifdef UNIV_DEBUG
fprintf(stderr,
"InnoDB: Note: Compression buffer not given, allocating...\n");
#endif
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 */
if (actual_size == 0 || actual_size > UNIV_PAGE_SIZE) {
fprintf(stderr,
"InnoDB: Corruption: We try to uncompress corrupted page\n"
"InnoDB: actual size %lu compression %s\n",
actual_size, fil_get_compression_alg_name(compression_alg));
fflush(stderr);
ut_error;
}

/* Get the actual size of compressed page */
actual_size = mach_read_from_2(buf+FIL_PAGE_DATA);
if (compression_alg == FIL_PAGE_COMPRESSION_ZLIB) {

#ifdef UNIV_DEBUG
fprintf(stderr,
Expand Down Expand Up @@ -242,17 +285,19 @@ fil_decompress_page(
"InnoDB: Note: Decompression succeeded for len %lu \n",
len);
#endif
} else if (compression_alg == FIL_PAGE_COMPRESSION_LZ4) {
err = LZ4_decompress_fast((const char *)buf+FIL_PAGE_DATA+FIL_PAGE_COMPRESSED_SIZE, (char *)in_buf, UNIV_PAGE_SIZE);

/* Copy the uncompressed page to the buffer pool, not
really any other options. */
memcpy(buf, in_buf, len);
if (err != actual_size) {
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, actual_size, len);
fflush(stderr);

// Need to free temporal buffer if no buffer was given
if (page_buf == NULL) {
ut_free(in_buf);
ut_error;
}

srv_stats.pages_page_decompressed.inc();
} else {
fprintf(stderr,
"InnoDB: Corruption: Page is marked as compressed\n"
Expand All @@ -263,6 +308,17 @@ fil_decompress_page(
fflush(stderr);
ut_error;
}

srv_stats.pages_page_decompressed.inc();

/* Copy the uncompressed page to the buffer pool, not
really any other options. */
memcpy(buf, in_buf, len);

// Need to free temporal buffer if no buffer was given
if (page_buf == NULL) {
ut_free(in_buf);
}
}


Loading

0 comments on commit 8c5d5bc

Please sign in to comment.