diff --git a/storage/innobase/buf/buf0dblwr.cc b/storage/innobase/buf/buf0dblwr.cc index 8a3d14db8a7..c903f5fbffa 100644 --- a/storage/innobase/buf/buf0dblwr.cc +++ b/storage/innobase/buf/buf0dblwr.cc @@ -383,7 +383,7 @@ buf_dblwr_init_or_load_pages( /* Read the trx sys header to check if we are using the doublewrite buffer */ off_t trx_sys_page = TRX_SYS_PAGE_NO * UNIV_PAGE_SIZE; - os_file_read(file, read_buf, trx_sys_page, UNIV_PAGE_SIZE); + os_file_read(file, read_buf, trx_sys_page, UNIV_PAGE_SIZE, FALSE); doublewrite = read_buf + TRX_SYS_DOUBLEWRITE; @@ -420,9 +420,9 @@ buf_dblwr_init_or_load_pages( block_bytes = TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * UNIV_PAGE_SIZE; - os_file_read(file, buf, block1 * UNIV_PAGE_SIZE, block_bytes); + os_file_read(file, buf, block1 * UNIV_PAGE_SIZE, block_bytes, FALSE); os_file_read(file, buf + block_bytes, block2 * UNIV_PAGE_SIZE, - block_bytes); + block_bytes, FALSE); /* Check if any of these pages is half-written in data files, in the intended position */ diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index 09d969556a6..f870a30aaa7 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -809,7 +809,9 @@ fil_node_open_file( set */ page = static_cast(ut_align(buf2, UNIV_PAGE_SIZE)); - success = os_file_read(node->handle, page, 0, UNIV_PAGE_SIZE); + success = os_file_read(node->handle, page, 0, UNIV_PAGE_SIZE, + space->flags); + space_id = fsp_header_get_space_id(page); flags = fsp_header_get_flags(page); page_size = fsp_flags_get_page_size(flags); @@ -2094,8 +2096,10 @@ fil_read_first_page( #endif /* UNIV_LOG_ARCHIVE */ lsn_t* min_flushed_lsn, /*!< out: min of flushed lsn values in data files */ - lsn_t* max_flushed_lsn) /*!< out: max of flushed + lsn_t* max_flushed_lsn, /*!< out: max of flushed lsn values in data files */ + ulint orig_space_id) /*!< in: original file space + id */ { byte* buf; byte* page; @@ -2108,10 +2112,20 @@ fil_read_first_page( page = static_cast(ut_align(buf, UNIV_PAGE_SIZE)); - os_file_read(data_file, page, 0, UNIV_PAGE_SIZE); + os_file_read(data_file, page, 0, UNIV_PAGE_SIZE, + orig_space_id != ULINT_UNDEFINED ? + fil_space_is_page_compressed(orig_space_id) : + FALSE); *flags = fsp_header_get_flags(page); + /* Page is page compressed page, need to decompress, before + continue. */ + if (fsp_flags_is_page_compressed(*flags)) { + ulint write_size=0; + fil_decompress_page(NULL, page, UNIV_PAGE_SIZE, &write_size); + } + *space_id = fsp_header_get_space_id(page); flushed_lsn = mach_read_from_8(page + FIL_PAGE_FILE_FLUSH_LSN); @@ -3275,7 +3289,7 @@ fil_create_link_file( } if (!os_file_write(link_filepath, file, filepath, 0, - strlen(filepath))) { + strlen(filepath))) { err = DB_ERROR; } @@ -3802,7 +3816,7 @@ fil_open_single_table_tablespace( #ifdef UNIV_LOG_ARCHIVE &space_arch_log_no, &space_arch_log_no, #endif /* UNIV_LOG_ARCHIVE */ - &def.lsn, &def.lsn); + &def.lsn, &def.lsn, id); def.valid = !def.check_msg; /* Validate this single-table-tablespace with SYS_TABLES, @@ -3827,7 +3841,7 @@ fil_open_single_table_tablespace( #ifdef UNIV_LOG_ARCHIVE &remote.arch_log_no, &remote.arch_log_no, #endif /* UNIV_LOG_ARCHIVE */ - &remote.lsn, &remote.lsn); + &remote.lsn, &remote.lsn, id); remote.valid = !remote.check_msg; /* Validate this single-table-tablespace with SYS_TABLES, @@ -3853,7 +3867,7 @@ fil_open_single_table_tablespace( #ifdef UNIV_LOG_ARCHIVE &dict.arch_log_no, &dict.arch_log_no, #endif /* UNIV_LOG_ARCHIVE */ - &dict.lsn, &dict.lsn); + &dict.lsn, &dict.lsn, id); dict.valid = !dict.check_msg; /* Validate this single-table-tablespace with SYS_TABLES, @@ -4117,7 +4131,8 @@ fil_user_tablespace_find_space_id( for (ulint j = 0; j < page_count; ++j) { - st = os_file_read(fsp->file, page, (j* page_size), page_size); + st = os_file_read(fsp->file, page, (j* page_size), page_size, + fsp_flags_is_page_compressed(fsp->flags)); if (!st) { ib_logf(IB_LOG_LEVEL_INFO, @@ -4230,7 +4245,7 @@ fil_user_tablespace_restore_page( err = os_file_write(fsp->filepath, fsp->file, page, (zip_size ? zip_size : page_size) * page_no, - buflen); + buflen); os_file_flush(fsp->file); out: @@ -4257,7 +4272,7 @@ check_first_page: #ifdef UNIV_LOG_ARCHIVE &fsp->arch_log_no, &fsp->arch_log_no, #endif /* UNIV_LOG_ARCHIVE */ - &fsp->lsn, &fsp->lsn)) { + &fsp->lsn, &fsp->lsn, ULINT_UNDEFINED)) { ib_logf(IB_LOG_LEVEL_ERROR, "%s in tablespace %s (table %s)", check_msg, fsp->filepath, tablename); @@ -4330,9 +4345,7 @@ fil_load_single_table_tablespace( fsp_open_info def; fsp_open_info remote; os_offset_t size; -#ifdef UNIV_HOTBACKUP fil_space_t* space; -#endif memset(&def, 0, sizeof(def)); memset(&remote, 0, sizeof(remote)); @@ -4354,7 +4367,8 @@ fil_load_single_table_tablespace( one of them is sent to this function. So if this table has already been loaded, there is nothing to do.*/ mutex_enter(&fil_system->mutex); - if (fil_space_get_by_name(tablename)) { + space = fil_space_get_by_name(tablename); + if (space) { mem_free(tablename); mutex_exit(&fil_system->mutex); return; @@ -6346,7 +6360,8 @@ fil_iterate( ut_ad(!(n_bytes % iter.page_size)); if (!os_file_read(iter.file, io_buffer, offset, - (ulint) n_bytes)) { + (ulint) n_bytes, + fil_space_is_page_compressed(space_id))) { ib_logf(IB_LOG_LEVEL_ERROR, "os_file_read() failed"); @@ -6485,7 +6500,8 @@ fil_tablespace_iterate( /* Read the first page and determine the page and zip size. */ - if (!os_file_read(file, page, 0, UNIV_PAGE_SIZE)) { + if (!os_file_read(file, page, 0, UNIV_PAGE_SIZE, + dict_tf_get_page_compression(table->flags))) { err = DB_IO_ERROR; diff --git a/storage/innobase/fil/fil0pagecompress.cc b/storage/innobase/fil/fil0pagecompress.cc index 7980bb1a7bd..d08ae3db07e 100644 --- a/storage/innobase/fil/fil0pagecompress.cc +++ b/storage/innobase/fil/fil0pagecompress.cc @@ -94,7 +94,7 @@ fil_decompress_page_2( { ulint page_type = mach_read_from_2(buf + FIL_PAGE_TYPE); - if (page_type != FIL_PAGE_COMPRESSED) { + if (page_type != FIL_PAGE_TYPE_COMPRESSED) { /* It is not a compressed page */ return; } @@ -471,7 +471,7 @@ fil_decompress_page( 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) { + if (ptype != FIL_PAGE_PAGE_COMPRESSED && ptype != FIL_PAGE_TYPE_COMPRESSED) { return; } @@ -486,7 +486,7 @@ fil_decompress_page( in_buf = page_buf; } - if (ptype == FIL_PAGE_COMPRESSED) { + if (ptype == FIL_PAGE_TYPE_COMPRESSED) { fil_decompress_page_2(in_buf, buf, len, write_size); // Need to free temporal buffer if no buffer was given diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h index 965b1c31e23..50e992f7627 100644 --- a/storage/innobase/include/fil0fil.h +++ b/storage/innobase/include/fil0fil.h @@ -180,8 +180,8 @@ static const ulint FIL_PAGE_COMPRESS_SIZE_V1 = FIL_PAGE_ORIGINAL_SIZE_V1 + 2; #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_COMPRESSED 13 /*!< Compressed page */ -#define FIL_PAGE_TYPE_LAST FIL_PAGE_COMPRESSED +#define FIL_PAGE_TYPE_COMPRESSED 13 /*!< Compressed page */ +#define FIL_PAGE_TYPE_LAST FIL_PAGE_TYPE_COMPRESSED /*!< Last page type */ /* @} */ @@ -423,8 +423,10 @@ fil_read_first_page( #endif /* UNIV_LOG_ARCHIVE */ lsn_t* min_flushed_lsn, /*!< out: min of flushed lsn values in data files */ - lsn_t* max_flushed_lsn) /*!< out: max of flushed + lsn_t* max_flushed_lsn, /*!< out: max of flushed lsn values in data files */ + ulint orig_space_id) /*!< in: file space id or + ULINT_UNDEFINED */ __attribute__((warn_unused_result)); /*******************************************************************//** Increments the count of pending operation, if space is not being deleted. diff --git a/storage/innobase/include/fil0pagecompress.h b/storage/innobase/include/fil0pagecompress.h index e3a7ffbcb49..395a158b8f7 100644 --- a/storage/innobase/include/fil0pagecompress.h +++ b/storage/innobase/include/fil0pagecompress.h @@ -47,6 +47,14 @@ fil_space_is_page_compressed( /*=========================*/ ulint id); /*!< in: space id */ /*******************************************************************//** +Returns the page compression flag of the space, or false if the space +is not compressed. The tablespace must be cached in the memory cache. +@return true if page compressed, false if not or space not found */ +ibool +fil_space_get_page_compressed( +/*=========================*/ + fil_space_t* space); /*!< in: space id */ +/*******************************************************************//** Returns the atomic writes flag of the space, or false if the space is not using atomic writes. The tablespace must be cached in the memory cache. @return atomic write table option value */ diff --git a/storage/innobase/include/os0file.h b/storage/innobase/include/os0file.h index b6c6f50865c..8f19d396c92 100644 --- a/storage/innobase/include/os0file.h +++ b/storage/innobase/include/os0file.h @@ -317,12 +317,12 @@ The wrapper functions have the prefix of "innodb_". */ n, message1, message2, write_size, \ page_compression, page_compression_level, __FILE__, __LINE__) -# define os_file_read(file, buf, offset, n) \ - pfs_os_file_read_func(file, buf, offset, n, __FILE__, __LINE__) +# define os_file_read(file, buf, offset, n, compressed) \ + pfs_os_file_read_func(file, buf, offset, n, compressed, __FILE__, __LINE__) -# define os_file_read_no_error_handling(file, buf, offset, n) \ +# define os_file_read_no_error_handling(file, buf, offset, n, compressed) \ pfs_os_file_read_no_error_handling_func(file, buf, offset, n, \ - __FILE__, __LINE__) + compressed, __FILE__, __LINE__) # define os_file_write(name, file, buf, offset, n) \ pfs_os_file_write_func(name, file, buf, offset, \ @@ -360,11 +360,11 @@ to original un-instrumented file I/O APIs */ os_aio_func(type, mode, name, file, buf, offset, n, \ message1, message2, write_size, page_compression, page_compression_level) -# define os_file_read(file, buf, offset, n) \ - os_file_read_func(file, buf, offset, n) +# define os_file_read(file, buf, offset, n, compressed) \ + os_file_read_func(file, buf, offset, n, compressed) -# define os_file_read_no_error_handling(file, buf, offset, n) \ - os_file_read_no_error_handling_func(file, buf, offset, n) +# define os_file_read_no_error_handling(file, buf, offset, n, compressed) \ + os_file_read_no_error_handling_func(file, buf, offset, n, compressed) # define os_file_write(name, file, buf, offset, n) \ os_file_write_func(name, file, buf, offset, n) @@ -715,6 +715,8 @@ pfs_os_file_read_func( void* buf, /*!< in: buffer where to read */ os_offset_t offset, /*!< in: file offset where to read */ ulint n, /*!< in: number of bytes to read */ + ibool compressed, /*!< in: is this file space + compressed ? */ const char* src_file,/*!< in: file name where func invoked */ ulint src_line);/*!< in: line where the func invoked */ @@ -733,6 +735,8 @@ pfs_os_file_read_no_error_handling_func( void* buf, /*!< in: buffer where to read */ os_offset_t offset, /*!< in: file offset where to read */ ulint n, /*!< in: number of bytes to read */ + ibool compressed, /*!< in: is this file space + compressed ? */ const char* src_file,/*!< in: file name where func invoked */ ulint src_line);/*!< in: line where the func invoked */ @@ -928,7 +932,9 @@ os_file_read_func( os_file_t file, /*!< in: handle to a file */ void* buf, /*!< in: buffer where to read */ os_offset_t offset, /*!< in: file offset where to read */ - ulint n); /*!< in: number of bytes to read */ + ulint n, /*!< in: number of bytes to read */ + ibool compressed); /*!< in: is this file space + compressed ? */ /*******************************************************************//** Rewind file to its start, read at most size - 1 bytes from it to str, and NUL-terminate str. All errors are silently ignored. This function is @@ -953,7 +959,9 @@ os_file_read_no_error_handling_func( os_file_t file, /*!< in: handle to a file */ void* buf, /*!< in: buffer where to read */ os_offset_t offset, /*!< in: file offset where to read */ - ulint n); /*!< in: number of bytes to read */ + ulint n, /*!< in: number of bytes to read */ + ibool compressed); /*!< in: is this file space + compressed ? */ /*******************************************************************//** NOTE! Use the corresponding macro os_file_write(), not directly this @@ -970,6 +978,7 @@ os_file_write_func( const void* buf, /*!< in: buffer from which to write */ os_offset_t offset, /*!< in: file offset where to write */ ulint n); /*!< in: number of bytes to write */ + /*******************************************************************//** Check the existence and type of the given file. @return TRUE if call succeeded */ diff --git a/storage/innobase/include/os0file.ic b/storage/innobase/include/os0file.ic index 9a3c91306c0..8e1cea585e6 100644 --- a/storage/innobase/include/os0file.ic +++ b/storage/innobase/include/os0file.ic @@ -261,6 +261,8 @@ pfs_os_file_read_func( void* buf, /*!< in: buffer where to read */ os_offset_t offset, /*!< in: file offset where to read */ ulint n, /*!< in: number of bytes to read */ + ibool compressed, /*!< in: is this file space + compressed ? */ const char* src_file,/*!< in: file name where func invoked */ ulint src_line)/*!< in: line where the func invoked */ { @@ -271,7 +273,7 @@ pfs_os_file_read_func( register_pfs_file_io_begin(&state, locker, file, n, PSI_FILE_READ, src_file, src_line); - result = os_file_read_func(file, buf, offset, n); + result = os_file_read_func(file, buf, offset, n, compressed); register_pfs_file_io_end(locker, n); @@ -294,6 +296,8 @@ pfs_os_file_read_no_error_handling_func( void* buf, /*!< in: buffer where to read */ os_offset_t offset, /*!< in: file offset where to read */ ulint n, /*!< in: number of bytes to read */ + ibool compressed, /*!< in: is this file space + compressed ? */ const char* src_file,/*!< in: file name where func invoked */ ulint src_line)/*!< in: line where the func invoked */ { @@ -304,7 +308,7 @@ pfs_os_file_read_no_error_handling_func( register_pfs_file_io_begin(&state, locker, file, n, PSI_FILE_READ, src_file, src_line); - result = os_file_read_no_error_handling_func(file, buf, offset, n); + result = os_file_read_no_error_handling_func(file, buf, offset, n, compressed); register_pfs_file_io_end(locker, n); diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc index 52e8ac841f3..45ca07bc7c4 100644 --- a/storage/innobase/os/os0file.cc +++ b/storage/innobase/os/os0file.cc @@ -2392,6 +2392,7 @@ os_file_set_size( } ret = os_file_write(name, file, buf, current_size, n_bytes); + if (!ret) { ut_free(buf2); goto error_handling; @@ -2816,7 +2817,9 @@ os_file_read_func( os_file_t file, /*!< in: handle to a file */ void* buf, /*!< in: buffer where to read */ os_offset_t offset, /*!< in: file offset where to read */ - ulint n) /*!< in: number of bytes to read */ + ulint n, /*!< in: number of bytes to read */ + ibool compressed) /*!< in: is this file space + compressed ? */ { #ifdef __WIN__ BOOL ret; @@ -2885,7 +2888,13 @@ try_again: os_mutex_exit(os_file_count_mutex); if (ret && len == n) { - fil_decompress_page(NULL, (byte *)buf, len, NULL); + /* Note that InnoDB writes files that are not formated + as file spaces and they do not have FIL_PAGE_TYPE + field, thus we must use here information is the actual + file space compressed. */ + if (compressed && fil_page_is_compressed((byte *)buf)) { + fil_decompress_page(NULL, (byte *)buf, len, NULL); + } return(TRUE); } @@ -2899,7 +2908,13 @@ try_again: ret = os_file_pread(file, buf, n, offset); if ((ulint) ret == n) { - fil_decompress_page(NULL, (byte *)buf, n, NULL); + /* Note that InnoDB writes files that are not formated + as file spaces and they do not have FIL_PAGE_TYPE + field, thus we must use here information is the actual + file space compressed. */ + if (compressed && fil_page_is_compressed((byte *)buf)) { + fil_decompress_page(NULL, (byte *)buf, n, NULL); + } return(TRUE); } @@ -2946,7 +2961,9 @@ os_file_read_no_error_handling_func( os_file_t file, /*!< in: handle to a file */ void* buf, /*!< in: buffer where to read */ os_offset_t offset, /*!< in: file offset where to read */ - ulint n) /*!< in: number of bytes to read */ + ulint n, /*!< in: number of bytes to read */ + ibool compressed) /*!< in: is this file space + compressed ? */ { #ifdef __WIN__ BOOL ret; @@ -3015,6 +3032,15 @@ try_again: os_mutex_exit(os_file_count_mutex); if (ret && len == n) { + + /* Note that InnoDB writes files that are not formated + as file spaces and they do not have FIL_PAGE_TYPE + field, thus we must use here information is the actual + file space compressed. */ + if (compressed && fil_page_is_compressed((byte *)buf)) { + fil_decompress_page(NULL, (byte *)buf, n, NULL); + } + return(TRUE); } #else /* __WIN__ */ @@ -3027,6 +3053,13 @@ try_again: ret = os_file_pread(file, buf, n, offset); if ((ulint) ret == n) { + /* Note that InnoDB writes files that are not formated + as file spaces and they do not have FIL_PAGE_TYPE + field, thus we must use here information is the actual + file space compressed. */ + if (compressed && fil_page_is_compressed((byte *)buf)) { + fil_decompress_page(NULL, (byte *)buf, n, NULL); + } return(TRUE); } @@ -3105,6 +3138,7 @@ os_file_write_func( ut_ad(file); ut_ad(buf); ut_ad(n > 0); + retry: low = (DWORD) offset & 0xFFFFFFFF; high = (DWORD) (offset >> 32); @@ -4920,7 +4954,8 @@ os_aio_func( and os_file_write_func() */ if (type == OS_FILE_READ) { - return(os_file_read_func(file, buf, offset, n)); + return(os_file_read_func(file, buf, offset, n, + page_compression)); } ut_ad(!srv_read_only_mode); @@ -5818,7 +5853,8 @@ consecutive_loop: } else { ret = os_file_read( aio_slot->file, combined_buf, - aio_slot->offset, total_len); + aio_slot->offset, total_len, + aio_slot->page_compression); } ut_a(ret); diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc index 24abd885f60..070c4ba7517 100644 --- a/storage/innobase/row/row0log.cc +++ b/storage/innobase/row/row0log.cc @@ -2546,7 +2546,7 @@ all_done: success = os_file_read_no_error_handling( OS_FILE_FROM_FD(index->online_log->fd), index->online_log->head.block, ofs, - srv_sort_buf_size); + srv_sort_buf_size, FALSE); if (!success) { fprintf(stderr, "InnoDB: unable to read temporary file" @@ -3377,7 +3377,7 @@ all_done: success = os_file_read_no_error_handling( OS_FILE_FROM_FD(index->online_log->fd), index->online_log->head.block, ofs, - srv_sort_buf_size); + srv_sort_buf_size, FALSE); if (!success) { fprintf(stderr, "InnoDB: unable to read temporary file" diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index 56cf9f1943c..ab97b5a9f28 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -777,7 +777,8 @@ row_merge_read( #endif /* UNIV_DEBUG */ success = os_file_read_no_error_handling(OS_FILE_FROM_FD(fd), buf, - ofs, srv_sort_buf_size); + ofs, srv_sort_buf_size, FALSE); + #ifdef POSIX_FADV_DONTNEED /* Each block is read exactly once. Free up the file cache. */ posix_fadvise(fd, ofs, srv_sort_buf_size, POSIX_FADV_DONTNEED); diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index 532cbf4f371..ece16c6bd70 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -1006,7 +1006,8 @@ check_first_page: #ifdef UNIV_LOG_ARCHIVE min_arch_log_no, max_arch_log_no, #endif /* UNIV_LOG_ARCHIVE */ - min_flushed_lsn, max_flushed_lsn); + min_flushed_lsn, max_flushed_lsn, + ULINT_UNDEFINED); if (check_msg) { diff --git a/storage/xtradb/buf/buf0dblwr.cc b/storage/xtradb/buf/buf0dblwr.cc index 17fa40b3fad..0f59375b256 100644 --- a/storage/xtradb/buf/buf0dblwr.cc +++ b/storage/xtradb/buf/buf0dblwr.cc @@ -383,7 +383,7 @@ buf_dblwr_init_or_load_pages( /* Read the trx sys header to check if we are using the doublewrite buffer */ off_t trx_sys_page = TRX_SYS_PAGE_NO * UNIV_PAGE_SIZE; - os_file_read(file, read_buf, trx_sys_page, UNIV_PAGE_SIZE); + os_file_read(file, read_buf, trx_sys_page, UNIV_PAGE_SIZE, FALSE); doublewrite = read_buf + TRX_SYS_DOUBLEWRITE; @@ -420,9 +420,9 @@ buf_dblwr_init_or_load_pages( block_bytes = TRX_SYS_DOUBLEWRITE_BLOCK_SIZE * UNIV_PAGE_SIZE; - os_file_read(file, buf, block1 * UNIV_PAGE_SIZE, block_bytes); + os_file_read(file, buf, block1 * UNIV_PAGE_SIZE, block_bytes, FALSE); os_file_read(file, buf + block_bytes, block2 * UNIV_PAGE_SIZE, - block_bytes); + block_bytes, FALSE); /* Check if any of these pages is half-written in data files, in the intended position */ diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc index bc2732f6a73..f7154b531bd 100644 --- a/storage/xtradb/fil/fil0fil.cc +++ b/storage/xtradb/fil/fil0fil.cc @@ -810,7 +810,9 @@ fil_node_open_file( set */ page = static_cast(ut_align(buf2, UNIV_PAGE_SIZE)); - success = os_file_read(node->handle, page, 0, UNIV_PAGE_SIZE); + success = os_file_read(node->handle, page, 0, UNIV_PAGE_SIZE, + space->flags); + space_id = fsp_header_get_space_id(page); flags = fsp_header_get_flags(page); page_size = fsp_flags_get_page_size(flags); @@ -2123,8 +2125,10 @@ fil_read_first_page( ulint* space_id, /*!< out: tablespace ID */ lsn_t* min_flushed_lsn, /*!< out: min of flushed lsn values in data files */ - lsn_t* max_flushed_lsn) /*!< out: max of flushed + lsn_t* max_flushed_lsn, /*!< out: max of flushed lsn values in data files */ + ulint orig_space_id) /*!< in: original file space + id */ { byte* buf; byte* page; @@ -2137,10 +2141,20 @@ fil_read_first_page( page = static_cast(ut_align(buf, UNIV_PAGE_SIZE)); - os_file_read(data_file, page, 0, UNIV_PAGE_SIZE); + os_file_read(data_file, page, 0, UNIV_PAGE_SIZE, + orig_space_id != ULINT_UNDEFINED ? + fil_space_is_page_compressed(orig_space_id) : + FALSE); *flags = fsp_header_get_flags(page); + /* Page is page compressed page, need to decompress, before + continue. */ + if (fsp_flags_is_page_compressed(*flags)) { + ulint write_size=0; + fil_decompress_page(NULL, page, UNIV_PAGE_SIZE, &write_size); + } + *space_id = fsp_header_get_space_id(page); flushed_lsn = mach_read_from_8(page + FIL_PAGE_FILE_FLUSH_LSN); @@ -3300,7 +3314,7 @@ fil_create_link_file( } if (!os_file_write(link_filepath, file, filepath, 0, - strlen(filepath))) { + strlen(filepath))) { err = DB_ERROR; } @@ -3824,7 +3838,7 @@ fil_open_single_table_tablespace( if (def.success) { def.check_msg = fil_read_first_page( def.file, FALSE, &def.flags, &def.id, - &def.lsn, &def.lsn); + &def.lsn, &def.lsn, id); def.valid = !def.check_msg; /* Validate this single-table-tablespace with SYS_TABLES, @@ -3846,7 +3860,7 @@ fil_open_single_table_tablespace( if (remote.success) { remote.check_msg = fil_read_first_page( remote.file, FALSE, &remote.flags, &remote.id, - &remote.lsn, &remote.lsn); + &remote.lsn, &remote.lsn, id); remote.valid = !remote.check_msg; /* Validate this single-table-tablespace with SYS_TABLES, @@ -3869,7 +3883,7 @@ fil_open_single_table_tablespace( if (dict.success) { dict.check_msg = fil_read_first_page( dict.file, FALSE, &dict.flags, &dict.id, - &dict.lsn, &dict.lsn); + &dict.lsn, &dict.lsn, id); dict.valid = !dict.check_msg; /* Validate this single-table-tablespace with SYS_TABLES, @@ -4133,7 +4147,8 @@ fil_user_tablespace_find_space_id( for (ulint j = 0; j < page_count; ++j) { - st = os_file_read(fsp->file, page, (j* page_size), page_size); + st = os_file_read(fsp->file, page, (j* page_size), page_size, + fsp_flags_is_page_compressed(fsp->flags)); if (!st) { ib_logf(IB_LOG_LEVEL_INFO, @@ -4246,7 +4261,7 @@ fil_user_tablespace_restore_page( err = os_file_write(fsp->filepath, fsp->file, page, (zip_size ? zip_size : page_size) * page_no, - buflen); + buflen); os_file_flush(fsp->file); out: @@ -4270,7 +4285,7 @@ check_first_page: fsp->success = TRUE; if (const char* check_msg = fil_read_first_page( fsp->file, FALSE, &fsp->flags, &fsp->id, - &fsp->lsn, &fsp->lsn)) { + &fsp->lsn, &fsp->lsn, ULINT_UNDEFINED)) { ib_logf(IB_LOG_LEVEL_ERROR, "%s in tablespace %s (table %s)", check_msg, fsp->filepath, tablename); @@ -4343,9 +4358,7 @@ fil_load_single_table_tablespace( fsp_open_info def; fsp_open_info remote; os_offset_t size; -#ifdef UNIV_HOTBACKUP fil_space_t* space; -#endif memset(&def, 0, sizeof(def)); memset(&remote, 0, sizeof(remote)); @@ -4367,7 +4380,8 @@ fil_load_single_table_tablespace( one of them is sent to this function. So if this table has already been loaded, there is nothing to do.*/ mutex_enter(&fil_system->mutex); - if (fil_space_get_by_name(tablename)) { + space = fil_space_get_by_name(tablename); + if (space) { mem_free(tablename); mutex_exit(&fil_system->mutex); return; @@ -6403,7 +6417,8 @@ fil_iterate( ut_ad(!(n_bytes % iter.page_size)); if (!os_file_read(iter.file, io_buffer, offset, - (ulint) n_bytes)) { + (ulint) n_bytes, + fil_space_is_page_compressed(space_id))) { ib_logf(IB_LOG_LEVEL_ERROR, "os_file_read() failed"); @@ -6542,7 +6557,8 @@ fil_tablespace_iterate( /* Read the first page and determine the page and zip size. */ - if (!os_file_read(file, page, 0, UNIV_PAGE_SIZE)) { + if (!os_file_read(file, page, 0, UNIV_PAGE_SIZE, + dict_tf_get_page_compression(table->flags))) { err = DB_IO_ERROR; diff --git a/storage/xtradb/fil/fil0pagecompress.cc b/storage/xtradb/fil/fil0pagecompress.cc index 4efd6a82efe..d8fae632016 100644 --- a/storage/xtradb/fil/fil0pagecompress.cc +++ b/storage/xtradb/fil/fil0pagecompress.cc @@ -94,7 +94,7 @@ fil_decompress_page_2( { ulint page_type = mach_read_from_2(buf + FIL_PAGE_TYPE); - if (page_type != FIL_PAGE_COMPRESSED) { + if (page_type != FIL_PAGE_TYPE_COMPRESSED) { /* It is not a compressed page */ return; } @@ -470,7 +470,7 @@ fil_decompress_page( 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) { + if (ptype != FIL_PAGE_PAGE_COMPRESSED && ptype != FIL_PAGE_TYPE_COMPRESSED) { return; } @@ -485,7 +485,7 @@ fil_decompress_page( in_buf = page_buf; } - if (ptype == FIL_PAGE_COMPRESSED) { + if (ptype == FIL_PAGE_TYPE_COMPRESSED) { fil_decompress_page_2(in_buf, buf, len, write_size); // Need to free temporal buffer if no buffer was given diff --git a/storage/xtradb/include/fil0fil.h b/storage/xtradb/include/fil0fil.h index 7dbb8d6123b..502883981a4 100644 --- a/storage/xtradb/include/fil0fil.h +++ b/storage/xtradb/include/fil0fil.h @@ -182,8 +182,8 @@ static const ulint FIL_PAGE_COMPRESS_SIZE_V1 = FIL_PAGE_ORIGINAL_SIZE_V1 + 2; #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_COMPRESSED 13 /*!< Compressed page */ -#define FIL_PAGE_TYPE_LAST FIL_PAGE_COMPRESSED +#define FIL_PAGE_TYPE_COMPRESSED 13 /*!< Compressed page */ +#define FIL_PAGE_TYPE_LAST FIL_PAGE_TYPE_COMPRESSED /*!< Last page type */ /* @} */ @@ -425,8 +425,10 @@ fil_read_first_page( ulint* space_id, /*!< out: tablespace ID */ lsn_t* min_flushed_lsn, /*!< out: min of flushed lsn values in data files */ - lsn_t* max_flushed_lsn) /*!< out: max of flushed + lsn_t* max_flushed_lsn, /*!< out: max of flushed lsn values in data files */ + ulint orig_space_id) /*!< in: file space id or + ULINT_UNDEFINED */ __attribute__((warn_unused_result)); /*******************************************************************//** Increments the count of pending operation, if space is not being deleted. diff --git a/storage/xtradb/include/fil0pagecompress.h b/storage/xtradb/include/fil0pagecompress.h index e3a7ffbcb49..395a158b8f7 100644 --- a/storage/xtradb/include/fil0pagecompress.h +++ b/storage/xtradb/include/fil0pagecompress.h @@ -47,6 +47,14 @@ fil_space_is_page_compressed( /*=========================*/ ulint id); /*!< in: space id */ /*******************************************************************//** +Returns the page compression flag of the space, or false if the space +is not compressed. The tablespace must be cached in the memory cache. +@return true if page compressed, false if not or space not found */ +ibool +fil_space_get_page_compressed( +/*=========================*/ + fil_space_t* space); /*!< in: space id */ +/*******************************************************************//** Returns the atomic writes flag of the space, or false if the space is not using atomic writes. The tablespace must be cached in the memory cache. @return atomic write table option value */ diff --git a/storage/xtradb/include/os0file.h b/storage/xtradb/include/os0file.h index 3d3d9a0f74f..76e77799b43 100644 --- a/storage/xtradb/include/os0file.h +++ b/storage/xtradb/include/os0file.h @@ -328,21 +328,21 @@ The wrapper functions have the prefix of "innodb_". */ page_compressed, page_compression_level, write_size, \ __FILE__, __LINE__) -# define os_file_read(file, buf, offset, n) \ - pfs_os_file_read_func(file, buf, offset, n, NULL, \ +# define os_file_read(file, buf, offset, n, compressed) \ + pfs_os_file_read_func(file, buf, offset, n, NULL, compressed, \ __FILE__, __LINE__) -# define os_file_read_trx(file, buf, offset, n, trx) \ - pfs_os_file_read_func(file, buf, offset, n, trx, \ +# define os_file_read_trx(file, buf, offset, n, trx, compressed) \ + pfs_os_file_read_func(file, buf, offset, n, trx, compressed, \ __FILE__, __LINE__) -# define os_file_read_no_error_handling(file, buf, offset, n) \ - pfs_os_file_read_no_error_handling_func(file, buf, offset, n, \ +# define os_file_read_no_error_handling(file, buf, offset, n, compressed) \ + pfs_os_file_read_no_error_handling_func(file, buf, offset, n, compressed, \ __FILE__, __LINE__) -# define os_file_write(name, file, buf, offset, n) \ - pfs_os_file_write_func(name, file, buf, offset, \ - n, __FILE__, __LINE__) +# define os_file_write(name, file, buf, offset, n) \ + pfs_os_file_write_func(name, file, buf, offset, n, \ + __FILE__, __LINE__) # define os_file_flush(file) \ pfs_os_file_flush_func(file, __FILE__, __LINE__) @@ -379,14 +379,14 @@ to original un-instrumented file I/O APIs */ message1, message2, space_id, trx, \ page_compressed, page_compression_level, write_size) -# define os_file_read(file, buf, offset, n) \ - os_file_read_func(file, buf, offset, n, NULL) +# define os_file_read(file, buf, offset, n, compressed) \ + os_file_read_func(file, buf, offset, n, NULL, compressed) -# define os_file_read_trx(file, buf, offset, n, trx) \ - os_file_read_func(file, buf, offset, n, trx) +# define os_file_read_trx(file, buf, offset, n, trx, compressed) \ + os_file_read_func(file, buf, offset, n, trx, compressed) -# define os_file_read_no_error_handling(file, buf, offset, n) \ - os_file_read_no_error_handling_func(file, buf, offset, n) +# define os_file_read_no_error_handling(file, buf, offset, n, compressed) \ + os_file_read_no_error_handling_func(file, buf, offset, n, compressed) # define os_file_write(name, file, buf, offset, n) \ os_file_write_func(name, file, buf, offset, n) @@ -741,7 +741,9 @@ pfs_os_file_read_func( void* buf, /*!< in: buffer where to read */ os_offset_t offset, /*!< in: file offset where to read */ ulint n, /*!< in: number of bytes to read */ - trx_t* trx, + trx_t* trx, /*!< in: trx */ + ibool compressed, /*!< in: is this file space + compressed ? */ const char* src_file,/*!< in: file name where func invoked */ ulint src_line);/*!< in: line where the func invoked */ @@ -760,6 +762,8 @@ pfs_os_file_read_no_error_handling_func( void* buf, /*!< in: buffer where to read */ os_offset_t offset, /*!< in: file offset where to read */ ulint n, /*!< in: number of bytes to read */ + ibool compressed, /*!< in: is this file space + compressed ? */ const char* src_file,/*!< in: file name where func invoked */ ulint src_line);/*!< in: line where the func invoked */ @@ -964,7 +968,9 @@ os_file_read_func( void* buf, /*!< in: buffer where to read */ os_offset_t offset, /*!< in: file offset where to read */ ulint n, /*!< in: number of bytes to read */ - trx_t* trx); + trx_t* trx, /*!< in: trx */ + ibool compressed); /*!< in: is this file space + compressed ? */ /*******************************************************************//** Rewind file to its start, read at most size - 1 bytes from it to str, and NUL-terminate str. All errors are silently ignored. This function is @@ -989,7 +995,9 @@ os_file_read_no_error_handling_func( os_file_t file, /*!< in: handle to a file */ void* buf, /*!< in: buffer where to read */ os_offset_t offset, /*!< in: file offset where to read */ - ulint n); /*!< in: number of bytes to read */ + ulint n, /*!< in: number of bytes to read */ + ibool compressed); /*!< in: is this file space + compressed ? */ /*******************************************************************//** NOTE! Use the corresponding macro os_file_write(), not directly this @@ -1006,6 +1014,7 @@ os_file_write_func( const void* buf, /*!< in: buffer from which to write */ os_offset_t offset, /*!< in: file offset where to write */ ulint n); /*!< in: number of bytes to write */ + /*******************************************************************//** Check the existence and type of the given file. @return TRUE if call succeeded */ diff --git a/storage/xtradb/include/os0file.ic b/storage/xtradb/include/os0file.ic index 5ad9e3f5461..61300387e1b 100644 --- a/storage/xtradb/include/os0file.ic +++ b/storage/xtradb/include/os0file.ic @@ -267,6 +267,8 @@ pfs_os_file_read_func( os_offset_t offset, /*!< in: file offset where to read */ ulint n, /*!< in: number of bytes to read */ trx_t* trx, + ibool compressed, /*!< in: is this file space + compressed ? */ const char* src_file,/*!< in: file name where func invoked */ ulint src_line)/*!< in: line where the func invoked */ { @@ -277,7 +279,7 @@ pfs_os_file_read_func( register_pfs_file_io_begin(&state, locker, file, n, PSI_FILE_READ, src_file, src_line); - result = os_file_read_func(file, buf, offset, n, trx); + result = os_file_read_func(file, buf, offset, n, trx, compressed); register_pfs_file_io_end(locker, n); @@ -300,6 +302,8 @@ pfs_os_file_read_no_error_handling_func( void* buf, /*!< in: buffer where to read */ os_offset_t offset, /*!< in: file offset where to read */ ulint n, /*!< in: number of bytes to read */ + ibool compressed, /*!< in: is this file space + compressed ? */ const char* src_file,/*!< in: file name where func invoked */ ulint src_line)/*!< in: line where the func invoked */ { @@ -310,7 +314,7 @@ pfs_os_file_read_no_error_handling_func( register_pfs_file_io_begin(&state, locker, file, n, PSI_FILE_READ, src_file, src_line); - result = os_file_read_no_error_handling_func(file, buf, offset, n); + result = os_file_read_no_error_handling_func(file, buf, offset, n, compressed); register_pfs_file_io_end(locker, n); diff --git a/storage/xtradb/log/log0online.cc b/storage/xtradb/log/log0online.cc index a4cded85f29..bc930572c09 100644 --- a/storage/xtradb/log/log0online.cc +++ b/storage/xtradb/log/log0online.cc @@ -283,7 +283,7 @@ log_online_read_bitmap_page( ut_a(bitmap_file->offset % MODIFIED_PAGE_BLOCK_SIZE == 0); success = os_file_read(bitmap_file->file, page, bitmap_file->offset, - MODIFIED_PAGE_BLOCK_SIZE); + MODIFIED_PAGE_BLOCK_SIZE, FALSE); if (UNIV_UNLIKELY(!success)) { @@ -1104,7 +1104,7 @@ log_online_write_bitmap_page( success = os_file_write(log_bmp_sys->out.name, log_bmp_sys->out.file, block, log_bmp_sys->out.offset, - MODIFIED_PAGE_BLOCK_SIZE); + MODIFIED_PAGE_BLOCK_SIZE); if (UNIV_UNLIKELY(!success)) { /* The following call prints an error message */ diff --git a/storage/xtradb/os/os0file.cc b/storage/xtradb/os/os0file.cc index 82eee4440f9..8366457b968 100644 --- a/storage/xtradb/os/os0file.cc +++ b/storage/xtradb/os/os0file.cc @@ -2514,6 +2514,7 @@ os_file_set_size( } ret = os_file_write(name, file, buf, current_size, n_bytes); + if (!ret) { ut_free(buf2); goto error_handling; @@ -3038,7 +3039,9 @@ os_file_read_func( void* buf, /*!< in: buffer where to read */ os_offset_t offset, /*!< in: file offset where to read */ ulint n, /*!< in: number of bytes to read */ - trx_t* trx) + trx_t* trx, + ibool compressed) /*!< in: is this file space + compressed ? */ { #ifdef __WIN__ BOOL ret; @@ -3081,7 +3084,13 @@ try_again: os_mutex_exit(os_file_count_mutex); if (ret && len == n) { - fil_decompress_page(NULL, (byte *)buf, len, NULL); + /* Note that InnoDB writes files that are not formated + as file spaces and they do not have FIL_PAGE_TYPE + field, thus we must use here information is the actual + file space compressed. */ + if (compressed && fil_page_is_compressed((byte *)buf)) { + fil_decompress_page(NULL, (byte *)buf, len, NULL); + } return(TRUE); } @@ -3096,7 +3105,13 @@ try_again: if ((ulint) ret == n) { - fil_decompress_page(NULL, (byte *)buf, n, NULL); + /* Note that InnoDB writes files that are not formated + as file spaces and they do not have FIL_PAGE_TYPE + field, thus we must use here information is the actual + file space compressed. */ + if (compressed && fil_page_is_compressed((byte *)buf)) { + fil_decompress_page(NULL, (byte *)buf, n, NULL); + } return(TRUE); } @@ -3140,7 +3155,9 @@ os_file_read_no_error_handling_func( os_file_t file, /*!< in: handle to a file */ void* buf, /*!< in: buffer where to read */ os_offset_t offset, /*!< in: file offset where to read */ - ulint n) /*!< in: number of bytes to read */ + ulint n, /*!< in: number of bytes to read */ + ibool compressed) /*!< in: is this file space + compressed ? */ { #ifdef __WIN__ BOOL ret; @@ -3185,6 +3202,15 @@ try_again: os_mutex_exit(os_file_count_mutex); if (ret && len == n) { + + /* Note that InnoDB writes files that are not formated + as file spaces and they do not have FIL_PAGE_TYPE + field, thus we must use here information is the actual + file space compressed. */ + if (compressed && fil_page_is_compressed((byte *)buf)) { + fil_decompress_page(NULL, (byte *)buf, n, NULL); + } + return(TRUE); } #else /* __WIN__ */ @@ -3198,7 +3224,13 @@ try_again: if ((ulint) ret == n) { - fil_decompress_page(NULL, (byte *)buf, n, NULL); + /* Note that InnoDB writes files that are not formated + as file spaces and they do not have FIL_PAGE_TYPE + field, thus we must use here information is the actual + file space compressed. */ + if (compressed && fil_page_is_compressed((byte *)buf)) { + fil_decompress_page(NULL, (byte *)buf, n, NULL); + } return(TRUE); } @@ -3269,6 +3301,7 @@ os_file_write_func( ut_ad(file); ut_ad(buf); ut_ad(n > 0); + retry: os_mutex_enter(os_file_count_mutex); @@ -5020,7 +5053,8 @@ os_aio_func( no need to use an i/o-handler thread */ if (type == OS_FILE_READ) { - ret = os_file_read_func(file, buf, offset, n, trx); + ret = os_file_read_func(file, buf, offset, n, trx, + page_compression); } else { ut_ad(!srv_read_only_mode); @@ -5311,12 +5345,16 @@ os_aio_windows_handle( } #ifdef HAVE_LZO - if (innodb_compression_algorithm == 3 && slot->lzo_mem == NULL) { + if (slot->page_compressed && + innodb_compression_algorithm == 3 && + slot->lzo_mem == NULL) { os_slot_alloc_lzo_mem(slot); } #endif if (slot->type == OS_FILE_READ) { - fil_decompress_page(slot->page_buf, slot->buf, slot->len, slot->write_size); + if (slot->page_compressed) { + 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) { @@ -5921,7 +5959,8 @@ consecutive_loop: } else { ret = os_file_read( aio_slot->file, combined_buf, - aio_slot->offset, total_len); + aio_slot->offset, total_len, + aio_slot->page_compression); } ut_a(ret); diff --git a/storage/xtradb/row/row0log.cc b/storage/xtradb/row/row0log.cc index 1240cf7fcc5..41d22cf07a8 100644 --- a/storage/xtradb/row/row0log.cc +++ b/storage/xtradb/row/row0log.cc @@ -2544,7 +2544,7 @@ all_done: success = os_file_read_no_error_handling( OS_FILE_FROM_FD(index->online_log->fd), index->online_log->head.block, ofs, - srv_sort_buf_size); + srv_sort_buf_size, FALSE); if (!success) { fprintf(stderr, "InnoDB: unable to read temporary file" @@ -3372,7 +3372,7 @@ all_done: success = os_file_read_no_error_handling( OS_FILE_FROM_FD(index->online_log->fd), index->online_log->head.block, ofs, - srv_sort_buf_size); + srv_sort_buf_size, FALSE); if (!success) { fprintf(stderr, "InnoDB: unable to read temporary file" diff --git a/storage/xtradb/row/row0merge.cc b/storage/xtradb/row/row0merge.cc index 80cda9078ff..0b2e966efe0 100644 --- a/storage/xtradb/row/row0merge.cc +++ b/storage/xtradb/row/row0merge.cc @@ -777,7 +777,8 @@ row_merge_read( #endif /* UNIV_DEBUG */ success = os_file_read_no_error_handling(OS_FILE_FROM_FD(fd), buf, - ofs, srv_sort_buf_size); + ofs, srv_sort_buf_size, FALSE); + #ifdef POSIX_FADV_DONTNEED /* Each block is read exactly once. Free up the file cache. */ posix_fadvise(fd, ofs, srv_sort_buf_size, POSIX_FADV_DONTNEED); diff --git a/storage/xtradb/srv/srv0start.cc b/storage/xtradb/srv/srv0start.cc index efc75dea34b..3aedede7c97 100644 --- a/storage/xtradb/srv/srv0start.cc +++ b/storage/xtradb/srv/srv0start.cc @@ -1028,7 +1028,7 @@ skip_size_check: check_first_page: check_msg = fil_read_first_page( files[i], one_opened, &flags, &space, - min_flushed_lsn, max_flushed_lsn); + min_flushed_lsn, max_flushed_lsn, ULINT_UNDEFINED); if (check_msg) {