You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

832 lines
31 KiB

9 years ago
MDEV-11623 MariaDB 10.1 fails to start datadir created with MariaDB 10.0/MySQL 5.6 using innodb-page-size!=16K The storage format of FSP_SPACE_FLAGS was accidentally broken already in MariaDB 10.1.0. This fix is bringing the format in line with other MySQL and MariaDB release series. Please refer to the comments that were added to fsp0fsp.h for details. This is an INCOMPATIBLE CHANGE that affects users of page_compression and non-default innodb_page_size. Upgrading to this release will correct the flags in the data files. If you want to downgrade to earlier MariaDB 10.1.x, please refer to the test innodb.101_compatibility how to reset the FSP_SPACE_FLAGS in the files. NOTE: MariaDB 10.1.0 to 10.1.20 can misinterpret uncompressed data files with innodb_page_size=4k or 64k as compressed innodb_page_size=16k files, and then probably fail when trying to access the pages. See the comments in the function fsp_flags_convert_from_101() for detailed analysis. Move PAGE_COMPRESSION to FSP_SPACE_FLAGS bit position 16. In this way, compressed innodb_page_size=16k tablespaces will not be mistaken for uncompressed ones by MariaDB 10.1.0 to 10.1.20. Derive PAGE_COMPRESSION_LEVEL, ATOMIC_WRITES and DATA_DIR from the dict_table_t::flags when the table is available, in fil_space_for_table_exists_in_mem() or fil_open_single_table_tablespace(). During crash recovery, fil_load_single_table_tablespace() will use innodb_compression_level for the PAGE_COMPRESSION_LEVEL. FSP_FLAGS_MEM_MASK: A bitmap of the memory-only fil_space_t::flags that are not to be written to FSP_SPACE_FLAGS. Currently, these will include PAGE_COMPRESSION_LEVEL, ATOMIC_WRITES and DATA_DIR. Introduce the macro FSP_FLAGS_PAGE_SSIZE(). We only support one innodb_page_size for the whole instance. When creating a dummy tablespace for the redo log, use fil_space_t::flags=0. The flags are never written to the redo log files. Remove many FSP_FLAGS_SET_ macros. dict_tf_verify_flags(): Remove. This is basically only duplicating the logic of dict_tf_to_fsp_flags(), used in a debug assertion. fil_space_t::mark: Remove. This flag was not used for anything. fil_space_for_table_exists_in_mem(): Remove the unnecessary parameter mark_space, and add a parameter for table flags. Check that fil_space_t::flags match the table flags, and adjust the (memory-only) flags based on the table flags. fil_node_open_file(): Remove some redundant or unreachable conditions, do not use stderr for output, and avoid unnecessary server aborts. fil_user_tablespace_restore_page(): Convert the flags, so that the correct page_size will be used when restoring a page from the doublewrite buffer. fil_space_get_page_compressed(), fsp_flags_is_page_compressed(): Remove. It suffices to have fil_space_is_page_compressed(). FSP_FLAGS_WIDTH_DATA_DIR, FSP_FLAGS_WIDTH_PAGE_COMPRESSION_LEVEL, FSP_FLAGS_WIDTH_ATOMIC_WRITES: Remove, because these flags do not exist in the FSP_SPACE_FLAGS but only in memory. fsp_flags_try_adjust(): New function, to adjust the FSP_SPACE_FLAGS in page 0. Called by fil_open_single_table_tablespace(), fil_space_for_table_exists_in_mem(), innobase_start_or_create_for_mysql() except if --innodb-read-only is active. fsp_flags_is_valid(ulint): Reimplement from the scratch, with accurate comments. Do not display any details of detected inconsistencies, because the output could be confusing when dealing with MariaDB 10.1.x data files. fsp_flags_convert_from_101(ulint): Convert flags from buggy MariaDB 10.1.x format, or return ULINT_UNDEFINED if the flags cannot be in MariaDB 10.1.x format. fsp_flags_match(): Check the flags when probing files. Implemented based on fsp_flags_is_valid() and fsp_flags_convert_from_101(). dict_check_tablespaces_and_store_max_id(): Do not access the page after committing the mini-transaction. IMPORT TABLESPACE fixes: AbstractCallback::init(): Convert the flags. FetchIndexRootPages::operator(): Check that the tablespace flags match the table flags. Do not attempt to convert tablespace flags to table flags, because the conversion would necessarily be lossy. PageConverter::update_header(): Write back the correct flags. This takes care of the flags in IMPORT TABLESPACE.
9 years ago
MDEV-11623 MariaDB 10.1 fails to start datadir created with MariaDB 10.0/MySQL 5.6 using innodb-page-size!=16K The storage format of FSP_SPACE_FLAGS was accidentally broken already in MariaDB 10.1.0. This fix is bringing the format in line with other MySQL and MariaDB release series. Please refer to the comments that were added to fsp0fsp.h for details. This is an INCOMPATIBLE CHANGE that affects users of page_compression and non-default innodb_page_size. Upgrading to this release will correct the flags in the data files. If you want to downgrade to earlier MariaDB 10.1.x, please refer to the test innodb.101_compatibility how to reset the FSP_SPACE_FLAGS in the files. NOTE: MariaDB 10.1.0 to 10.1.20 can misinterpret uncompressed data files with innodb_page_size=4k or 64k as compressed innodb_page_size=16k files, and then probably fail when trying to access the pages. See the comments in the function fsp_flags_convert_from_101() for detailed analysis. Move PAGE_COMPRESSION to FSP_SPACE_FLAGS bit position 16. In this way, compressed innodb_page_size=16k tablespaces will not be mistaken for uncompressed ones by MariaDB 10.1.0 to 10.1.20. Derive PAGE_COMPRESSION_LEVEL, ATOMIC_WRITES and DATA_DIR from the dict_table_t::flags when the table is available, in fil_space_for_table_exists_in_mem() or fil_open_single_table_tablespace(). During crash recovery, fil_load_single_table_tablespace() will use innodb_compression_level for the PAGE_COMPRESSION_LEVEL. FSP_FLAGS_MEM_MASK: A bitmap of the memory-only fil_space_t::flags that are not to be written to FSP_SPACE_FLAGS. Currently, these will include PAGE_COMPRESSION_LEVEL, ATOMIC_WRITES and DATA_DIR. Introduce the macro FSP_FLAGS_PAGE_SSIZE(). We only support one innodb_page_size for the whole instance. When creating a dummy tablespace for the redo log, use fil_space_t::flags=0. The flags are never written to the redo log files. Remove many FSP_FLAGS_SET_ macros. dict_tf_verify_flags(): Remove. This is basically only duplicating the logic of dict_tf_to_fsp_flags(), used in a debug assertion. fil_space_t::mark: Remove. This flag was not used for anything. fil_space_for_table_exists_in_mem(): Remove the unnecessary parameter mark_space, and add a parameter for table flags. Check that fil_space_t::flags match the table flags, and adjust the (memory-only) flags based on the table flags. fil_node_open_file(): Remove some redundant or unreachable conditions, do not use stderr for output, and avoid unnecessary server aborts. fil_user_tablespace_restore_page(): Convert the flags, so that the correct page_size will be used when restoring a page from the doublewrite buffer. fil_space_get_page_compressed(), fsp_flags_is_page_compressed(): Remove. It suffices to have fil_space_is_page_compressed(). FSP_FLAGS_WIDTH_DATA_DIR, FSP_FLAGS_WIDTH_PAGE_COMPRESSION_LEVEL, FSP_FLAGS_WIDTH_ATOMIC_WRITES: Remove, because these flags do not exist in the FSP_SPACE_FLAGS but only in memory. fsp_flags_try_adjust(): New function, to adjust the FSP_SPACE_FLAGS in page 0. Called by fil_open_single_table_tablespace(), fil_space_for_table_exists_in_mem(), innobase_start_or_create_for_mysql() except if --innodb-read-only is active. fsp_flags_is_valid(ulint): Reimplement from the scratch, with accurate comments. Do not display any details of detected inconsistencies, because the output could be confusing when dealing with MariaDB 10.1.x data files. fsp_flags_convert_from_101(ulint): Convert flags from buggy MariaDB 10.1.x format, or return ULINT_UNDEFINED if the flags cannot be in MariaDB 10.1.x format. fsp_flags_match(): Check the flags when probing files. Implemented based on fsp_flags_is_valid() and fsp_flags_convert_from_101(). dict_check_tablespaces_and_store_max_id(): Do not access the page after committing the mini-transaction. IMPORT TABLESPACE fixes: AbstractCallback::init(): Convert the flags. FetchIndexRootPages::operator(): Check that the tablespace flags match the table flags. Do not attempt to convert tablespace flags to table flags, because the conversion would necessarily be lossy. PageConverter::update_header(): Write back the correct flags. This takes care of the flags in IMPORT TABLESPACE.
9 years ago
MDEV-11623 MariaDB 10.1 fails to start datadir created with MariaDB 10.0/MySQL 5.6 using innodb-page-size!=16K The storage format of FSP_SPACE_FLAGS was accidentally broken already in MariaDB 10.1.0. This fix is bringing the format in line with other MySQL and MariaDB release series. Please refer to the comments that were added to fsp0fsp.h for details. This is an INCOMPATIBLE CHANGE that affects users of page_compression and non-default innodb_page_size. Upgrading to this release will correct the flags in the data files. If you want to downgrade to earlier MariaDB 10.1.x, please refer to the test innodb.101_compatibility how to reset the FSP_SPACE_FLAGS in the files. NOTE: MariaDB 10.1.0 to 10.1.20 can misinterpret uncompressed data files with innodb_page_size=4k or 64k as compressed innodb_page_size=16k files, and then probably fail when trying to access the pages. See the comments in the function fsp_flags_convert_from_101() for detailed analysis. Move PAGE_COMPRESSION to FSP_SPACE_FLAGS bit position 16. In this way, compressed innodb_page_size=16k tablespaces will not be mistaken for uncompressed ones by MariaDB 10.1.0 to 10.1.20. Derive PAGE_COMPRESSION_LEVEL, ATOMIC_WRITES and DATA_DIR from the dict_table_t::flags when the table is available, in fil_space_for_table_exists_in_mem() or fil_open_single_table_tablespace(). During crash recovery, fil_load_single_table_tablespace() will use innodb_compression_level for the PAGE_COMPRESSION_LEVEL. FSP_FLAGS_MEM_MASK: A bitmap of the memory-only fil_space_t::flags that are not to be written to FSP_SPACE_FLAGS. Currently, these will include PAGE_COMPRESSION_LEVEL, ATOMIC_WRITES and DATA_DIR. Introduce the macro FSP_FLAGS_PAGE_SSIZE(). We only support one innodb_page_size for the whole instance. When creating a dummy tablespace for the redo log, use fil_space_t::flags=0. The flags are never written to the redo log files. Remove many FSP_FLAGS_SET_ macros. dict_tf_verify_flags(): Remove. This is basically only duplicating the logic of dict_tf_to_fsp_flags(), used in a debug assertion. fil_space_t::mark: Remove. This flag was not used for anything. fil_space_for_table_exists_in_mem(): Remove the unnecessary parameter mark_space, and add a parameter for table flags. Check that fil_space_t::flags match the table flags, and adjust the (memory-only) flags based on the table flags. fil_node_open_file(): Remove some redundant or unreachable conditions, do not use stderr for output, and avoid unnecessary server aborts. fil_user_tablespace_restore_page(): Convert the flags, so that the correct page_size will be used when restoring a page from the doublewrite buffer. fil_space_get_page_compressed(), fsp_flags_is_page_compressed(): Remove. It suffices to have fil_space_is_page_compressed(). FSP_FLAGS_WIDTH_DATA_DIR, FSP_FLAGS_WIDTH_PAGE_COMPRESSION_LEVEL, FSP_FLAGS_WIDTH_ATOMIC_WRITES: Remove, because these flags do not exist in the FSP_SPACE_FLAGS but only in memory. fsp_flags_try_adjust(): New function, to adjust the FSP_SPACE_FLAGS in page 0. Called by fil_open_single_table_tablespace(), fil_space_for_table_exists_in_mem(), innobase_start_or_create_for_mysql() except if --innodb-read-only is active. fsp_flags_is_valid(ulint): Reimplement from the scratch, with accurate comments. Do not display any details of detected inconsistencies, because the output could be confusing when dealing with MariaDB 10.1.x data files. fsp_flags_convert_from_101(ulint): Convert flags from buggy MariaDB 10.1.x format, or return ULINT_UNDEFINED if the flags cannot be in MariaDB 10.1.x format. fsp_flags_match(): Check the flags when probing files. Implemented based on fsp_flags_is_valid() and fsp_flags_convert_from_101(). dict_check_tablespaces_and_store_max_id(): Do not access the page after committing the mini-transaction. IMPORT TABLESPACE fixes: AbstractCallback::init(): Convert the flags. FetchIndexRootPages::operator(): Check that the tablespace flags match the table flags. Do not attempt to convert tablespace flags to table flags, because the conversion would necessarily be lossy. PageConverter::update_header(): Write back the correct flags. This takes care of the flags in IMPORT TABLESPACE.
9 years ago
MDEV-11623 MariaDB 10.1 fails to start datadir created with MariaDB 10.0/MySQL 5.6 using innodb-page-size!=16K The storage format of FSP_SPACE_FLAGS was accidentally broken already in MariaDB 10.1.0. This fix is bringing the format in line with other MySQL and MariaDB release series. Please refer to the comments that were added to fsp0fsp.h for details. This is an INCOMPATIBLE CHANGE that affects users of page_compression and non-default innodb_page_size. Upgrading to this release will correct the flags in the data files. If you want to downgrade to earlier MariaDB 10.1.x, please refer to the test innodb.101_compatibility how to reset the FSP_SPACE_FLAGS in the files. NOTE: MariaDB 10.1.0 to 10.1.20 can misinterpret uncompressed data files with innodb_page_size=4k or 64k as compressed innodb_page_size=16k files, and then probably fail when trying to access the pages. See the comments in the function fsp_flags_convert_from_101() for detailed analysis. Move PAGE_COMPRESSION to FSP_SPACE_FLAGS bit position 16. In this way, compressed innodb_page_size=16k tablespaces will not be mistaken for uncompressed ones by MariaDB 10.1.0 to 10.1.20. Derive PAGE_COMPRESSION_LEVEL, ATOMIC_WRITES and DATA_DIR from the dict_table_t::flags when the table is available, in fil_space_for_table_exists_in_mem() or fil_open_single_table_tablespace(). During crash recovery, fil_load_single_table_tablespace() will use innodb_compression_level for the PAGE_COMPRESSION_LEVEL. FSP_FLAGS_MEM_MASK: A bitmap of the memory-only fil_space_t::flags that are not to be written to FSP_SPACE_FLAGS. Currently, these will include PAGE_COMPRESSION_LEVEL, ATOMIC_WRITES and DATA_DIR. Introduce the macro FSP_FLAGS_PAGE_SSIZE(). We only support one innodb_page_size for the whole instance. When creating a dummy tablespace for the redo log, use fil_space_t::flags=0. The flags are never written to the redo log files. Remove many FSP_FLAGS_SET_ macros. dict_tf_verify_flags(): Remove. This is basically only duplicating the logic of dict_tf_to_fsp_flags(), used in a debug assertion. fil_space_t::mark: Remove. This flag was not used for anything. fil_space_for_table_exists_in_mem(): Remove the unnecessary parameter mark_space, and add a parameter for table flags. Check that fil_space_t::flags match the table flags, and adjust the (memory-only) flags based on the table flags. fil_node_open_file(): Remove some redundant or unreachable conditions, do not use stderr for output, and avoid unnecessary server aborts. fil_user_tablespace_restore_page(): Convert the flags, so that the correct page_size will be used when restoring a page from the doublewrite buffer. fil_space_get_page_compressed(), fsp_flags_is_page_compressed(): Remove. It suffices to have fil_space_is_page_compressed(). FSP_FLAGS_WIDTH_DATA_DIR, FSP_FLAGS_WIDTH_PAGE_COMPRESSION_LEVEL, FSP_FLAGS_WIDTH_ATOMIC_WRITES: Remove, because these flags do not exist in the FSP_SPACE_FLAGS but only in memory. fsp_flags_try_adjust(): New function, to adjust the FSP_SPACE_FLAGS in page 0. Called by fil_open_single_table_tablespace(), fil_space_for_table_exists_in_mem(), innobase_start_or_create_for_mysql() except if --innodb-read-only is active. fsp_flags_is_valid(ulint): Reimplement from the scratch, with accurate comments. Do not display any details of detected inconsistencies, because the output could be confusing when dealing with MariaDB 10.1.x data files. fsp_flags_convert_from_101(ulint): Convert flags from buggy MariaDB 10.1.x format, or return ULINT_UNDEFINED if the flags cannot be in MariaDB 10.1.x format. fsp_flags_match(): Check the flags when probing files. Implemented based on fsp_flags_is_valid() and fsp_flags_convert_from_101(). dict_check_tablespaces_and_store_max_id(): Do not access the page after committing the mini-transaction. IMPORT TABLESPACE fixes: AbstractCallback::init(): Convert the flags. FetchIndexRootPages::operator(): Check that the tablespace flags match the table flags. Do not attempt to convert tablespace flags to table flags, because the conversion would necessarily be lossy. PageConverter::update_header(): Write back the correct flags. This takes care of the flags in IMPORT TABLESPACE.
9 years ago
MDEV-11679 Remove redundant function fsp_header_get_crypt_offset() fsp_header_get_crypt_offset(): Remove. xdes_arr_size(): Remove. fsp_header_get_encryption_offset(): Make this an inline function. The correctness of this change was ensured with the following patch that ensures that the two functions returned the same value, only differing by FSP_HEADER_OFFSET (38 bytes): diff --git a/storage/innobase/fsp/fsp0fsp.cc b/storage/innobase/fsp/fsp0fsp.cc index f2a4c6bf218..e96c788b7df 100644 --- a/storage/innobase/fsp/fsp0fsp.cc +++ b/storage/innobase/fsp/fsp0fsp.cc @@ -850,6 +850,7 @@ fsp_parse_init_file_page( return(ptr); } +static ulint fsp_header_get_encryption_offset(const page_size_t&); /**********************************************************************//** Initializes the fsp system. */ void @@ -868,6 +869,31 @@ fsp_init(void) #endif /* Does nothing at the moment */ + + for (ulint sz = 4096; sz <= 65536; sz *= 2) { + ulint m; + if (sz <= 16384) { + for (ulint ph = 1024; ph <= sz; ph *= 2) { + const page_size_t ps(ph, sz, true); + ulint maria = fsp_header_get_crypt_offset(ps, &m), + oracle = fsp_header_get_encryption_offset(ps); + if (maria != oracle + 38) { + ib::error() << "zip size mismatch: " + << maria << "!=" << oracle + << "(" << ph <<","<<sz<<")" + << m; + } + } + } + const page_size_t p(sz, sz, false); + ulint maria = fsp_header_get_crypt_offset(p, &m), + oracle = fsp_header_get_encryption_offset(p); + if (maria != oracle + 38) { + ib::error() << "size mismatch: " + << maria << "!=" << oracle + << "(" <<sz<<")" << m; + } + } } /**********************************************************************//**
9 years ago
9 years ago
9 years ago
MDEV-11623 MariaDB 10.1 fails to start datadir created with MariaDB 10.0/MySQL 5.6 using innodb-page-size!=16K The storage format of FSP_SPACE_FLAGS was accidentally broken already in MariaDB 10.1.0. This fix is bringing the format in line with other MySQL and MariaDB release series. Please refer to the comments that were added to fsp0fsp.h for details. This is an INCOMPATIBLE CHANGE that affects users of page_compression and non-default innodb_page_size. Upgrading to this release will correct the flags in the data files. If you want to downgrade to earlier MariaDB 10.1.x, please refer to the test innodb.101_compatibility how to reset the FSP_SPACE_FLAGS in the files. NOTE: MariaDB 10.1.0 to 10.1.20 can misinterpret uncompressed data files with innodb_page_size=4k or 64k as compressed innodb_page_size=16k files, and then probably fail when trying to access the pages. See the comments in the function fsp_flags_convert_from_101() for detailed analysis. Move PAGE_COMPRESSION to FSP_SPACE_FLAGS bit position 16. In this way, compressed innodb_page_size=16k tablespaces will not be mistaken for uncompressed ones by MariaDB 10.1.0 to 10.1.20. Derive PAGE_COMPRESSION_LEVEL, ATOMIC_WRITES and DATA_DIR from the dict_table_t::flags when the table is available, in fil_space_for_table_exists_in_mem() or fil_open_single_table_tablespace(). During crash recovery, fil_load_single_table_tablespace() will use innodb_compression_level for the PAGE_COMPRESSION_LEVEL. FSP_FLAGS_MEM_MASK: A bitmap of the memory-only fil_space_t::flags that are not to be written to FSP_SPACE_FLAGS. Currently, these will include PAGE_COMPRESSION_LEVEL, ATOMIC_WRITES and DATA_DIR. Introduce the macro FSP_FLAGS_PAGE_SSIZE(). We only support one innodb_page_size for the whole instance. When creating a dummy tablespace for the redo log, use fil_space_t::flags=0. The flags are never written to the redo log files. Remove many FSP_FLAGS_SET_ macros. dict_tf_verify_flags(): Remove. This is basically only duplicating the logic of dict_tf_to_fsp_flags(), used in a debug assertion. fil_space_t::mark: Remove. This flag was not used for anything. fil_space_for_table_exists_in_mem(): Remove the unnecessary parameter mark_space, and add a parameter for table flags. Check that fil_space_t::flags match the table flags, and adjust the (memory-only) flags based on the table flags. fil_node_open_file(): Remove some redundant or unreachable conditions, do not use stderr for output, and avoid unnecessary server aborts. fil_user_tablespace_restore_page(): Convert the flags, so that the correct page_size will be used when restoring a page from the doublewrite buffer. fil_space_get_page_compressed(), fsp_flags_is_page_compressed(): Remove. It suffices to have fil_space_is_page_compressed(). FSP_FLAGS_WIDTH_DATA_DIR, FSP_FLAGS_WIDTH_PAGE_COMPRESSION_LEVEL, FSP_FLAGS_WIDTH_ATOMIC_WRITES: Remove, because these flags do not exist in the FSP_SPACE_FLAGS but only in memory. fsp_flags_try_adjust(): New function, to adjust the FSP_SPACE_FLAGS in page 0. Called by fil_open_single_table_tablespace(), fil_space_for_table_exists_in_mem(), innobase_start_or_create_for_mysql() except if --innodb-read-only is active. fsp_flags_is_valid(ulint): Reimplement from the scratch, with accurate comments. Do not display any details of detected inconsistencies, because the output could be confusing when dealing with MariaDB 10.1.x data files. fsp_flags_convert_from_101(ulint): Convert flags from buggy MariaDB 10.1.x format, or return ULINT_UNDEFINED if the flags cannot be in MariaDB 10.1.x format. fsp_flags_match(): Check the flags when probing files. Implemented based on fsp_flags_is_valid() and fsp_flags_convert_from_101(). dict_check_tablespaces_and_store_max_id(): Do not access the page after committing the mini-transaction. IMPORT TABLESPACE fixes: AbstractCallback::init(): Convert the flags. FetchIndexRootPages::operator(): Check that the tablespace flags match the table flags. Do not attempt to convert tablespace flags to table flags, because the conversion would necessarily be lossy. PageConverter::update_header(): Write back the correct flags. This takes care of the flags in IMPORT TABLESPACE.
9 years ago
MDEV-11623 MariaDB 10.1 fails to start datadir created with MariaDB 10.0/MySQL 5.6 using innodb-page-size!=16K The storage format of FSP_SPACE_FLAGS was accidentally broken already in MariaDB 10.1.0. This fix is bringing the format in line with other MySQL and MariaDB release series. Please refer to the comments that were added to fsp0fsp.h for details. This is an INCOMPATIBLE CHANGE that affects users of page_compression and non-default innodb_page_size. Upgrading to this release will correct the flags in the data files. If you want to downgrade to earlier MariaDB 10.1.x, please refer to the test innodb.101_compatibility how to reset the FSP_SPACE_FLAGS in the files. NOTE: MariaDB 10.1.0 to 10.1.20 can misinterpret uncompressed data files with innodb_page_size=4k or 64k as compressed innodb_page_size=16k files, and then probably fail when trying to access the pages. See the comments in the function fsp_flags_convert_from_101() for detailed analysis. Move PAGE_COMPRESSION to FSP_SPACE_FLAGS bit position 16. In this way, compressed innodb_page_size=16k tablespaces will not be mistaken for uncompressed ones by MariaDB 10.1.0 to 10.1.20. Derive PAGE_COMPRESSION_LEVEL, ATOMIC_WRITES and DATA_DIR from the dict_table_t::flags when the table is available, in fil_space_for_table_exists_in_mem() or fil_open_single_table_tablespace(). During crash recovery, fil_load_single_table_tablespace() will use innodb_compression_level for the PAGE_COMPRESSION_LEVEL. FSP_FLAGS_MEM_MASK: A bitmap of the memory-only fil_space_t::flags that are not to be written to FSP_SPACE_FLAGS. Currently, these will include PAGE_COMPRESSION_LEVEL, ATOMIC_WRITES and DATA_DIR. Introduce the macro FSP_FLAGS_PAGE_SSIZE(). We only support one innodb_page_size for the whole instance. When creating a dummy tablespace for the redo log, use fil_space_t::flags=0. The flags are never written to the redo log files. Remove many FSP_FLAGS_SET_ macros. dict_tf_verify_flags(): Remove. This is basically only duplicating the logic of dict_tf_to_fsp_flags(), used in a debug assertion. fil_space_t::mark: Remove. This flag was not used for anything. fil_space_for_table_exists_in_mem(): Remove the unnecessary parameter mark_space, and add a parameter for table flags. Check that fil_space_t::flags match the table flags, and adjust the (memory-only) flags based on the table flags. fil_node_open_file(): Remove some redundant or unreachable conditions, do not use stderr for output, and avoid unnecessary server aborts. fil_user_tablespace_restore_page(): Convert the flags, so that the correct page_size will be used when restoring a page from the doublewrite buffer. fil_space_get_page_compressed(), fsp_flags_is_page_compressed(): Remove. It suffices to have fil_space_is_page_compressed(). FSP_FLAGS_WIDTH_DATA_DIR, FSP_FLAGS_WIDTH_PAGE_COMPRESSION_LEVEL, FSP_FLAGS_WIDTH_ATOMIC_WRITES: Remove, because these flags do not exist in the FSP_SPACE_FLAGS but only in memory. fsp_flags_try_adjust(): New function, to adjust the FSP_SPACE_FLAGS in page 0. Called by fil_open_single_table_tablespace(), fil_space_for_table_exists_in_mem(), innobase_start_or_create_for_mysql() except if --innodb-read-only is active. fsp_flags_is_valid(ulint): Reimplement from the scratch, with accurate comments. Do not display any details of detected inconsistencies, because the output could be confusing when dealing with MariaDB 10.1.x data files. fsp_flags_convert_from_101(ulint): Convert flags from buggy MariaDB 10.1.x format, or return ULINT_UNDEFINED if the flags cannot be in MariaDB 10.1.x format. fsp_flags_match(): Check the flags when probing files. Implemented based on fsp_flags_is_valid() and fsp_flags_convert_from_101(). dict_check_tablespaces_and_store_max_id(): Do not access the page after committing the mini-transaction. IMPORT TABLESPACE fixes: AbstractCallback::init(): Convert the flags. FetchIndexRootPages::operator(): Check that the tablespace flags match the table flags. Do not attempt to convert tablespace flags to table flags, because the conversion would necessarily be lossy. PageConverter::update_header(): Write back the correct flags. This takes care of the flags in IMPORT TABLESPACE.
9 years ago
MDEV-11623 MariaDB 10.1 fails to start datadir created with MariaDB 10.0/MySQL 5.6 using innodb-page-size!=16K The storage format of FSP_SPACE_FLAGS was accidentally broken already in MariaDB 10.1.0. This fix is bringing the format in line with other MySQL and MariaDB release series. Please refer to the comments that were added to fsp0fsp.h for details. This is an INCOMPATIBLE CHANGE that affects users of page_compression and non-default innodb_page_size. Upgrading to this release will correct the flags in the data files. If you want to downgrade to earlier MariaDB 10.1.x, please refer to the test innodb.101_compatibility how to reset the FSP_SPACE_FLAGS in the files. NOTE: MariaDB 10.1.0 to 10.1.20 can misinterpret uncompressed data files with innodb_page_size=4k or 64k as compressed innodb_page_size=16k files, and then probably fail when trying to access the pages. See the comments in the function fsp_flags_convert_from_101() for detailed analysis. Move PAGE_COMPRESSION to FSP_SPACE_FLAGS bit position 16. In this way, compressed innodb_page_size=16k tablespaces will not be mistaken for uncompressed ones by MariaDB 10.1.0 to 10.1.20. Derive PAGE_COMPRESSION_LEVEL, ATOMIC_WRITES and DATA_DIR from the dict_table_t::flags when the table is available, in fil_space_for_table_exists_in_mem() or fil_open_single_table_tablespace(). During crash recovery, fil_load_single_table_tablespace() will use innodb_compression_level for the PAGE_COMPRESSION_LEVEL. FSP_FLAGS_MEM_MASK: A bitmap of the memory-only fil_space_t::flags that are not to be written to FSP_SPACE_FLAGS. Currently, these will include PAGE_COMPRESSION_LEVEL, ATOMIC_WRITES and DATA_DIR. Introduce the macro FSP_FLAGS_PAGE_SSIZE(). We only support one innodb_page_size for the whole instance. When creating a dummy tablespace for the redo log, use fil_space_t::flags=0. The flags are never written to the redo log files. Remove many FSP_FLAGS_SET_ macros. dict_tf_verify_flags(): Remove. This is basically only duplicating the logic of dict_tf_to_fsp_flags(), used in a debug assertion. fil_space_t::mark: Remove. This flag was not used for anything. fil_space_for_table_exists_in_mem(): Remove the unnecessary parameter mark_space, and add a parameter for table flags. Check that fil_space_t::flags match the table flags, and adjust the (memory-only) flags based on the table flags. fil_node_open_file(): Remove some redundant or unreachable conditions, do not use stderr for output, and avoid unnecessary server aborts. fil_user_tablespace_restore_page(): Convert the flags, so that the correct page_size will be used when restoring a page from the doublewrite buffer. fil_space_get_page_compressed(), fsp_flags_is_page_compressed(): Remove. It suffices to have fil_space_is_page_compressed(). FSP_FLAGS_WIDTH_DATA_DIR, FSP_FLAGS_WIDTH_PAGE_COMPRESSION_LEVEL, FSP_FLAGS_WIDTH_ATOMIC_WRITES: Remove, because these flags do not exist in the FSP_SPACE_FLAGS but only in memory. fsp_flags_try_adjust(): New function, to adjust the FSP_SPACE_FLAGS in page 0. Called by fil_open_single_table_tablespace(), fil_space_for_table_exists_in_mem(), innobase_start_or_create_for_mysql() except if --innodb-read-only is active. fsp_flags_is_valid(ulint): Reimplement from the scratch, with accurate comments. Do not display any details of detected inconsistencies, because the output could be confusing when dealing with MariaDB 10.1.x data files. fsp_flags_convert_from_101(ulint): Convert flags from buggy MariaDB 10.1.x format, or return ULINT_UNDEFINED if the flags cannot be in MariaDB 10.1.x format. fsp_flags_match(): Check the flags when probing files. Implemented based on fsp_flags_is_valid() and fsp_flags_convert_from_101(). dict_check_tablespaces_and_store_max_id(): Do not access the page after committing the mini-transaction. IMPORT TABLESPACE fixes: AbstractCallback::init(): Convert the flags. FetchIndexRootPages::operator(): Check that the tablespace flags match the table flags. Do not attempt to convert tablespace flags to table flags, because the conversion would necessarily be lossy. PageConverter::update_header(): Write back the correct flags. This takes care of the flags in IMPORT TABLESPACE.
9 years ago
MDEV-11623 MariaDB 10.1 fails to start datadir created with MariaDB 10.0/MySQL 5.6 using innodb-page-size!=16K The storage format of FSP_SPACE_FLAGS was accidentally broken already in MariaDB 10.1.0. This fix is bringing the format in line with other MySQL and MariaDB release series. Please refer to the comments that were added to fsp0fsp.h for details. This is an INCOMPATIBLE CHANGE that affects users of page_compression and non-default innodb_page_size. Upgrading to this release will correct the flags in the data files. If you want to downgrade to earlier MariaDB 10.1.x, please refer to the test innodb.101_compatibility how to reset the FSP_SPACE_FLAGS in the files. NOTE: MariaDB 10.1.0 to 10.1.20 can misinterpret uncompressed data files with innodb_page_size=4k or 64k as compressed innodb_page_size=16k files, and then probably fail when trying to access the pages. See the comments in the function fsp_flags_convert_from_101() for detailed analysis. Move PAGE_COMPRESSION to FSP_SPACE_FLAGS bit position 16. In this way, compressed innodb_page_size=16k tablespaces will not be mistaken for uncompressed ones by MariaDB 10.1.0 to 10.1.20. Derive PAGE_COMPRESSION_LEVEL, ATOMIC_WRITES and DATA_DIR from the dict_table_t::flags when the table is available, in fil_space_for_table_exists_in_mem() or fil_open_single_table_tablespace(). During crash recovery, fil_load_single_table_tablespace() will use innodb_compression_level for the PAGE_COMPRESSION_LEVEL. FSP_FLAGS_MEM_MASK: A bitmap of the memory-only fil_space_t::flags that are not to be written to FSP_SPACE_FLAGS. Currently, these will include PAGE_COMPRESSION_LEVEL, ATOMIC_WRITES and DATA_DIR. Introduce the macro FSP_FLAGS_PAGE_SSIZE(). We only support one innodb_page_size for the whole instance. When creating a dummy tablespace for the redo log, use fil_space_t::flags=0. The flags are never written to the redo log files. Remove many FSP_FLAGS_SET_ macros. dict_tf_verify_flags(): Remove. This is basically only duplicating the logic of dict_tf_to_fsp_flags(), used in a debug assertion. fil_space_t::mark: Remove. This flag was not used for anything. fil_space_for_table_exists_in_mem(): Remove the unnecessary parameter mark_space, and add a parameter for table flags. Check that fil_space_t::flags match the table flags, and adjust the (memory-only) flags based on the table flags. fil_node_open_file(): Remove some redundant or unreachable conditions, do not use stderr for output, and avoid unnecessary server aborts. fil_user_tablespace_restore_page(): Convert the flags, so that the correct page_size will be used when restoring a page from the doublewrite buffer. fil_space_get_page_compressed(), fsp_flags_is_page_compressed(): Remove. It suffices to have fil_space_is_page_compressed(). FSP_FLAGS_WIDTH_DATA_DIR, FSP_FLAGS_WIDTH_PAGE_COMPRESSION_LEVEL, FSP_FLAGS_WIDTH_ATOMIC_WRITES: Remove, because these flags do not exist in the FSP_SPACE_FLAGS but only in memory. fsp_flags_try_adjust(): New function, to adjust the FSP_SPACE_FLAGS in page 0. Called by fil_open_single_table_tablespace(), fil_space_for_table_exists_in_mem(), innobase_start_or_create_for_mysql() except if --innodb-read-only is active. fsp_flags_is_valid(ulint): Reimplement from the scratch, with accurate comments. Do not display any details of detected inconsistencies, because the output could be confusing when dealing with MariaDB 10.1.x data files. fsp_flags_convert_from_101(ulint): Convert flags from buggy MariaDB 10.1.x format, or return ULINT_UNDEFINED if the flags cannot be in MariaDB 10.1.x format. fsp_flags_match(): Check the flags when probing files. Implemented based on fsp_flags_is_valid() and fsp_flags_convert_from_101(). dict_check_tablespaces_and_store_max_id(): Do not access the page after committing the mini-transaction. IMPORT TABLESPACE fixes: AbstractCallback::init(): Convert the flags. FetchIndexRootPages::operator(): Check that the tablespace flags match the table flags. Do not attempt to convert tablespace flags to table flags, because the conversion would necessarily be lossy. PageConverter::update_header(): Write back the correct flags. This takes care of the flags in IMPORT TABLESPACE.
9 years ago
  1. /*****************************************************************************
  2. Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
  3. Copyright (c) 2013, 2017, MariaDB Corporation.
  4. This program is free software; you can redistribute it and/or modify it under
  5. the terms of the GNU General Public License as published by the Free Software
  6. Foundation; version 2 of the License.
  7. This program is distributed in the hope that it will be useful, but WITHOUT
  8. ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
  9. FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  10. You should have received a copy of the GNU General Public License along with
  11. this program; if not, write to the Free Software Foundation, Inc.,
  12. 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
  13. *****************************************************************************/
  14. /**************************************************//**
  15. @file include/fsp0fsp.h
  16. File space management
  17. Created 12/18/1995 Heikki Tuuri
  18. *******************************************************/
  19. #ifndef fsp0fsp_h
  20. #define fsp0fsp_h
  21. #include "univ.i"
  22. #include "fsp0types.h"
  23. #ifndef UNIV_INNOCHECKSUM
  24. #include "fsp0space.h"
  25. #include "fut0lst.h"
  26. #include "mtr0mtr.h"
  27. #include "page0types.h"
  28. #include "rem0types.h"
  29. #include "ut0byte.h"
  30. #endif /* !UNIV_INNOCHECKSUM */
  31. #include "fsp0types.h"
  32. /** @return the PAGE_SSIZE flags for the current innodb_page_size */
  33. #define FSP_FLAGS_PAGE_SSIZE() \
  34. ((UNIV_PAGE_SIZE == UNIV_PAGE_SIZE_ORIG) ? \
  35. 0 : (UNIV_PAGE_SIZE_SHIFT - UNIV_ZIP_SIZE_SHIFT_MIN + 1) \
  36. << FSP_FLAGS_POS_PAGE_SSIZE)
  37. /* @defgroup Compatibility macros for MariaDB 10.1.0 through 10.1.20;
  38. see the table in fsp0types.h @{ */
  39. /** Zero relative shift position of the PAGE_COMPRESSION field */
  40. #define FSP_FLAGS_POS_PAGE_COMPRESSION_MARIADB101 \
  41. (FSP_FLAGS_POS_ATOMIC_BLOBS \
  42. + FSP_FLAGS_WIDTH_ATOMIC_BLOBS)
  43. /** Zero relative shift position of the PAGE_COMPRESSION_LEVEL field */
  44. #define FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL_MARIADB101 \
  45. (FSP_FLAGS_POS_PAGE_COMPRESSION_MARIADB101 + 1)
  46. /** Zero relative shift position of the ATOMIC_WRITES field */
  47. #define FSP_FLAGS_POS_ATOMIC_WRITES_MARIADB101 \
  48. (FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL_MARIADB101 + 4)
  49. /** Zero relative shift position of the PAGE_SSIZE field */
  50. #define FSP_FLAGS_POS_PAGE_SSIZE_MARIADB101 \
  51. (FSP_FLAGS_POS_ATOMIC_WRITES_MARIADB101 + 2)
  52. /** Bit mask of the PAGE_COMPRESSION field */
  53. #define FSP_FLAGS_MASK_PAGE_COMPRESSION_MARIADB101 \
  54. (1U << FSP_FLAGS_POS_PAGE_COMPRESSION_MARIADB101)
  55. /** Bit mask of the PAGE_COMPRESSION_LEVEL field */
  56. #define FSP_FLAGS_MASK_PAGE_COMPRESSION_LEVEL_MARIADB101 \
  57. (15U << FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL_MARIADB101)
  58. /** Bit mask of the ATOMIC_WRITES field */
  59. #define FSP_FLAGS_MASK_ATOMIC_WRITES_MARIADB101 \
  60. (3U << FSP_FLAGS_POS_ATOMIC_WRITES_MARIADB101)
  61. /** Bit mask of the PAGE_SSIZE field */
  62. #define FSP_FLAGS_MASK_PAGE_SSIZE_MARIADB101 \
  63. (15U << FSP_FLAGS_POS_PAGE_SSIZE_MARIADB101)
  64. /** Return the value of the PAGE_COMPRESSION field */
  65. #define FSP_FLAGS_GET_PAGE_COMPRESSION_MARIADB101(flags) \
  66. ((flags & FSP_FLAGS_MASK_PAGE_COMPRESSION_MARIADB101) \
  67. >> FSP_FLAGS_POS_PAGE_COMPRESSION_MARIADB101)
  68. /** Return the value of the PAGE_COMPRESSION_LEVEL field */
  69. #define FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL_MARIADB101(flags) \
  70. ((flags & FSP_FLAGS_MASK_PAGE_COMPRESSION_LEVEL_MARIADB101) \
  71. >> FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL_MARIADB101)
  72. /** Return the value of the PAGE_SSIZE field */
  73. #define FSP_FLAGS_GET_PAGE_SSIZE_MARIADB101(flags) \
  74. ((flags & FSP_FLAGS_MASK_PAGE_SSIZE_MARIADB101) \
  75. >> FSP_FLAGS_POS_PAGE_SSIZE_MARIADB101)
  76. /* @} */
  77. /* @defgroup Tablespace Header Constants (moved from fsp0fsp.c) @{ */
  78. /** Offset of the space header within a file page */
  79. #define FSP_HEADER_OFFSET FIL_PAGE_DATA
  80. /* The data structures in files are defined just as byte strings in C */
  81. typedef byte fsp_header_t;
  82. typedef byte xdes_t;
  83. /* SPACE HEADER
  84. ============
  85. File space header data structure: this data structure is contained in the
  86. first page of a space. The space for this header is reserved in every extent
  87. descriptor page, but used only in the first. */
  88. /*-------------------------------------*/
  89. #define FSP_SPACE_ID 0 /* space id */
  90. #define FSP_NOT_USED 4 /* this field contained a value up to
  91. which we know that the modifications
  92. in the database have been flushed to
  93. the file space; not used now */
  94. #define FSP_SIZE 8 /* Current size of the space in
  95. pages */
  96. #define FSP_FREE_LIMIT 12 /* Minimum page number for which the
  97. free list has not been initialized:
  98. the pages >= this limit are, by
  99. definition, free; note that in a
  100. single-table tablespace where size
  101. < 64 pages, this number is 64, i.e.,
  102. we have initialized the space
  103. about the first extent, but have not
  104. physically allocated those pages to the
  105. file */
  106. #define FSP_SPACE_FLAGS 16 /* fsp_space_t.flags, similar to
  107. dict_table_t::flags */
  108. #define FSP_FRAG_N_USED 20 /* number of used pages in the
  109. FSP_FREE_FRAG list */
  110. #define FSP_FREE 24 /* list of free extents */
  111. #define FSP_FREE_FRAG (24 + FLST_BASE_NODE_SIZE)
  112. /* list of partially free extents not
  113. belonging to any segment */
  114. #define FSP_FULL_FRAG (24 + 2 * FLST_BASE_NODE_SIZE)
  115. /* list of full extents not belonging
  116. to any segment */
  117. #define FSP_SEG_ID (24 + 3 * FLST_BASE_NODE_SIZE)
  118. /* 8 bytes which give the first unused
  119. segment id */
  120. #define FSP_SEG_INODES_FULL (32 + 3 * FLST_BASE_NODE_SIZE)
  121. /* list of pages containing segment
  122. headers, where all the segment inode
  123. slots are reserved */
  124. #define FSP_SEG_INODES_FREE (32 + 4 * FLST_BASE_NODE_SIZE)
  125. /* list of pages containing segment
  126. headers, where not all the segment
  127. header slots are reserved */
  128. /*-------------------------------------*/
  129. /* File space header size */
  130. #define FSP_HEADER_SIZE (32 + 5 * FLST_BASE_NODE_SIZE)
  131. #define FSP_FREE_ADD 4 /* this many free extents are added
  132. to the free list from above
  133. FSP_FREE_LIMIT at a time */
  134. /* @} */
  135. /* @defgroup File Segment Inode Constants (moved from fsp0fsp.c) @{ */
  136. /* FILE SEGMENT INODE
  137. ==================
  138. Segment inode which is created for each segment in a tablespace. NOTE: in
  139. purge we assume that a segment having only one currently used page can be
  140. freed in a few steps, so that the freeing cannot fill the file buffer with
  141. bufferfixed file pages. */
  142. typedef byte fseg_inode_t;
  143. #define FSEG_INODE_PAGE_NODE FSEG_PAGE_DATA
  144. /* the list node for linking
  145. segment inode pages */
  146. #define FSEG_ARR_OFFSET (FSEG_PAGE_DATA + FLST_NODE_SIZE)
  147. /*-------------------------------------*/
  148. #define FSEG_ID 0 /* 8 bytes of segment id: if this is 0,
  149. it means that the header is unused */
  150. #define FSEG_NOT_FULL_N_USED 8
  151. /* number of used segment pages in
  152. the FSEG_NOT_FULL list */
  153. #define FSEG_FREE 12
  154. /* list of free extents of this
  155. segment */
  156. #define FSEG_NOT_FULL (12 + FLST_BASE_NODE_SIZE)
  157. /* list of partially free extents */
  158. #define FSEG_FULL (12 + 2 * FLST_BASE_NODE_SIZE)
  159. /* list of full extents */
  160. #define FSEG_MAGIC_N (12 + 3 * FLST_BASE_NODE_SIZE)
  161. /* magic number used in debugging */
  162. #define FSEG_FRAG_ARR (16 + 3 * FLST_BASE_NODE_SIZE)
  163. /* array of individual pages
  164. belonging to this segment in fsp
  165. fragment extent lists */
  166. #define FSEG_FRAG_ARR_N_SLOTS (FSP_EXTENT_SIZE / 2)
  167. /* number of slots in the array for
  168. the fragment pages */
  169. #define FSEG_FRAG_SLOT_SIZE 4 /* a fragment page slot contains its
  170. page number within space, FIL_NULL
  171. means that the slot is not in use */
  172. /*-------------------------------------*/
  173. #define FSEG_INODE_SIZE \
  174. (16 + 3 * FLST_BASE_NODE_SIZE \
  175. + FSEG_FRAG_ARR_N_SLOTS * FSEG_FRAG_SLOT_SIZE)
  176. #define FSP_SEG_INODES_PER_PAGE(page_size) \
  177. ((page_size.physical() - FSEG_ARR_OFFSET - 10) / FSEG_INODE_SIZE)
  178. /* Number of segment inodes which fit on a
  179. single page */
  180. #define FSEG_MAGIC_N_VALUE 97937874
  181. #define FSEG_FILLFACTOR 8 /* If this value is x, then if
  182. the number of unused but reserved
  183. pages in a segment is less than
  184. reserved pages * 1/x, and there are
  185. at least FSEG_FRAG_LIMIT used pages,
  186. then we allow a new empty extent to
  187. be added to the segment in
  188. fseg_alloc_free_page. Otherwise, we
  189. use unused pages of the segment. */
  190. #define FSEG_FRAG_LIMIT FSEG_FRAG_ARR_N_SLOTS
  191. /* If the segment has >= this many
  192. used pages, it may be expanded by
  193. allocating extents to the segment;
  194. until that only individual fragment
  195. pages are allocated from the space */
  196. #define FSEG_FREE_LIST_LIMIT 40 /* If the reserved size of a segment
  197. is at least this many extents, we
  198. allow extents to be put to the free
  199. list of the extent: at most
  200. FSEG_FREE_LIST_MAX_LEN many */
  201. #define FSEG_FREE_LIST_MAX_LEN 4
  202. /* @} */
  203. /* @defgroup Extent Descriptor Constants (moved from fsp0fsp.c) @{ */
  204. /* EXTENT DESCRIPTOR
  205. =================
  206. File extent descriptor data structure: contains bits to tell which pages in
  207. the extent are free and which contain old tuple version to clean. */
  208. /*-------------------------------------*/
  209. #define XDES_ID 0 /* The identifier of the segment
  210. to which this extent belongs */
  211. #define XDES_FLST_NODE 8 /* The list node data structure
  212. for the descriptors */
  213. #define XDES_STATE (FLST_NODE_SIZE + 8)
  214. /* contains state information
  215. of the extent */
  216. #define XDES_BITMAP (FLST_NODE_SIZE + 12)
  217. /* Descriptor bitmap of the pages
  218. in the extent */
  219. /*-------------------------------------*/
  220. #define XDES_BITS_PER_PAGE 2 /* How many bits are there per page */
  221. #define XDES_FREE_BIT 0 /* Index of the bit which tells if
  222. the page is free */
  223. #define XDES_CLEAN_BIT 1 /* NOTE: currently not used!
  224. Index of the bit which tells if
  225. there are old versions of tuples
  226. on the page */
  227. /* States of a descriptor */
  228. #define XDES_FREE 1 /* extent is in free list of space */
  229. #define XDES_FREE_FRAG 2 /* extent is in free fragment list of
  230. space */
  231. #define XDES_FULL_FRAG 3 /* extent is in full fragment list of
  232. space */
  233. #define XDES_FSEG 4 /* extent belongs to a segment */
  234. /** File extent data structure size in bytes. */
  235. #define XDES_SIZE \
  236. (XDES_BITMAP \
  237. + UT_BITS_IN_BYTES(FSP_EXTENT_SIZE * XDES_BITS_PER_PAGE))
  238. /** File extent data structure size in bytes for MAX page size. */
  239. #define XDES_SIZE_MAX \
  240. (XDES_BITMAP \
  241. + UT_BITS_IN_BYTES(FSP_EXTENT_SIZE_MAX * XDES_BITS_PER_PAGE))
  242. /** File extent data structure size in bytes for MIN page size. */
  243. #define XDES_SIZE_MIN \
  244. (XDES_BITMAP \
  245. + UT_BITS_IN_BYTES(FSP_EXTENT_SIZE_MIN * XDES_BITS_PER_PAGE))
  246. /** Offset of the descriptor array on a descriptor page */
  247. #define XDES_ARR_OFFSET (FSP_HEADER_OFFSET + FSP_HEADER_SIZE)
  248. #ifndef UNIV_INNOCHECKSUM
  249. /* @} */
  250. /**********************************************************************//**
  251. Gets the size of the system tablespace from the tablespace header. If
  252. we do not have an auto-extending data file, this should be equal to
  253. the size of the data files. If there is an auto-extending data file,
  254. this can be smaller.
  255. @return size in pages */
  256. ulint
  257. fsp_header_get_tablespace_size(void);
  258. /*================================*/
  259. /** Calculate the number of pages to extend a datafile.
  260. We extend single-table tablespaces first one extent at a time,
  261. but 4 at a time for bigger tablespaces. It is not enough to extend always
  262. by one extent, because we need to add at least one extent to FSP_FREE.
  263. A single extent descriptor page will track many extents. And the extent
  264. that uses its extent descriptor page is put onto the FSP_FREE_FRAG list.
  265. Extents that do not use their extent descriptor page are added to FSP_FREE.
  266. The physical page size is used to determine how many extents are tracked
  267. on one extent descriptor page. See xdes_calc_descriptor_page().
  268. @param[in] page_size page_size of the datafile
  269. @param[in] size current number of pages in the datafile
  270. @return number of pages to extend the file. */
  271. ulint
  272. fsp_get_pages_to_extend_ibd(
  273. const page_size_t& page_size,
  274. ulint size);
  275. /** Calculate the number of physical pages in an extent for this file.
  276. @param[in] page_size page_size of the datafile
  277. @return number of pages in an extent for this file. */
  278. UNIV_INLINE
  279. ulint
  280. fsp_get_extent_size_in_pages(const page_size_t& page_size)
  281. {
  282. return(FSP_EXTENT_SIZE * UNIV_PAGE_SIZE / page_size.physical());
  283. }
  284. /**********************************************************************//**
  285. Reads the space id from the first page of a tablespace.
  286. @return space id, ULINT UNDEFINED if error */
  287. ulint
  288. fsp_header_get_space_id(
  289. /*====================*/
  290. const page_t* page); /*!< in: first page of a tablespace */
  291. /** Read a tablespace header field.
  292. @param[in] page first page of a tablespace
  293. @param[in] field the header field
  294. @return the contents of the header field */
  295. inline
  296. ulint
  297. fsp_header_get_field(const page_t* page, ulint field)
  298. {
  299. return(mach_read_from_4(FSP_HEADER_OFFSET + field + page));
  300. }
  301. /** Read the flags from the tablespace header page.
  302. @param[in] page first page of a tablespace
  303. @return the contents of FSP_SPACE_FLAGS */
  304. inline
  305. ulint
  306. fsp_header_get_flags(const page_t* page)
  307. {
  308. return(fsp_header_get_field(page, FSP_SPACE_FLAGS));
  309. }
  310. /** Get the byte offset of encryption information in page 0.
  311. @param[in] ps page size
  312. @return byte offset relative to FSP_HEADER_OFFSET */
  313. inline MY_ATTRIBUTE((pure, warn_unused_result))
  314. ulint
  315. fsp_header_get_encryption_offset(const page_size_t& ps)
  316. {
  317. return XDES_ARR_OFFSET + XDES_SIZE * ps.physical() / FSP_EXTENT_SIZE;
  318. }
  319. /** Check the encryption key from the first page of a tablespace.
  320. @param[in] fsp_flags tablespace flags
  321. @param[in] page first page of a tablespace
  322. @return true if success */
  323. bool
  324. fsp_header_check_encryption_key(
  325. ulint fsp_flags,
  326. page_t* page);
  327. /**********************************************************************//**
  328. Writes the space id and flags to a tablespace header. The flags contain
  329. row type, physical/compressed page size, and logical/uncompressed page
  330. size of the tablespace. */
  331. void
  332. fsp_header_init_fields(
  333. /*===================*/
  334. page_t* page, /*!< in/out: first page in the space */
  335. ulint space_id, /*!< in: space id */
  336. ulint flags); /*!< in: tablespace flags (FSP_SPACE_FLAGS):
  337. 0, or table->flags if newer than COMPACT */
  338. /** Initialize a tablespace header.
  339. @param[in] space_id space id
  340. @param[in] size current size in blocks
  341. @param[in,out] mtr mini-transaction */
  342. void
  343. fsp_header_init(ulint space_id, ulint size, mtr_t* mtr);
  344. /**********************************************************************//**
  345. Increases the space size field of a space. */
  346. void
  347. fsp_header_inc_size(
  348. /*================*/
  349. ulint space_id, /*!< in: space id */
  350. ulint size_inc, /*!< in: size increment in pages */
  351. mtr_t* mtr); /*!< in/out: mini-transaction */
  352. /**********************************************************************//**
  353. Creates a new segment.
  354. @return the block where the segment header is placed, x-latched, NULL
  355. if could not create segment because of lack of space */
  356. buf_block_t*
  357. fseg_create(
  358. /*========*/
  359. ulint space_id,/*!< in: space id */
  360. ulint page, /*!< in: page where the segment header is placed: if
  361. this is != 0, the page must belong to another segment,
  362. if this is 0, a new page will be allocated and it
  363. will belong to the created segment */
  364. ulint byte_offset, /*!< in: byte offset of the created segment header
  365. on the page */
  366. mtr_t* mtr); /*!< in/out: mini-transaction */
  367. /**********************************************************************//**
  368. Creates a new segment.
  369. @return the block where the segment header is placed, x-latched, NULL
  370. if could not create segment because of lack of space */
  371. buf_block_t*
  372. fseg_create_general(
  373. /*================*/
  374. ulint space_id,/*!< in: space id */
  375. ulint page, /*!< in: page where the segment header is placed: if
  376. this is != 0, the page must belong to another segment,
  377. if this is 0, a new page will be allocated and it
  378. will belong to the created segment */
  379. ulint byte_offset, /*!< in: byte offset of the created segment header
  380. on the page */
  381. ibool has_done_reservation, /*!< in: TRUE if the caller has already
  382. done the reservation for the pages with
  383. fsp_reserve_free_extents (at least 2 extents: one for
  384. the inode and the other for the segment) then there is
  385. no need to do the check for this individual
  386. operation */
  387. mtr_t* mtr); /*!< in/out: mini-transaction */
  388. /**********************************************************************//**
  389. Calculates the number of pages reserved by a segment, and how many pages are
  390. currently used.
  391. @return number of reserved pages */
  392. ulint
  393. fseg_n_reserved_pages(
  394. /*==================*/
  395. fseg_header_t* header, /*!< in: segment header */
  396. ulint* used, /*!< out: number of pages used (<= reserved) */
  397. mtr_t* mtr); /*!< in/out: mini-transaction */
  398. /**********************************************************************//**
  399. Allocates a single free page from a segment. This function implements
  400. the intelligent allocation strategy which tries to minimize
  401. file space fragmentation.
  402. @param[in,out] seg_header segment header
  403. @param[in] hint hint of which page would be desirable
  404. @param[in] direction if the new page is needed because
  405. of an index page split, and records are
  406. inserted there in order, into which
  407. direction they go alphabetically: FSP_DOWN,
  408. FSP_UP, FSP_NO_DIR
  409. @param[in,out] mtr mini-transaction
  410. @return X-latched block, or NULL if no page could be allocated */
  411. #define fseg_alloc_free_page(seg_header, hint, direction, mtr) \
  412. fseg_alloc_free_page_general(seg_header, hint, direction, \
  413. FALSE, mtr, mtr)
  414. /**********************************************************************//**
  415. Allocates a single free page from a segment. This function implements
  416. the intelligent allocation strategy which tries to minimize file space
  417. fragmentation.
  418. @retval NULL if no page could be allocated
  419. @retval block, rw_lock_x_lock_count(&block->lock) == 1 if allocation succeeded
  420. (init_mtr == mtr, or the page was not previously freed in mtr)
  421. @retval block (not allocated or initialized) otherwise */
  422. buf_block_t*
  423. fseg_alloc_free_page_general(
  424. /*=========================*/
  425. fseg_header_t* seg_header,/*!< in/out: segment header */
  426. ulint hint, /*!< in: hint of which page would be
  427. desirable */
  428. byte direction,/*!< in: if the new page is needed because
  429. of an index page split, and records are
  430. inserted there in order, into which
  431. direction they go alphabetically: FSP_DOWN,
  432. FSP_UP, FSP_NO_DIR */
  433. ibool has_done_reservation, /*!< in: TRUE if the caller has
  434. already done the reservation for the page
  435. with fsp_reserve_free_extents, then there
  436. is no need to do the check for this individual
  437. page */
  438. mtr_t* mtr, /*!< in/out: mini-transaction */
  439. mtr_t* init_mtr)/*!< in/out: mtr or another mini-transaction
  440. in which the page should be initialized.
  441. If init_mtr!=mtr, but the page is already
  442. latched in mtr, do not initialize the page. */
  443. MY_ATTRIBUTE((warn_unused_result, nonnull));
  444. /** Reserves free pages from a tablespace. All mini-transactions which may
  445. use several pages from the tablespace should call this function beforehand
  446. and reserve enough free extents so that they certainly will be able
  447. to do their operation, like a B-tree page split, fully. Reservations
  448. must be released with function fil_space_release_free_extents!
  449. The alloc_type below has the following meaning: FSP_NORMAL means an
  450. operation which will probably result in more space usage, like an
  451. insert in a B-tree; FSP_UNDO means allocation to undo logs: if we are
  452. deleting rows, then this allocation will in the long run result in
  453. less space usage (after a purge); FSP_CLEANING means allocation done
  454. in a physical record delete (like in a purge) or other cleaning operation
  455. which will result in less space usage in the long run. We prefer the latter
  456. two types of allocation: when space is scarce, FSP_NORMAL allocations
  457. will not succeed, but the latter two allocations will succeed, if possible.
  458. The purpose is to avoid dead end where the database is full but the
  459. user cannot free any space because these freeing operations temporarily
  460. reserve some space.
  461. Single-table tablespaces whose size is < FSP_EXTENT_SIZE pages are a special
  462. case. In this function we would liberally reserve several extents for
  463. every page split or merge in a B-tree. But we do not want to waste disk space
  464. if the table only occupies < FSP_EXTENT_SIZE pages. That is why we apply
  465. different rules in that special case, just ensuring that there are n_pages
  466. free pages available.
  467. @param[out] n_reserved number of extents actually reserved; if we
  468. return true and the tablespace size is <
  469. FSP_EXTENT_SIZE pages, then this can be 0,
  470. otherwise it is n_ext
  471. @param[in] space_id tablespace identifier
  472. @param[in] n_ext number of extents to reserve
  473. @param[in] alloc_type page reservation type (FSP_BLOB, etc)
  474. @param[in,out] mtr the mini transaction
  475. @param[in] n_pages for small tablespaces (tablespace size is
  476. less than FSP_EXTENT_SIZE), number of free
  477. pages to reserve.
  478. @return true if we were able to make the reservation */
  479. bool
  480. fsp_reserve_free_extents(
  481. ulint* n_reserved,
  482. ulint space_id,
  483. ulint n_ext,
  484. fsp_reserve_t alloc_type,
  485. mtr_t* mtr,
  486. ulint n_pages = 2);
  487. /** Calculate how many KiB of new data we will be able to insert to the
  488. tablespace without running out of space.
  489. @param[in] space_id tablespace ID
  490. @return available space in KiB
  491. @retval UINTMAX_MAX if unknown */
  492. uintmax_t
  493. fsp_get_available_space_in_free_extents(
  494. ulint space_id);
  495. /** Calculate how many KiB of new data we will be able to insert to the
  496. tablespace without running out of space. Start with a space object that has
  497. been acquired by the caller who holds it for the calculation,
  498. @param[in] space tablespace object from fil_space_acquire()
  499. @return available space in KiB */
  500. uintmax_t
  501. fsp_get_available_space_in_free_extents(
  502. const fil_space_t* space);
  503. /**********************************************************************//**
  504. Frees a single page of a segment. */
  505. void
  506. fseg_free_page_func(
  507. fseg_header_t* seg_header, /*!< in: segment header */
  508. ulint space_id, /*!< in: space id */
  509. ulint page, /*!< in: page offset */
  510. #ifdef BTR_CUR_HASH_ADAPT
  511. bool ahi, /*!< in: whether we may need to drop
  512. the adaptive hash index */
  513. #endif /* BTR_CUR_HASH_ADAPT */
  514. mtr_t* mtr); /*!< in/out: mini-transaction */
  515. #ifdef BTR_CUR_HASH_ADAPT
  516. # define fseg_free_page(header, space_id, page, ahi, mtr) \
  517. fseg_free_page_func(header, space_id, page, ahi, mtr)
  518. #else /* BTR_CUR_HASH_ADAPT */
  519. # define fseg_free_page(header, space_id, page, ahi, mtr) \
  520. fseg_free_page_func(header, space_id, page, mtr)
  521. #endif /* BTR_CUR_HASH_ADAPT */
  522. /** Determine whether a page is free.
  523. @param[in,out] space tablespace
  524. @param[in] page page number
  525. @return whether the page is marked as free */
  526. bool
  527. fseg_page_is_free(fil_space_t* space, unsigned page)
  528. MY_ATTRIBUTE((nonnull, warn_unused_result));
  529. /**********************************************************************//**
  530. Frees part of a segment. This function can be used to free a segment
  531. by repeatedly calling this function in different mini-transactions.
  532. Doing the freeing in a single mini-transaction might result in
  533. too big a mini-transaction.
  534. @return TRUE if freeing completed */
  535. ibool
  536. fseg_free_step_func(
  537. fseg_header_t* header, /*!< in, own: segment header; NOTE: if the header
  538. resides on the first page of the frag list
  539. of the segment, this pointer becomes obsolete
  540. after the last freeing step */
  541. #ifdef BTR_CUR_HASH_ADAPT
  542. bool ahi, /*!< in: whether we may need to drop
  543. the adaptive hash index */
  544. #endif /* BTR_CUR_HASH_ADAPT */
  545. mtr_t* mtr) /*!< in/out: mini-transaction */
  546. MY_ATTRIBUTE((warn_unused_result));
  547. #ifdef BTR_CUR_HASH_ADAPT
  548. # define fseg_free_step(header, ahi, mtr) fseg_free_step_func(header, ahi, mtr)
  549. #else /* BTR_CUR_HASH_ADAPT */
  550. # define fseg_free_step(header, ahi, mtr) fseg_free_step_func(header, mtr)
  551. #endif /* BTR_CUR_HASH_ADAPT */
  552. /**********************************************************************//**
  553. Frees part of a segment. Differs from fseg_free_step because this function
  554. leaves the header page unfreed.
  555. @return TRUE if freeing completed, except the header page */
  556. ibool
  557. fseg_free_step_not_header_func(
  558. fseg_header_t* header, /*!< in: segment header which must reside on
  559. the first fragment page of the segment */
  560. #ifdef BTR_CUR_HASH_ADAPT
  561. bool ahi, /*!< in: whether we may need to drop
  562. the adaptive hash index */
  563. #endif /* BTR_CUR_HASH_ADAPT */
  564. mtr_t* mtr) /*!< in/out: mini-transaction */
  565. MY_ATTRIBUTE((warn_unused_result));
  566. #ifdef BTR_CUR_HASH_ADAPT
  567. # define fseg_free_step_not_header(header, ahi, mtr) \
  568. fseg_free_step_not_header_func(header, ahi, mtr)
  569. #else /* BTR_CUR_HASH_ADAPT */
  570. # define fseg_free_step_not_header(header, ahi, mtr) \
  571. fseg_free_step_not_header_func(header, mtr)
  572. #endif /* BTR_CUR_HASH_ADAPT */
  573. /** Checks if a page address is an extent descriptor page address.
  574. @param[in] page_id page id
  575. @param[in] page_size page size
  576. @return TRUE if a descriptor page */
  577. UNIV_INLINE
  578. ibool
  579. fsp_descr_page(
  580. const page_id_t& page_id,
  581. const page_size_t& page_size);
  582. /***********************************************************//**
  583. Parses a redo log record of a file page init.
  584. @return end of log record or NULL */
  585. byte*
  586. fsp_parse_init_file_page(
  587. /*=====================*/
  588. byte* ptr, /*!< in: buffer */
  589. byte* end_ptr, /*!< in: buffer end */
  590. buf_block_t* block); /*!< in: block or NULL */
  591. #ifdef UNIV_BTR_PRINT
  592. /*******************************************************************//**
  593. Writes info of a segment. */
  594. void
  595. fseg_print(
  596. /*=======*/
  597. fseg_header_t* header, /*!< in: segment header */
  598. mtr_t* mtr); /*!< in/out: mini-transaction */
  599. #endif /* UNIV_BTR_PRINT */
  600. /** Convert FSP_SPACE_FLAGS from the buggy MariaDB 10.1.0..10.1.20 format.
  601. @param[in] flags the contents of FSP_SPACE_FLAGS
  602. @return the flags corrected from the buggy MariaDB 10.1 format
  603. @retval ULINT_UNDEFINED if the flags are not in the buggy 10.1 format */
  604. MY_ATTRIBUTE((warn_unused_result, const))
  605. UNIV_INLINE
  606. ulint
  607. fsp_flags_convert_from_101(ulint flags)
  608. {
  609. DBUG_EXECUTE_IF("fsp_flags_is_valid_failure",
  610. return(ULINT_UNDEFINED););
  611. if (flags == 0) {
  612. return(flags);
  613. }
  614. if (flags >> 18) {
  615. /* The most significant FSP_SPACE_FLAGS bit that was ever set
  616. by MariaDB 10.1.0 to 10.1.20 was bit 17 (misplaced DATA_DIR flag).
  617. The flags must be less than 1<<18 in order to be valid. */
  618. return(ULINT_UNDEFINED);
  619. }
  620. if ((flags & (FSP_FLAGS_MASK_POST_ANTELOPE | FSP_FLAGS_MASK_ATOMIC_BLOBS))
  621. == FSP_FLAGS_MASK_ATOMIC_BLOBS) {
  622. /* If the "atomic blobs" flag (indicating
  623. ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED) flag
  624. is set, then the "post Antelope" (ROW_FORMAT!=REDUNDANT) flag
  625. must also be set. */
  626. return(ULINT_UNDEFINED);
  627. }
  628. /* Bits 6..10 denote compression in MariaDB 10.1.0 to 10.1.20.
  629. They must be either 0b00000 or 0b00011 through 0b10011.
  630. In correct versions, these bits would be
  631. 0bd0sss where d is the DATA_DIR flag (garbage bit) and
  632. sss is the PAGE_SSIZE (3, 4, 6, or 7).
  633. NOTE: MariaDB 10.1.0 to 10.1.20 can misinterpret
  634. uncompressed data files with innodb_page_size=4k or 64k as
  635. compressed innodb_page_size=16k files. Below is an exhaustive
  636. state space analysis.
  637. -0by1zzz: impossible (the bit 4 must be clean; see above)
  638. -0b101xx: DATA_DIR, innodb_page_size>4k: invalid (COMPRESSION_LEVEL>9)
  639. +0bx0011: innodb_page_size=4k:
  640. !!! Misinterpreted as COMPRESSION_LEVEL=9 or 1, COMPRESSION=1.
  641. -0bx0010: impossible, because sss must be 0b011 or 0b1xx
  642. -0bx0001: impossible, because sss must be 0b011 or 0b1xx
  643. -0b10000: DATA_DIR, innodb_page_size=16:
  644. invalid (COMPRESSION_LEVEL=8 but COMPRESSION=0)
  645. +0b00111: no DATA_DIR, innodb_page_size=64k:
  646. !!! Misinterpreted as COMPRESSION_LEVEL=3, COMPRESSION=1.
  647. -0b00101: impossible, because sss must be 0 for 16k, not 0b101
  648. -0b001x0: no DATA_DIR, innodb_page_size=32k or 8k:
  649. invalid (COMPRESSION_LEVEL=3 but COMPRESSION=0)
  650. +0b00000: innodb_page_size=16k (looks like COMPRESSION=0)
  651. ??? Could actually be compressed; see PAGE_SSIZE below */
  652. const ulint level = FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL_MARIADB101(
  653. flags);
  654. if (FSP_FLAGS_GET_PAGE_COMPRESSION_MARIADB101(flags) != (level != 0)
  655. || level > 9) {
  656. /* The compression flags are not in the buggy MariaDB
  657. 10.1 format. */
  658. return(ULINT_UNDEFINED);
  659. }
  660. if (!(~flags & FSP_FLAGS_MASK_ATOMIC_WRITES_MARIADB101)) {
  661. /* The ATOMIC_WRITES flags cannot be 0b11.
  662. (The bits 11..12 should actually never be 0b11,
  663. because in MySQL they would be SHARED|TEMPORARY.) */
  664. return(ULINT_UNDEFINED);
  665. }
  666. /* Bits 13..16 are the wrong position for PAGE_SSIZE, and they
  667. should contain one of the values 3,4,6,7, that is, be of the form
  668. 0b0011 or 0b01xx (except 0b0110).
  669. In correct versions, these bits should be 0bc0se
  670. where c is the MariaDB COMPRESSED flag
  671. and e is the MySQL 5.7 ENCRYPTION flag
  672. and s is the MySQL 8.0 SDI flag. MariaDB can only support s=0, e=0.
  673. Compressed innodb_page_size=16k tables with correct FSP_SPACE_FLAGS
  674. will be properly rejected by older MariaDB 10.1.x because they
  675. would read as PAGE_SSIZE>=8 which is not valid. */
  676. const ulint ssize = FSP_FLAGS_GET_PAGE_SSIZE_MARIADB101(flags);
  677. if (ssize == 1 || ssize == 2 || ssize == 5 || ssize & 8) {
  678. /* the page_size is not between 4k and 64k;
  679. 16k should be encoded as 0, not 5 */
  680. return(ULINT_UNDEFINED);
  681. }
  682. const ulint zssize = FSP_FLAGS_GET_ZIP_SSIZE(flags);
  683. if (zssize == 0) {
  684. /* not ROW_FORMAT=COMPRESSED */
  685. } else if (zssize > (ssize ? ssize : 5)) {
  686. /* invalid KEY_BLOCK_SIZE */
  687. return(ULINT_UNDEFINED);
  688. } else if (~flags & (FSP_FLAGS_MASK_POST_ANTELOPE
  689. | FSP_FLAGS_MASK_ATOMIC_BLOBS)) {
  690. /* both these flags should be set for
  691. ROW_FORMAT=COMPRESSED */
  692. return(ULINT_UNDEFINED);
  693. }
  694. flags = ((flags & 0x3f) | ssize << FSP_FLAGS_POS_PAGE_SSIZE
  695. | FSP_FLAGS_GET_PAGE_COMPRESSION_MARIADB101(flags)
  696. << FSP_FLAGS_POS_PAGE_COMPRESSION);
  697. ut_ad(fsp_flags_is_valid(flags, false));
  698. return(flags);
  699. }
  700. /** Compare tablespace flags.
  701. @param[in] expected expected flags from dict_tf_to_fsp_flags()
  702. @param[in] actual flags read from FSP_SPACE_FLAGS
  703. @return whether the flags match */
  704. MY_ATTRIBUTE((warn_unused_result))
  705. UNIV_INLINE
  706. bool
  707. fsp_flags_match(ulint expected, ulint actual)
  708. {
  709. expected &= ~FSP_FLAGS_MEM_MASK;
  710. ut_ad(fsp_flags_is_valid(expected, false));
  711. if (actual == expected) {
  712. return(true);
  713. }
  714. actual = fsp_flags_convert_from_101(actual);
  715. return(actual == expected);
  716. }
  717. /** Calculates the descriptor index within a descriptor page.
  718. @param[in] page_size page size
  719. @param[in] offset page offset
  720. @return descriptor index */
  721. UNIV_INLINE
  722. ulint
  723. xdes_calc_descriptor_index(
  724. const page_size_t& page_size,
  725. ulint offset);
  726. /**********************************************************************//**
  727. Gets a descriptor bit of a page.
  728. @return TRUE if free */
  729. UNIV_INLINE
  730. ibool
  731. xdes_get_bit(
  732. /*=========*/
  733. const xdes_t* descr, /*!< in: descriptor */
  734. ulint bit, /*!< in: XDES_FREE_BIT or XDES_CLEAN_BIT */
  735. ulint offset);/*!< in: page offset within extent:
  736. 0 ... FSP_EXTENT_SIZE - 1 */
  737. /** Calculates the page where the descriptor of a page resides.
  738. @param[in] page_size page size
  739. @param[in] offset page offset
  740. @return descriptor page offset */
  741. UNIV_INLINE
  742. ulint
  743. xdes_calc_descriptor_page(
  744. const page_size_t& page_size,
  745. ulint offset);
  746. #endif /* UNIV_INNOCHECKSUM */
  747. #include "fsp0fsp.ic"
  748. #endif