1
0
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:
Marko Mäkelä
2018-10-04 16:12:04 +03:00
parent 2badefb066
commit 941ca92a2c

View File

@@ -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);