diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2021-08-18 16:51:52 +0300 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2021-08-18 16:51:52 +0300 |
commit | f84e28c119b495da77e197f7cd18af4048fc3126 (patch) | |
tree | 5957008a7725e23cc6331b1251ff5d3f6b725076 /sql | |
parent | ac2857a5fbf851d90171ac55f23385869ee6ba83 (diff) | |
parent | e4901d9523ab838ea13bb0278980f8707aa2c581 (diff) | |
download | mariadb-git-f84e28c119b495da77e197f7cd18af4048fc3126.tar.gz |
Merge 10.3 into 10.4
Diffstat (limited to 'sql')
-rw-r--r-- | sql/field.cc | 3 | ||||
-rw-r--r-- | sql/field.h | 33 | ||||
-rw-r--r-- | sql/filesort.cc | 9 | ||||
-rw-r--r-- | sql/ha_partition.cc | 215 | ||||
-rw-r--r-- | sql/ha_partition.h | 11 | ||||
-rw-r--r-- | sql/handler.cc | 4 | ||||
-rw-r--r-- | sql/item_jsonfunc.h | 2 | ||||
-rw-r--r-- | sql/sql_class.cc | 4 | ||||
-rw-r--r-- | sql/sql_insert.cc | 4 | ||||
-rw-r--r-- | sql/sql_lex.cc | 5 | ||||
-rw-r--r-- | sql/sql_parse.cc | 4 | ||||
-rw-r--r-- | sql/sql_view.cc | 2 | ||||
-rw-r--r-- | sql/table.cc | 4 | ||||
-rw-r--r-- | sql/table.h | 2 | ||||
-rw-r--r-- | sql/wsrep_client_service.cc | 6 | ||||
-rw-r--r-- | sql/wsrep_high_priority_service.cc | 23 | ||||
-rw-r--r-- | sql/wsrep_mysqld.cc | 66 | ||||
-rw-r--r-- | sql/wsrep_mysqld.h | 4 | ||||
-rw-r--r-- | sql/wsrep_thd.cc | 15 | ||||
-rw-r--r-- | sql/wsrep_thd.h | 6 | ||||
-rw-r--r-- | sql/wsrep_var.cc | 4 |
21 files changed, 261 insertions, 165 deletions
diff --git a/sql/field.cc b/sql/field.cc index b391234b866..8b82077f452 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -1,6 +1,6 @@ /* Copyright (c) 2000, 2017, Oracle and/or its affiliates. - Copyright (c) 2008, 2020, MariaDB + Copyright (c) 2008, 2021, MariaDB This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -8556,6 +8556,7 @@ int Field_blob::store(const char *from,size_t length,CHARSET_INFO *cs) rc= well_formed_copy_with_check((char*) value.ptr(), (uint) new_length, cs, from, length, length, true, ©_len); + value.length(copy_len); Field_blob::store_length(copy_len); bmove(ptr+packlength,(uchar*) &tmp,sizeof(char*)); diff --git a/sql/field.h b/sql/field.h index 477c64727b3..5c2ba4c5c84 100644 --- a/sql/field.h +++ b/sql/field.h @@ -4030,6 +4030,12 @@ public: uchar *new_ptr, uint32 length, uchar *new_null_ptr, uint new_null_bit); void sql_type(String &str) const; + /** + Copy blob buffer into internal storage "value" and update record pointer. + + @retval true Memory allocation error + @retval false Success + */ inline bool copy() { uchar *tmp= get_ptr(); @@ -4042,6 +4048,33 @@ public: memcpy(ptr+packlength, &tmp, sizeof(char*)); return 0; } + void swap(String &inout, bool set_read_value) + { + if (set_read_value) + read_value.swap(inout); + else + value.swap(inout); + } + /** + Return pointer to blob cache or NULL if not cached. + */ + String * cached(bool *set_read_value) + { + char *tmp= (char *) get_ptr(); + if (!value.is_empty() && tmp == value.ptr()) + { + *set_read_value= false; + return &value; + } + + if (!read_value.is_empty() && tmp == read_value.ptr()) + { + *set_read_value= true; + return &read_value; + } + + return NULL; + } /* store value for the duration of the current read record */ inline void swap_value_and_read_value() { diff --git a/sql/filesort.cc b/sql/filesort.cc index aa25474be1a..ee19dfcb386 100644 --- a/sql/filesort.cc +++ b/sql/filesort.cc @@ -597,6 +597,15 @@ const char* dbug_print_table_row(TABLE *table) } +const char* dbug_print_row(TABLE *table, uchar *rec) +{ + table->move_fields(table->field, rec, table->record[0]); + const char* ret= dbug_print_table_row(table); + table->move_fields(table->field, table->record[0], rec); + return ret; +} + + /* Print a text, SQL-like record representation into dbug trace. diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 50b9149ef0c..c8d5d68b5d6 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -5289,58 +5289,68 @@ bool ha_partition::init_record_priority_queue() /* Initialize the ordered record buffer. */ - if (!m_ordered_rec_buffer) - { - size_t alloc_len; - uint used_parts= bitmap_bits_set(&m_part_info->read_partitions); - - if (used_parts == 0) /* Do nothing since no records expected. */ - DBUG_RETURN(false); + size_t alloc_len; + uint used_parts= bitmap_bits_set(&m_part_info->read_partitions); - /* Allocate record buffer for each used partition. */ - m_priority_queue_rec_len= m_rec_length + PARTITION_BYTES_IN_POS; - if (!m_using_extended_keys) - m_priority_queue_rec_len += get_open_file_sample()->ref_length; - alloc_len= used_parts * m_priority_queue_rec_len; - /* Allocate a key for temporary use when setting up the scan. */ - alloc_len+= table_share->max_key_length; + if (used_parts == 0) /* Do nothing since no records expected. */ + DBUG_RETURN(false); - if (!(m_ordered_rec_buffer= (uchar*)my_malloc(alloc_len, MYF(MY_WME)))) - DBUG_RETURN(true); + /* Allocate record buffer for each used partition. */ + m_priority_queue_rec_len= m_rec_length + ORDERED_REC_OFFSET; + if (!m_using_extended_keys) + m_priority_queue_rec_len+= get_open_file_sample()->ref_length; + alloc_len= used_parts * m_priority_queue_rec_len; + /* Allocate a key for temporary use when setting up the scan. */ + alloc_len+= table_share->max_key_length; + Ordered_blob_storage **blob_storage; + Ordered_blob_storage *objs; + const size_t n_all= used_parts * table->s->blob_fields; + + if (!my_multi_malloc(MYF(MY_WME), &m_ordered_rec_buffer, alloc_len, + &blob_storage, n_all * sizeof *blob_storage, + &objs, n_all * sizeof *objs, NULL)) + DBUG_RETURN(true); - /* - We set-up one record per partition and each record has 2 bytes in - front where the partition id is written. This is used by ordered - index_read. - We also set-up a reference to the first record for temporary use in - setting up the scan. - */ - char *ptr= (char*) m_ordered_rec_buffer; - uint i; - for (i= bitmap_get_first_set(&m_part_info->read_partitions); - i < m_tot_parts; - i= bitmap_get_next_set(&m_part_info->read_partitions, i)) + /* + We set-up one record per partition and each record has 2 bytes in + front where the partition id is written. This is used by ordered + index_read. + We also set-up a reference to the first record for temporary use in + setting up the scan. + */ + char *ptr= (char*) m_ordered_rec_buffer; + uint i; + for (i= bitmap_get_first_set(&m_part_info->read_partitions); + i < m_tot_parts; + i= bitmap_get_next_set(&m_part_info->read_partitions, i)) + { + DBUG_PRINT("info", ("init rec-buf for part %u", i)); + if (table->s->blob_fields) { - DBUG_PRINT("info", ("init rec-buf for part %u", i)); - int2store(ptr, i); - ptr+= m_priority_queue_rec_len; + for (uint j= 0; j < table->s->blob_fields; ++j, ++objs) + blob_storage[j]= new (objs) Ordered_blob_storage; + *((Ordered_blob_storage ***) ptr)= blob_storage; + blob_storage+= table->s->blob_fields; } - m_start_key.key= (const uchar*)ptr; + int2store(ptr + sizeof(String **), i); + ptr+= m_priority_queue_rec_len; + } + m_start_key.key= (const uchar*)ptr; - /* Initialize priority queue, initialized to reading forward. */ - int (*cmp_func)(void *, uchar *, uchar *); - void *cmp_arg= (void*) this; - if (!m_using_extended_keys && !(table_flags() & HA_SLOW_CMP_REF)) - cmp_func= cmp_key_rowid_part_id; - else - cmp_func= cmp_key_part_id; - DBUG_PRINT("info", ("partition queue_init(1) used_parts: %u", used_parts)); - if (init_queue(&m_queue, used_parts, 0, 0, cmp_func, cmp_arg, 0, 0)) - { - my_free(m_ordered_rec_buffer); - m_ordered_rec_buffer= NULL; - DBUG_RETURN(true); - } + /* Initialize priority queue, initialized to reading forward. */ + int (*cmp_func)(void *, uchar *, uchar *); + void *cmp_arg= (void*) this; + if (!m_using_extended_keys && !(table_flags() & HA_SLOW_CMP_REF)) + cmp_func= cmp_key_rowid_part_id; + else + cmp_func= cmp_key_part_id; + DBUG_PRINT("info", ("partition queue_init(1) used_parts: %u", used_parts)); + if (init_queue(&m_queue, used_parts, ORDERED_PART_NUM_OFFSET, + 0, cmp_func, cmp_arg, 0, 0)) + { + my_free(m_ordered_rec_buffer); + m_ordered_rec_buffer= NULL; + DBUG_RETURN(true); } DBUG_RETURN(false); } @@ -5355,6 +5365,20 @@ void ha_partition::destroy_record_priority_queue() DBUG_ENTER("ha_partition::destroy_record_priority_queue"); if (m_ordered_rec_buffer) { + if (table->s->blob_fields) + { + char *ptr= (char *) m_ordered_rec_buffer; + for (uint i= bitmap_get_first_set(&m_part_info->read_partitions); + i < m_tot_parts; + i= bitmap_get_next_set(&m_part_info->read_partitions, i)) + { + Ordered_blob_storage **blob_storage= *((Ordered_blob_storage ***) ptr); + for (uint b= 0; b < table->s->blob_fields; ++b) + blob_storage[b]->blob.free(); + ptr+= m_priority_queue_rec_len; + } + } + delete_queue(&m_queue); my_free(m_ordered_rec_buffer); m_ordered_rec_buffer= NULL; @@ -5582,12 +5606,10 @@ static int cmp_part_ids(uchar *ref1, uchar *ref2) extern "C" int cmp_key_part_id(void *ptr, uchar *ref1, uchar *ref2) { ha_partition *file= (ha_partition*)ptr; - int res; - if ((res= key_rec_cmp(file->m_curr_key_info, ref1 + PARTITION_BYTES_IN_POS, - ref2 + PARTITION_BYTES_IN_POS))) - { + if (int res= key_rec_cmp(file->m_curr_key_info, + ref1 + PARTITION_BYTES_IN_POS, + ref2 + PARTITION_BYTES_IN_POS)) return res; - } return cmp_part_ids(ref1, ref2); } @@ -6836,6 +6858,48 @@ int ha_partition::pre_ft_end() } +void ha_partition::swap_blobs(uchar * rec_buf, Ordered_blob_storage ** storage, bool restore) +{ + uint *ptr, *end; + uint blob_n= 0; + table->move_fields(table->field, rec_buf, table->record[0]); + for (ptr= table->s->blob_field, end= ptr + table->s->blob_fields; + ptr != end; ++ptr, ++blob_n) + { + DBUG_ASSERT(*ptr < table->s->fields); + Field_blob *blob= (Field_blob*) table->field[*ptr]; + DBUG_ASSERT(blob->flags & BLOB_FLAG); + DBUG_ASSERT(blob->field_index == *ptr); + if (!bitmap_is_set(table->read_set, *ptr) || blob->is_null()) + continue; + + Ordered_blob_storage &s= *storage[blob_n]; + + if (restore) + { + /* + We protect only blob cache (value or read_value). If the cache was + empty that doesn't mean the blob was empty. Blobs allocated by a + storage engine should work just fine. + */ + if (!s.blob.is_empty()) + blob->swap(s.blob, s.set_read_value); + } + else + { + bool set_read_value; + String *cached= blob->cached(&set_read_value); + if (cached) + { + cached->swap(s.blob); + s.set_read_value= set_read_value; + } + } + } + table->move_fields(table->field, table->record[0], rec_buf); +} + + /** Initialize a full text search using the extended API. @@ -7549,8 +7613,8 @@ int ha_partition::handle_ordered_index_scan(uchar *buf, bool reverse_order) { DBUG_PRINT("info", ("reading from part %u (scan_type: %u)", i, m_index_scan_type)); - DBUG_ASSERT(i == uint2korr(part_rec_buf_ptr)); - uchar *rec_buf_ptr= part_rec_buf_ptr + PARTITION_BYTES_IN_POS; + DBUG_ASSERT(i == uint2korr(part_rec_buf_ptr + ORDERED_PART_NUM_OFFSET)); + uchar *rec_buf_ptr= part_rec_buf_ptr + ORDERED_REC_OFFSET; handler *file= m_file[i]; switch (m_index_scan_type) { @@ -7630,6 +7694,12 @@ int ha_partition::handle_ordered_index_scan(uchar *buf, bool reverse_order) Initialize queue without order first, simply insert */ queue_element(&m_queue, j++)= part_rec_buf_ptr; + if (table->s->blob_fields) + { + Ordered_blob_storage **storage= + *((Ordered_blob_storage ***) part_rec_buf_ptr); + swap_blobs(rec_buf_ptr, storage, false); + } } else if (error == HA_ERR_KEY_NOT_FOUND) { @@ -7672,7 +7742,7 @@ int ha_partition::handle_ordered_index_scan(uchar *buf, bool reverse_order) DBUG_PRINT("info", ("partition !bitmap_is_set(&m_mrr_used_partitions, i)")); continue; } - DBUG_ASSERT(i == uint2korr(part_rec_buf_ptr)); + DBUG_ASSERT(i == uint2korr(part_rec_buf_ptr + ORDERED_PART_NUM_OFFSET)); if (smallest_range_seq == m_stock_range_seq[i]) { m_stock_range_seq[i]= 0; @@ -7719,12 +7789,17 @@ void ha_partition::return_top_record(uchar *buf) { uint part_id; uchar *key_buffer= queue_top(&m_queue); - uchar *rec_buffer= key_buffer + PARTITION_BYTES_IN_POS; + uchar *rec_buffer= key_buffer + ORDERED_REC_OFFSET; DBUG_ENTER("ha_partition::return_top_record"); DBUG_PRINT("enter", ("partition this: %p", this)); - part_id= uint2korr(key_buffer); + part_id= uint2korr(key_buffer + ORDERED_PART_NUM_OFFSET); memcpy(buf, rec_buffer, m_rec_length); + if (table->s->blob_fields) + { + Ordered_blob_storage **storage= *((Ordered_blob_storage ***) key_buffer); + swap_blobs(buf, storage, true); + } m_last_part= part_id; DBUG_PRINT("info", ("partition m_last_part: %u", m_last_part)); m_top_entry= part_id; @@ -7776,7 +7851,7 @@ int ha_partition::handle_ordered_index_scan_key_not_found() This partition is used and did return HA_ERR_KEY_NOT_FOUND in index_read_map. */ - curr_rec_buf= part_buf + PARTITION_BYTES_IN_POS; + curr_rec_buf= part_buf + ORDERED_REC_OFFSET; error= m_file[i]->ha_index_next(curr_rec_buf); /* HA_ERR_KEY_NOT_FOUND is not allowed from index_next! */ DBUG_ASSERT(error != HA_ERR_KEY_NOT_FOUND); @@ -7827,7 +7902,8 @@ int ha_partition::handle_ordered_next(uchar *buf, bool is_next_same) DBUG_RETURN(HA_ERR_END_OF_FILE); uint part_id= m_top_entry; - uchar *rec_buf= queue_top(&m_queue) + PARTITION_BYTES_IN_POS; + uchar *part_rec_buf_ptr= queue_top(&m_queue); + uchar *rec_buf= part_rec_buf_ptr + ORDERED_REC_OFFSET; handler *file; if (m_key_not_found) @@ -7869,7 +7945,16 @@ int ha_partition::handle_ordered_next(uchar *buf, bool is_next_same) if (m_index_scan_type == partition_read_range) { error= file->read_range_next(); - memcpy(rec_buf, table->record[0], m_rec_length); + if (likely(!error)) + { + memcpy(rec_buf, table->record[0], m_rec_length); + if (table->s->blob_fields) + { + Ordered_blob_storage **storage= + *((Ordered_blob_storage ***) part_rec_buf_ptr); + swap_blobs(rec_buf, storage, false); + } + } } else if (m_index_scan_type == partition_read_multi_range) { @@ -7906,6 +7991,11 @@ int ha_partition::handle_ordered_next(uchar *buf, bool is_next_same) DBUG_PRINT("info", ("m_mrr_range_current->id: %u", m_mrr_range_current->id)); memcpy(rec_buf, table->record[0], m_rec_length); + if (table->s->blob_fields) + { + Ordered_blob_storage **storage= *((Ordered_blob_storage ***) part_rec_buf_ptr); + swap_blobs(rec_buf, storage, false); + } if (((PARTITION_KEY_MULTI_RANGE *) m_range_info[part_id])->id != m_mrr_range_current->id) { @@ -7956,9 +8046,8 @@ int ha_partition::handle_ordered_next(uchar *buf, bool is_next_same) DBUG_PRINT("info",("partition !bitmap_is_set(&m_mrr_used_partitions, i)")); continue; } - DBUG_PRINT("info",("partition uint2korr: %u", - uint2korr(part_rec_buf_ptr))); - DBUG_ASSERT(i == uint2korr(part_rec_buf_ptr)); + DBUG_ASSERT(i == uint2korr(part_rec_buf_ptr + + ORDERED_PART_NUM_OFFSET)); DBUG_PRINT("info", ("partition m_stock_range_seq[%u]: %u", i, m_stock_range_seq[i])); if (smallest_range_seq == m_stock_range_seq[i]) @@ -8047,7 +8136,7 @@ int ha_partition::handle_ordered_prev(uchar *buf) DBUG_RETURN(HA_ERR_END_OF_FILE); uint part_id= m_top_entry; - uchar *rec_buf= queue_top(&m_queue) + PARTITION_BYTES_IN_POS; + uchar *rec_buf= queue_top(&m_queue) + ORDERED_REC_OFFSET; handler *file= m_file[part_id]; if (unlikely((error= file->ha_index_prev(rec_buf)))) diff --git a/sql/ha_partition.h b/sql/ha_partition.h index 240d71447ec..8b2c42d94bc 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -21,7 +21,17 @@ #include "sql_partition.h" /* part_id_range, partition_element */ #include "queues.h" /* QUEUE */ +struct Ordered_blob_storage +{ + String blob; + bool set_read_value; + Ordered_blob_storage() : set_read_value(false) + {} +}; + #define PARTITION_BYTES_IN_POS 2 +#define ORDERED_PART_NUM_OFFSET sizeof(Ordered_blob_storage **) +#define ORDERED_REC_OFFSET (ORDERED_PART_NUM_OFFSET + PARTITION_BYTES_IN_POS) /** Struct used for partition_name_hash */ @@ -927,6 +937,7 @@ private: int handle_ordered_next(uchar * buf, bool next_same); int handle_ordered_prev(uchar * buf); void return_top_record(uchar * buf); + void swap_blobs(uchar* rec_buf, Ordered_blob_storage ** storage, bool restore); public: /* ------------------------------------------------------------------------- diff --git a/sql/handler.cc b/sql/handler.cc index 757fa95a9a3..6b8c39cb0c4 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -1,5 +1,5 @@ /* Copyright (c) 2000, 2016, Oracle and/or its affiliates. - Copyright (c) 2009, 2021, MariaDB Corporation. + Copyright (c) 2009, 2020, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1946,7 +1946,7 @@ int ha_rollback_trans(THD *thd, bool all) if (thd->is_error()) { WSREP_DEBUG("ha_rollback_trans(%lld, %s) rolled back: %s: %s; is_real %d", - thd->thread_id, all?"TRUE":"FALSE", wsrep_thd_query(thd), + thd->thread_id, all?"TRUE":"FALSE", WSREP_QUERY(thd), thd->get_stmt_da()->message(), is_real_trans); } (void) wsrep_after_rollback(thd, all); diff --git a/sql/item_jsonfunc.h b/sql/item_jsonfunc.h index c703533f799..798c5d502db 100644 --- a/sql/item_jsonfunc.h +++ b/sql/item_jsonfunc.h @@ -375,7 +375,7 @@ public: const char *func_name() const { return mode_insert ? - (mode_replace ? "json_set" : "json_insert") : "json_update"; + (mode_replace ? "json_set" : "json_insert") : "json_replace"; } Item *get_copy(THD *thd) { return get_item_copy<Item_func_json_insert>(thd, this); } diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 3040aeba4ba..28bf77c94e8 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -5228,8 +5228,8 @@ extern "C" bool thd_is_strict_mode(const MYSQL_THD thd) */ void thd_get_query_start_data(THD *thd, char *buf) { - LEX_CSTRING field_name; - Field_timestampf f((uchar *)buf, NULL, 0, Field::NONE, &field_name, NULL, 6); + Field_timestampf f((uchar *)buf, nullptr, 0, Field::NONE, &empty_clex_str, + nullptr, 6); f.store_TIME(thd->query_start(), thd->query_start_sec_part()); } diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index cbd815eb8fd..e04062d66d5 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1,6 +1,6 @@ /* Copyright (c) 2000, 2016, Oracle and/or its affiliates. - Copyright (c) 2010, 2021, MariaDB Corporation + Copyright (c) 2010, 2019, MariaDB Corporation This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -4782,7 +4782,7 @@ bool select_create::send_eof() { WSREP_DEBUG("select_create commit failed, thd: %llu err: %s %s", thd->thread_id, - wsrep_thd_transaction_state_str(thd), wsrep_thd_query(thd)); + wsrep_thd_transaction_state_str(thd), WSREP_QUERY(thd)); mysql_mutex_unlock(&thd->LOCK_thd_data); abort_result_set(); DBUG_RETURN(true); diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 1ec5d0b0550..c6db441220e 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -2998,7 +2998,7 @@ bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num) prepared statement */ Query_arena *arena= thd->stmt_arena; - const uint n_elems= (n_sum_items + + const size_t n_elems= (n_sum_items + n_child_sum_items + item_list.elements + select_n_reserved + @@ -3006,7 +3006,8 @@ bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num) select_n_where_fields + order_group_num + hidden_bit_fields + - fields_in_window_functions) * 5; + fields_in_window_functions) * (size_t) 5; + DBUG_ASSERT(n_elems % 5 == 0); if (!ref_pointer_array.is_null()) { /* diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 8999397fee7..9e78a1a95e2 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -7845,7 +7845,7 @@ static bool wsrep_mysql_parse(THD *thd, char *rawbuf, uint length, DBUG_ASSERT(!debug_sync_set_action(thd, STRING_WITH_LEN(act))); }); WSREP_DEBUG("wsrep retrying AC query: %lu %s", - thd->wsrep_retry_counter, wsrep_thd_query(thd)); + thd->wsrep_retry_counter, WSREP_QUERY(thd)); wsrep_prepare_for_autocommit_retry(thd, rawbuf, length, parser_state); if (thd->lex->explain) delete_explain_query(thd->lex); @@ -7859,7 +7859,7 @@ static bool wsrep_mysql_parse(THD *thd, char *rawbuf, uint length, is_autocommit, thd->wsrep_retry_counter, thd->variables.wsrep_retry_autocommit, - wsrep_thd_query(thd)); + WSREP_QUERY(thd)); my_error(ER_LOCK_DEADLOCK, MYF(0)); thd->reset_kill_query(); thd->wsrep_retry_counter= 0; // reset diff --git a/sql/sql_view.cc b/sql/sql_view.cc index c81b5db0d26..9d4ba09f1b3 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -837,7 +837,7 @@ int mariadb_fix_view(THD *thd, TABLE_LIST *view, bool wrong_checksum, if ((view->md5.str= (char *)thd->alloc(32 + 1)) == NULL) DBUG_RETURN(HA_ADMIN_FAILED); } - view->calc_md5(view->md5.str); + view->calc_md5(const_cast<char*>(view->md5.str)); view->md5.length= 32; } view->mariadb_version= MYSQL_VERSION_ID; diff --git a/sql/table.cc b/sql/table.cc index 4ed47998ecc..d7e892b1dfd 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -5297,12 +5297,12 @@ void TABLE::reset_item_list(List<Item> *item_list, uint skip) const buffer buffer for md5 writing */ -void TABLE_LIST::calc_md5(const char *buffer) +void TABLE_LIST::calc_md5(char *buffer) { uchar digest[16]; compute_md5_hash(digest, select_stmt.str, select_stmt.length); - sprintf((char *) buffer, + sprintf(buffer, "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x", digest[0], digest[1], digest[2], digest[3], digest[4], digest[5], digest[6], digest[7], diff --git a/sql/table.h b/sql/table.h index 05add349fb0..a674f7953ef 100644 --- a/sql/table.h +++ b/sql/table.h @@ -2652,7 +2652,7 @@ struct TABLE_LIST List<String> *partition_names; #endif /* WITH_PARTITION_STORAGE_ENGINE */ - void calc_md5(const char *buffer); + void calc_md5(char *buffer); int view_check_option(THD *thd, bool ignore_failure); bool create_field_translation(THD *thd); bool setup_underlying(THD *thd); diff --git a/sql/wsrep_client_service.cc b/sql/wsrep_client_service.cc index f045e5d271a..89621619a23 100644 --- a/sql/wsrep_client_service.cc +++ b/sql/wsrep_client_service.cc @@ -1,4 +1,4 @@ -/* Copyright 2018-2021 Codership Oy <info@codership.com> +/* Copyright 2018 Codership Oy <info@codership.com> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -109,14 +109,14 @@ int Wsrep_client_service::prepare_data_for_replication() "affected rows: %llu, " "changed tables: %d, " "sql_log_bin: %d", - wsrep_thd_query(m_thd), + WSREP_QUERY(m_thd), m_thd->get_stmt_da()->affected_rows(), stmt_has_updated_trans_table(m_thd), m_thd->variables.sql_log_bin); } else { - WSREP_DEBUG("empty rbr buffer, query: %s", wsrep_thd_query(m_thd)); + WSREP_DEBUG("empty rbr buffer, query: %s", WSREP_QUERY(m_thd)); } } DBUG_RETURN(0); diff --git a/sql/wsrep_high_priority_service.cc b/sql/wsrep_high_priority_service.cc index 452242dfd23..0da71c3eda5 100644 --- a/sql/wsrep_high_priority_service.cc +++ b/sql/wsrep_high_priority_service.cc @@ -1,4 +1,4 @@ -/* Copyright 2018-2021 Codership Oy <info@codership.com> +/* Copyright 2018 Codership Oy <info@codership.com> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -379,16 +379,6 @@ int Wsrep_high_priority_service::apply_toi(const wsrep::ws_meta& ws_meta, WSREP_DEBUG("Wsrep_high_priority_service::apply_toi: %lld", client_state.toi_meta().seqno().get()); - DBUG_EXECUTE_IF("sync.wsrep_apply_toi", - { - const char act[]= - "now " - "SIGNAL sync.wsrep_apply_toi_reached " - "WAIT_FOR signal.wsrep_apply_toi"; - DBUG_ASSERT(!debug_sync_set_action(thd, - STRING_WITH_LEN(act))); - };); - int ret= wsrep_apply_events(thd, m_rli, data.data(), data.size()); if (ret != 0 || thd->wsrep_has_ignored_error) { @@ -437,15 +427,6 @@ int Wsrep_high_priority_service::log_dummy_write_set(const wsrep::ws_handle& ws_ DBUG_PRINT("info", ("Wsrep_high_priority_service::log_dummy_write_set: seqno=%lld", ws_meta.seqno().get())); - DBUG_EXECUTE_IF("sync.wsrep_log_dummy_write_set", - { - const char act[]= - "now " - "SIGNAL sync.wsrep_log_dummy_write_set_reached "; - DBUG_ASSERT(!debug_sync_set_action(m_thd, - STRING_WITH_LEN(act))); - };); - if (ws_meta.ordered()) { wsrep::client_state& cs(m_thd->wsrep_cs()); @@ -677,7 +658,7 @@ Wsrep_replayer_service::~Wsrep_replayer_service() DBUG_ASSERT(0); WSREP_ERROR("trx_replay failed for: %d, schema: %s, query: %s", m_replay_status, - orig_thd->db.str, wsrep_thd_query(orig_thd)); + orig_thd->db.str, WSREP_QUERY(orig_thd)); unireg_abort(1); } } diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index bf1e4e32b49..cabf066abf4 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -1,4 +1,4 @@ -/* Copyright 2008-2021 Codership Oy <http://www.codership.com> +/* Copyright 2008-2015 Codership Oy <http://www.codership.com> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -2008,10 +2008,10 @@ static int wsrep_TOI_begin(THD *thd, const char *db, const char *table, { DBUG_ASSERT(thd->variables.wsrep_OSU_method == WSREP_OSU_TOI); - WSREP_DEBUG("TOI Begin for %s", wsrep_thd_query(thd)); + WSREP_DEBUG("TOI Begin for %s", WSREP_QUERY(thd)); if (wsrep_can_run_in_toi(thd, db, table, table_list) == false) { - WSREP_DEBUG("No TOI for %s", wsrep_thd_query(thd)); + WSREP_DEBUG("No TOI for %s", WSREP_QUERY(thd)); return 1; } @@ -2039,7 +2039,7 @@ static int wsrep_TOI_begin(THD *thd, const char *db, const char *table, /* non replicated DDL, affecting temporary tables only */ WSREP_DEBUG("TO isolation skipped, sql: %s." "Only temporary tables affected.", - wsrep_thd_query(thd)); + WSREP_QUERY(thd)); if (buf) my_free(buf); return -1; } @@ -2054,7 +2054,7 @@ static int wsrep_TOI_begin(THD *thd, const char *db, const char *table, { DBUG_ASSERT(cs.current_error()); WSREP_DEBUG("to_execute_start() failed for %llu: %s, seqno: %lld", - thd->thread_id, wsrep_thd_query(thd), + thd->thread_id, WSREP_QUERY(thd), (long long)wsrep_thd_trx_seqno(thd)); /* jump to error handler in mysql_execute_command() */ @@ -2065,32 +2065,15 @@ static int wsrep_TOI_begin(THD *thd, const char *db, const char *table, "Maximum size exceeded.", ret, (thd->db.str ? thd->db.str : "(null)"), - wsrep_thd_query(thd)); + WSREP_QUERY(thd)); my_error(ER_ERROR_DURING_COMMIT, MYF(0), WSREP_SIZE_EXCEEDED); break; - case wsrep::e_deadlock_error: - WSREP_WARN("TO isolation failed for: %d, schema: %s, sql: %s. " - "Deadlock error.", - ret, - (thd->db.str ? thd->db.str : "(null)"), - wsrep_thd_query(thd)); - my_error(ER_LOCK_DEADLOCK, MYF(0)); - break; - case wsrep::e_timeout_error: - WSREP_WARN("TO isolation failed for: %d, schema: %s, sql: %s. " - "Operation timed out.", - ret, - (thd->db.str ? thd->db.str : "(null)"), - wsrep_thd_query(thd)); - my_error(ER_LOCK_WAIT_TIMEOUT, MYF(0)); - break; default: WSREP_WARN("TO isolation failed for: %d, schema: %s, sql: %s. " - "Check your wsrep connection state and retry the query.", + "Check wsrep connection state and retry the query.", ret, (thd->db.str ? thd->db.str : "(null)"), - wsrep_thd_query(thd)); - + WSREP_QUERY(thd)); if (!thd->is_error()) { my_error(ER_LOCK_DEADLOCK, MYF(0), "WSREP replication failed. Check " @@ -2123,19 +2106,19 @@ static void wsrep_TOI_end(THD *thd) { if (!ret) { WSREP_DEBUG("TO END: %lld: %s", - client_state.toi_meta().seqno().get(), wsrep_thd_query(thd)); + client_state.toi_meta().seqno().get(), WSREP_QUERY(thd)); } else { WSREP_WARN("TO isolation end failed for: %d, sql: %s", - ret, wsrep_thd_query(thd)); + ret, WSREP_QUERY(thd)); } } static int wsrep_RSU_begin(THD *thd, const char *db_, const char *table_) { WSREP_DEBUG("RSU BEGIN: %lld, : %s", wsrep_thd_trx_seqno(thd), - wsrep_thd_query(thd)); + WSREP_QUERY(thd)); if (thd->wsrep_cs().begin_rsu(5000)) { WSREP_WARN("RSU begin failed"); @@ -2150,7 +2133,7 @@ static int wsrep_RSU_begin(THD *thd, const char *db_, const char *table_) static void wsrep_RSU_end(THD *thd) { WSREP_DEBUG("RSU END: %lld : %s", wsrep_thd_trx_seqno(thd), - wsrep_thd_query(thd)); + WSREP_QUERY(thd)); if (thd->wsrep_cs().end_rsu()) { WSREP_WARN("Failed to end RSU, server may need to be restarted"); @@ -2192,7 +2175,7 @@ int wsrep_to_isolation_begin(THD *thd, const char *db_, const char *table_, if (wsrep_debug && thd->mdl_context.has_locks()) { WSREP_DEBUG("thread holds MDL locks at TI begin: %s %llu", - wsrep_thd_query(thd), thd->thread_id); + WSREP_QUERY(thd), thd->thread_id); } /* @@ -2208,6 +2191,13 @@ int wsrep_to_isolation_begin(THD *thd, const char *db_, const char *table_, thd->variables.auto_increment_increment= 1; } + /* + TOI operations will ignore provided lock_wait_timeout and restore it + after operation is done. + */ + thd->variables.saved_lock_wait_timeout= thd->variables.lock_wait_timeout; + thd->variables.lock_wait_timeout= LONG_TIMEOUT; + if (thd->variables.wsrep_on && wsrep_thd_is_local(thd)) { switch (thd->variables.wsrep_OSU_method) { @@ -2223,19 +2213,8 @@ int wsrep_to_isolation_begin(THD *thd, const char *db_, const char *table_, ret= -1; break; } - switch (ret) { - case 0: /* wsrep_TOI_begin sould set toi mode */ - if (thd->variables.wsrep_OSU_method == WSREP_OSU_TOI) - { - /* - TOI operations ignore the provided lock_wait_timeout once replicated, - and restore it after operation is done. - */ - thd->variables.saved_lock_wait_timeout= thd->variables.lock_wait_timeout; - thd->variables.lock_wait_timeout= LONG_TIMEOUT; - } - break; + case 0: /* wsrep_TOI_begin sould set toi mode */ break; case 1: /* TOI replication skipped, treat as success */ ret= 0; @@ -2254,9 +2233,10 @@ void wsrep_to_isolation_end(THD *thd) DBUG_ASSERT(wsrep_thd_is_local_toi(thd) || wsrep_thd_is_in_rsu(thd)); + thd->variables.lock_wait_timeout= thd->variables.saved_lock_wait_timeout; + if (wsrep_thd_is_local_toi(thd)) { - thd->variables.lock_wait_timeout= thd->variables.saved_lock_wait_timeout; DBUG_ASSERT(thd->variables.wsrep_OSU_method == WSREP_OSU_TOI); wsrep_TOI_end(thd); } diff --git a/sql/wsrep_mysqld.h b/sql/wsrep_mysqld.h index db3e9b09b51..748d93c72aa 100644 --- a/sql/wsrep_mysqld.h +++ b/sql/wsrep_mysqld.h @@ -1,4 +1,4 @@ -/* Copyright 2008-2021 Codership Oy <http://www.codership.com> +/* Copyright 2008-2017 Codership Oy <http://www.codership.com> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -289,6 +289,8 @@ static inline bool wsrep_cluster_address_exists() return wsrep_cluster_address && wsrep_cluster_address[0]; } +#define WSREP_QUERY(thd) (thd->query()) + extern my_bool wsrep_ready_get(); extern void wsrep_ready_wait(); diff --git a/sql/wsrep_thd.cc b/sql/wsrep_thd.cc index 2e02110d697..d8f3d8959e0 100644 --- a/sql/wsrep_thd.cc +++ b/sql/wsrep_thd.cc @@ -340,20 +340,11 @@ int wsrep_abort_thd(THD *bf_thd_ptr, THD *victim_thd_ptr, my_bool signal) DBUG_RETURN(1); } -bool wsrep_bf_abort(THD* bf_thd, THD* victim_thd) +bool wsrep_bf_abort(const THD* bf_thd, THD* victim_thd) { WSREP_LOG_THD(bf_thd, "BF aborter before"); WSREP_LOG_THD(victim_thd, "victim before"); - - DBUG_EXECUTE_IF("sync.wsrep_bf_abort", - { - const char act[]= - "now " - "SIGNAL sync.wsrep_bf_abort_reached " - "WAIT_FOR signal.wsrep_bf_abort"; - DBUG_ASSERT(!debug_sync_set_action(bf_thd, - STRING_WITH_LEN(act))); - };); + wsrep::seqno bf_seqno(bf_thd->wsrep_trx().ws_meta().seqno()); if (WSREP(victim_thd) && !victim_thd->wsrep_trx().active()) { @@ -371,8 +362,6 @@ bool wsrep_bf_abort(THD* bf_thd, THD* victim_thd) } bool ret; - wsrep::seqno bf_seqno(bf_thd->wsrep_trx().ws_meta().seqno()); - if (wsrep_thd_is_toi(bf_thd)) { ret= victim_thd->wsrep_cs().total_order_bf_abort(bf_seqno); diff --git a/sql/wsrep_thd.h b/sql/wsrep_thd.h index 560dbbdab44..d24d8e6358f 100644 --- a/sql/wsrep_thd.h +++ b/sql/wsrep_thd.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2013-2021 Codership Oy <info@codership.com> +/* Copyright (C) 2013 Codership Oy <info@codership.com> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -87,7 +87,7 @@ int wsrep_show_bf_aborts (THD *thd, SHOW_VAR *var, char *buff, bool wsrep_create_appliers(long threads, bool mutex_protected=false); void wsrep_create_rollbacker(); -bool wsrep_bf_abort(THD* bf_thd, THD* victim_thd); +bool wsrep_bf_abort(const THD*, THD*); int wsrep_abort_thd(THD *bf_thd_ptr, THD *victim_thd_ptr, my_bool signal); extern void wsrep_thd_set_PA_safe(void *thd_ptr, my_bool safe); @@ -292,7 +292,7 @@ static inline void wsrep_log_thd(const THD *thd, (thd->get_stmt_da()->is_error() ? thd->get_stmt_da()->message() : "") #ifdef WSREP_THD_LOG_QUERIES , thd->lex->sql_command, - wsrep_thd_query(thd) + WSREP_QUERY(thd) #endif /* WSREP_OBSERVER_LOG_QUERIES */ ); } diff --git a/sql/wsrep_var.cc b/sql/wsrep_var.cc index cd7b9bdf870..e4cfd0d89c9 100644 --- a/sql/wsrep_var.cc +++ b/sql/wsrep_var.cc @@ -1,4 +1,4 @@ -/* Copyright 2008-2021 Codership Oy <http://www.codership.com> +/* Copyright 2008-2015 Codership Oy <http://www.codership.com> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -794,7 +794,7 @@ bool wsrep_desync_check (sys_var *self, THD* thd, set_var* var) ret= Wsrep_server_state::instance().provider().desync(); if (ret) { WSREP_WARN ("SET desync failed %d for schema: %s, query: %s", ret, - thd->db.str, wsrep_thd_query(thd)); + thd->db.str, WSREP_QUERY(thd)); my_error (ER_CANNOT_USER, MYF(0), "'desync'", thd->query()); return true; } |