summaryrefslogtreecommitdiff
path: root/storage/innobase
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2022-03-29 16:16:21 +0300
committerMarko Mäkelä <marko.makela@mariadb.com>2022-03-29 16:16:21 +0300
commitb242c3141f263f9f73f179ad5edd385906109262 (patch)
treefcba93da0a91e2b615e4f85a5ba449641641b49f /storage/innobase
parentb2fa874e462e7352be173a3075a65e49f2fcc404 (diff)
parentc14f60a72f28bb5102d529b3946c2daf8f3b590b (diff)
downloadmariadb-git-b242c3141f263f9f73f179ad5edd385906109262.tar.gz
Merge 10.5 into 10.6
Diffstat (limited to 'storage/innobase')
-rw-r--r--storage/innobase/buf/buf0buf.cc42
-rw-r--r--storage/innobase/fil/fil0fil.cc3
-rw-r--r--storage/innobase/fts/fts0fts.cc4
-rw-r--r--storage/innobase/include/mtr0mtr.h9
-rw-r--r--storage/innobase/mtr/mtr0mtr.cc59
-rw-r--r--storage/innobase/row/row0sel.cc43
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