Commit 90c52e52 authored by Jan Lindström's avatar Jan Lindström

MDEV-12615: InnoDB page compression method snappy mostly does not compress pages

Snappy compression method require that output buffer
used for compression is bigger than input buffer.
Similarly lzo require additional work memory buffer.
Increase the allocated buffer accordingly.

buf_tmp_buffer_t: removed unnecessary lzo_mem, crypt_buf_free and
comp_buf_free.

buf_pool_reserve_tmp_slot: use alligned_alloc and if snappy
available allocate size based on snappy_max_compressed_length and
if lzo is available increase buffer by LZO1X_1_15_MEM_COMPRESS.

fil_compress_page: Remove unneeded lzo mem (we use same buffer)
and if output buffer is not yet allocated allocate based similarly
as above.

Decompression does not require additional work area.

    Modify test to use same test as other compression method tests.
parent f8802009
...@@ -64,10 +64,38 @@ Created 11/5/1995 Heikki Tuuri ...@@ -64,10 +64,38 @@ Created 11/5/1995 Heikki Tuuri
#include "ut0byte.h" #include "ut0byte.h"
#include <new> #include <new>
#ifdef UNIV_LINUX
#include <stdlib.h>
#endif
#ifdef HAVE_LZO #ifdef HAVE_LZO
#include "lzo/lzo1x.h" #include "lzo/lzo1x.h"
#endif #endif
#ifdef HAVE_SNAPPY
#include "snappy-c.h"
#endif
inline void* aligned_malloc(size_t size, size_t align) {
void *result;
#ifdef _MSC_VER
result = _aligned_malloc(size, align);
#else
if(posix_memalign(&result, align, size)) {
result = 0;
}
#endif
return result;
}
inline void aligned_free(void *ptr) {
#ifdef _MSC_VER
_aligned_free(ptr);
#else
free(ptr);
#endif
}
/* /*
IMPLEMENTATION OF THE BUFFER POOL IMPLEMENTATION OF THE BUFFER POOL
================================= =================================
...@@ -1555,20 +1583,14 @@ buf_pool_free_instance( ...@@ -1555,20 +1583,14 @@ buf_pool_free_instance(
if (buf_pool->tmp_arr) { if (buf_pool->tmp_arr) {
for(ulint i = 0; i < buf_pool->tmp_arr->n_slots; i++) { for(ulint i = 0; i < buf_pool->tmp_arr->n_slots; i++) {
buf_tmp_buffer_t* slot = &(buf_pool->tmp_arr->slots[i]); buf_tmp_buffer_t* slot = &(buf_pool->tmp_arr->slots[i]);
#ifdef HAVE_LZO if (slot && slot->crypt_buf) {
if (slot && slot->lzo_mem) { aligned_free(slot->crypt_buf);
ut_free(slot->lzo_mem); slot->crypt_buf = NULL;
slot->lzo_mem = NULL;
}
#endif
if (slot && slot->crypt_buf_free) {
ut_free(slot->crypt_buf_free);
slot->crypt_buf_free = NULL;
} }
if (slot && slot->comp_buf_free) { if (slot && slot->comp_buf) {
ut_free(slot->comp_buf_free); aligned_free(slot->comp_buf);
slot->comp_buf_free = NULL; slot->comp_buf = NULL;
} }
} }
} }
...@@ -6024,22 +6046,27 @@ buf_pool_reserve_tmp_slot( ...@@ -6024,22 +6046,27 @@ buf_pool_reserve_tmp_slot(
buf_pool_mutex_exit(buf_pool); buf_pool_mutex_exit(buf_pool);
/* Allocate temporary memory for encryption/decryption */ /* Allocate temporary memory for encryption/decryption */
if (free_slot->crypt_buf_free == NULL) { if (free_slot->crypt_buf == NULL) {
free_slot->crypt_buf_free = static_cast<byte *>(ut_malloc(UNIV_PAGE_SIZE*2)); free_slot->crypt_buf = static_cast<byte*>(aligned_malloc(UNIV_PAGE_SIZE, UNIV_PAGE_SIZE));
free_slot->crypt_buf = static_cast<byte *>(ut_align(free_slot->crypt_buf_free, UNIV_PAGE_SIZE)); memset(free_slot->crypt_buf, 0, UNIV_PAGE_SIZE);
memset(free_slot->crypt_buf_free, 0, UNIV_PAGE_SIZE *2);
} }
/* For page compressed tables allocate temporary memory for /* For page compressed tables allocate temporary memory for
compression/decompression */ compression/decompression */
if (compressed && free_slot->comp_buf_free == NULL) { if (compressed && free_slot->comp_buf == NULL) {
free_slot->comp_buf_free = static_cast<byte *>(ut_malloc(UNIV_PAGE_SIZE*2)); ulint size = UNIV_PAGE_SIZE;
free_slot->comp_buf = static_cast<byte *>(ut_align(free_slot->comp_buf_free, UNIV_PAGE_SIZE));
memset(free_slot->comp_buf_free, 0, UNIV_PAGE_SIZE *2); /* Both snappy and lzo compression methods require that
#ifdef HAVE_LZO output buffer used for compression is bigger than input
free_slot->lzo_mem = static_cast<byte *>(ut_malloc(LZO1X_1_15_MEM_COMPRESS)); buffer. Increase the allocated buffer size accordingly. */
memset(free_slot->lzo_mem, 0, LZO1X_1_15_MEM_COMPRESS); #if HAVE_SNAPPY
size = snappy_max_compressed_length(size);
#endif
#if HAVE_LZO
size += LZO1X_1_15_MEM_COMPRESS;
#endif #endif
free_slot->comp_buf = static_cast<byte*>(aligned_malloc(size, UNIV_PAGE_SIZE));
memset(free_slot->comp_buf, 0, size);
} }
return (free_slot); return (free_slot);
...@@ -6127,8 +6154,7 @@ buf_page_encrypt_before_write( ...@@ -6127,8 +6154,7 @@ buf_page_encrypt_before_write(
fsp_flags_get_page_compression_level(space->flags), fsp_flags_get_page_compression_level(space->flags),
fil_space_get_block_size(space, bpage->offset), fil_space_get_block_size(space, bpage->offset),
encrypted, encrypted,
&out_len, &out_len);
IF_LZO(slot->lzo_mem, NULL));
bpage->real_size = out_len; bpage->real_size = out_len;
......
...@@ -6744,8 +6744,7 @@ fil_iterate( ...@@ -6744,8 +6744,7 @@ fil_iterate(
0,/* FIXME: compression level */ 0,/* FIXME: compression level */
512,/* FIXME: use proper block size */ 512,/* FIXME: use proper block size */
encrypted, encrypted,
&len, &len);
NULL);
updated = true; updated = true;
} }
......
...@@ -99,17 +99,16 @@ fil_compress_page( ...@@ -99,17 +99,16 @@ fil_compress_page(
ulint level, /* in: compression level */ ulint level, /* in: compression level */
ulint block_size, /*!< in: block size */ ulint block_size, /*!< in: block size */
bool encrypted, /*!< in: is page also encrypted */ bool encrypted, /*!< in: is page also encrypted */
ulint* out_len, /*!< out: actual length of compressed ulint* out_len) /*!< out: actual length of compressed
page */ page */
byte* lzo_mem) /*!< in: temporal memory used by LZO */
{ {
int err = Z_OK; int err = Z_OK;
int comp_level = level; int comp_level = level;
ulint header_len = FIL_PAGE_DATA + FIL_PAGE_COMPRESSED_SIZE; ulint header_len = FIL_PAGE_DATA + FIL_PAGE_COMPRESSED_SIZE;
ulint write_size=0; ulint write_size = 0;
/* Cache to avoid change during function execution */ /* Cache to avoid change during function execution */
ulint comp_method = innodb_compression_algorithm; ulint comp_method = innodb_compression_algorithm;
bool allocated=false; bool allocated = false;
/* page_compression does not apply to tables or tablespaces /* page_compression does not apply to tables or tablespaces
that use ROW_FORMAT=COMPRESSED */ that use ROW_FORMAT=COMPRESSED */
...@@ -121,13 +120,23 @@ fil_compress_page( ...@@ -121,13 +120,23 @@ fil_compress_page(
if (!out_buf) { if (!out_buf) {
allocated = true; allocated = true;
out_buf = static_cast<byte *>(ut_malloc(UNIV_PAGE_SIZE)); ulint size = UNIV_PAGE_SIZE;
#ifdef HAVE_LZO
/* Both snappy and lzo compression methods require that
output buffer used for compression is bigger than input
buffer. Increase the allocated buffer size accordingly. */
#if HAVE_SNAPPY
if (comp_method == PAGE_SNAPPY_ALGORITHM) {
size = snappy_max_compressed_length(size);
}
#endif
#if HAVE_LZO
if (comp_method == PAGE_LZO_ALGORITHM) { if (comp_method == PAGE_LZO_ALGORITHM) {
lzo_mem = static_cast<byte *>(ut_malloc(LZO1X_1_15_MEM_COMPRESS)); size += LZO1X_1_15_MEM_COMPRESS;
memset(lzo_mem, 0, LZO1X_1_15_MEM_COMPRESS);
} }
#endif #endif
out_buf = static_cast<byte *>(ut_malloc(size));
} }
ut_ad(buf); ut_ad(buf);
...@@ -163,6 +172,7 @@ fil_compress_page( ...@@ -163,6 +172,7 @@ fil_compress_page(
switch(comp_method) { switch(comp_method) {
#ifdef HAVE_LZ4 #ifdef HAVE_LZ4
case PAGE_LZ4_ALGORITHM: case PAGE_LZ4_ALGORITHM:
#ifdef HAVE_LZ4_COMPRESS_DEFAULT #ifdef HAVE_LZ4_COMPRESS_DEFAULT
err = LZ4_compress_default((const char *)buf, err = LZ4_compress_default((const char *)buf,
(char *)out_buf+header_len, len, write_size); (char *)out_buf+header_len, len, write_size);
...@@ -197,7 +207,7 @@ fil_compress_page( ...@@ -197,7 +207,7 @@ fil_compress_page(
#ifdef HAVE_LZO #ifdef HAVE_LZO
case PAGE_LZO_ALGORITHM: case PAGE_LZO_ALGORITHM:
err = lzo1x_1_15_compress( err = lzo1x_1_15_compress(
buf, len, out_buf+header_len, &write_size, lzo_mem); buf, len, out_buf+header_len, &write_size, out_buf+UNIV_PAGE_SIZE);
if (err != LZO_E_OK || write_size > UNIV_PAGE_SIZE-header_len) { if (err != LZO_E_OK || write_size > UNIV_PAGE_SIZE-header_len) {
if (space && !space->printed_compression_failure) { if (space && !space->printed_compression_failure) {
...@@ -288,6 +298,7 @@ fil_compress_page( ...@@ -288,6 +298,7 @@ fil_compress_page(
case PAGE_SNAPPY_ALGORITHM: case PAGE_SNAPPY_ALGORITHM:
{ {
snappy_status cstatus; snappy_status cstatus;
write_size = snappy_max_compressed_length(UNIV_PAGE_SIZE);
cstatus = snappy_compress( cstatus = snappy_compress(
(const char *)buf, (const char *)buf,
...@@ -443,11 +454,6 @@ fil_compress_page( ...@@ -443,11 +454,6 @@ fil_compress_page(
err_exit: err_exit:
if (allocated) { if (allocated) {
ut_free(out_buf); ut_free(out_buf);
#ifdef HAVE_LZO
if (comp_method == PAGE_LZO_ALGORITHM) {
ut_free(lzo_mem);
}
#endif
} }
return (buf); return (buf);
...@@ -509,7 +515,7 @@ fil_decompress_page( ...@@ -509,7 +515,7 @@ fil_decompress_page(
ptype != FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED)) { ptype != FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED)) {
ib_logf(IB_LOG_LEVEL_ERROR, ib_logf(IB_LOG_LEVEL_ERROR,
"Corruption: We try to uncompress corrupted page" "Corruption: We try to uncompress corrupted page"
" CRC %lu type %lu len %lu.", " CRC " ULINTPF " type " ULINTPF " len " ULINTPF ".",
mach_read_from_4(buf+FIL_PAGE_SPACE_OR_CHKSUM), mach_read_from_4(buf+FIL_PAGE_SPACE_OR_CHKSUM),
mach_read_from_2(buf+FIL_PAGE_TYPE), len); mach_read_from_2(buf+FIL_PAGE_TYPE), len);
...@@ -533,7 +539,7 @@ fil_decompress_page( ...@@ -533,7 +539,7 @@ fil_decompress_page(
if (actual_size == 0 || actual_size > UNIV_PAGE_SIZE) { if (actual_size == 0 || actual_size > UNIV_PAGE_SIZE) {
ib_logf(IB_LOG_LEVEL_ERROR, ib_logf(IB_LOG_LEVEL_ERROR,
"Corruption: We try to uncompress corrupted page" "Corruption: We try to uncompress corrupted page"
" actual size %lu compression %s.", " actual size " ULINTPF " compression %s.",
actual_size, fil_get_compression_alg_name(compression_alg)); actual_size, fil_get_compression_alg_name(compression_alg));
fflush(stderr); fflush(stderr);
if (return_error) { if (return_error) {
...@@ -548,12 +554,9 @@ fil_decompress_page( ...@@ -548,12 +554,9 @@ fil_decompress_page(
*write_size = actual_size; *write_size = actual_size;
} }
#ifdef UNIV_PAGECOMPRESS_DEBUG DBUG_PRINT("compress",
ib_logf(IB_LOG_LEVEL_INFO, ("Preparing for decompress for len " ULINTPF ".",
"Preparing for decompress for len %lu\n", actual_size));
actual_size);
#endif /* UNIV_PAGECOMPRESS_DEBUG */
switch(compression_alg) { switch(compression_alg) {
case PAGE_ZLIB_ALGORITHM: case PAGE_ZLIB_ALGORITHM:
...@@ -565,7 +568,7 @@ fil_decompress_page( ...@@ -565,7 +568,7 @@ fil_decompress_page(
ib_logf(IB_LOG_LEVEL_ERROR, ib_logf(IB_LOG_LEVEL_ERROR,
"Corruption: Page is marked as compressed" "Corruption: Page is marked as compressed"
" but uncompress failed with error %d " " but uncompress failed with error %d "
" size %lu len %lu.", " size " ULINTPF " len " ULINTPF ".",
err, actual_size, len); err, actual_size, len);
fflush(stderr); fflush(stderr);
...@@ -584,9 +587,10 @@ fil_decompress_page( ...@@ -584,9 +587,10 @@ fil_decompress_page(
if (err != (int)actual_size) { if (err != (int)actual_size) {
ib_logf(IB_LOG_LEVEL_ERROR, ib_logf(IB_LOG_LEVEL_ERROR,
"Corruption: Page is marked as compressed" "Corruption: Page is marked as compressed"
" but decompression read only %d bytes " " but uncompress failed with error %d "
" size %lu len %lu.", " size " ULINTPF " len " ULINTPF ".",
err, actual_size, len); err, actual_size, len);
fflush(stderr); fflush(stderr);
if (return_error) { if (return_error) {
...@@ -598,16 +602,17 @@ fil_decompress_page( ...@@ -598,16 +602,17 @@ fil_decompress_page(
#endif /* HAVE_LZ4 */ #endif /* HAVE_LZ4 */
#ifdef HAVE_LZO #ifdef HAVE_LZO
case PAGE_LZO_ALGORITHM: { case PAGE_LZO_ALGORITHM: {
ulint olen=0; ulint olen = 0;
err = lzo1x_decompress((const unsigned char *)buf+header_len, err = lzo1x_decompress((const unsigned char *)buf+header_len,
actual_size,(unsigned char *)in_buf, &olen, NULL); actual_size,(unsigned char *)in_buf, &olen, NULL);
if (err != LZO_E_OK || (olen == 0 || olen > UNIV_PAGE_SIZE)) { if (err != LZO_E_OK || (olen == 0 || olen > UNIV_PAGE_SIZE)) {
ib_logf(IB_LOG_LEVEL_ERROR, ib_logf(IB_LOG_LEVEL_ERROR,
"Corruption: Page is marked as compressed" "Corruption: Page is marked as compressed"
" but decompression read only %ld bytes" " but uncompress failed with error %d "
" size %lu len %lu.", " size " ULINTPF " len " ULINTPF ".",
olen, actual_size, len); err, actual_size, len);
fflush(stderr); fflush(stderr);
if (return_error) { if (return_error) {
...@@ -642,7 +647,7 @@ fil_decompress_page( ...@@ -642,7 +647,7 @@ fil_decompress_page(
ib_logf(IB_LOG_LEVEL_ERROR, ib_logf(IB_LOG_LEVEL_ERROR,
"Corruption: Page is marked as compressed" "Corruption: Page is marked as compressed"
" but decompression read only %ld bytes" " but decompression read only %ld bytes"
" size %lu len %lu.", " size " ULINTPF "len " ULINTPF ".",
dst_pos, actual_size, len); dst_pos, actual_size, len);
fflush(stderr); fflush(stderr);
...@@ -671,7 +676,7 @@ fil_decompress_page( ...@@ -671,7 +676,7 @@ fil_decompress_page(
ib_logf(IB_LOG_LEVEL_ERROR, ib_logf(IB_LOG_LEVEL_ERROR,
"Corruption: Page is marked as compressed" "Corruption: Page is marked as compressed"
" but decompression read only %du bytes" " but decompression read only %du bytes"
" size %lu len %lu err %d.", " size " ULINTPF " len " ULINTPF " err %d.",
dst_pos, actual_size, len, err); dst_pos, actual_size, len, err);
fflush(stderr); fflush(stderr);
...@@ -687,7 +692,7 @@ fil_decompress_page( ...@@ -687,7 +692,7 @@ fil_decompress_page(
case PAGE_SNAPPY_ALGORITHM: case PAGE_SNAPPY_ALGORITHM:
{ {
snappy_status cstatus; snappy_status cstatus;
ulint olen = 0; ulint olen = UNIV_PAGE_SIZE;
cstatus = snappy_uncompress( cstatus = snappy_uncompress(
(const char *)(buf+header_len), (const char *)(buf+header_len),
...@@ -695,11 +700,11 @@ fil_decompress_page( ...@@ -695,11 +700,11 @@ fil_decompress_page(
(char *)in_buf, (char *)in_buf,
(size_t*)&olen); (size_t*)&olen);
if (cstatus != SNAPPY_OK || (olen == 0 || olen > UNIV_PAGE_SIZE)) { if (cstatus != SNAPPY_OK || olen != UNIV_PAGE_SIZE) {
ib_logf(IB_LOG_LEVEL_ERROR, ib_logf(IB_LOG_LEVEL_ERROR,
"Corruption: Page is marked as compressed" "Corruption: Page is marked as compressed"
" but decompression read only %lu bytes" " but decompression read only " ULINTPF " bytes"
" size %lu len %lu err %d.", " size " ULINTPF " len " ULINTPF " err %d.",
olen, actual_size, len, (int)cstatus); olen, actual_size, len, (int)cstatus);
fflush(stderr); fflush(stderr);
...@@ -708,6 +713,7 @@ fil_decompress_page( ...@@ -708,6 +713,7 @@ fil_decompress_page(
} }
ut_error; ut_error;
} }
break; break;
} }
#endif /* HAVE_SNAPPY */ #endif /* HAVE_SNAPPY */
...@@ -733,8 +739,7 @@ fil_decompress_page( ...@@ -733,8 +739,7 @@ fil_decompress_page(
memcpy(buf, in_buf, len); memcpy(buf, in_buf, len);
error_return: error_return:
// Need to free temporal buffer if no buffer was given if (page_buf != in_buf) {
if (page_buf == NULL) {
ut_free(in_buf); ut_free(in_buf);
} }
} }
...@@ -1545,20 +1545,13 @@ directory (buf) to see it. Do not use from outside! */ ...@@ -1545,20 +1545,13 @@ directory (buf) to see it. Do not use from outside! */
typedef struct { typedef struct {
bool reserved; /*!< true if this slot is reserved bool reserved; /*!< true if this slot is reserved
*/ */
#ifdef HAVE_LZO
byte* lzo_mem; /*!< Temporal memory used by LZO */
#endif
byte* crypt_buf; /*!< for encryption the data needs to be byte* crypt_buf; /*!< for encryption the data needs to be
copied to a separate buffer before it's copied to a separate buffer before it's
encrypted&written. this as a page can be encrypted&written. this as a page can be
read while it's being flushed */ read while it's being flushed */
byte* crypt_buf_free; /*!< for encryption, allocated buffer
that is then alligned */
byte* comp_buf; /*!< for compression we need byte* comp_buf; /*!< for compression we need
temporal buffer because page temporal buffer because page
can be read while it's being flushed */ can be read while it's being flushed */
byte* comp_buf_free; /*!< for compression, allocated
buffer that is then alligned */
byte* out_buf; /*!< resulting buffer after byte* out_buf; /*!< resulting buffer after
encryption/compression. This is a encryption/compression. This is a
pointer and not allocated. */ pointer and not allocated. */
......
...@@ -65,9 +65,8 @@ fil_compress_page( ...@@ -65,9 +65,8 @@ fil_compress_page(
ulint level, /* in: compression level */ ulint level, /* in: compression level */
ulint block_size, /*!< in: block size */ ulint block_size, /*!< in: block size */
bool encrypted, /*!< in: is page also encrypted */ bool encrypted, /*!< in: is page also encrypted */
ulint* out_len, /*!< out: actual length of compressed ulint* out_len); /*!< out: actual length of compressed
page */ page */
byte* lzo_mem); /*!< in: temporal memory used by LZO */
/****************************************************************//** /****************************************************************//**
For page compressed pages decompress the page after actual read For page compressed pages decompress the page after actual read
......
...@@ -65,6 +65,18 @@ Created 11/5/1995 Heikki Tuuri ...@@ -65,6 +65,18 @@ Created 11/5/1995 Heikki Tuuri
#include "fil0pagecompress.h" #include "fil0pagecompress.h"
#include "ha_prototypes.h" #include "ha_prototypes.h"
#ifdef UNIV_LINUX
#include <stdlib.h>
#endif
#ifdef HAVE_LZO
#include "lzo/lzo1x.h"
#endif
#ifdef HAVE_SNAPPY
#include "snappy-c.h"
#endif
/** Decrypt a page. /** Decrypt a page.
@param[in,out] bpage Page control block @param[in,out] bpage Page control block
@param[in,out] space tablespace @param[in,out] space tablespace
...@@ -77,6 +89,26 @@ buf_page_decrypt_after_read(buf_page_t* bpage, fil_space_t* space) ...@@ -77,6 +89,26 @@ buf_page_decrypt_after_read(buf_page_t* bpage, fil_space_t* space)
/* prototypes for new functions added to ha_innodb.cc */ /* prototypes for new functions added to ha_innodb.cc */
trx_t* innobase_get_trx(); trx_t* innobase_get_trx();
inline void* aligned_malloc(size_t size, size_t align) {
void *result;
#ifdef _MSC_VER
result = _aligned_malloc(size, align);
#else
if(posix_memalign(&result, align, size)) {
result = 0;
}
#endif
return result;
}
inline void aligned_free(void *ptr) {
#ifdef _MSC_VER
_aligned_free(ptr);
#else
free(ptr);
#endif
}
static inline static inline
void void
_increment_page_get_statistics(buf_block_t* block, trx_t* trx) _increment_page_get_statistics(buf_block_t* block, trx_t* trx)
...@@ -108,10 +140,6 @@ _increment_page_get_statistics(buf_block_t* block, trx_t* trx) ...@@ -108,10 +140,6 @@ _increment_page_get_statistics(buf_block_t* block, trx_t* trx)
return; return;
} }
#ifdef HAVE_LZO
#include "lzo/lzo1x.h"
#endif
/* /*
IMPLEMENTATION OF THE BUFFER POOL IMPLEMENTATION OF THE BUFFER POOL
================================= =================================
...@@ -1639,20 +1667,14 @@ buf_pool_free_instance( ...@@ -1639,20 +1667,14 @@ buf_pool_free_instance(
if (buf_pool->tmp_arr) { if (buf_pool->tmp_arr) {
for(ulint i = 0; i < buf_pool->tmp_arr->n_slots; i++) { for(ulint i = 0; i < buf_pool->tmp_arr->n_slots; i++) {
buf_tmp_buffer_t* slot = &(buf_pool->tmp_arr->slots[i]); buf_tmp_buffer_t* slot = &(buf_pool->tmp_arr->slots[i]);
#ifdef HAVE_LZO if (slot && slot->crypt_buf) {
if (slot && slot->lzo_mem) { aligned_free(slot->crypt_buf);
ut_free(slot->lzo_mem); slot->crypt_buf = NULL;
slot->lzo_mem = NULL;
}
#endif
if (slot && slot->crypt_buf_free) {
ut_free(slot->crypt_buf_free);
slot->crypt_buf_free = NULL;
} }
if (slot && slot->comp_buf_free) { if (slot && slot->comp_buf) {
ut_free(slot->comp_buf_free); aligned_free(slot->comp_buf);
slot->comp_buf_free = NULL; slot->comp_buf = NULL;
} }
} }
} }
...@@ -6171,22 +6193,27 @@ buf_pool_reserve_tmp_slot( ...@@ -6171,22 +6193,27 @@ buf_pool_reserve_tmp_slot(
buf_pool_mutex_exit(buf_pool); buf_pool_mutex_exit(buf_pool);
/* Allocate temporary memory for encryption/decryption */ /* Allocate temporary memory for encryption/decryption */
if (free_slot->crypt_buf_free == NULL) { if (free_slot->crypt_buf == NULL) {
free_slot->crypt_buf_free = static_cast<byte *>(ut_malloc(UNIV_PAGE_SIZE*2)); free_slot->crypt_buf = static_cast<byte*>(aligned_malloc(UNIV_PAGE_SIZE, UNIV_PAGE_SIZE));
free_slot->crypt_buf = static_cast<byte *>(ut_align(free_slot->crypt_buf_free, UNIV_PAGE_SIZE)); memset(free_slot->crypt_buf, 0, UNIV_PAGE_SIZE);
memset(free_slot->crypt_buf_free, 0, UNIV_PAGE_SIZE *2);
} }
/* For page compressed tables allocate temporary memory for /* For page compressed tables allocate temporary memory for
compression/decompression */ compression/decompression */
if (compressed && free_slot->comp_buf_free == NULL) { if (compressed && free_slot->comp_buf == NULL) {
free_slot->comp_buf_free = static_cast<byte *>(ut_malloc(UNIV_PAGE_SIZE*2)); ulint size = UNIV_PAGE_SIZE;
free_slot->comp_buf = static_cast<byte *>(ut_align(free_slot->comp_buf_free, UNIV_PAGE_SIZE));
memset(free_slot->comp_buf_free, 0, UNIV_PAGE_SIZE *2); /* Both snappy and lzo compression methods require that
#ifdef HAVE_LZO output buffer used for compression is bigger than input
free_slot->lzo_mem = static_cast<byte *>(ut_malloc(LZO1X_1_15_MEM_COMPRESS)); buffer. Increase the allocated buffer size accordingly. */
memset(free_slot->lzo_mem, 0, LZO1X_1_15_MEM_COMPRESS); #if HAVE_SNAPPY
size = snappy_max_compressed_length(size);
#endif
#if HAVE_LZO
size += LZO1X_1_15_MEM_COMPRESS;
#endif #endif
free_slot->comp_buf = static_cast<byte*>(aligned_malloc(size, UNIV_PAGE_SIZE));
memset(free_slot->comp_buf, 0, size);
} }
return (free_slot); return (free_slot);
...@@ -6274,8 +6301,7 @@ buf_page_encrypt_before_write( ...@@ -6274,8 +6301,7 @@ buf_page_encrypt_before_write(
fsp_flags_get_page_compression_level(space->flags), fsp_flags_get_page_compression_level(space->flags),
fil_space_get_block_size(space, bpage->offset), fil_space_get_block_size(space, bpage->offset),
encrypted, encrypted,
&out_len, &out_len);
IF_LZO(slot->lzo_mem, NULL));
bpage->real_size = out_len; bpage->real_size = out_len;
......
...@@ -7090,8 +7090,7 @@ fil_iterate( ...@@ -7090,8 +7090,7 @@ fil_iterate(
0,/* FIXME: compression level */ 0,/* FIXME: compression level */
512,/* FIXME: use proper block size */ 512,/* FIXME: use proper block size */
encrypted, encrypted,
&len, &len);
NULL);
updated = true; updated = true;
} }
......
...@@ -99,17 +99,16 @@ fil_compress_page( ...@@ -99,17 +99,16 @@ fil_compress_page(
ulint level, /* in: compression level */ ulint level, /* in: compression level */
ulint block_size, /*!< in: block size */ ulint block_size, /*!< in: block size */
bool encrypted, /*!< in: is page also encrypted */ bool encrypted, /*!< in: is page also encrypted */
ulint* out_len, /*!< out: actual length of compressed ulint* out_len) /*!< out: actual length of compressed
page */ page */
byte* lzo_mem) /*!< in: temporal memory used by LZO */
{ {
int err = Z_OK; int err = Z_OK;
int comp_level = level; int comp_level = level;
ulint header_len = FIL_PAGE_DATA + FIL_PAGE_COMPRESSED_SIZE; ulint header_len = FIL_PAGE_DATA + FIL_PAGE_COMPRESSED_SIZE;
ulint write_size=0; ulint write_size = 0;
/* Cache to avoid change during function execution */ /* Cache to avoid change during function execution */
ulint comp_method = innodb_compression_algorithm; ulint comp_method = innodb_compression_algorithm;
bool allocated=false; bool allocated = false;
/* page_compression does not apply to tables or tablespaces /* page_compression does not apply to tables or tablespaces
that use ROW_FORMAT=COMPRESSED */ that use ROW_FORMAT=COMPRESSED */
...@@ -121,13 +120,23 @@ fil_compress_page( ...@@ -121,13 +120,23 @@ fil_compress_page(
if (!out_buf) { if (!out_buf) {
allocated = true; allocated = true;
out_buf = static_cast<byte *>(ut_malloc(UNIV_PAGE_SIZE)); ulint size = UNIV_PAGE_SIZE;
#ifdef HAVE_LZO
/* Both snappy and lzo compression methods require that
output buffer used for compression is bigger than input
buffer. Increase the allocated buffer size accordingly. */
#if HAVE_SNAPPY
if (comp_method == PAGE_SNAPPY_ALGORITHM) {
size = snappy_max_compressed_length(size);
}
#endif
#if HAVE_LZO
if (comp_method == PAGE_LZO_ALGORITHM) { if (comp_method == PAGE_LZO_ALGORITHM) {
lzo_mem = static_cast<byte *>(ut_malloc(LZO1X_1_15_MEM_COMPRESS)); size += LZO1X_1_15_MEM_COMPRESS;
memset(lzo_mem, 0, LZO1X_1_15_MEM_COMPRESS);
} }
#endif #endif
out_buf = static_cast<byte *>(ut_malloc(size));
} }
ut_ad(buf); ut_ad(buf);
...@@ -163,6 +172,7 @@ fil_compress_page( ...@@ -163,6 +172,7 @@ fil_compress_page(
switch(comp_method) { switch(comp_method) {
#ifdef HAVE_LZ4 #ifdef HAVE_LZ4
case PAGE_LZ4_ALGORITHM: case PAGE_LZ4_ALGORITHM:
#ifdef HAVE_LZ4_COMPRESS_DEFAULT #ifdef HAVE_LZ4_COMPRESS_DEFAULT
err = LZ4_compress_default((const char *)buf, err = LZ4_compress_default((const char *)buf,
(char *)out_buf+header_len, len, write_size); (char *)out_buf+header_len, len, write_size);
...@@ -197,7 +207,7 @@ fil_compress_page( ...@@ -197,7 +207,7 @@ fil_compress_page(
#ifdef HAVE_LZO #ifdef HAVE_LZO
case PAGE_LZO_ALGORITHM: case PAGE_LZO_ALGORITHM:
err = lzo1x_1_15_compress( err = lzo1x_1_15_compress(
buf, len, out_buf+header_len, &write_size, lzo_mem); buf, len, out_buf+header_len, &write_size, out_buf+UNIV_PAGE_SIZE);
if (err != LZO_E_OK || write_size > UNIV_PAGE_SIZE-header_len) { if (err != LZO_E_OK || write_size > UNIV_PAGE_SIZE-header_len) {
if (space && !space->printed_compression_failure) { if (space && !space->printed_compression_failure) {
...@@ -288,6 +298,7 @@ fil_compress_page( ...@@ -288,6 +298,7 @@ fil_compress_page(
case PAGE_SNAPPY_ALGORITHM: case PAGE_SNAPPY_ALGORITHM:
{ {
snappy_status cstatus; snappy_status cstatus;
write_size = snappy_max_compressed_length(UNIV_PAGE_SIZE);
cstatus = snappy_compress( cstatus = snappy_compress(
(const char *)buf, (const char *)buf,
...@@ -443,11 +454,6 @@ fil_compress_page( ...@@ -443,11 +454,6 @@ fil_compress_page(
err_exit: err_exit:
if (allocated) { if (allocated) {
ut_free(out_buf); ut_free(out_buf);
#ifdef HAVE_LZO
if (comp_method == PAGE_LZO_ALGORITHM) {
ut_free(lzo_mem);
}
#endif
} }
return (buf); return (buf);
...@@ -509,7 +515,7 @@ fil_decompress_page( ...@@ -509,7 +515,7 @@ fil_decompress_page(
ptype != FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED)) { ptype != FIL_PAGE_PAGE_COMPRESSED_ENCRYPTED)) {
ib_logf(IB_LOG_LEVEL_ERROR, ib_logf(IB_LOG_LEVEL_ERROR,
"Corruption: We try to uncompress corrupted page" "Corruption: We try to uncompress corrupted page"
" CRC %lu type %lu len %lu.", " CRC " ULINTPF " type " ULINTPF " len " ULINTPF ".",
mach_read_from_4(buf+FIL_PAGE_SPACE_OR_CHKSUM), mach_read_from_4(buf+FIL_PAGE_SPACE_OR_CHKSUM),
mach_read_from_2(buf+FIL_PAGE_TYPE), len); mach_read_from_2(buf+FIL_PAGE_TYPE), len);
...@@ -533,7 +539,7 @@ fil_decompress_page( ...@@ -533,7 +539,7 @@ fil_decompress_page(
if (actual_size == 0 || actual_size > UNIV_PAGE_SIZE) { if (actual_size == 0 || actual_size > UNIV_PAGE_SIZE) {
ib_logf(IB_LOG_LEVEL_ERROR, ib_logf(IB_LOG_LEVEL_ERROR,
"Corruption: We try to uncompress corrupted page" "Corruption: We try to uncompress corrupted page"
" actual size %lu compression %s.", " actual size " ULINTPF " compression %s.",
actual_size, fil_get_compression_alg_name(compression_alg)); actual_size, fil_get_compression_alg_name(compression_alg));
fflush(stderr); fflush(stderr);
if (return_error) { if (return_error) {
...@@ -548,12 +554,9 @@ fil_decompress_page( ...@@ -548,12 +554,9 @@ fil_decompress_page(
*write_size = actual_size; *write_size = actual_size;
} }
#ifdef UNIV_PAGECOMPRESS_DEBUG DBUG_PRINT("compress",
ib_logf(IB_LOG_LEVEL_INFO, ("Preparing for decompress for len " ULINTPF ".",
"Preparing for decompress for len %lu\n", actual_size));
actual_size);
#endif /* UNIV_PAGECOMPRESS_DEBUG */
switch(compression_alg) { switch(compression_alg) {
case PAGE_ZLIB_ALGORITHM: case PAGE_ZLIB_ALGORITHM:
...@@ -565,7 +568,7 @@ fil_decompress_page( ...@@ -565,7 +568,7 @@ fil_decompress_page(
ib_logf(IB_LOG_LEVEL_ERROR, ib_logf(IB_LOG_LEVEL_ERROR,
"Corruption: Page is marked as compressed" "Corruption: Page is marked as compressed"
" but uncompress failed with error %d " " but uncompress failed with error %d "
" size %lu len %lu.", " size " ULINTPF " len " ULINTPF ".",
err, actual_size, len); err, actual_size, len);
fflush(stderr); fflush(stderr);
...@@ -584,9 +587,10 @@ fil_decompress_page( ...@@ -584,9 +587,10 @@ fil_decompress_page(
if (err != (int)actual_size) { if (err != (int)actual_size) {
ib_logf(IB_LOG_LEVEL_ERROR, ib_logf(IB_LOG_LEVEL_ERROR,
"Corruption: Page is marked as compressed" "Corruption: Page is marked as compressed"
" but decompression read only %d bytes " " but uncompress failed with error %d "
" size %lu len %lu.", " size " ULINTPF " len " ULINTPF ".",
err, actual_size, len); err, actual_size, len);
fflush(stderr); fflush(stderr);
if (return_error) { if (return_error) {
...@@ -598,16 +602,17 @@ fil_decompress_page( ...@@ -598,16 +602,17 @@ fil_decompress_page(
#endif /* HAVE_LZ4 */ #endif /* HAVE_LZ4 */
#ifdef HAVE_LZO #ifdef HAVE_LZO
case PAGE_LZO_ALGORITHM: { case PAGE_LZO_ALGORITHM: {
ulint olen=0; ulint olen = 0;
err = lzo1x_decompress((const unsigned char *)buf+header_len, err = lzo1x_decompress((const unsigned char *)buf+header_len,
actual_size,(unsigned char *)in_buf, &olen, NULL); actual_size,(unsigned char *)in_buf, &olen, NULL);
if (err != LZO_E_OK || (olen == 0 || olen > UNIV_PAGE_SIZE)) { if (err != LZO_E_OK || (olen == 0 || olen > UNIV_PAGE_SIZE)) {
ib_logf(IB_LOG_LEVEL_ERROR, ib_logf(IB_LOG_LEVEL_ERROR,
"Corruption: Page is marked as compressed" "Corruption: Page is marked as compressed"
" but decompression read only %ld bytes" " but uncompress failed with error %d "
" size %lu len %lu.", " size " ULINTPF " len " ULINTPF ".",
olen, actual_size, len); err, actual_size, len);
fflush(stderr); fflush(stderr);
if (return_error) { if (return_error) {
...@@ -642,7 +647,7 @@ fil_decompress_page( ...@@ -642,7 +647,7 @@ fil_decompress_page(
ib_logf(IB_LOG_LEVEL_ERROR, ib_logf(IB_LOG_LEVEL_ERROR,
"Corruption: Page is marked as compressed" "Corruption: Page is marked as compressed"
" but decompression read only %ld bytes" " but decompression read only %ld bytes"
" size %lu len %lu.", " size " ULINTPF "len " ULINTPF ".",
dst_pos, actual_size, len); dst_pos, actual_size, len);
fflush(stderr); fflush(stderr);
...@@ -671,7 +676,7 @@ fil_decompress_page( ...@@ -671,7 +676,7 @@ fil_decompress_page(
ib_logf(IB_LOG_LEVEL_ERROR, ib_logf(IB_LOG_LEVEL_ERROR,
"Corruption: Page is marked as compressed" "Corruption: Page is marked as compressed"
" but decompression read only %du bytes" " but decompression read only %du bytes"
" size %lu len %lu err %d.", " size " ULINTPF " len " ULINTPF " err %d.",
dst_pos, actual_size, len, err); dst_pos, actual_size, len, err);
fflush(stderr); fflush(stderr);
...@@ -687,7 +692,7 @@ fil_decompress_page( ...@@ -687,7 +692,7 @@ fil_decompress_page(
case PAGE_SNAPPY_ALGORITHM: case PAGE_SNAPPY_ALGORITHM:
{ {
snappy_status cstatus; snappy_status cstatus;
ulint olen = 0; ulint olen = UNIV_PAGE_SIZE;
cstatus = snappy_uncompress( cstatus = snappy_uncompress(
(const char *)(buf+header_len), (const char *)(buf+header_len),
...@@ -695,11 +700,11 @@ fil_decompress_page( ...@@ -695,11 +700,11 @@ fil_decompress_page(
(char *)in_buf, (char *)in_buf,
(size_t*)&olen); (size_t*)&olen);
if (cstatus != SNAPPY_OK || (olen == 0 || olen > UNIV_PAGE_SIZE)) { if (cstatus != SNAPPY_OK || olen != UNIV_PAGE_SIZE) {
ib_logf(IB_LOG_LEVEL_ERROR, ib_logf(IB_LOG_LEVEL_ERROR,
"Corruption: Page is marked as compressed" "Corruption: Page is marked as compressed"
" but decompression read only %lu bytes" " but decompression read only " ULINTPF " bytes"
" size %lu len %lu err %d.", " size " ULINTPF " len " ULINTPF " err %d.",
olen, actual_size, len, (int)cstatus); olen, actual_size, len, (int)cstatus);
fflush(stderr); fflush(stderr);
...@@ -708,6 +713,7 @@ fil_decompress_page( ...@@ -708,6 +713,7 @@ fil_decompress_page(
} }
ut_error; ut_error;
} }
break; break;
} }
#endif /* HAVE_SNAPPY */ #endif /* HAVE_SNAPPY */
...@@ -733,8 +739,7 @@ fil_decompress_page( ...@@ -733,8 +739,7 @@ fil_decompress_page(
memcpy(buf, in_buf, len); memcpy(buf, in_buf, len);
error_return: error_return:
// Need to free temporal buffer if no buffer was given if (page_buf != in_buf) {
if (page_buf == NULL) {
ut_free(in_buf); ut_free(in_buf);
} }
} }
...@@ -1577,20 +1577,13 @@ directory (buf) to see it. Do not use from outside! */ ...@@ -1577,20 +1577,13 @@ directory (buf) to see it. Do not use from outside! */
typedef struct { typedef struct {
bool reserved; /*!< true if this slot is reserved bool reserved; /*!< true if this slot is reserved
*/ */
#ifdef HAVE_LZO
byte* lzo_mem; /*!< Temporal memory used by LZO */
#endif
byte* crypt_buf; /*!< for encryption the data needs to be byte* crypt_buf; /*!< for encryption the data needs to be
copied to a separate buffer before it's copied to a separate buffer before it's
encrypted&written. this as a page can be encrypted&written. this as a page can be
read while it's being flushed */ read while it's being flushed */
byte* crypt_buf_free; /*!< for encryption, allocated buffer
that is then alligned */
byte* comp_buf; /*!< for compression we need byte* comp_buf; /*!< for compression we need
temporal buffer because page temporal buffer because page
can be read while it's being flushed */ can be read while it's being flushed */
byte* comp_buf_free; /*!< for compression, allocated
buffer that is then alligned */
byte* out_buf; /*!< resulting buffer after byte* out_buf; /*!< resulting buffer after
encryption/compression. This is a encryption/compression. This is a
pointer and not allocated. */ pointer and not allocated. */
......
...@@ -65,9 +65,8 @@ fil_compress_page( ...@@ -65,9 +65,8 @@ fil_compress_page(
ulint level, /* in: compression level */ ulint level, /* in: compression level */
ulint block_size, /*!< in: block size */ ulint block_size, /*!< in: block size */
bool encrypted, /*!< in: is page also encrypted */ bool encrypted, /*!< in: is page also encrypted */
ulint* out_len, /*!< out: actual length of compressed ulint* out_len); /*!< out: actual length of compressed
page */ page */
byte* lzo_mem); /*!< in: temporal memory used by LZO */
/****************************************************************//** /****************************************************************//**
For page compressed pages decompress the page after actual read For page compressed pages decompress the page after actual read
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment