diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2022-03-29 16:16:21 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2022-03-29 16:16:21 +0300 |
commit | b242c3141f263f9f73f179ad5edd385906109262 (patch) | |
tree | fcba93da0a91e2b615e4f85a5ba449641641b49f /storage/innobase | |
parent | b2fa874e462e7352be173a3075a65e49f2fcc404 (diff) | |
parent | c14f60a72f28bb5102d529b3946c2daf8f3b590b (diff) | |
download | mariadb-git-b242c3141f263f9f73f179ad5edd385906109262.tar.gz |
Merge 10.5 into 10.6
Diffstat (limited to 'storage/innobase')
-rw-r--r-- | storage/innobase/buf/buf0buf.cc | 42 | ||||
-rw-r--r-- | storage/innobase/fil/fil0fil.cc | 3 | ||||
-rw-r--r-- | storage/innobase/fts/fts0fts.cc | 4 | ||||
-rw-r--r-- | storage/innobase/include/mtr0mtr.h | 9 | ||||
-rw-r--r-- | storage/innobase/mtr/mtr0mtr.cc | 59 | ||||
-rw-r--r-- | storage/innobase/row/row0sel.cc | 43 |
6 files changed, 96 insertions, 64 deletions
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 24eef21d461..b948fefe55a 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -635,10 +635,6 @@ buf_page_is_corrupted( return false; } -#ifndef UNIV_INNOCHECKSUM - uint32_t crc32 = 0; - bool crc32_inited = false; -#endif /* !UNIV_INNOCHECKSUM */ const ulint zip_size = fil_space_t::zip_size(fsp_flags); const uint16_t page_type = fil_page_get_type(read_buf); @@ -733,6 +729,8 @@ buf_page_is_corrupted( return false; } + const uint32_t crc32 = buf_calc_page_crc32(read_buf); + /* Very old versions of InnoDB only stored 8 byte lsn to the start and the end of the page. */ @@ -743,18 +741,14 @@ buf_page_is_corrupted( != mach_read_from_4(read_buf + FIL_PAGE_LSN) && checksum_field2 != BUF_NO_CHECKSUM_MAGIC) { - crc32 = buf_calc_page_crc32(read_buf); - crc32_inited = true; - DBUG_EXECUTE_IF( "page_intermittent_checksum_mismatch", { - static int page_counter; - if (page_counter++ == 2) { - crc32++; - } - }); + static int page_counter; + if (page_counter++ == 2) return true; + }); - if (checksum_field2 != crc32 + if ((checksum_field1 != crc32 + || checksum_field2 != crc32) && checksum_field2 != buf_calc_page_old_checksum(read_buf)) { return true; @@ -764,25 +758,11 @@ buf_page_is_corrupted( switch (checksum_field1) { case 0: case BUF_NO_CHECKSUM_MAGIC: - break; - default: - if (!crc32_inited) { - crc32 = buf_calc_page_crc32(read_buf); - crc32_inited = true; - } - - if (checksum_field1 != crc32 - && checksum_field1 - != buf_calc_page_new_checksum(read_buf)) { - return true; - } + return false; } - - return crc32_inited - && ((checksum_field1 == crc32 - && checksum_field2 != crc32) - || (checksum_field1 != crc32 - && checksum_field2 == crc32)); + return (checksum_field1 != crc32 || checksum_field2 != crc32) + && checksum_field1 + != buf_calc_page_new_checksum(read_buf); } #endif /* !UNIV_INNOCHECKSUM */ } diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index 230c6efa743..e62b2e538d4 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -1775,9 +1775,10 @@ char* fil_make_filepath(const char *path, const fil_space_t::name_type &name, if (path != NULL) { memcpy(full_name, path, path_len); len = path_len; - full_name[len] = '\0'; } + full_name[len] = '\0'; + if (trim_name) { /* Find the offset of the last DIR separator and set it to null in order to strip off the old basename from this path. */ diff --git a/storage/innobase/fts/fts0fts.cc b/storage/innobase/fts/fts0fts.cc index c8aa6aab35a..964a216cd39 100644 --- a/storage/innobase/fts/fts0fts.cc +++ b/storage/innobase/fts/fts0fts.cc @@ -2219,9 +2219,7 @@ fts_trx_table_create( fts_trx_table_t* ftt; ftt = static_cast<fts_trx_table_t*>( - mem_heap_alloc(fts_trx->heap, sizeof(*ftt))); - - memset(ftt, 0x0, sizeof(*ftt)); + mem_heap_zalloc(fts_trx->heap, sizeof *ftt)); ftt->table = table; ftt->fts_trx = fts_trx; diff --git a/storage/innobase/include/mtr0mtr.h b/storage/innobase/include/mtr0mtr.h index 8f74343ba64..9d0f48a36b7 100644 --- a/storage/innobase/include/mtr0mtr.h +++ b/storage/innobase/include/mtr0mtr.h @@ -100,6 +100,15 @@ struct mtr_t { /** Commit the mini-transaction. */ void commit(); + /** Release latches till savepoint. To simplify the code only + MTR_MEMO_S_LOCK and MTR_MEMO_PAGE_S_FIX slot types are allowed to be + released, otherwise it would be neccesary to add one more argument in the + function to point out what slot types are allowed for rollback, and this + would be overengineering as currently the function is used only in one place + in the code. + @param savepoint savepoint, can be obtained with get_savepoint */ + void rollback_to_savepoint(ulint savepoint); + /** Commit a mini-transaction that is shrinking a tablespace. @param space tablespace that is being shrunk */ ATTRIBUTE_COLD void commit_shrink(fil_space_t &space); diff --git a/storage/innobase/mtr/mtr0mtr.cc b/storage/innobase/mtr/mtr0mtr.cc index c5bfb355392..74d7a9a3376 100644 --- a/storage/innobase/mtr/mtr0mtr.cc +++ b/storage/innobase/mtr/mtr0mtr.cc @@ -299,6 +299,50 @@ struct ReleaseAll { } }; +/** Stops iteration is savepoint is reached */ +template <typename Functor> struct TillSavepoint +{ + + /** Constructor + @param[in] functor functor which is called if savepoint is not reached + @param[in] savepoint savepoint value to rollback + @param[in] used current position in slots container */ + TillSavepoint(const Functor &functor, ulint savepoint, ulint used) + : functor(functor), + m_slots_count((used - savepoint) / sizeof(mtr_memo_slot_t)) + { + ut_ad(savepoint); + ut_ad(used >= savepoint); + } + + /** @return true if savepoint is not reached, false otherwise */ + bool operator()(mtr_memo_slot_t *slot) + { +#ifdef UNIV_DEBUG + /** This check is added because the code is invoked only from + row_search_mvcc() to release latches acquired during clustered index search + for secondary index record. To make it more universal we could add one more + member in this functor for debug build to pass only certain slot types, + but this is currently not necessary. */ + switch (slot->type) + { + case MTR_MEMO_S_LOCK: + case MTR_MEMO_PAGE_S_FIX: + break; + default: + ut_a(false); + } +#endif + return m_slots_count-- && functor(slot); + } + +private: + /** functor to invoke */ + const Functor &functor; + /** slots count left till savepoint */ + ulint m_slots_count; +}; + #ifdef UNIV_DEBUG /** Check that all slots have been handled. */ struct DebugCheck { @@ -468,6 +512,21 @@ void mtr_t::commit() release_resources(); } +/** Release latches till savepoint. To simplify the code only +MTR_MEMO_S_LOCK and MTR_MEMO_PAGE_S_FIX slot types are allowed to be +released, otherwise it would be neccesary to add one more argument in the +function to point out what slot types are allowed for rollback, and this +would be overengineering as corrently the function is used only in one place +in the code. +@param savepoint savepoint, can be obtained with get_savepoint */ +void mtr_t::rollback_to_savepoint(ulint savepoint) +{ + Iterate<TillSavepoint<ReleaseLatches>> iteration( + TillSavepoint<ReleaseLatches>(ReleaseLatches(), savepoint, + get_savepoint())); + m_memo.for_each_block_in_reverse(iteration); +} + /** Shrink a tablespace. */ struct Shrink { diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc index f208ca51d69..e01637d22cc 100644 --- a/storage/innobase/row/row0sel.cc +++ b/storage/innobase/row/row0sel.cc @@ -3602,14 +3602,12 @@ record with the same ordering prefix in in the B-tree index @param[in] latch_mode latch mode wished in restoration @param[in] pcur cursor whose position has been stored @param[in] moves_up true if the cursor moves up in the index -@param[in] mtr mtr; CAUTION: may commit mtr temporarily! -@param[in] select_lock_type select lock type +@param[in,out] mtr mtr; CAUTION: may commit mtr temporarily! @return true if we may need to process the record the cursor is now positioned on (i.e. we should not go to the next record yet) */ static bool sel_restore_position_for_mysql(bool *same_user_rec, ulint latch_mode, btr_pcur_t *pcur, - bool moves_up, mtr_t *mtr, - lock_mode select_lock_type) + bool moves_up, mtr_t *mtr) { auto status = pcur->restore_position(latch_mode, mtr); @@ -3632,8 +3630,7 @@ static bool sel_restore_position_for_mysql(bool *same_user_rec, switch (pcur->rel_pos) { case BTR_PCUR_ON: if (!*same_user_rec && moves_up) { - if (status == btr_pcur_t::SAME_UNIQ - && select_lock_type != LOCK_NONE) + if (status == btr_pcur_t::SAME_UNIQ) return true; next: if (btr_pcur_move_to_next(pcur, mtr) @@ -4326,7 +4323,7 @@ row_search_mvcc( const rec_t* clust_rec; Row_sel_get_clust_rec_for_mysql row_sel_get_clust_rec_for_mysql; ibool unique_search = FALSE; - ibool mtr_has_extra_clust_latch = FALSE; + ulint mtr_extra_clust_savepoint = 0; bool moves_up = false; /* if the returned record was locked and we did a semi-consistent read (fetch the newest committed version), then this is set to @@ -4698,7 +4695,7 @@ wait_table_again: bool need_to_process = sel_restore_position_for_mysql( &same_user_rec, BTR_SEARCH_LEAF, - pcur, moves_up, &mtr, prebuilt->select_lock_type); + pcur, moves_up, &mtr); if (UNIV_UNLIKELY(need_to_process)) { if (UNIV_UNLIKELY(prebuilt->row_read_type @@ -5445,7 +5442,7 @@ requires_clust_rec: /* It was a non-clustered index and we must fetch also the clustered index record */ - mtr_has_extra_clust_latch = TRUE; + mtr_extra_clust_savepoint = mtr.get_savepoint(); ut_ad(!vrow); /* The following call returns 'offsets' associated with @@ -5744,27 +5741,15 @@ next_rec: /* No need to do store restore for R-tree */ mtr.commit(); mtr.start(); - mtr_has_extra_clust_latch = FALSE; - } else if (mtr_has_extra_clust_latch) { - /* If we have extra cluster latch, we must commit - mtr if we are moving to the next non-clustered + mtr_extra_clust_savepoint = 0; + } else if (mtr_extra_clust_savepoint) { + /* We must release any clustered index latches + if we are moving to the next non-clustered index record, because we could break the latching order if we would access a different clustered index page right away without releasing the previous. */ - - btr_pcur_store_position(pcur, &mtr); - mtr.commit(); - mtr_has_extra_clust_latch = FALSE; - - mtr.start(); - - if (sel_restore_position_for_mysql(&same_user_rec, - BTR_SEARCH_LEAF, - pcur, moves_up, &mtr, - prebuilt->select_lock_type) - ) { - goto rec_loop; - } + mtr.rollback_to_savepoint(mtr_extra_clust_savepoint); + mtr_extra_clust_savepoint = 0; } if (moves_up) { @@ -5824,7 +5809,7 @@ page_read_error: lock_table_wait: mtr.commit(); - mtr_has_extra_clust_latch = FALSE; + mtr_extra_clust_savepoint = 0; trx->error_state = err; thr->lock_state = QUE_THR_LOCK_ROW; @@ -5846,7 +5831,7 @@ lock_table_wait: if (!dict_index_is_spatial(index)) { sel_restore_position_for_mysql( &same_user_rec, BTR_SEARCH_LEAF, pcur, - moves_up, &mtr, prebuilt->select_lock_type); + moves_up, &mtr); } if (trx->isolation_level <= TRX_ISO_READ_COMMITTED |