mirror of
https://github.com/MariaDB/server.git
synced 2025-10-12 12:25:37 +03:00
MDEV-11369: Perform validation at IMPORT TABLESPACE
btr_cur_instant_root_init(): Check the "infimum" and "supremum" record strings already here, and not later in btr_cur_instant_root_init(). In this way, we can properly reject files from later versions where instant ALTER TABLE could support further operations that change the format of InnoDB clustered indexes.
This commit is contained in:
@@ -392,24 +392,28 @@ when loading a table definition.
|
||||
@return error code
|
||||
@retval DB_SUCCESS if no error occurred
|
||||
@retval DB_CORRUPTION if any corruption was noticed */
|
||||
static
|
||||
dberr_t
|
||||
btr_cur_instant_init_low(dict_index_t* index, mtr_t* mtr)
|
||||
static dberr_t btr_cur_instant_init_low(dict_index_t* index, mtr_t* mtr)
|
||||
{
|
||||
ut_ad(index->is_primary());
|
||||
ut_ad(index->n_core_null_bytes == dict_index_t::NO_CORE_NULL_BYTES);
|
||||
ut_ad(index->table->supports_instant());
|
||||
ut_ad(index->table->is_readable());
|
||||
|
||||
page_t* root = btr_root_get(index, mtr);
|
||||
|
||||
if (!root || btr_cur_instant_root_init(index, root)) {
|
||||
const fil_space_t* space = index->table->space;
|
||||
if (!space) {
|
||||
unreadable:
|
||||
ib::error() << "Table " << index->table->name
|
||||
<< " has an unreadable root page";
|
||||
index->table->corrupted = true;
|
||||
return DB_CORRUPTION;
|
||||
}
|
||||
|
||||
page_t* root = btr_root_get(index, mtr);
|
||||
|
||||
if (!root || btr_cur_instant_root_init(index, root)) {
|
||||
goto unreadable;
|
||||
}
|
||||
|
||||
ut_ad(index->n_core_null_bytes != dict_index_t::NO_CORE_NULL_BYTES);
|
||||
|
||||
if (fil_page_get_type(root) == FIL_PAGE_INDEX) {
|
||||
@@ -417,17 +421,6 @@ btr_cur_instant_init_low(dict_index_t* index, mtr_t* mtr)
|
||||
return DB_SUCCESS;
|
||||
}
|
||||
|
||||
/* In a later format, these fields in a FIL_PAGE_TYPE_INSTANT
|
||||
root page could be repurposed for something else. */
|
||||
if (memcmp(page_get_infimum_rec(root), "infimum", 8)
|
||||
|| memcmp(page_get_supremum_rec(root), "supremum", 8)) {
|
||||
incompatible:
|
||||
ib::error() << "Table " << index->table->name
|
||||
<< " contains unrecognizable instant ALTER metadata";
|
||||
index->table->corrupted = true;
|
||||
return DB_CORRUPTION;
|
||||
}
|
||||
|
||||
btr_cur_t cur;
|
||||
dberr_t err = btr_cur_open_at_index_side(true, index, BTR_SEARCH_LEAF,
|
||||
&cur, 0, mtr);
|
||||
@@ -466,7 +459,11 @@ incompatible:
|
||||
|
||||
if (info_bits != REC_INFO_MIN_REC_FLAG
|
||||
|| (comp && rec_get_status(rec) != REC_STATUS_COLUMNS_ADDED)) {
|
||||
goto incompatible;
|
||||
incompatible:
|
||||
ib::error() << "Table " << index->table->name
|
||||
<< " contains unrecognizable instant ALTER metadata";
|
||||
index->table->corrupted = true;
|
||||
return DB_CORRUPTION;
|
||||
}
|
||||
|
||||
/* Read the metadata. We can get here on server restart
|
||||
@@ -558,8 +555,7 @@ index root page.
|
||||
@param[in] index clustered index that is on its first access
|
||||
@param[in] page clustered index root page
|
||||
@return whether the page is corrupted */
|
||||
bool
|
||||
btr_cur_instant_root_init(dict_index_t* index, const page_t* page)
|
||||
bool btr_cur_instant_root_init(dict_index_t* index, const page_t* page)
|
||||
{
|
||||
ut_ad(page_is_root(page));
|
||||
ut_ad(!page_is_comp(page) == !dict_table_is_comp(index->table));
|
||||
@@ -590,7 +586,8 @@ btr_cur_instant_root_init(dict_index_t* index, const page_t* page)
|
||||
break;
|
||||
}
|
||||
|
||||
uint16_t n = page_get_instant(page);
|
||||
const uint16_t n = page_get_instant(page);
|
||||
|
||||
if (n < index->n_uniq + DATA_ROLL_PTR || n > index->n_fields) {
|
||||
/* The PRIMARY KEY (or hidden DB_ROW_ID) and
|
||||
DB_TRX_ID,DB_ROLL_PTR columns must always be present
|
||||
@@ -599,6 +596,14 @@ btr_cur_instant_root_init(dict_index_t* index, const page_t* page)
|
||||
dictionary. */
|
||||
return true;
|
||||
}
|
||||
|
||||
if (memcmp(page_get_infimum_rec(page), "infimum", 8)
|
||||
|| memcmp(page_get_supremum_rec(page), "supremum", 8)) {
|
||||
/* In a later format, these fields in a FIL_PAGE_TYPE_INSTANT
|
||||
root page could be repurposed for something else. */
|
||||
return true;
|
||||
}
|
||||
|
||||
index->n_core_fields = n;
|
||||
ut_ad(!index->is_dummy);
|
||||
ut_d(index->is_dummy = true);
|
||||
|
Reference in New Issue
Block a user