diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2023-03-06 13:37:12 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2023-03-06 13:37:12 +0200 |
commit | 669a0c6efb89cd5df4eb117c9c44694a9fbeb52c (patch) | |
tree | 93af8832773ce9f91db2c961bb2d2f4d49d3b027 | |
parent | 550b8d76b3be360b1c7984a2531e094cd4c37f8c (diff) | |
parent | 25c048066a9557d1aa506220316c6fa57be5da91 (diff) | |
download | mariadb-git-669a0c6efb89cd5df4eb117c9c44694a9fbeb52c.tar.gz |
Merge 10.6 into 10.8
-rw-r--r-- | mysql-test/include/not_valgrind_build.inc | 4 | ||||
-rw-r--r-- | mysql-test/suite/sys_vars/t/innodb_log_checkpoint_now_basic.test | 2 | ||||
-rw-r--r-- | mysys/mulalloc.c | 19 | ||||
-rw-r--r-- | mysys/my_alloc.c | 12 | ||||
-rw-r--r-- | sql/opt_subselect.cc | 5 | ||||
-rw-r--r-- | sql/select_handler.cc | 15 | ||||
-rw-r--r-- | sql/sql_class.cc | 1 | ||||
-rw-r--r-- | sql/sql_class.h | 1 | ||||
-rw-r--r-- | sql/sql_expression_cache.cc | 2 | ||||
-rw-r--r-- | sql/sql_select.cc | 20 | ||||
-rw-r--r-- | sql/sql_show.cc | 23 | ||||
-rw-r--r-- | sql/sql_union.cc | 4 | ||||
-rw-r--r-- | sql/temporary_tables.cc | 6 | ||||
-rw-r--r-- | storage/innobase/include/trx0trx.h | 2 | ||||
-rw-r--r-- | storage/innobase/trx/trx0purge.cc | 92 | ||||
-rw-r--r-- | storage/innobase/trx/trx0trx.cc | 5 | ||||
-rw-r--r-- | storage/maria/ha_maria.cc | 18 | ||||
-rw-r--r-- | storage/maria/ma_blockrec.c | 25 | ||||
-rw-r--r-- | storage/maria/ma_open.c | 2 | ||||
-rw-r--r-- | storage/myisam/ha_myisam.cc | 14 |
20 files changed, 172 insertions, 100 deletions
diff --git a/mysql-test/include/not_valgrind_build.inc b/mysql-test/include/not_valgrind_build.inc index 2b60f11bfc7..b62a1bc953b 100644 --- a/mysql-test/include/not_valgrind_build.inc +++ b/mysql-test/include/not_valgrind_build.inc @@ -1,4 +1,4 @@ -if (`select version() like '%valgrind%'`) +if (`select version() like '%valgrind%' || version() like '%asan%'`) { - skip Does not run with binaries built with valgrind; + skip Does not run with binaries built with valgrind or asan; } diff --git a/mysql-test/suite/sys_vars/t/innodb_log_checkpoint_now_basic.test b/mysql-test/suite/sys_vars/t/innodb_log_checkpoint_now_basic.test index 331803fff86..f59ebf649c3 100644 --- a/mysql-test/suite/sys_vars/t/innodb_log_checkpoint_now_basic.test +++ b/mysql-test/suite/sys_vars/t/innodb_log_checkpoint_now_basic.test @@ -1,5 +1,7 @@ --source include/have_innodb.inc --source include/have_debug.inc +# Valgrind builds may block on this one +--source include/not_valgrind.inc SET @start_global_value = @@global.innodb_log_checkpoint_now; SELECT @start_global_value; diff --git a/mysys/mulalloc.c b/mysys/mulalloc.c index 357f9315f2b..51f8d61b574 100644 --- a/mysys/mulalloc.c +++ b/mysys/mulalloc.c @@ -17,6 +17,11 @@ #include "mysys_priv.h" #include <stdarg.h> +#ifndef DBUG_OFF +/* Put a protected barrier after every element when using my_multi_malloc() */ +#define ALLOC_BARRIER +#endif + /* Malloc many pointers at the same time Only ptr1 can be free'd, and doing this will free all @@ -45,6 +50,9 @@ void* my_multi_malloc(PSI_memory_key key, myf myFlags, ...) { length=va_arg(args,uint); tot_length+=ALIGN_SIZE(length); +#ifdef ALLOC_BARRIER + tot_length+= ALIGN_SIZE(1); +#endif } va_end(args); @@ -58,6 +66,10 @@ void* my_multi_malloc(PSI_memory_key key, myf myFlags, ...) *ptr=res; length=va_arg(args,uint); res+=ALIGN_SIZE(length); +#ifdef ALLOC_BARRIER + TRASH_FREE(res, ALIGN_SIZE(1)); + res+= ALIGN_SIZE(1); +#endif } va_end(args); DBUG_RETURN((void*) start); @@ -89,6 +101,9 @@ void *my_multi_malloc_large(PSI_memory_key key, myf myFlags, ...) { length=va_arg(args,ulonglong); tot_length+=ALIGN_SIZE(length); +#ifdef ALLOC_BARRIER + tot_length+= ALIGN_SIZE(1); +#endif } va_end(args); @@ -102,6 +117,10 @@ void *my_multi_malloc_large(PSI_memory_key key, myf myFlags, ...) *ptr=res; length=va_arg(args,ulonglong); res+=ALIGN_SIZE(length); +#ifdef ALLOC_BARRIER + TRASH_FREE(res, ALIGN_SIZE(1)); + res+= ALIGN_SIZE(1); +#endif } va_end(args); DBUG_RETURN((void*) start); diff --git a/mysys/my_alloc.c b/mysys/my_alloc.c index a5b855f9604..43f26751f27 100644 --- a/mysys/my_alloc.c +++ b/mysys/my_alloc.c @@ -28,6 +28,11 @@ #undef EXTRA_DEBUG #define EXTRA_DEBUG +#ifndef DBUG_OFF +/* Put a protected barrier after every element when using multi_alloc_root() */ +#define ALLOC_BARRIER +#endif + /* data packed in MEM_ROOT -> min_malloc */ /* Don't allocate too small blocks */ @@ -396,6 +401,9 @@ void *multi_alloc_root(MEM_ROOT *root, ...) { length= va_arg(args, uint); tot_length+= ALIGN_SIZE(length); +#ifdef ALLOC_BARRIER + tot_length+= ALIGN_SIZE(1); +#endif } va_end(args); @@ -409,6 +417,10 @@ void *multi_alloc_root(MEM_ROOT *root, ...) *ptr= res; length= va_arg(args, uint); res+= ALIGN_SIZE(length); +#ifdef ALLOC_BARRIER + TRASH_FREE(res, ALIGN_SIZE(1)); + res+= ALIGN_SIZE(1); +#endif } va_end(args); DBUG_RETURN((void*) start); diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index f2fcca75a8a..46db641987b 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -4187,6 +4187,7 @@ bool setup_sj_materialization_part1(JOIN_TAB *sjm_tab) } sjm->sjm_table_param.field_count= subq_select->item_list.elements; + sjm->sjm_table_param.func_count= sjm->sjm_table_param.field_count; sjm->sjm_table_param.force_not_null_cols= TRUE; if (!(sjm->table= create_tmp_table(thd, &sjm->sjm_table_param, @@ -5802,14 +5803,14 @@ TABLE *create_dummy_tmp_table(THD *thd) DBUG_ENTER("create_dummy_tmp_table"); TABLE *table; TMP_TABLE_PARAM sjm_table_param; - sjm_table_param.init(); - sjm_table_param.field_count= 1; List<Item> sjm_table_cols; const LEX_CSTRING dummy_name= { STRING_WITH_LEN("dummy") }; Item *column_item= new (thd->mem_root) Item_int(thd, 1); if (!column_item) DBUG_RETURN(NULL); + sjm_table_param.init(); + sjm_table_param.field_count= sjm_table_param.func_count= 1; sjm_table_cols.push_back(column_item, thd->mem_root); if (!(table= create_tmp_table(thd, &sjm_table_param, sjm_table_cols, (ORDER*) 0, diff --git a/sql/select_handler.cc b/sql/select_handler.cc index 795ed8eb641..b0b8e58623d 100644 --- a/sql/select_handler.cc +++ b/sql/select_handler.cc @@ -51,18 +51,19 @@ select_handler::~select_handler() TABLE *select_handler::create_tmp_table(THD *thd, SELECT_LEX *select) { - DBUG_ENTER("select_handler::create_tmp_table"); List<Item> types; TMP_TABLE_PARAM tmp_table_param; + TABLE *table; + DBUG_ENTER("select_handler::create_tmp_table"); + if (select->master_unit()->join_union_item_types(thd, types, 1)) DBUG_RETURN(NULL); tmp_table_param.init(); - tmp_table_param.field_count= types.elements; - - TABLE *table= ::create_tmp_table(thd, &tmp_table_param, types, - (ORDER *) 0, false, 0, - TMP_TABLE_ALL_COLUMNS, 1, - &empty_clex_str, true, false); + tmp_table_param.field_count= tmp_table_param.func_count= types.elements; + table= ::create_tmp_table(thd, &tmp_table_param, types, + (ORDER *) 0, false, 0, + TMP_TABLE_ALL_COLUMNS, 1, + &empty_clex_str, true, false); DBUG_RETURN(table); } diff --git a/sql/sql_class.cc b/sql/sql_class.cc index cf190f2743a..3858cbfca45 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -4287,6 +4287,7 @@ create_result_table(THD *thd_arg, List<Item> *column_types, { DBUG_ASSERT(table == 0); tmp_table_param.field_count= column_types->elements; + tmp_table_param.func_count= tmp_table_param.field_count; tmp_table_param.bit_fields_as_long= bit_fields_as_long; if (! (table= create_tmp_table(thd_arg, &tmp_table_param, *column_types, diff --git a/sql/sql_class.h b/sql/sql_class.h index 9c1b76e08a7..5f04b21398b 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -6266,6 +6266,7 @@ public: @see opt_sum_query, count_field_types */ uint sum_func_count; + uint copy_func_count; // Allocated copy fields uint hidden_field_count; uint group_parts,group_length,group_null_parts; diff --git a/sql/sql_expression_cache.cc b/sql/sql_expression_cache.cc index bc44ecd79fa..69d85f3343d 100644 --- a/sql/sql_expression_cache.cc +++ b/sql/sql_expression_cache.cc @@ -114,7 +114,7 @@ void Expression_cache_tmptable::init() cache_table_param.init(); /* dependent items and result */ - cache_table_param.field_count= items.elements; + cache_table_param.field_count= cache_table_param.func_count= items.elements; /* postpone table creation to index description */ cache_table_param.skip_create_table= 1; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 214167af3ec..448fcd30a47 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3514,7 +3514,8 @@ bool JOIN::make_aggr_tables_info() if (gbh) { - if (!(pushdown_query= new (thd->mem_root) Pushdown_query(select_lex, gbh))) + if (!(pushdown_query= new (thd->mem_root) Pushdown_query(select_lex, + gbh))) DBUG_RETURN(1); /* We must store rows in the tmp table if we need to do an ORDER BY @@ -3534,6 +3535,7 @@ bool JOIN::make_aggr_tables_info() if (!(curr_tab->tmp_table_param= new TMP_TABLE_PARAM(tmp_table_param))) DBUG_RETURN(1); + curr_tab->tmp_table_param->func_count= all_fields.elements; TABLE* table= create_tmp_table(thd, curr_tab->tmp_table_param, all_fields, NULL, distinct, @@ -19123,6 +19125,7 @@ TABLE *Create_tmp_table::start(THD *thd, */ if (param->precomputed_group_by) copy_func_count+= param->sum_func_count; + param->copy_func_count= copy_func_count; init_sql_alloc(key_memory_TABLE, &own_root, TABLE_ALLOC_BLOCK_SIZE, 0, MYF(MY_THREAD_SPECIFIC)); @@ -19327,8 +19330,9 @@ bool Create_tmp_table::add_fields(THD *thd, We here distinguish between UNION and multi-table-updates by the fact that in the later case group is set to the row pointer. - The test for item->marker == 4 is ensure we don't create a group-by - key over a bit field as heap tables can't handle that. + The test for item->marker == MARKER_NULL_KEY is ensure we + don't create a group-by key over a bit field as heap tables + can't handle that. */ DBUG_ASSERT(!param->schema_table); Field *new_field= @@ -19395,6 +19399,7 @@ bool Create_tmp_table::add_fields(THD *thd, new_field->flags|= FIELD_PART_OF_TMP_UNIQUE; } } + DBUG_ASSERT(fieldnr == m_field_count[other] + m_field_count[distinct]); DBUG_ASSERT(m_blob_count == m_blobs_count[other] + m_blobs_count[distinct]); share->fields= fieldnr; @@ -19403,6 +19408,8 @@ bool Create_tmp_table::add_fields(THD *thd, share->blob_field[m_blob_count]= 0; // End marker copy_func[0]= 0; // End marker param->func_count= (uint) (copy_func - param->items_to_copy); + DBUG_ASSERT(param->func_count <= param->copy_func_count); + share->column_bitmap_size= bitmap_buffer_size(share->fields); thd->mem_root= mem_root_save; @@ -26852,6 +26859,11 @@ bool JOIN::rollup_init() Item **ref_array; tmp_table_param.quick_group= 0; // Can't create groups in tmp table + /* + Each group can potentially be replaced with Item_func_rollup_const() which + needs a copy_func placeholder. + */ + tmp_table_param.func_count+= send_group_parts; rollup.state= ROLLUP::STATE_INITED; /* @@ -26876,7 +26888,6 @@ bool JOIN::rollup_init() ref_array= (Item**) (rollup.ref_pointer_arrays+send_group_parts); - /* Prepare space for field list for the different levels These will be filled up in rollup_make_fields() @@ -27040,7 +27051,6 @@ bool JOIN::rollup_make_fields(List<Item> &fields_arg, List<Item> &sel_fields, /* Point to first hidden field */ uint ref_array_ix= fields_arg.elements-1; - /* Remember where the sum functions ends for the previous level */ sum_funcs_end[pos+1]= *func; diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 87cd0889df9..ccc4438c39c 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -8239,27 +8239,34 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list) TABLE *table; ST_SCHEMA_TABLE *schema_table= table_list->schema_table; ST_FIELD_INFO *fields= schema_table->fields_info; - bool need_all_fieds= table_list->schema_table_reformed || // SHOW command + bool need_all_fields= table_list->schema_table_reformed || // SHOW command thd->lex->only_view_structure(); // need table structure + bool keep_row_order; + TMP_TABLE_PARAM *tmp_table_param; + SELECT_LEX *select_lex; DBUG_ENTER("create_schema_table"); for (; !fields->end_marker(); fields++) field_count++; - TMP_TABLE_PARAM *tmp_table_param = new (thd->mem_root) TMP_TABLE_PARAM; + tmp_table_param = new (thd->mem_root) TMP_TABLE_PARAM; tmp_table_param->init(); tmp_table_param->table_charset= system_charset_info; tmp_table_param->field_count= field_count; tmp_table_param->schema_table= 1; - SELECT_LEX *select_lex= table_list->select_lex; - bool keep_row_order= is_show_command(thd); - if (!(table= create_tmp_table_for_schema(thd, tmp_table_param, *schema_table, - (select_lex->options | thd->variables.option_bits | TMP_TABLE_ALL_COLUMNS), - table_list->alias, !need_all_fieds, keep_row_order))) + select_lex= table_list->select_lex; + keep_row_order= is_show_command(thd); + if (!(table= + create_tmp_table_for_schema(thd, tmp_table_param, *schema_table, + (select_lex->options | + thd->variables.option_bits | + TMP_TABLE_ALL_COLUMNS), + table_list->alias, !need_all_fields, + keep_row_order))) DBUG_RETURN(0); my_bitmap_map* bitmaps= (my_bitmap_map*) thd->alloc(bitmap_buffer_size(field_count)); - my_bitmap_init(&table->def_read_set, (my_bitmap_map*) bitmaps, field_count); + my_bitmap_init(&table->def_read_set, bitmaps, field_count); table->read_set= &table->def_read_set; bitmap_clear_all(table->read_set); table_list->schema_table_param= tmp_table_param; diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 758edbdcbaa..f88f515f0d2 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -344,6 +344,7 @@ select_unit::create_result_table(THD *thd_arg, List<Item> *column_types, DBUG_ASSERT(table == 0); tmp_table_param.init(); tmp_table_param.field_count= column_types->elements; + tmp_table_param.func_count= tmp_table_param.field_count; tmp_table_param.bit_fields_as_long= bit_fields_as_long; tmp_table_param.hidden_field_count= hidden; @@ -384,7 +385,8 @@ select_union_recursive::create_result_table(THD *thd_arg, return true; incr_table_param.init(); - incr_table_param.field_count= column_types->elements; + incr_table_param.field_count= incr_table_param.func_count= + column_types->elements; incr_table_param.bit_fields_as_long= bit_fields_as_long; if (! (incr_table= create_tmp_table(thd_arg, &incr_table_param, *column_types, (ORDER*) 0, false, 1, diff --git a/sql/temporary_tables.cc b/sql/temporary_tables.cc index 5aacd0e6e99..a477aef0bc3 100644 --- a/sql/temporary_tables.cc +++ b/sql/temporary_tables.cc @@ -921,9 +921,8 @@ bool THD::has_temporary_tables() uint THD::create_tmp_table_def_key(char *key, const char *db, const char *table_name) { - DBUG_ENTER("THD::create_tmp_table_def_key"); - uint key_length; + DBUG_ENTER("THD::create_tmp_table_def_key"); key_length= tdc_create_key(key, db, table_name); int4store(key + key_length, variables.server_id); @@ -1172,11 +1171,10 @@ TABLE *THD::open_temporary_table(TMP_TABLE_SHARE *share, */ bool THD::find_and_use_tmp_table(const TABLE_LIST *tl, TABLE **out_table) { - DBUG_ENTER("THD::find_and_use_tmp_table"); - char key[MAX_DBKEY_LENGTH]; uint key_length; bool result; + DBUG_ENTER("THD::find_and_use_tmp_table"); key_length= create_tmp_table_def_key(key, tl->get_db_name(), tl->get_table_name()); 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); } |