diff options
Diffstat (limited to 'storage/innobase/row/row0import.cc')
-rw-r--r-- | storage/innobase/row/row0import.cc | 50 |
1 files changed, 31 insertions, 19 deletions
diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index f3ed3998aa7..e11f4e8a26d 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -253,19 +253,17 @@ public: } /** Position the cursor on the first user record. */ - void open(buf_block_t* block) UNIV_NOTHROW + rec_t* open(buf_block_t* block) noexcept + MY_ATTRIBUTE((warn_unused_result)) { page_cur_set_before_first(block, &m_cur); - - if (!end()) { - next(); - } + return next(); } /** Move to the next record. */ - void next() UNIV_NOTHROW + rec_t* next() noexcept MY_ATTRIBUTE((warn_unused_result)) { - page_cur_move_to_next(&m_cur); + return page_cur_move_to_next(&m_cur); } /** @@ -1520,6 +1518,8 @@ inline bool IndexPurge::open() noexcept return false; rec_t *rec= page_rec_get_next(btr_pcur_get_rec(&m_pcur)); + if (!rec) + return false; if (rec_is_metadata(rec, *m_index)) /* Skip the metadata pseudo-record. */ btr_pcur_get_page_cur(&m_pcur)->rec= rec; @@ -1531,7 +1531,9 @@ Position the cursor on the next record. @return DB_SUCCESS or error code */ dberr_t IndexPurge::next() noexcept { - btr_pcur_move_to_next_on_page(&m_pcur); + if (UNIV_UNLIKELY(!btr_pcur_move_to_next_on_page(&m_pcur))) { + return DB_CORRUPTION; + } /* When switching pages, commit the mini-transaction in order to release the latch on the old page. */ @@ -1569,8 +1571,8 @@ dberr_t IndexPurge::next() noexcept &m_mtr)) { return err; } - } else { - btr_pcur_move_to_next_on_page(&m_pcur); + } else if (!btr_pcur_move_to_next_on_page(&m_pcur)) { + return DB_CORRUPTION; } } while (!btr_pcur_is_on_user_rec(&m_pcur)); @@ -1787,7 +1789,9 @@ PageConverter::update_records( /* This will also position the cursor on the first user record. */ - m_rec_iter.open(block); + if (!m_rec_iter.open(block)) { + return DB_CORRUPTION; + } while (!m_rec_iter.end()) { rec_t* rec = m_rec_iter.current(); @@ -1818,17 +1822,19 @@ PageConverter::update_records( optimistic delete. */ if (deleted) { + ++m_index->m_stats.m_n_deleted; /* A successful purge will move the cursor to the next record. */ - if (!purge()) { - m_rec_iter.next(); + if (purge()) { + continue; } - - ++m_index->m_stats.m_n_deleted; } else { ++m_index->m_stats.m_n_rows; - m_rec_iter.next(); + } + + if (!m_rec_iter.next()) { + return DB_CORRUPTION; } } @@ -3167,6 +3173,8 @@ static dberr_t handle_instant_metadata(dict_table_t *table, while (btr_page_get_level(page.get()) != 0) { const rec_t *rec= page_rec_get_next(page_get_infimum_rec(page.get())); + if (!rec) + return DB_CORRUPTION; /* Relax the assertion in rec_init_offsets(). */ ut_ad(!index->in_instant_init); @@ -3191,18 +3199,22 @@ static dberr_t handle_instant_metadata(dict_table_t *table, return err; } - const auto *rec= page_rec_get_next(page_get_infimum_rec(page.get())); + const auto *rec= page_rec_get_next_const(page_get_infimum_rec(page.get())); const auto comp= dict_table_is_comp(index->table); - const auto info_bits= rec_get_info_bits(rec, comp); - if (page_rec_is_supremum(rec) || !(info_bits & REC_INFO_MIN_REC_FLAG)) + if (!rec || page_rec_is_supremum(rec)) { + corrupted_metadata: ib::error() << "Table " << index->table->name << " is missing instant ALTER metadata"; index->table->corrupted= true; return DB_CORRUPTION; } + const auto info_bits= rec_get_info_bits(rec, comp); + if (!(info_bits & REC_INFO_MIN_REC_FLAG)) + goto corrupted_metadata; + if ((info_bits & ~REC_INFO_DELETED_FLAG) != REC_INFO_MIN_REC_FLAG || (comp && rec_get_status(rec) != REC_STATUS_INSTANT)) { |