summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
authorMarko Mäkelä <marko.makela@mariadb.com>2023-03-06 13:38:16 +0200
committerMarko Mäkelä <marko.makela@mariadb.com>2023-03-06 13:38:16 +0200
commit46a7603813e74b48e948a5287c40a93fbb5bbf4d (patch)
tree221cc43562b2df5e3e25442236756f9c992859d3 /storage
parentc3246e4bf0b578276d776b378d24b805d85dff24 (diff)
parent669a0c6efb89cd5df4eb117c9c44694a9fbeb52c (diff)
downloadmariadb-git-46a7603813e74b48e948a5287c40a93fbb5bbf4d.tar.gz
Merge 10.8 into 10.9
Diffstat (limited to 'storage')
-rw-r--r--storage/innobase/btr/btr0cur.cc5
-rw-r--r--storage/innobase/include/trx0trx.h2
-rw-r--r--storage/innobase/trx/trx0purge.cc92
-rw-r--r--storage/innobase/trx/trx0trx.cc5
-rw-r--r--storage/maria/ha_maria.cc18
-rw-r--r--storage/maria/ma_blockrec.c25
-rw-r--r--storage/maria/ma_open.c2
-rw-r--r--storage/myisam/ha_myisam.cc14
8 files changed, 91 insertions, 72 deletions
diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc
index ec1b72244b4..8d19064a658 100644
--- a/storage/innobase/btr/btr0cur.cc
+++ b/storage/innobase/btr/btr0cur.cc
@@ -1011,9 +1011,10 @@ dberr_t btr_cur_t::search_leaf(const dtuple_t *tuple, page_cur_mode_t mode,
# ifdef UNIV_SEARCH_PERF_STAT
info->n_searches++;
# endif
+ bool ahi_enabled= btr_search_enabled && !index()->is_ibuf();
/* We do a dirty read of btr_search_enabled below,
and btr_search_guess_on_hash() will have to check it again. */
- if (!btr_search_enabled);
+ if (!ahi_enabled);
else if (btr_search_guess_on_hash(index(), info, tuple, mode,
latch_mode, this, mtr))
{
@@ -1335,7 +1336,7 @@ release_tree:
reached_latched_leaf:
#ifdef BTR_CUR_HASH_ADAPT
- if (btr_search_enabled && !(tuple->info_bits & REC_INFO_MIN_REC_FLAG))
+ if (ahi_enabled && !(tuple->info_bits & REC_INFO_MIN_REC_FLAG))
{
if (page_cur_search_with_match_bytes(tuple, mode,
&up_match, &up_bytes,
diff --git a/storage/innobase/include/trx0trx.h b/storage/innobase/include/trx0trx.h
index 0450be89cfb..7d2c3297769 100644
--- a/storage/innobase/include/trx0trx.h
+++ b/storage/innobase/include/trx0trx.h
@@ -1109,6 +1109,8 @@ public:
ut_ad(!dict_operation);
ut_ad(!apply_online_log);
ut_ad(!is_not_inheriting_locks());
+ ut_ad(check_foreigns);
+ ut_ad(check_unique_secondary);
}
/** This has to be invoked on SAVEPOINT or at the end of a statement.
diff --git a/storage/innobase/trx/trx0purge.cc b/storage/innobase/trx/trx0purge.cc
index e5f8f38ce6c..4c8c5842e13 100644
--- a/storage/innobase/trx/trx0purge.cc
+++ b/storage/innobase/trx/trx0purge.cc
@@ -395,6 +395,7 @@ static dberr_t
trx_purge_free_segment(mtr_t &mtr, trx_rseg_t* rseg, fil_addr_t hdr_addr)
{
mtr.commit();
+ log_free_check();
mtr.start();
const page_id_t hdr_page_id{rseg->space->id, hdr_addr.page};
@@ -402,61 +403,48 @@ trx_purge_free_segment(mtr_t &mtr, trx_rseg_t* rseg, fil_addr_t hdr_addr)
buf_block_t *rseg_hdr= rseg->get(&mtr, &err);
if (!rseg_hdr)
return err;
- if (buf_block_t *block= buf_page_get_gen(hdr_page_id, 0, RW_X_LATCH,
- nullptr, BUF_GET_POSSIBLY_FREED,
- &mtr, &err))
- {
- /* Mark the last undo log totally purged, so that if the system
- crashes, the tail of the undo log will not get accessed again. The
- list of pages in the undo log tail gets inconsistent during the
- freeing of the segment, and therefore purge should not try to
- access them again. */
- mtr.write<2,mtr_t::MAYBE_NOP>(*block, block->page.frame +
- hdr_addr.boffset + TRX_UNDO_NEEDS_PURGE, 0U);
- while (!fseg_free_step_not_header(TRX_UNDO_SEG_HDR + TRX_UNDO_FSEG_HEADER +
- block->page.frame, &mtr))
- {
- rseg_hdr->fix();
- block->fix();
- mtr.commit();
- mtr.start();
- rseg_hdr->page.lock.x_lock();
- block->page.lock.x_lock();
- mtr.memo_push(rseg_hdr, MTR_MEMO_PAGE_X_FIX);
- mtr.memo_push(block, MTR_MEMO_PAGE_X_MODIFY);
- }
+ buf_block_t *block= buf_page_get_gen(hdr_page_id, 0, RW_X_LATCH,
+ nullptr, BUF_GET_POSSIBLY_FREED,
+ &mtr, &err);
+ if (!block)
+ return err;
+
+ const uint32_t seg_size=
+ flst_get_len(TRX_UNDO_SEG_HDR + TRX_UNDO_PAGE_LIST + block->page.frame);
+
+ err= trx_purge_remove_log_hdr(rseg_hdr, block, hdr_addr.boffset, &mtr);
+ if (UNIV_UNLIKELY(err != DB_SUCCESS))
+ return err;
+
+ ut_ad(rseg->curr_size >= seg_size);
+ rseg->curr_size-= seg_size;
+ rseg->history_size--;
+
+ byte *hist= TRX_RSEG + TRX_RSEG_HISTORY_SIZE + rseg_hdr->page.frame;
+ ut_ad(mach_read_from_4(hist) >= seg_size);
+ mtr.write<4>(*rseg_hdr, hist, mach_read_from_4(hist) - seg_size);
- /* The page list may now be inconsistent, but the length field
- stored in the list base node tells us how big it was before we
- started the freeing. */
- const uint32_t seg_size=
- flst_get_len(TRX_UNDO_SEG_HDR + TRX_UNDO_PAGE_LIST + block->page.frame);
-
- /* We may free the undo log segment header page; it must be freed
- within the same mtr as the undo log header is removed from the
- history list: otherwise, in case of a database crash, the segment
- could become inaccessible garbage in the file space. */
- err= trx_purge_remove_log_hdr(rseg_hdr, block, hdr_addr.boffset, &mtr);
- if (UNIV_UNLIKELY(err != DB_SUCCESS))
- return err;
- byte *hist= TRX_RSEG + TRX_RSEG_HISTORY_SIZE + rseg_hdr->page.frame;
- if (UNIV_UNLIKELY(mach_read_from_4(hist) < seg_size))
- return DB_CORRUPTION;
- mtr.write<4>(*rseg_hdr, hist, mach_read_from_4(hist) - seg_size);
-
- /* Here we assume that a file segment with just the header page
- can be freed in a few steps, so that the buffer pool is not
- flooded with bufferfixed pages: see the note in fsp0fsp.cc. */
- while (!fseg_free_step(TRX_UNDO_SEG_HDR + TRX_UNDO_FSEG_HEADER +
- block->page.frame, &mtr));
-
- ut_ad(rseg->curr_size >= seg_size);
-
- rseg->history_size--;
- rseg->curr_size -= seg_size;
+ while (!fseg_free_step_not_header(TRX_UNDO_SEG_HDR + TRX_UNDO_FSEG_HEADER +
+ block->page.frame, &mtr))
+ {
+ block->fix();
+ mtr.commit();
+ /* NOTE: If the server is killed after the log that was produced
+ up to this point was written, and before the log from the mtr.commit()
+ in our caller is written, then the pages belonging to the
+ undo log will become unaccessible garbage.
+
+ This does not matters when using multiple innodb_undo_tablespaces;
+ innodb_undo_log_truncate=ON will be able to reclaim the space. */
+ log_free_check();
+ mtr.start();
+ block->page.lock.x_lock();
+ mtr.memo_push(block, MTR_MEMO_PAGE_X_MODIFY);
}
- return err;
+ while (!fseg_free_step(TRX_UNDO_SEG_HDR + TRX_UNDO_FSEG_HEADER +
+ block->page.frame, &mtr));
+ return DB_SUCCESS;
}
/** Remove unnecessary history data from a rollback segment.
diff --git a/storage/innobase/trx/trx0trx.cc b/storage/innobase/trx/trx0trx.cc
index 4975e72ef0f..837f12a39dd 100644
--- a/storage/innobase/trx/trx0trx.cc
+++ b/storage/innobase/trx/trx0trx.cc
@@ -385,9 +385,10 @@ void trx_t::free()
dict_operation= false;
trx_sys.deregister_trx(this);
+ check_unique_secondary= true;
+ check_foreigns= true;
assert_freed();
trx_sys.rw_trx_hash.put_pins(this);
-
mysql_thd= nullptr;
// FIXME: We need to avoid this heap free/alloc for each commit.
@@ -1373,6 +1374,8 @@ void trx_t::commit_cleanup()
state= TRX_STATE_NOT_STARTED;
mod_tables.clear();
+ check_foreigns= true;
+ check_unique_secondary= true;
assert_freed();
trx_init(this);
mutex.wr_unlock();
diff --git a/storage/maria/ha_maria.cc b/storage/maria/ha_maria.cc
index 21d9a00b94e..c245dcea036 100644
--- a/storage/maria/ha_maria.cc
+++ b/storage/maria/ha_maria.cc
@@ -2690,12 +2690,22 @@ int ha_maria::info(uint flag)
share->db_record_offset= maria_info.record_offset;
if (share->key_parts)
{
- ulong *to= table->key_info[0].rec_per_key, *end;
double *from= maria_info.rec_per_key;
- for (end= to+ share->key_parts ; to < end ; to++, from++)
- *to= (ulong) (*from + 0.5);
+ KEY *key, *key_end;
+ for (key= table->key_info, key_end= key + share->keys;
+ key < key_end ; key++)
+ {
+ ulong *to= key->rec_per_key;
+ /* Some temporary tables does not allocate rec_per_key */
+ if (to)
+ {
+ for (ulong *end= to+ key->user_defined_key_parts ;
+ to < end ;
+ to++, from++)
+ *to= (ulong) (*from + 0.5);
+ }
+ }
}
-
/*
Set data_file_name and index_file_name to point at the symlink value
if table is symlinked (Ie; Real name is not same as generated name)
diff --git a/storage/maria/ma_blockrec.c b/storage/maria/ma_blockrec.c
index baa777edcf0..98ef5c21e55 100644
--- a/storage/maria/ma_blockrec.c
+++ b/storage/maria/ma_blockrec.c
@@ -2780,7 +2780,8 @@ static my_bool write_block_record(MARIA_HA *info,
const uchar *field_pos;
ulong length;
if ((record[column->null_pos] & column->null_bit) ||
- (row->empty_bits[column->empty_pos] & column->empty_bit))
+ (column->empty_bit &&
+ (row->empty_bits[column->empty_pos] & column->empty_bit)))
continue;
field_pos= record + column->offset;
@@ -4887,7 +4888,8 @@ int _ma_read_block_record2(MARIA_HA *info, uchar *record,
uchar *field_pos= record + column->offset;
/* First check if field is present in record */
if ((record[column->null_pos] & column->null_bit) ||
- (cur_row->empty_bits[column->empty_pos] & column->empty_bit))
+ (column->empty_bit &&
+ (cur_row->empty_bits[column->empty_pos] & column->empty_bit)))
{
bfill(record + column->offset, column->fill_length,
type == FIELD_SKIP_ENDSPACE ? ' ' : 0);
@@ -4970,8 +4972,9 @@ int _ma_read_block_record2(MARIA_HA *info, uchar *record,
{
uint size_length;
if ((record[blob_field->null_pos] & blob_field->null_bit) ||
- (cur_row->empty_bits[blob_field->empty_pos] &
- blob_field->empty_bit))
+ (blob_field->empty_bit &
+ (cur_row->empty_bits[blob_field->empty_pos] &
+ blob_field->empty_bit)))
continue;
size_length= blob_field->length - portable_sizeof_char_ptr;
blob_lengths+= _ma_calc_blob_length(size_length, length_data);
@@ -5825,7 +5828,8 @@ static size_t fill_insert_undo_parts(MARIA_HA *info, const uchar *record,
const uchar *column_pos;
size_t column_length;
if ((record[column->null_pos] & column->null_bit) ||
- cur_row->empty_bits[column->empty_pos] & column->empty_bit)
+ (column->empty_bit &&
+ cur_row->empty_bits[column->empty_pos] & column->empty_bit))
continue;
column_pos= record+ column->offset;
@@ -6006,7 +6010,8 @@ static size_t fill_update_undo_parts(MARIA_HA *info, const uchar *oldrec,
*/
continue;
}
- if (old_row->empty_bits[column->empty_pos] & column->empty_bit)
+ if (column->empty_bit &&
+ (old_row->empty_bits[column->empty_pos] & column->empty_bit))
{
if (new_row->empty_bits[column->empty_pos] & column->empty_bit)
continue; /* Both are empty; skip */
@@ -6022,8 +6027,9 @@ static size_t fill_update_undo_parts(MARIA_HA *info, const uchar *oldrec,
log the original value
*/
new_column_is_empty= ((newrec[column->null_pos] & column->null_bit) ||
- (new_row->empty_bits[column->empty_pos] &
- column->empty_bit));
+ (column->empty_bit &&
+ (new_row->empty_bits[column->empty_pos] &
+ column->empty_bit)));
old_column_pos= oldrec + column->offset;
new_column_pos= newrec + column->offset;
@@ -7196,7 +7202,8 @@ my_bool _ma_apply_undo_row_delete(MARIA_HA *info, LSN undo_lsn,
column++, null_field_lengths++)
{
if ((record[column->null_pos] & column->null_bit) ||
- row.empty_bits[column->empty_pos] & column->empty_bit)
+ (column->empty_bit &&
+ row.empty_bits[column->empty_pos] & column->empty_bit))
{
if (column->type != FIELD_BLOB)
*null_field_lengths= 0;
diff --git a/storage/maria/ma_open.c b/storage/maria/ma_open.c
index 2d9174b4380..7702355b7d1 100644
--- a/storage/maria/ma_open.c
+++ b/storage/maria/ma_open.c
@@ -117,7 +117,7 @@ static MARIA_HA *maria_clone_internal(MARIA_SHARE *share,
&info.blobs,sizeof(MARIA_BLOB)*share->base.blobs,
&info.buff,(share->base.max_key_block_length*2+
share->base.max_key_length),
- &info.lastkey_buff,share->base.max_key_length*2+1,
+ &info.lastkey_buff,share->base.max_key_length*3,
&info.first_mbr_key, share->base.max_key_length,
&info.maria_rtree_recursion_state,
share->have_rtree ? 1024 : 0,
diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc
index a1de9edd997..c0419da7e71 100644
--- a/storage/myisam/ha_myisam.cc
+++ b/storage/myisam/ha_myisam.cc
@@ -2144,9 +2144,17 @@ int ha_myisam::info(uint flag)
share->keys_for_keyread.intersect(share->keys_in_use);
share->db_record_offset= misam_info.record_offset;
if (share->key_parts)
- memcpy((char*) table->key_info[0].rec_per_key,
- (char*) misam_info.rec_per_key,
- sizeof(table->key_info[0].rec_per_key[0])*share->key_parts);
+ {
+ ulong *from= misam_info.rec_per_key;
+ KEY *key, *key_end;
+ for (key= table->key_info, key_end= key + share->keys;
+ key < key_end ; key++)
+ {
+ memcpy(key->rec_per_key, from,
+ key->user_defined_key_parts * sizeof(*from));
+ from+= key->user_defined_key_parts;
+ }
+ }
if (table_share->tmp_table == NO_TMP_TABLE)
mysql_mutex_unlock(&table_share->LOCK_share);
}