mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 20:42:30 +01:00
Follow-up fix to MDEV-12026: FIL_SPACE_FLAGS trump fil_space_t::flags
Whenever we are reading the first page of a data file, we may have to adjust the provisionally created fil_space_t::flags to match what is actually inside the data files. In this way, we will never accidentally change the format of a data file. fil_node_t::read_page0(): After validating the FIL_SPACE_FLAGS, always assign them to space->flags. btr_root_adjust_on_import(), Datafile::validate_to_dd(), fil_space_for_table_exists_in_mem(): Adapt to the fix in fil_node_t::read_page0(). fsp_flags_try_adjust(): Skip the adjustment if full_crc32 is being used. This adjustment was introduced in MDEV-11623 for upgrading from MariaDB 10.1.0 to 10.1.20, which used an accidentally changed format of FIL_SPACE_FLAGS. MariaDB before 10.4.3 never set the flag that now indicates the full_crc32 format.
This commit is contained in:
parent
9c7299365f
commit
2151aed44d
3 changed files with 39 additions and 14 deletions
|
@ -392,9 +392,21 @@ btr_root_adjust_on_import(
|
|||
} else {
|
||||
/* Check that the table flags and the tablespace
|
||||
flags match. */
|
||||
err = (dict_tf_to_fsp_flags(table->flags)
|
||||
== table->space->flags)
|
||||
? DB_SUCCESS : DB_CORRUPTION;
|
||||
ulint tf = dict_tf_to_fsp_flags(table->flags);
|
||||
ulint sf = table->space->flags;
|
||||
sf &= ~FSP_FLAGS_MEM_MASK;
|
||||
tf &= ~FSP_FLAGS_MEM_MASK;
|
||||
if (fil_space_t::is_flags_equal(tf, sf)
|
||||
|| fil_space_t::is_flags_equal(sf, tf)) {
|
||||
mutex_enter(&fil_system.mutex);
|
||||
table->space->flags = (table->space->flags
|
||||
& ~FSP_FLAGS_MEM_MASK)
|
||||
| (tf & FSP_FLAGS_MEM_MASK);
|
||||
mutex_exit(&fil_system.mutex);
|
||||
err = DB_SUCCESS;
|
||||
} else {
|
||||
err = DB_CORRUPTION;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
err = DB_SUCCESS;
|
||||
|
|
|
@ -507,8 +507,8 @@ bool fil_node_t::read_page0(bool first)
|
|||
+ page);
|
||||
if (!fil_space_t::is_valid_flags(flags, space->id)) {
|
||||
ulint cflags = fsp_flags_convert_from_101(flags);
|
||||
if (cflags == ULINT_UNDEFINED
|
||||
|| (cflags ^ space->flags) & ~FSP_FLAGS_MEM_MASK) {
|
||||
if (cflags == ULINT_UNDEFINED) {
|
||||
invalid:
|
||||
ib::error()
|
||||
<< "Expected tablespace flags "
|
||||
<< ib::hex(space->flags)
|
||||
|
@ -518,9 +518,19 @@ bool fil_node_t::read_page0(bool first)
|
|||
return false;
|
||||
}
|
||||
|
||||
ulint cf = cflags & ~FSP_FLAGS_MEM_MASK;
|
||||
ulint sf = space->flags & ~FSP_FLAGS_MEM_MASK;
|
||||
|
||||
if (!fil_space_t::is_flags_equal(cf, sf)
|
||||
&& !fil_space_t::is_flags_equal(sf, cf)) {
|
||||
goto invalid;
|
||||
}
|
||||
|
||||
flags = cflags;
|
||||
}
|
||||
|
||||
ut_ad(!(flags & FSP_FLAGS_MEM_MASK));
|
||||
|
||||
/* Try to read crypt_data from page 0 if it is not yet read. */
|
||||
if (!space->crypt_data) {
|
||||
space->crypt_data = fil_space_read_crypt_data(
|
||||
|
@ -552,10 +562,7 @@ bool fil_node_t::read_page0(bool first)
|
|||
size_bytes &= ~os_offset_t(mask);
|
||||
}
|
||||
|
||||
if (space->flags != flags
|
||||
&& fil_space_t::is_flags_equal(flags, space->flags)) {
|
||||
space->flags = flags;
|
||||
}
|
||||
space->flags = (space->flags & FSP_FLAGS_MEM_MASK) | flags;
|
||||
|
||||
this->size = ulint(size_bytes / psize);
|
||||
space->size += this->size;
|
||||
|
@ -3887,7 +3894,7 @@ void fsp_flags_try_adjust(fil_space_t* space, ulint flags)
|
|||
{
|
||||
ut_ad(!srv_read_only_mode);
|
||||
ut_ad(fil_space_t::is_valid_flags(flags, space->id));
|
||||
if (space->full_crc32()) {
|
||||
if (space->full_crc32() || fil_space_t::full_crc32(flags)) {
|
||||
return;
|
||||
}
|
||||
if (!space->size && (space->purpose != FIL_TYPE_TABLESPACE
|
||||
|
@ -3947,7 +3954,11 @@ fil_space_for_table_exists_in_mem(
|
|||
|
||||
mutex_enter(&fil_system.mutex);
|
||||
if (fil_space_t* space = fil_space_get_by_id(id)) {
|
||||
if ((space->flags ^ expected_flags) & ~FSP_FLAGS_MEM_MASK) {
|
||||
ulint tf = expected_flags & ~FSP_FLAGS_MEM_MASK;
|
||||
ulint sf = space->flags & ~FSP_FLAGS_MEM_MASK;
|
||||
|
||||
if (!fil_space_t::is_flags_equal(tf, sf)
|
||||
&& !fil_space_t::is_flags_equal(sf, tf)) {
|
||||
goto func_exit;
|
||||
}
|
||||
|
||||
|
@ -3963,7 +3974,8 @@ fil_space_for_table_exists_in_mem(
|
|||
|
||||
/* Adjust the flags that are in FSP_FLAGS_MEM_MASK.
|
||||
FSP_SPACE_FLAGS will not be written back here. */
|
||||
space->flags = expected_flags;
|
||||
space->flags = (space->flags & ~FSP_FLAGS_MEM_MASK)
|
||||
| (expected_flags & FSP_FLAGS_MEM_MASK);
|
||||
mutex_exit(&fil_system.mutex);
|
||||
if (!srv_read_only_mode) {
|
||||
fsp_flags_try_adjust(space, expected_flags
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
/*****************************************************************************
|
||||
|
||||
Copyright (c) 2013, 2016, Oracle and/or its affiliates. All Rights Reserved.
|
||||
Copyright (c) 2017, 2018, MariaDB Corporation.
|
||||
Copyright (c) 2017, 2019, MariaDB Corporation.
|
||||
|
||||
This program is free software; you can redistribute it and/or modify it under
|
||||
the terms of the GNU General Public License as published by the Free Software
|
||||
|
@ -409,7 +409,8 @@ Datafile::validate_to_dd(ulint space_id, ulint flags)
|
|||
If the datafile is a file-per-table tablespace then also match
|
||||
the row format and zip page size. */
|
||||
if (m_space_id == space_id
|
||||
&& fil_space_t::is_flags_equal(m_flags, flags)) {
|
||||
&& (fil_space_t::is_flags_equal(flags, m_flags)
|
||||
|| fil_space_t::is_flags_equal(m_flags, flags))) {
|
||||
/* Datafile matches the tablespace expected. */
|
||||
return(DB_SUCCESS);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue