Commit ed0793e0 authored by Eugene Kosov's avatar Eugene Kosov Committed by Marko Mäkelä

MDEV-19783: Add more REC_INFO_MIN_REC_FLAG checks

btr_cur_pessimistic_delete(): code changed in a way that allows
to put more REC_INFO_MIN_REC_FLAG assertions inside btr_set_min_rec_mark().
Without that change tests innodb.innodb-table-online,
innodb.temp_table_savepoint and innodb_zip.prefix_index_liftedlimit fail.

Removed basically duplicated page_zip_validate() calls
which fails because of temporary(!) invariant violation.
That fixed innodb_zip.wl5522_debug_zip and
innodb_zip.prefix_index_liftedlimit
parent 99dc40d6
...@@ -3309,25 +3309,22 @@ btr_parse_set_min_rec_mark( ...@@ -3309,25 +3309,22 @@ btr_parse_set_min_rec_mark(
return(ptr + 2); return(ptr + 2);
} }
/****************************************************************//** /** Sets a record as the predefined minimum record. */
Sets a record as the predefined minimum record. */ void btr_set_min_rec_mark(rec_t* rec, mtr_t* mtr)
void
btr_set_min_rec_mark(
/*=================*/
rec_t* rec, /*!< in: record */
mtr_t* mtr) /*!< in: mtr */
{ {
ulint info_bits; const bool comp = page_rec_is_comp(rec);
if (page_rec_is_comp(rec)) { ut_ad(rec == page_rec_get_next_const(page_get_infimum_rec(
info_bits = rec_get_info_bits(rec, TRUE); page_align(rec))));
ut_ad(!(rec_get_info_bits(page_rec_get_next(rec), comp)
& REC_INFO_MIN_REC_FLAG));
size_t info_bits = rec_get_info_bits(rec, comp);
if (comp) {
rec_set_info_bits_new(rec, info_bits | REC_INFO_MIN_REC_FLAG); rec_set_info_bits_new(rec, info_bits | REC_INFO_MIN_REC_FLAG);
btr_set_min_rec_mark_log(rec, MLOG_COMP_REC_MIN_MARK, mtr); btr_set_min_rec_mark_log(rec, MLOG_COMP_REC_MIN_MARK, mtr);
} else { } else {
info_bits = rec_get_info_bits(rec, FALSE);
rec_set_info_bits_old(rec, info_bits | REC_INFO_MIN_REC_FLAG); rec_set_info_bits_old(rec, info_bits | REC_INFO_MIN_REC_FLAG);
btr_set_min_rec_mark_log(rec, MLOG_REC_MIN_MARK, mtr); btr_set_min_rec_mark_log(rec, MLOG_REC_MIN_MARK, mtr);
......
...@@ -5277,8 +5277,15 @@ btr_cur_pessimistic_delete( ...@@ -5277,8 +5277,15 @@ btr_cur_pessimistic_delete(
#endif /* UNIV_ZIP_DEBUG */ #endif /* UNIV_ZIP_DEBUG */
} }
if (flags == 0) { rec_t* next_rec = NULL;
lock_update_delete(block, rec); bool min_mark_next_rec = false;
if (page_is_leaf(page)) {
ut_ad(!(rec_get_info_bits(rec, page_rec_is_comp(rec))
& REC_INFO_MIN_REC_FLAG));
if (flags == 0) {
lock_update_delete(block, rec);
}
} }
if (UNIV_UNLIKELY(page_get_n_recs(page) < 2) if (UNIV_UNLIKELY(page_get_n_recs(page) < 2)
...@@ -5297,20 +5304,14 @@ btr_cur_pessimistic_delete( ...@@ -5297,20 +5304,14 @@ btr_cur_pessimistic_delete(
if (page_is_leaf(page)) { if (page_is_leaf(page)) {
btr_search_update_hash_on_delete(cursor); btr_search_update_hash_on_delete(cursor);
} else if (UNIV_UNLIKELY(page_rec_is_first(rec, page))) { } else if (UNIV_UNLIKELY(page_rec_is_first(rec, page))) {
rec_t* next_rec = page_rec_get_next(rec); next_rec = page_rec_get_next(rec);
if (!page_has_prev(page)) { if (!page_has_prev(page)) {
/* If we delete the leftmost node pointer on a /* If we delete the leftmost node pointer on a
non-leaf level, we must mark the new leftmost node non-leaf level, we must mark the new leftmost node
pointer as the predefined minimum record */ pointer as the predefined minimum record */
/* This will make page_zip_validate() fail until min_mark_next_rec = true;
page_cur_delete_rec() completes. This is harmless,
because everything will take place within a single
mini-transaction and because writing to the redo log
is an atomic operation (performed by mtr_commit()). */
btr_set_min_rec_mark(next_rec, mtr);
} else if (dict_index_is_spatial(index)) { } else if (dict_index_is_spatial(index)) {
/* For rtree, if delete the leftmost node pointer, /* For rtree, if delete the leftmost node pointer,
we need to update parent page. */ we need to update parent page. */
...@@ -5379,6 +5380,11 @@ btr_cur_pessimistic_delete( ...@@ -5379,6 +5380,11 @@ btr_cur_pessimistic_delete(
block->page.size, mtr); block->page.size, mtr);
page_cur_delete_rec(btr_cur_get_page_cur(cursor), index, page_cur_delete_rec(btr_cur_get_page_cur(cursor), index,
offsets, mtr); offsets, mtr);
if (min_mark_next_rec) {
btr_set_min_rec_mark(next_rec, mtr);
}
#ifdef UNIV_ZIP_DEBUG #ifdef UNIV_ZIP_DEBUG
ut_a(!page_zip || page_zip_validate(page_zip, page, index)); ut_a(!page_zip || page_zip_validate(page_zip, page, index));
#endif /* UNIV_ZIP_DEBUG */ #endif /* UNIV_ZIP_DEBUG */
......
...@@ -508,14 +508,10 @@ btr_insert_on_non_leaf_level_func( ...@@ -508,14 +508,10 @@ btr_insert_on_non_leaf_level_func(
mtr_t* mtr); /*!< in: mtr */ mtr_t* mtr); /*!< in: mtr */
#define btr_insert_on_non_leaf_level(f,i,l,t,m) \ #define btr_insert_on_non_leaf_level(f,i,l,t,m) \
btr_insert_on_non_leaf_level_func(f,i,l,t,__FILE__,__LINE__,m) btr_insert_on_non_leaf_level_func(f,i,l,t,__FILE__,__LINE__,m)
/****************************************************************//**
Sets a record as the predefined minimum record. */ /** Sets a record as the predefined minimum record. */
void void btr_set_min_rec_mark(rec_t* rec, mtr_t* mtr) MY_ATTRIBUTE((nonnull));
btr_set_min_rec_mark(
/*=================*/
rec_t* rec, /*!< in/out: record */
mtr_t* mtr) /*!< in: mtr */
MY_ATTRIBUTE((nonnull));
/** Seek to the parent page of a B-tree page. /** Seek to the parent page of a B-tree page.
@param[in,out] index b-tree @param[in,out] index b-tree
@param[in] block child page @param[in] block child page
......
...@@ -659,6 +659,10 @@ page_rec_get_next_low( ...@@ -659,6 +659,10 @@ page_rec_get_next_low(
return(NULL); return(NULL);
} }
ut_ad(page_rec_is_infimum(rec)
|| !(rec_get_info_bits(page + offs, comp)
& REC_INFO_MIN_REC_FLAG));
return(page + offs); return(page + offs);
} }
......
...@@ -2421,10 +2421,6 @@ page_cur_delete_rec( ...@@ -2421,10 +2421,6 @@ page_cur_delete_rec(
if (cur_n_owned <= PAGE_DIR_SLOT_MIN_N_OWNED) { if (cur_n_owned <= PAGE_DIR_SLOT_MIN_N_OWNED) {
page_dir_balance_slot(page, page_zip, cur_slot_no); page_dir_balance_slot(page, page_zip, cur_slot_no);
} }
#ifdef UNIV_ZIP_DEBUG
ut_a(!page_zip || page_zip_validate(page_zip, page, index));
#endif /* UNIV_ZIP_DEBUG */
} }
#ifdef UNIV_COMPILE_TEST_FUNCS #ifdef UNIV_COMPILE_TEST_FUNCS
......
...@@ -4291,10 +4291,6 @@ page_zip_clear_rec( ...@@ -4291,10 +4291,6 @@ page_zip_clear_rec(
} else { } else {
ut_ad(!rec_offs_any_extern(offsets)); ut_ad(!rec_offs_any_extern(offsets));
} }
#ifdef UNIV_ZIP_DEBUG
ut_a(page_zip_validate(page_zip, page, index));
#endif /* UNIV_ZIP_DEBUG */
} }
/**********************************************************************//** /**********************************************************************//**
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment