diff options
author | Marko Mäkelä <marko.makela@mariadb.com> | 2021-03-19 13:06:31 +0200 |
---|---|---|
committer | Marko Mäkelä <marko.makela@mariadb.com> | 2021-03-19 13:09:21 +0200 |
commit | be881ec4572b1cecd497436c5db471a83b6ae728 (patch) | |
tree | 966fef6744a55d6b0decd0ccee14d89774734c07 /storage | |
parent | 190a8312f598fc4892331225104297f6288f23ac (diff) | |
parent | 550cf13eb3e8a25826a0fa67935fc28ee7adb0c8 (diff) | |
download | mariadb-git-be881ec4572b1cecd497436c5db471a83b6ae728.tar.gz |
Merge 10.4 into 10.5
Diffstat (limited to 'storage')
-rw-r--r-- | storage/innobase/.clang-format-old (renamed from storage/innobase/.clang-format) | 0 | ||||
-rw-r--r-- | storage/innobase/btr/btr0cur.cc | 1 | ||||
-rw-r--r-- | storage/innobase/handler/ha_innodb.cc | 386 | ||||
-rw-r--r-- | storage/innobase/include/ha_prototypes.h | 4 | ||||
-rw-r--r-- | storage/innobase/include/os0file.h | 3 | ||||
-rw-r--r-- | storage/innobase/include/trx0sys.h | 8 | ||||
-rw-r--r-- | storage/innobase/os/os0file.cc | 3 | ||||
-rw-r--r-- | storage/innobase/rem/rem0rec.cc | 3 | ||||
-rw-r--r-- | storage/innobase/trx/trx0i_s.cc | 11 |
9 files changed, 256 insertions, 163 deletions
diff --git a/storage/innobase/.clang-format b/storage/innobase/.clang-format-old index 54f7b47bc88..54f7b47bc88 100644 --- a/storage/innobase/.clang-format +++ b/storage/innobase/.clang-format-old diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc index e34677cfcb3..b9b581f3675 100644 --- a/storage/innobase/btr/btr0cur.cc +++ b/storage/innobase/btr/btr0cur.cc @@ -1184,7 +1184,6 @@ static ulint btr_node_ptr_max_size(const dict_index_t* index) TABLE_STATS_NAME) || !strcmp(index->table->name.m_name, INDEX_STATS_NAME))) { - ut_ad(!strcmp(field->name, "table_name")); /* Interpret "table_name" as VARCHAR(199) even if it was incorrectly defined as VARCHAR(64). While the caller of ha_innobase enforces the diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 4f1e4c243ba..2fc18464180 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -2114,6 +2114,72 @@ innobase_raw_format( return(ut_str_sql_format(buf_tmp, buf_tmp_used, buf, buf_size)); } +/* +The helper function nlz(x) calculates the number of leading zeros +in the binary representation of the number "x", either using a +built-in compiler function or a substitute trick based on the use +of the multiplication operation and a table indexed by the prefix +of the multiplication result: +*/ +#ifdef __GNUC__ +#define nlz(x) __builtin_clzll(x) +#elif defined(_MSC_VER) && !defined(_M_CEE_PURE) && \ + (defined(_M_IX86) || defined(_M_X64) || defined(_M_ARM64)) +#ifndef __INTRIN_H_ +#pragma warning(push, 4) +#pragma warning(disable: 4255 4668) +#include <intrin.h> +#pragma warning(pop) +#endif +__forceinline unsigned int nlz (ulonglong x) +{ +#if defined(_M_IX86) || defined(_M_X64) + unsigned long n; +#ifdef _M_X64 + _BitScanReverse64(&n, x); + return (unsigned int) n ^ 63; +#else + unsigned long y = (unsigned long) (x >> 32); + unsigned int m = 31; + if (y == 0) + { + y = (unsigned long) x; + m = 63; + } + _BitScanReverse(&n, y); + return (unsigned int) n ^ m; +#endif +#elif defined(_M_ARM64) + return _CountLeadingZeros(x); +#endif +} +#else +inline unsigned int nlz (ulonglong x) +{ + static unsigned char table [48] = { + 32, 6, 5, 0, 4, 12, 0, 20, + 15, 3, 11, 0, 0, 18, 25, 31, + 8, 14, 2, 0, 10, 0, 0, 0, + 0, 0, 0, 21, 0, 0, 19, 26, + 7, 0, 13, 0, 16, 1, 22, 27, + 9, 0, 17, 23, 28, 24, 29, 30 + }; + unsigned int y= (unsigned int) (x >> 32); + unsigned int n= 0; + if (y == 0) { + y= (unsigned int) x; + n= 32; + } + y = y | (y >> 1); // Propagate leftmost 1-bit to the right. + y = y | (y >> 2); + y = y | (y >> 4); + y = y | (y >> 8); + y = y & ~(y >> 16); + y = y * 0x3EF5D037; + return n + table[y >> 26]; +} +#endif + /*********************************************************************//** Compute the next autoinc value. @@ -2142,85 +2208,93 @@ innobase_next_autoinc( ulonglong max_value) /*!< in: max value for type */ { ulonglong next_value; - ulonglong block = need * step; + ulonglong block; /* Should never be 0. */ ut_a(need > 0); - ut_a(block > 0); + ut_a(step > 0); ut_a(max_value > 0); - /* - Allow auto_increment to go over max_value up to max ulonglong. - This allows us to detect that all values are exhausted. - If we don't do this, we will return max_value several times - and get duplicate key errors instead of auto increment value - out of range. - */ - max_value= (~(ulonglong) 0); + /* + We need to calculate the "block" value equal to the product + "step * need". However, when calculating this product, an integer + overflow can occur, so we cannot simply use the usual multiplication + operation. The snippet below calculates the product of two numbers + and detects an unsigned integer overflow: + */ + unsigned int m= nlz(need); + unsigned int n= nlz(step); + if (m + n <= 8 * sizeof(ulonglong) - 2) { + // The bit width of the original values is too large, + // therefore we are guaranteed to get an overflow. + goto overflow; + } + block = need * (step >> 1); + if ((longlong) block < 0) { + goto overflow; + } + block += block; + if (step & 1) { + block += need; + if (block < need) { + goto overflow; + } + } + + /* Check for overflow. Current can be > max_value if the value + is in reality a negative value. Also, the visual studio compiler + converts large double values (which hypothetically can then be + passed here as the values of the "current" parameter) automatically + into unsigned long long datatype maximum value: */ + if (current > max_value) { + goto overflow; + } /* According to MySQL documentation, if the offset is greater than the step then the offset is ignored. */ - if (offset > block) { + if (offset > step) { offset = 0; } - /* Check for overflow. Current can be > max_value if the value is - in reality a negative value.The visual studio compilers converts - large double values automatically into unsigned long long datatype - maximum value */ - - if (block >= max_value - || offset > max_value - || current >= max_value - || max_value - offset <= offset) { - - next_value = max_value; + /* + Let's round the current value to within a step-size block: + */ + if (current > offset) { + next_value = current - offset; } else { - ut_a(max_value > current); - - ulonglong free = max_value - current; - - if (free < offset || free - offset <= block) { - next_value = max_value; - } else { - next_value = 0; - } + next_value = offset - current; } + next_value -= next_value % step; - if (next_value == 0) { - ulonglong next; - - if (current > offset) { - next = (current - offset) / step; - } else { - next = (offset - current) / step; - } - - ut_a(max_value > next); - next_value = next * step; - /* Check for multiplication overflow. */ - ut_a(next_value >= next); - ut_a(max_value > next_value); - - /* Check for overflow */ - if (max_value - next_value >= block) { - - next_value += block; - - if (max_value - next_value >= offset) { - next_value += offset; - } else { - next_value = max_value; - } - } else { - next_value = max_value; - } + /* + Add an offset to the next value and check that the addition + does not cause an integer overflow: + */ + next_value += offset; + if (next_value < offset) { + goto overflow; } - ut_a(next_value != 0); - ut_a(next_value <= max_value); + /* + Add a block to the next value and check that the addition + does not cause an integer overflow: + */ + next_value += block; + if (next_value < block) { + goto overflow; + } return(next_value); + +overflow: + /* + Allow auto_increment to go over max_value up to max ulonglong. + This allows us to detect that all values are exhausted. + If we don't do this, we will return max_value several times + and get duplicate key errors instead of auto increment value + out of range: + */ + return(~(ulonglong) 0); } /********************************************************************//** @@ -6078,7 +6152,7 @@ wsrep_innobase_mysql_sort( unsigned char* str, /* in: data field */ ulint str_length, /* in: data field length, not UNIV_SQL_NULL */ - unsigned int buf_length) /* in: total str buffer length */ + ulint buf_length) /* in: total str buffer length */ { CHARSET_INFO* charset; @@ -6100,8 +6174,8 @@ wsrep_innobase_mysql_sort( case MYSQL_TYPE_LONG_BLOB: case MYSQL_TYPE_VARCHAR: { - uchar tmp_str[REC_VERSION_56_MAX_INDEX_COL_LEN] = {'\0'}; - ulint tmp_length = REC_VERSION_56_MAX_INDEX_COL_LEN; + uchar *tmp_str; + ulint tmp_length; /* Use the charset number to pick the right charset struct for the comparison. Since the MySQL function get_charset may be @@ -6124,7 +6198,11 @@ wsrep_innobase_mysql_sort( } } - ut_a(str_length <= tmp_length); + // Note that strnxfrm may change length of string + tmp_length= charset->coll->strnxfrmlen(charset, str_length); + tmp_length= ut_max(str_length, tmp_length) + 1; + tmp_str= static_cast<uchar *>(ut_malloc_nokey(tmp_length)); + ut_ad(str_length <= tmp_length); memcpy(tmp_str, str, str_length); tmp_length = charset->strnxfrm(str, str_length, @@ -6148,6 +6226,7 @@ wsrep_innobase_mysql_sort( ret_length = tmp_length; } + ut_free(tmp_str); break; } case MYSQL_TYPE_DECIMAL : @@ -6493,7 +6572,7 @@ wsrep_store_key_val_for_row( THD* thd, TABLE* table, uint keynr, /*!< in: key number */ - char* buff, /*!< in/out: buffer for the key value (in MySQL + uchar* buff, /*!< in/out: buffer for the key value (in MySQL format) */ uint buff_len,/*!< in: buffer length */ const uchar* record, @@ -6502,7 +6581,7 @@ wsrep_store_key_val_for_row( KEY* key_info = table->key_info + keynr; KEY_PART_INFO* key_part = key_info->key_part; KEY_PART_INFO* end = key_part + key_info->user_defined_key_parts; - char* buff_start = buff; + uchar* buff_start = buff; enum_field_types mysql_type; Field* field; ulint buff_space = buff_len; @@ -6513,8 +6592,7 @@ wsrep_store_key_val_for_row( *key_is_null = true; for (; key_part != end; key_part++) { - - uchar sorted[REC_VERSION_56_MAX_INDEX_COL_LEN] = {'\0'}; + uchar *sorted = nullptr; bool part_is_null = false; if (key_part->null_bit) { @@ -6593,10 +6671,14 @@ wsrep_store_key_val_for_row( true_len = key_len; } + const ulint max_len = true_len; + sorted= static_cast<uchar *>(ut_malloc_nokey(max_len+1)); memcpy(sorted, data, true_len); true_len = wsrep_innobase_mysql_sort( mysql_type, cs->number, sorted, true_len, - REC_VERSION_56_MAX_INDEX_COL_LEN); + max_len); + ut_ad(true_len <= max_len); + if (wsrep_protocol_version > 1) { /* Note that we always reserve the maximum possible length of the true VARCHAR in the key value, though @@ -6681,11 +6763,13 @@ wsrep_store_key_val_for_row( true_len = key_len; } + const ulint max_len= true_len; + sorted= static_cast<uchar *>(ut_malloc_nokey(max_len+1)); memcpy(sorted, blob_data, true_len); true_len = wsrep_innobase_mysql_sort( mysql_type, cs->number, sorted, true_len, - REC_VERSION_56_MAX_INDEX_COL_LEN); - + max_len); + ut_ad(true_len <= max_len); /* Note that we always reserve the maximum possible length of the BLOB prefix in the key value. */ @@ -6761,10 +6845,14 @@ wsrep_store_key_val_for_row( cs->mbmaxlen), &error); } + + const ulint max_len = true_len; + sorted= static_cast<uchar *>(ut_malloc_nokey(max_len+1)); memcpy(sorted, src_start, true_len); true_len = wsrep_innobase_mysql_sort( mysql_type, cs->number, sorted, true_len, - REC_VERSION_56_MAX_INDEX_COL_LEN); + max_len); + ut_ad(true_len <= max_len); if (true_len > buff_space) { fprintf (stderr, @@ -6779,6 +6867,11 @@ wsrep_store_key_val_for_row( buff += true_len; buff_space -= true_len; } + + if (sorted) { + ut_free(sorted); + sorted= NULL; + } } ut_a(buff <= buff_start + buff_len); @@ -7587,7 +7680,6 @@ ha_innobase::write_row( /* Handling of errors related to auto-increment. */ if (auto_inc_used) { ulonglong auto_inc; - ulonglong col_max_value; /* Note the number of rows processed for this statement, used by get_auto_increment() to determine the number of AUTO-INC @@ -7597,11 +7689,6 @@ ha_innobase::write_row( --trx->n_autoinc_rows; } - /* We need the upper limit of the col type to check for - whether we update the table autoinc counter or not. */ - col_max_value = - table->next_number_field->get_max_int_value(); - /* Get the value that MySQL attempted to store in the table.*/ auto_inc = table->next_number_field->val_uint(); @@ -7666,36 +7753,25 @@ ha_innobase::write_row( if (auto_inc >= m_prebuilt->autoinc_last_value) { set_max_autoinc: + /* We need the upper limit of the col type to check for + whether we update the table autoinc counter or not. */ + ulonglong col_max_value = + table->next_number_field->get_max_int_value(); + /* This should filter out the negative values set explicitly by the user. */ if (auto_inc <= col_max_value) { + ut_ad(m_prebuilt->autoinc_increment > 0); ulonglong offset; ulonglong increment; dberr_t err; -#ifdef WITH_WSREP - /* Applier threads which are processing - ROW events and don't go through server - level autoinc processing, therefore - m_prebuilt autoinc values don't get - properly assigned. Fetch values from - server side. */ - if (trx->is_wsrep() && - wsrep_thd_is_applying(m_user_thd)) - { - wsrep_thd_auto_increment_variables( - m_user_thd, &offset, &increment); - } - else -#endif /* WITH_WSREP */ - { - ut_a(m_prebuilt->autoinc_increment > 0); - offset = m_prebuilt->autoinc_offset; - increment = m_prebuilt->autoinc_increment; - } + + offset = m_prebuilt->autoinc_offset; + increment = m_prebuilt->autoinc_increment; + auto_inc = innobase_next_autoinc( - auto_inc, - 1, increment, offset, + auto_inc, 1, increment, offset, col_max_value); err = innobase_set_max_autoinc( @@ -8391,39 +8467,37 @@ ha_innobase::update_row( /* A value for an AUTO_INCREMENT column was specified in the UPDATE statement. */ - ulonglong offset; - ulonglong increment; -#ifdef WITH_WSREP - /* Applier threads which are processing - ROW events and don't go through server - level autoinc processing, therefore - m_prebuilt autoinc values don't get - properly assigned. Fetch values from - server side. */ - if (trx->is_wsrep() && wsrep_thd_is_applying(m_user_thd)) - wsrep_thd_auto_increment_variables( - m_user_thd, &offset, &increment); - else -#endif /* WITH_WSREP */ - offset = m_prebuilt->autoinc_offset, - increment = m_prebuilt->autoinc_increment; - - autoinc = innobase_next_autoinc( - autoinc, 1, increment, offset, - table->found_next_number_field->get_max_int_value()); - - error = innobase_set_max_autoinc(autoinc); - - if (m_prebuilt->table->persistent_autoinc) { - /* Update the PAGE_ROOT_AUTO_INC. Yes, we do - this even if dict_table_t::autoinc already was - greater than autoinc, because we cannot know - if any INSERT actually used (and wrote to - PAGE_ROOT_AUTO_INC) a value bigger than our - autoinc. */ - btr_write_autoinc(dict_table_get_first_index( - m_prebuilt->table), - autoinc); + /* We need the upper limit of the col type to check for + whether we update the table autoinc counter or not. */ + ulonglong col_max_value = + table->found_next_number_field->get_max_int_value(); + + /* This should filter out the negative + values set explicitly by the user. */ + if (autoinc <= col_max_value) { + ulonglong offset; + ulonglong increment; + + offset = m_prebuilt->autoinc_offset; + increment = m_prebuilt->autoinc_increment; + + autoinc = innobase_next_autoinc( + autoinc, 1, increment, offset, + col_max_value); + + error = innobase_set_max_autoinc(autoinc); + + if (m_prebuilt->table->persistent_autoinc) { + /* Update the PAGE_ROOT_AUTO_INC. Yes, we do + this even if dict_table_t::autoinc already was + greater than autoinc, because we cannot know + if any INSERT actually used (and wrote to + PAGE_ROOT_AUTO_INC) a value bigger than our + autoinc. */ + btr_write_autoinc(dict_table_get_first_index( + m_prebuilt->table), + autoinc); + } } } @@ -9820,7 +9894,7 @@ wsrep_append_key( THD *thd, trx_t *trx, TABLE_SHARE *table_share, - const char* key, + const uchar* key, uint16_t key_len, Wsrep_service_key_type key_type /*!< in: access type of this key (shared, exclusive, semi...) */ @@ -9931,8 +10005,8 @@ ha_innobase::wsrep_append_keys( } if (wsrep_protocol_version == 0) { - char keyval[WSREP_MAX_SUPPORTED_KEY_LENGTH+1] = {'\0'}; - char *key = &keyval[0]; + uchar keyval[WSREP_MAX_SUPPORTED_KEY_LENGTH+1] = {'\0'}; + uchar *key = &keyval[0]; bool is_null; auto len = wsrep_store_key_val_for_row( @@ -9973,12 +10047,12 @@ ha_innobase::wsrep_append_keys( /* keyval[] shall contain an ordinal number at byte 0 and the actual key data shall be written at byte 1. Hence the total data length is the key length + 1 */ - char keyval0[WSREP_MAX_SUPPORTED_KEY_LENGTH+1] = {'\0'}; - char keyval1[WSREP_MAX_SUPPORTED_KEY_LENGTH+1] = {'\0'}; - keyval0[0] = (char)i; - keyval1[0] = (char)i; - char* key0 = &keyval0[1]; - char* key1 = &keyval1[1]; + uchar keyval0[WSREP_MAX_SUPPORTED_KEY_LENGTH+1]= {'\0'}; + uchar keyval1[WSREP_MAX_SUPPORTED_KEY_LENGTH+1]= {'\0'}; + keyval0[0] = (uchar)i; + keyval1[0] = (uchar)i; + uchar* key0 = &keyval0[1]; + uchar* key1 = &keyval1[1]; if (!tab) { WSREP_WARN("MariaDB-InnoDB key mismatch %s %s", @@ -10054,22 +10128,20 @@ ha_innobase::wsrep_append_keys( /* if no PK, calculate hash of full row, to be the key value */ if (!key_appended && wsrep_certify_nonPK) { uchar digest[16]; - int rcode; wsrep_calc_row_hash(digest, record0, table, m_prebuilt); - if ((rcode = wsrep_append_key(thd, trx, table_share, - (const char*) digest, 16, - key_type))) { + if (int rcode = wsrep_append_key(thd, trx, table_share, + digest, 16, key_type)) { DBUG_RETURN(rcode); } if (record1) { wsrep_calc_row_hash( digest, record1, table, m_prebuilt); - if ((rcode = wsrep_append_key(thd, trx, table_share, - (const char*) digest, - 16, key_type))) { + if (int rcode = wsrep_append_key(thd, trx, table_share, + digest, 16, + key_type)) { DBUG_RETURN(rcode); } } @@ -14232,6 +14304,13 @@ ha_innobase::info_low( if (dict_stats_is_persistent_enabled(ib_table)) { if (is_analyze) { + row_mysql_lock_data_dictionary( + m_prebuilt->trx); + dict_stats_recalc_pool_del(ib_table); + dict_stats_wait_bg_to_stop_using_table( + ib_table, m_prebuilt->trx); + row_mysql_unlock_data_dictionary( + m_prebuilt->trx); opt = DICT_STATS_RECALC_PERSISTENT; } else { /* This is e.g. 'SHOW INDEXES', fetch @@ -14244,6 +14323,13 @@ ha_innobase::info_low( ret = dict_stats_update(ib_table, opt); + if (opt == DICT_STATS_RECALC_PERSISTENT) { + mutex_enter(&dict_sys.mutex); + ib_table->stats_bg_flag + &= byte(~BG_STAT_SHOULD_QUIT); + mutex_exit(&dict_sys.mutex); + } + if (ret != DB_SUCCESS) { m_prebuilt->trx->op_info = ""; DBUG_RETURN(HA_ERR_GENERIC); diff --git a/storage/innobase/include/ha_prototypes.h b/storage/innobase/include/ha_prototypes.h index 820214de774..559de415b01 100644 --- a/storage/innobase/include/ha_prototypes.h +++ b/storage/innobase/include/ha_prototypes.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2006, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2020, MariaDB Corporation. +Copyright (c) 2017, 2021, 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 the Free Software @@ -221,7 +221,7 @@ innobase_casedn_str( void wsrep_innobase_kill_one_trx(THD *bf_thd, trx_t *victim_trx, bool signal); ulint wsrep_innobase_mysql_sort(int mysql_type, uint charset_number, unsigned char* str, ulint str_length, - unsigned int buf_length); + ulint buf_length); #endif /* WITH_WSREP */ extern "C" struct charset_info_st *thd_charset(THD *thd); diff --git a/storage/innobase/include/os0file.h b/storage/innobase/include/os0file.h index 3dae92217ec..ad9c2156f76 100644 --- a/storage/innobase/include/os0file.h +++ b/storage/innobase/include/os0file.h @@ -2,7 +2,7 @@ Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. Copyright (c) 2009, Percona Inc. -Copyright (c) 2013, 2020, MariaDB Corporation. +Copyright (c) 2013, 2021, MariaDB Corporation. Portions of this file contain modifications contributed and copyrighted by Percona Inc.. Those modifications are @@ -155,7 +155,6 @@ static const ulint OS_FILE_NORMAL = 62; /** Types for file create @{ */ static const ulint OS_DATA_FILE = 100; static const ulint OS_LOG_FILE = 101; -static const ulint OS_DATA_TEMP_FILE = 102; static const ulint OS_DATA_FILE_NO_O_DIRECT = 103; /* @} */ diff --git a/storage/innobase/include/trx0sys.h b/storage/innobase/include/trx0sys.h index 0cda6b3ddd4..9985932af13 100644 --- a/storage/innobase/include/trx0sys.h +++ b/storage/innobase/include/trx0sys.h @@ -834,6 +834,14 @@ public: mutex_exit(&mutex); } + template <typename Callable> void for_each(Callable &&callback) + { + mutex_enter(&mutex); + for (auto &trx : trx_list) + callback(trx); + mutex_exit(&mutex); + } + void freeze() const { mutex_enter(&mutex); } void unfreeze() const { mutex_exit(&mutex); } diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc index 55a8c565afb..4ee7e5af0c7 100644 --- a/storage/innobase/os/os0file.cc +++ b/storage/innobase/os/os0file.cc @@ -1385,7 +1385,6 @@ os_file_create_func( ut_a(type == OS_LOG_FILE || type == OS_DATA_FILE - || type == OS_DATA_TEMP_FILE || type == OS_DATA_FILE_NO_O_DIRECT); ut_a(purpose == OS_FILE_AIO || purpose == OS_FILE_NORMAL); @@ -1432,7 +1431,7 @@ os_file_create_func( /* We disable OS caching (O_DIRECT) only on data files */ if (!read_only && *success - && type != OS_LOG_FILE && type != OS_DATA_TEMP_FILE + && type != OS_LOG_FILE && type != OS_DATA_FILE_NO_O_DIRECT && (srv_file_flush_method == SRV_O_DIRECT || srv_file_flush_method == SRV_O_DIRECT_NO_FSYNC)) { diff --git a/storage/innobase/rem/rem0rec.cc b/storage/innobase/rem/rem0rec.cc index bb92a726c61..aae621b6f56 100644 --- a/storage/innobase/rem/rem0rec.cc +++ b/storage/innobase/rem/rem0rec.cc @@ -2753,8 +2753,7 @@ wsrep_rec_get_foreign_key( (int) (col_f->prtype & DATA_MYSQL_TYPE_MASK), dtype_get_charset_coll(col_f->prtype), - buf, static_cast<uint>(len), - static_cast<uint>(*buf_len)); + buf, len, *buf_len); break; case DATA_BLOB: case DATA_BINARY: diff --git a/storage/innobase/trx/trx0i_s.cc b/storage/innobase/trx/trx0i_s.cc index d3d2b742d84..22a0926a6de 100644 --- a/storage/innobase/trx/trx0i_s.cc +++ b/storage/innobase/trx/trx0i_s.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2007, 2015, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2020, MariaDB Corporation. +Copyright (c) 2017, 2021, 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 the Free Software @@ -1203,11 +1203,14 @@ static void fetch_data_into_cache(trx_i_s_cache_t *cache) trx_i_s_cache_clear(cache); /* Capture the state of transactions */ - trx_sys.trx_list.for_each([cache](const trx_t &trx) { - if (!cache->is_truncated && trx_is_started(&trx) && + trx_sys.trx_list.for_each([cache](trx_t &trx) { + if (!cache->is_truncated && trx.state != TRX_STATE_NOT_STARTED && &trx != purge_sys.query->trx) { - fetch_data_into_cache_low(cache, &trx); + mutex_enter(&trx.mutex); + if (trx.state != TRX_STATE_NOT_STARTED) + fetch_data_into_cache_low(cache, &trx); + mutex_exit(&trx.mutex); } }); cache->is_truncated= false; |