summaryrefslogtreecommitdiff
path: root/storage/innobase
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2018-10-04 16:12:04 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2018-10-04 16:12:04 +0300
commit941ca92a2ca3990020b23bcc92e7ca98dcc8f814 (patch)
treedec4d105b19f8cd21ebd9dc1a09737a7d136da3d /storage/innobase
parent2badefb06625c448b07c734dcc20703ab8d42139 (diff)
downloadmariadb-git-941ca92a2ca3990020b23bcc92e7ca98dcc8f814.tar.gz
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.
Diffstat (limited to 'storage/innobase')
-rw-r--r--storage/innobase/btr/btr0cur.cc47
1 files changed, 26 insertions, 21 deletions
diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc
index aa56911d337..27975abe0ab 100644
--- a/storage/innobase/btr/btr0cur.cc
+++ b/storage/innobase/btr/btr0cur.cc
@@ -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);