From a2a2e32c02643a0cec111511220227703fda1cd5 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Mon, 1 Jul 2024 20:15:00 +0200 Subject: Merging upstream version 1:11.4.2. Signed-off-by: Daniel Baumann --- storage/myisammrg/ha_myisammrg.cc | 59 +++++++---- storage/myisammrg/ha_myisammrg.h | 115 +++++++++++---------- storage/myisammrg/myrg_info.c | 58 +++++------ .../storage_engine/type_char_indexes.rdiff | 9 -- 4 files changed, 133 insertions(+), 108 deletions(-) (limited to 'storage/myisammrg') diff --git a/storage/myisammrg/ha_myisammrg.cc b/storage/myisammrg/ha_myisammrg.cc index d37636ab..b46d0312 100644 --- a/storage/myisammrg/ha_myisammrg.cc +++ b/storage/myisammrg/ha_myisammrg.cc @@ -339,6 +339,33 @@ static void myrg_set_external_ref(MYRG_INFO *m_info, void *ext_ref_arg) } } +IO_AND_CPU_COST ha_myisammrg::rnd_pos_time(ha_rows rows) +{ + IO_AND_CPU_COST cost= handler::rnd_pos_time(rows); + /* + Row data is not cached. costs.row_lookup_cost includes the cost of + the reading the row from system (probably cached by the OS). + */ + cost.io= 0; + return cost; +} + +IO_AND_CPU_COST ha_myisammrg::keyread_time(uint index, ulong ranges, + ha_rows rows, + ulonglong blocks) +{ + IO_AND_CPU_COST cost= handler::keyread_time(index, ranges, rows, blocks); + if (!blocks) + { + cost.io*= file->tables; + cost.cpu*= file->tables; + } + /* Add the cost of having to do a key lookup in all trees */ + if (file->tables) + cost.cpu+= (file->tables-1) * (ranges * KEY_LOOKUP_COST); + return cost; +} + /** Open a MERGE parent table, but not its children. @@ -1246,7 +1273,6 @@ int ha_myisammrg::delete_all_rows() int ha_myisammrg::info(uint flag) { MYMERGE_INFO mrg_info; - DBUG_ASSERT(this->file->children_attached); (void) myrg_status(file,&mrg_info,flag); /* The following fails if one has not compiled MySQL with -DBIG_TABLES @@ -1273,26 +1299,17 @@ int ha_myisammrg::info(uint flag) table->s->keys_in_use.set_prefix(table->s->keys); stats.mean_rec_length= mrg_info.reclength; - /* + /* The handler::block_size is used all over the code in index scan cost calculations. It is used to get number of disk seeks required to retrieve a number of index tuples. - If the merge table has N underlying tables, then (assuming underlying - tables have equal size, the only "simple" approach we can use) - retrieving X index records from a merge table will require N times more - disk seeks compared to doing the same on a MyISAM table with equal - number of records. - In the edge case (file_tables > myisam_block_size) we'll get - block_size==0, and index calculation code will act as if we need one - disk seek to retrieve one index tuple. - - TODO: In 5.2 index scan cost calculation will be factored out into a - virtual function in class handler and we'll be able to remove this hack. + If the merge table has N underlying tables, there will be + N more disk seeks compared to a scanning a normal MyISAM table. + The number of bytes read is the rougly the same for a normal MyISAM + and a MyISAM merge tables. */ - stats.block_size= 0; - if (file->tables) - stats.block_size= myisam_block_size / file->tables; - + stats.block_size= myisam_block_size; + stats.update_time= 0; #if SIZEOF_OFF_T > 4 ref_length=6; // Should be big enough @@ -1744,6 +1761,12 @@ int myisammrg_panic(handlerton *hton, ha_panic_function flag) return myrg_panic(flag); } +static void myisammrg_update_optimizer_costs(OPTIMIZER_COSTS *costs) +{ + myisam_update_optimizer_costs(costs); +} + + static int myisammrg_init(void *p) { handlerton *myisammrg_hton; @@ -1759,7 +1782,7 @@ static int myisammrg_init(void *p) myisammrg_hton->panic= myisammrg_panic; myisammrg_hton->flags= HTON_NO_PARTITION; myisammrg_hton->tablefile_extensions= ha_myisammrg_exts; - + myisammrg_hton->update_optimizer_costs= myisammrg_update_optimizer_costs; return 0; } diff --git a/storage/myisammrg/ha_myisammrg.h b/storage/myisammrg/ha_myisammrg.h index 9964add9..12189b79 100644 --- a/storage/myisammrg/ha_myisammrg.h +++ b/storage/myisammrg/ha_myisammrg.h @@ -82,8 +82,8 @@ public: ha_myisammrg(handlerton *hton, TABLE_SHARE *table_arg); ~ha_myisammrg(); - const char *index_type(uint key_number); - ulonglong table_flags() const + const char *index_type(uint key_number) override; + ulonglong table_flags() const override { return (HA_REC_NOT_IN_SEQ | HA_AUTO_PART_KEY | HA_NO_TRANSACTIONS | HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE | @@ -93,70 +93,81 @@ public: HA_NO_COPY_ON_ALTER | HA_DUPLICATE_POS | HA_CAN_MULTISTEP_MERGE); } - ulong index_flags(uint inx, uint part, bool all_parts) const + ulong index_flags(uint inx, uint part, bool all_parts) const override { return ((table_share->key_info[inx].algorithm == HA_KEY_ALG_FULLTEXT) ? 0 : HA_READ_NEXT | HA_READ_PREV | HA_READ_RANGE | HA_READ_ORDER | HA_KEYREAD_ONLY); } - uint max_supported_keys() const { return MI_MAX_KEY; } - uint max_supported_key_length() const { return HA_MAX_KEY_LENGTH; } - uint max_supported_key_part_length() const { return HA_MAX_KEY_LENGTH; } - double scan_time() - { return ulonglong2double(stats.data_file_length) / IO_SIZE + file->tables; } - - int open(const char *name, int mode, uint test_if_locked); - int add_children_list(void); - int attach_children(void); - int detach_children(void); - virtual handler *clone(const char *name, MEM_ROOT *mem_root); - int close(void); - int write_row(const uchar * buf); - int update_row(const uchar * old_data, const uchar * new_data); - int delete_row(const uchar * buf); + uint max_supported_keys() const override { return MI_MAX_KEY; } + uint max_supported_key_length() const override { return HA_MAX_KEY_LENGTH; } + uint max_supported_key_part_length() const override + { return HA_MAX_KEY_LENGTH; } + IO_AND_CPU_COST scan_time() override + { + IO_AND_CPU_COST cost; + cost.io= (ulonglong2double(stats.data_file_length) / IO_SIZE + + file->tables), + cost.cpu= records() * ROW_NEXT_FIND_COST; + return cost; + } + IO_AND_CPU_COST rnd_pos_time(ha_rows rows) override; + IO_AND_CPU_COST keyread_time(uint index, ulong ranges, ha_rows rows, + ulonglong blocks) override; + int open(const char *name, int mode, uint test_if_locked) override; + handler *clone(const char *name, MEM_ROOT *mem_root) override; + int close(void) override; + int write_row(const uchar * buf) override; + int update_row(const uchar * old_data, const uchar * new_data) override; + int delete_row(const uchar * buf) override; int index_read_map(uchar *buf, const uchar *key, key_part_map keypart_map, - enum ha_rkey_function find_flag); + enum ha_rkey_function find_flag) override; int index_read_idx_map(uchar *buf, uint index, const uchar *key, key_part_map keypart_map, - enum ha_rkey_function find_flag); - int index_read_last_map(uchar *buf, const uchar *key, key_part_map keypart_map); - int index_next(uchar * buf); - int index_prev(uchar * buf); - int index_first(uchar * buf); - int index_last(uchar * buf); - int index_next_same(uchar *buf, const uchar *key, uint keylen); - int rnd_init(bool scan); - int rnd_next(uchar *buf); - int rnd_pos(uchar * buf, uchar *pos); - void position(const uchar *record); + enum ha_rkey_function find_flag) override; + int index_read_last_map(uchar *buf, const uchar *key, key_part_map keypart_map) override; + int index_next(uchar * buf) override; + int index_prev(uchar * buf) override; + int index_first(uchar * buf) override; + int index_last(uchar * buf) override; + int index_next_same(uchar *buf, const uchar *key, uint keylen) override; + int rnd_init(bool scan) override; + int rnd_next(uchar *buf) override; + int rnd_pos(uchar * buf, uchar *pos) override; + void position(const uchar *record) override; ha_rows records_in_range(uint inx, const key_range *start_key, - const key_range *end_key, page_range *pages); - int delete_all_rows(); - int info(uint); - int reset(void); - int extra(enum ha_extra_function operation); - int extra_opt(enum ha_extra_function operation, ulong cache_size); - int external_lock(THD *thd, int lock_type); - uint lock_count(void) const; - int create_mrg(const char *name, HA_CREATE_INFO *create_info); - int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info); + const key_range *end_key, page_range *pages) override; + int delete_all_rows() override; + int info(uint) override; + int reset(void) override; + int extra(enum ha_extra_function operation) override; + int extra_opt(enum ha_extra_function operation, ulong cache_size) override; + int external_lock(THD *thd, int lock_type) override; + uint lock_count(void) const override; + int create(const char *name, TABLE *form, HA_CREATE_INFO *create_info) override; THR_LOCK_DATA **store_lock(THD *thd, THR_LOCK_DATA **to, - enum thr_lock_type lock_type); - void update_create_info(HA_CREATE_INFO *create_info); - void append_create_info(String *packet); - MYRG_INFO *myrg_info() { return file; } - TABLE *table_ptr() { return table; } + enum thr_lock_type lock_type) override; + void update_create_info(HA_CREATE_INFO *create_info) override; + void append_create_info(String *packet) override; enum_alter_inplace_result check_if_supported_inplace_alter(TABLE *, - Alter_inplace_info *); + Alter_inplace_info *) override; bool inplace_alter_table(TABLE *altered_table, - Alter_inplace_info *ha_alter_info); - int check(THD* thd, HA_CHECK_OPT* check_opt); - ha_rows records(); - virtual uint count_query_cache_dependant_tables(uint8 *tables_type); + Alter_inplace_info *ha_alter_info) override; + int check(THD* thd, HA_CHECK_OPT* check_opt) override; + ha_rows records() override; + virtual uint count_query_cache_dependant_tables(uint8 *tables_type) override; virtual my_bool register_query_cache_dependant_tables(THD *thd, Query_cache *cache, Query_cache_block_table **block, - uint *n); - virtual void set_lock_type(enum thr_lock_type lock); + uint *n) override; + virtual void set_lock_type(enum thr_lock_type lock) override; + + /* Internal interface functions, not part of the normal handler interface */ + int add_children_list(void); + int attach_children(void); + int detach_children(void); + int create_mrg(const char *name, HA_CREATE_INFO *create_info); + MYRG_INFO *myrg_info() { return file; } + TABLE *table_ptr() { return table; } }; diff --git a/storage/myisammrg/myrg_info.c b/storage/myisammrg/myrg_info.c index 1d78c650..649b43d0 100644 --- a/storage/myisammrg/myrg_info.c +++ b/storage/myisammrg/myrg_info.c @@ -33,6 +33,8 @@ int myrg_status(MYRG_INFO *info,register MYMERGE_INFO *x,int flag) MYRG_TABLE *current_table; DBUG_ENTER("myrg_status"); + x->errkey= 0; + x->dupp_key_pos= 0; if (!(current_table = info->current_table) && info->open_tables != info->end_table) current_table = info->open_tables; @@ -44,42 +46,40 @@ int myrg_status(MYRG_INFO *info,register MYMERGE_INFO *x,int flag) MYRG_TABLE *file; info->records=info->del=info->data_file_length=0; - for (file=info->open_tables ; file != info->end_table ; file++) + if (likely(info->children_attached)) { - file->file_offset=info->data_file_length; - info->data_file_length+=file->table->s->state.state.data_file_length; - info->records+=file->table->s->state.state.records; - info->del+=file->table->s->state.state.del; - DBUG_PRINT("info2",("table: %s, offset: %lu", - file->table->filename,(ulong) file->file_offset)); + for (file=info->open_tables ; file != info->end_table ; file++) + { + file->file_offset=info->data_file_length; + info->data_file_length+=file->table->s->state.state.data_file_length; + info->records+=file->table->s->state.state.records; + info->del+=file->table->s->state.state.del; + DBUG_PRINT("info2",("table: %s, offset: %lu", + file->table->filename,(ulong) file->file_offset)); + } + if (current_table) + { + /* + errkey is set to the index number of the myisam tables. But + since the MERGE table can have less keys than the MyISAM + tables, errkey cannot be be used as an index into the key_info + on the server. This value will be overwritten with MAX_KEY by + the MERGE engine. + */ + x->errkey= current_table->table->errkey; + /* + Calculate the position of the duplicate key to be the sum of the + offset of the myisam file and the offset into the file at which + the duplicate key is located. + */ + x->dupp_key_pos= current_table->file_offset + current_table->table->dupp_key_pos; + } } x->records= info->records; x->deleted= info->del; x->data_file_length= info->data_file_length; x->reclength= info->reclength; x->options= info->options; - if (current_table) - { - /* - errkey is set to the index number of the myisam tables. But - since the MERGE table can have less keys than the MyISAM - tables, errkey cannot be be used as an index into the key_info - on the server. This value will be overwritten with MAX_KEY by - the MERGE engine. - */ - x->errkey= current_table->table->errkey; - /* - Calculate the position of the duplicate key to be the sum of the - offset of the myisam file and the offset into the file at which - the duplicate key is located. - */ - x->dupp_key_pos= current_table->file_offset + current_table->table->dupp_key_pos; - } - else - { - x->errkey= 0; - x->dupp_key_pos= 0; - } x->rec_per_key = info->rec_per_key_part; } DBUG_RETURN(0); diff --git a/storage/myisammrg/mysql-test/storage_engine/type_char_indexes.rdiff b/storage/myisammrg/mysql-test/storage_engine/type_char_indexes.rdiff index 797907fa..78c47ded 100644 --- a/storage/myisammrg/mysql-test/storage_engine/type_char_indexes.rdiff +++ b/storage/myisammrg/mysql-test/storage_engine/type_char_indexes.rdiff @@ -1,14 +1,5 @@ --- suite/storage_engine/type_char_indexes.result 2014-10-12 14:22:11.000000000 +0400 +++ suite/storage_engine/type_char_indexes.reject 2014-10-12 14:22:41.000000000 +0400 -@@ -100,7 +100,7 @@ - Warning 1681 'engine_condition_pushdown=on' is deprecated and will be removed in a future release. - EXPLAIN SELECT c,c20,v16,v128 FROM t1 WHERE c > 'a'; - id select_type table type possible_keys key key_len ref rows Extra --# # # range c_v c_v # # # Using index condition -+# # # ALL c_v NULL # # # Using where - SELECT c,c20,v16,v128 FROM t1 WHERE c > 'a'; - c c20 v16 v128 - b char3 varchar1a varchar1b @@ -137,7 +137,7 @@ r3a EXPLAIN SELECT c,c20,v16,v128 FROM t1 WHERE v16 = 'varchar1a' OR v16 = 'varchar3a' ORDER BY v16; -- cgit v1.2.3