diff options
Diffstat (limited to 'storage')
34 files changed, 373 insertions, 221 deletions
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index c31d9aef8eb..37fbd4dd853 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -2845,12 +2845,7 @@ re_evict: block->fix(); mysql_mutex_unlock(&buf_pool.mutex); - buf_flush_list(); - buf_flush_wait_batch_end_acquiring_mutex(false); - while (buf_flush_list_space(space)); - /* Wait for page write completion. */ - block->page.lock.u_lock(); - block->page.lock.u_unlock(); + buf_flush_sync(); state = block->page.state(); diff --git a/storage/innobase/buf/buf0dblwr.cc b/storage/innobase/buf/buf0dblwr.cc index 707006ed16a..9c78c5c563e 100644 --- a/storage/innobase/buf/buf0dblwr.cc +++ b/storage/innobase/buf/buf0dblwr.cc @@ -214,8 +214,7 @@ too_small: TRX_SYS_DOUBLEWRITE_SPACE_ID_STORED_N); mtr.commit(); - /* Flush the modified pages to disk and make a checkpoint */ - log_make_checkpoint(); + buf_flush_wait_flushed(mtr.commit_lsn()); /* Remove doublewrite pages from LRU */ buf_pool_invalidate(); diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc index aa2768560da..1116beee0bb 100644 --- a/storage/innobase/buf/buf0flu.cc +++ b/storage/innobase/buf/buf0flu.cc @@ -1480,7 +1480,7 @@ void buf_flush_wait_batch_end(bool lru) @param lsn buf_pool.get_oldest_modification(LSN_MAX) target @return the number of processed pages @retval 0 if a buf_pool.flush_list batch is already running */ -ulint buf_flush_list(ulint max_n, lsn_t lsn) +static ulint buf_flush_list(ulint max_n= ULINT_UNDEFINED, lsn_t lsn= LSN_MAX) { ut_ad(lsn); @@ -1772,6 +1772,30 @@ ATTRIBUTE_COLD void log_make_checkpoint() while (!log_checkpoint()); } +/** Wait for all dirty pages up to an LSN to be written out. +NOTE: The calling thread is not allowed to hold any buffer page latches! */ +static void buf_flush_wait(lsn_t lsn) +{ + ut_ad(lsn <= log_sys.get_lsn()); + + while (buf_pool.get_oldest_modification(lsn) < lsn) + { + if (buf_flush_sync_lsn < lsn) + { + buf_flush_sync_lsn= lsn; + buf_pool.page_cleaner_set_idle(false); + pthread_cond_signal(&buf_pool.do_flush_list); + } + my_cond_wait(&buf_pool.done_flush_list, + &buf_pool.flush_list_mutex.m_mutex); + } + + /* Wait for the checkpoint. */ + while (buf_flush_sync_lsn) + my_cond_wait(&buf_pool.done_flush_list, + &buf_pool.flush_list_mutex.m_mutex); +} + /** Wait until all persistent pages are flushed up to a limit. @param sync_lsn buf_pool.get_oldest_modification(LSN_MAX) to wait for */ ATTRIBUTE_COLD void buf_flush_wait_flushed(lsn_t sync_lsn) @@ -1788,6 +1812,7 @@ ATTRIBUTE_COLD void buf_flush_wait_flushed(lsn_t sync_lsn) if (buf_pool.get_oldest_modification(sync_lsn) < sync_lsn) { + MONITOR_INC(MONITOR_FLUSH_SYNC_WAITS); #if 1 /* FIXME: remove this, and guarantee that the page cleaner serves us */ if (UNIV_UNLIKELY(!buf_page_cleaner_is_active)) { @@ -1802,35 +1827,21 @@ ATTRIBUTE_COLD void buf_flush_wait_flushed(lsn_t sync_lsn) MONITOR_FLUSH_SYNC_COUNT, MONITOR_FLUSH_SYNC_PAGES, n_pages); } - MONITOR_INC(MONITOR_FLUSH_SYNC_WAITS); mysql_mutex_lock(&buf_pool.flush_list_mutex); } while (buf_pool.get_oldest_modification(sync_lsn) < sync_lsn); - - goto try_checkpoint; } + else #endif - if (buf_flush_sync_lsn < sync_lsn) - { - buf_flush_sync_lsn= sync_lsn; - pthread_cond_signal(&buf_pool.do_flush_list); - } - - do { - tpool::tpool_wait_begin(); thd_wait_begin(nullptr, THD_WAIT_DISKIO); - my_cond_wait(&buf_pool.done_flush_list, - &buf_pool.flush_list_mutex.m_mutex); - thd_wait_end(nullptr); + tpool::tpool_wait_begin(); + buf_flush_wait(sync_lsn); tpool::tpool_wait_end(); - - MONITOR_INC(MONITOR_FLUSH_SYNC_WAITS); + thd_wait_end(nullptr); } - while (buf_pool.get_oldest_modification(sync_lsn) < sync_lsn); } -try_checkpoint: mysql_mutex_unlock(&buf_pool.flush_list_mutex); if (UNIV_UNLIKELY(log_sys.last_checkpoint_lsn < sync_lsn)) @@ -1863,8 +1874,11 @@ ATTRIBUTE_COLD void buf_flush_ahead(lsn_t lsn, bool furious) { mysql_mutex_lock(&buf_pool.flush_list_mutex); if (limit < lsn) + { limit= lsn; - pthread_cond_signal(&buf_pool.do_flush_list); + buf_pool.page_cleaner_set_idle(false); + pthread_cond_signal(&buf_pool.do_flush_list); + } mysql_mutex_unlock(&buf_pool.flush_list_mutex); } } @@ -1898,10 +1912,6 @@ ATTRIBUTE_COLD static void buf_flush_sync_for_checkpoint(lsn_t lsn) MONITOR_FLUSH_SYNC_PAGES, n_flushed); } - /* Attempt to perform a log checkpoint upon completing each batch. */ - if (recv_recovery_is_on()) - recv_sys.apply(true); - switch (srv_file_flush_method) { case SRV_NOSYNC: case SRV_O_DIRECT_NO_FSYNC: @@ -1918,7 +1928,8 @@ ATTRIBUTE_COLD static void buf_flush_sync_for_checkpoint(lsn_t lsn) mysql_mutex_unlock(&log_sys.flush_order_mutex); const lsn_t checkpoint_lsn= measure ? measure : newest_lsn; - if (checkpoint_lsn > log_sys.last_checkpoint_lsn + SIZE_OF_FILE_CHECKPOINT) + if (!recv_recovery_is_on() && + checkpoint_lsn > log_sys.last_checkpoint_lsn + SIZE_OF_FILE_CHECKPOINT) { mysql_mutex_unlock(&buf_pool.flush_list_mutex); log_checkpoint_low(checkpoint_lsn, newest_lsn); @@ -1942,7 +1953,7 @@ ATTRIBUTE_COLD static void buf_flush_sync_for_checkpoint(lsn_t lsn) else if (measure >= buf_flush_async_lsn) buf_flush_async_lsn= 0; - /* wake up buf_flush_wait_flushed() */ + /* wake up buf_flush_wait() */ pthread_cond_broadcast(&buf_pool.done_flush_list); lsn= std::max(lsn, target); @@ -2200,7 +2211,7 @@ furious_flush: if (UNIV_UNLIKELY(lsn_limit != 0)) { buf_flush_sync_lsn= 0; - /* wake up buf_flush_wait_flushed() */ + /* wake up buf_flush_wait() */ pthread_cond_broadcast(&buf_pool.done_flush_list); } unemployed: @@ -2270,7 +2281,7 @@ unemployed: if (UNIV_UNLIKELY(lsn_limit != 0)) { n_flushed= buf_flush_list(srv_max_io_capacity, lsn_limit); - /* wake up buf_flush_wait_flushed() */ + /* wake up buf_flush_wait() */ pthread_cond_broadcast(&buf_pool.done_flush_list); goto try_checkpoint; } @@ -2369,6 +2380,7 @@ ATTRIBUTE_COLD void buf_flush_page_cleaner_init() std::thread(buf_flush_page_cleaner).detach(); } +#if defined(HAVE_SYSTEMD) && !defined(EMBEDDED_LIBRARY) /** @return the number of dirty pages in the buffer pool */ static ulint buf_flush_list_length() { @@ -2377,6 +2389,7 @@ static ulint buf_flush_list_length() mysql_mutex_unlock(&buf_pool.flush_list_mutex); return len; } +#endif /** Flush the buffer pool on shutdown. */ ATTRIBUTE_COLD void buf_flush_buffer_pool() @@ -2387,13 +2400,15 @@ ATTRIBUTE_COLD void buf_flush_buffer_pool() service_manager_extend_timeout(INNODB_EXTEND_TIMEOUT_INTERVAL, "Waiting to flush the buffer pool"); - while (buf_pool.n_flush_list() || buf_flush_list_length()) + mysql_mutex_lock(&buf_pool.flush_list_mutex); + + while (buf_pool.get_oldest_modification(0)) { + mysql_mutex_unlock(&buf_pool.flush_list_mutex); buf_flush_list(srv_max_io_capacity); - timespec abstime; - if (buf_pool.n_flush_list()) { + timespec abstime; service_manager_extend_timeout(INNODB_EXTEND_TIMEOUT_INTERVAL, "Waiting to flush " ULINTPF " pages", buf_flush_list_length()); @@ -2404,22 +2419,46 @@ ATTRIBUTE_COLD void buf_flush_buffer_pool() &abstime); mysql_mutex_unlock(&buf_pool.mutex); } + mysql_mutex_lock(&buf_pool.flush_list_mutex); } + mysql_mutex_unlock(&buf_pool.flush_list_mutex); ut_ad(!buf_pool.any_io_pending()); } +/** Synchronously flush dirty blocks during recv_sys_t::apply(). +NOTE: The calling thread is not allowed to hold any buffer page latches! */ +void buf_flush_sync_batch(lsn_t lsn) +{ + thd_wait_begin(nullptr, THD_WAIT_DISKIO); + tpool::tpool_wait_begin(); + mysql_mutex_lock(&buf_pool.flush_list_mutex); + buf_flush_wait(lsn); + mysql_mutex_unlock(&buf_pool.flush_list_mutex); + tpool::tpool_wait_end(); + thd_wait_end(nullptr); +} + /** Synchronously flush dirty blocks. NOTE: The calling thread is not allowed to hold any buffer page latches! */ void buf_flush_sync() { + if (recv_recovery_is_on()) + recv_sys.apply(true); + + thd_wait_begin(nullptr, THD_WAIT_DISKIO); + tpool::tpool_wait_begin(); + mysql_mutex_lock(&buf_pool.flush_list_mutex); for (;;) { - const ulint n_flushed= buf_flush_list(srv_max_io_capacity); - buf_flush_wait_batch_end_acquiring_mutex(false); - if (!n_flushed && !buf_flush_list_length()) - return; + const lsn_t lsn= log_sys.get_lsn(); + buf_flush_wait(lsn); + if (lsn == log_sys.get_lsn()) + break; } + mysql_mutex_unlock(&buf_pool.flush_list_mutex); + tpool::tpool_wait_end(); + thd_wait_end(nullptr); } #ifdef UNIV_DEBUG diff --git a/storage/innobase/eval/eval0eval.cc b/storage/innobase/eval/eval0eval.cc index 193a5814a78..73ab113cff5 100644 --- a/storage/innobase/eval/eval0eval.cc +++ b/storage/innobase/eval/eval0eval.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1997, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2019, MariaDB Corporation. +Copyright (c) 2019, 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 @@ -378,12 +378,23 @@ eval_substr( str1 = static_cast<byte*>(dfield_get_data(que_node_get_val(arg1))); + const ulint str1_len = dfield_get_len(que_node_get_val(arg1)); + len1 = (ulint) eval_node_get_int_val(arg2); len2 = (ulint) eval_node_get_int_val(arg3); dfield = que_node_get_val(func_node); - dfield_set_data(dfield, str1 + len1, len2); + if (len1 > str1_len) { + len2 = 0; + } else { + str1 += len1; + if (len2 > str1_len - len1) { + len2 = str1_len - len1; + } + } + + dfield_set_data(dfield, str1, len2); } /*****************************************************************//** diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc index 780ed60adac..5a792a59664 100644 --- a/storage/innobase/fil/fil0crypt.cc +++ b/storage/innobase/fil/fil0crypt.cc @@ -2249,6 +2249,9 @@ Adjust encrypt tables @param[in] val New setting for innodb-encrypt-tables */ void fil_crypt_set_encrypt_tables(ulong val) { + if (!fil_crypt_threads_inited) + return; + mysql_mutex_lock(&fil_crypt_threads_mutex); mysql_mutex_lock(&fil_system.mutex); diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index ba1b2a7883c..a82e5ba20c7 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -9856,12 +9856,20 @@ wsrep_append_foreign_key( dict_foreign_t* foreign, /*!< in: foreign key constraint */ const rec_t* rec, /*!<in: clustered index record */ dict_index_t* index, /*!<in: clustered index */ - ibool referenced, /*!<in: is check for referenced table */ + bool referenced, /*!<in: is check for + referenced table */ + upd_node_t* upd_node, /*<!in: update node */ + bool pa_disable, /*<!in: disable parallel apply ?*/ Wsrep_service_key_type key_type) /*!< in: access type of this key (shared, exclusive, reference...) */ { - if (!trx->is_wsrep() || !wsrep_thd_is_local(trx->mysql_thd)) { + ut_ad(trx->is_wsrep()); + + if (!wsrep_thd_is_local(trx->mysql_thd)) return DB_SUCCESS; + + if (upd_node && wsrep_protocol_version < 4) { + key_type = WSREP_SERVICE_KEY_SHARED; } THD* thd = trx->mysql_thd; @@ -9927,8 +9935,7 @@ wsrep_append_foreign_key( WSREP_WARN("FK: %s missing in query: %s", (!foreign->referenced_table) ? "referenced table" : "foreign table", - (wsrep_thd_query(thd)) ? - wsrep_thd_query(thd) : "void"); + wsrep_thd_query(thd)); return DB_ERROR; } @@ -10006,20 +10013,24 @@ wsrep_append_foreign_key( wkey_part, (size_t*)&wkey.key_parts_num)) { WSREP_WARN("key prepare failed for cascaded FK: %s", - (wsrep_thd_query(thd)) ? - wsrep_thd_query(thd) : "void"); + wsrep_thd_query(thd)); return DB_ERROR; } + rcode = wsrep_thd_append_key(thd, &wkey, 1, key_type); + if (rcode) { - DBUG_PRINT("wsrep", ("row key failed: " ULINTPF, rcode)); WSREP_ERROR("Appending cascaded fk row key failed: %s, " ULINTPF, - (wsrep_thd_query(thd)) ? - wsrep_thd_query(thd) : "void", rcode); + wsrep_thd_query(thd), + rcode); return DB_ERROR; } + if (pa_disable) { + wsrep_thd_set_PA_unsafe(trx->mysql_thd); + } + return DB_SUCCESS; } diff --git a/storage/innobase/include/buf0flu.h b/storage/innobase/include/buf0flu.h index 65a58815f40..665fd1115e7 100644 --- a/storage/innobase/include/buf0flu.h +++ b/storage/innobase/include/buf0flu.h @@ -79,13 +79,6 @@ buf_flush_init_for_writing( void* page_zip_, bool use_full_checksum); -/** Write out dirty blocks from buf_pool.flush_list. -@param max_n wished maximum mumber of blocks flushed -@param lsn buf_pool.get_oldest_modification(LSN_MAX) target -@return the number of processed pages -@retval 0 if a buf_pool.flush_list batch is already running */ -ulint buf_flush_list(ulint max_n= ULINT_UNDEFINED, lsn_t lsn= LSN_MAX); - /** Try to flush dirty pages that belong to a given tablespace. @param space tablespace @param n_flushed number of pages written @@ -151,6 +144,10 @@ ATTRIBUTE_COLD void buf_flush_buffer_pool(); void buf_flush_validate(); #endif /* UNIV_DEBUG */ +/** Synchronously flush dirty blocks during recv_sys_t::apply(). +NOTE: The calling thread is not allowed to hold any buffer page latches! */ +void buf_flush_sync_batch(lsn_t lsn); + /** Synchronously flush dirty blocks. NOTE: The calling thread is not allowed to hold any buffer page latches! */ void buf_flush_sync(); diff --git a/storage/innobase/include/dict0mem.h b/storage/innobase/include/dict0mem.h index 919dd48a032..744ef5316ef 100644 --- a/storage/innobase/include/dict0mem.h +++ b/storage/innobase/include/dict0mem.h @@ -1184,6 +1184,13 @@ public: /** @return whether this is the change buffer */ bool is_ibuf() const { return UNIV_UNLIKELY(type & DICT_IBUF); } + /** @return whether this is a normal B-tree index + (not the change buffer, not SPATIAL or FULLTEXT) */ + bool is_btree() const { + return UNIV_LIKELY(!(type & (DICT_IBUF | DICT_SPATIAL + | DICT_FTS | DICT_CORRUPT))); + } + /** @return whether the index includes virtual columns */ bool has_virtual() const { return type & DICT_VIRTUAL; } diff --git a/storage/innobase/include/mtr0mtr.h b/storage/innobase/include/mtr0mtr.h index f72a94d4a39..0b04c0729eb 100644 --- a/storage/innobase/include/mtr0mtr.h +++ b/storage/innobase/include/mtr0mtr.h @@ -1,8 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2012, Facebook Inc. -Copyright (c) 2013, 2021, MariaDB Corporation. +Copyright (c) 2013, 2022, 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 diff --git a/storage/innobase/include/os0file.h b/storage/innobase/include/os0file.h index 17680f9b3dc..ce26a0187a9 100644 --- a/storage/innobase/include/os0file.h +++ b/storage/innobase/include/os0file.h @@ -1118,8 +1118,7 @@ void os_aio_free(); @retval DB_IO_ERROR on I/O error */ dberr_t os_aio(const IORequest &type, void *buf, os_offset_t offset, size_t n); -/** Wait until there are no pending asynchronous writes. -Only used on FLUSH TABLES...FOR EXPORT. */ +/** Wait until there are no pending asynchronous writes. */ void os_aio_wait_until_no_pending_writes(); /** Wait until all pending asynchronous reads have completed. */ diff --git a/storage/innobase/include/page0zip.ic b/storage/innobase/include/page0zip.ic index 7cf42a04b57..afc877c3720 100644 --- a/storage/innobase/include/page0zip.ic +++ b/storage/innobase/include/page0zip.ic @@ -1,8 +1,7 @@ /***************************************************************************** Copyright (c) 2005, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2012, Facebook Inc. -Copyright (c) 2017, 2021, MariaDB Corporation. +Copyright (c) 2017, 2022, 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 diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h index 6e8e2952876..c936947db1c 100644 --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h @@ -517,7 +517,7 @@ do { \ #ifdef HAVE_PSI_STAGE_INTERFACE /** Performance schema stage event for monitoring ALTER TABLE progress -everything after flush log_make_checkpoint(). */ +in ha_innobase::commit_inplace_alter_table(). */ extern PSI_stage_info srv_stage_alter_table_end; /** Performance schema stage event for monitoring ALTER TABLE progress diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index 14540cadcaf..b8086083f80 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -1,8 +1,7 @@ /***************************************************************************** Copyright (c) 1997, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2012, Facebook Inc. -Copyright (c) 2013, 2021, MariaDB Corporation. +Copyright (c) 2013, 2022, 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 @@ -57,9 +56,6 @@ Created 9/20/1997 Heikki Tuuri #include "fil0pagecompress.h" #include "log.h" -/** Read-ahead area in applying log records to file pages */ -#define RECV_READ_AHEAD_AREA 32U - /** The recovery system */ recv_sys_t recv_sys; /** TRUE when recv_init_crash_recovery() has been called. */ @@ -838,13 +834,16 @@ processed: space->free_len= flst_get_len(FSP_HEADER_OFFSET + FSP_FREE + page); fil_node_t *node= UT_LIST_GET_FIRST(space->chain); if (!space->acquire()) + { +free_space: + fil_space_free(it->first, false); goto next_item; + } if (os_file_write(IORequestWrite, node->name, node->handle, - page, 0, fil_space_t::physical_size(flags) != - DB_SUCCESS)) + page, 0, fil_space_t::physical_size(flags)) != DB_SUCCESS) { space->release(); - goto next_item; + goto free_space; } space->release(); it->second.space= space; @@ -2949,11 +2948,9 @@ page number. TRANSACTIONAL_TARGET static void recv_read_in_area(page_id_t page_id) { - uint32_t page_nos[RECV_READ_AHEAD_AREA]; - compile_time_assert(ut_is_2pow(RECV_READ_AHEAD_AREA)); - page_id.set_page_no(ut_2pow_round(page_id.page_no(), - RECV_READ_AHEAD_AREA)); - const ulint up_limit = page_id.page_no() + RECV_READ_AHEAD_AREA; + uint32_t page_nos[32]; + page_id.set_page_no(ut_2pow_round(page_id.page_no(), 32U)); + const uint32_t up_limit = page_id.page_no() + 32; uint32_t* p = page_nos; for (recv_sys_t::map::iterator i= recv_sys.pages.lower_bound(page_id); @@ -3282,7 +3279,7 @@ next_page: /* Instead of flushing, last_batch could sort the buf_pool.flush_list in ascending order of buf_page_t::oldest_modification. */ - buf_flush_sync(); + buf_flush_sync_batch(recovered_lsn); if (!last_batch) { diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc index 613bef9b724..fea1eda17e9 100644 --- a/storage/innobase/os/os0file.cc +++ b/storage/innobase/os/os0file.cc @@ -3811,8 +3811,7 @@ static void os_aio_wait_until_no_pending_writes_low() tpool::tpool_wait_end(); } -/** Wait until there are no pending asynchronous writes. -Only used on FLUSH TABLES...FOR EXPORT. */ +/** Wait until there are no pending asynchronous writes. */ void os_aio_wait_until_no_pending_writes() { os_aio_wait_until_no_pending_writes_low(); diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index 54dda7bd901..0382b4abf4a 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -2189,8 +2189,6 @@ row_import_cleanup( DBUG_EXECUTE_IF("ib_import_before_checkpoint_crash", DBUG_SUICIDE();); - log_make_checkpoint(); - return(err); } diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index c2c87cf3a78..b7688c7bfe4 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -973,7 +973,9 @@ dberr_t wsrep_append_foreign_key(trx_t *trx, dict_foreign_t* foreign, const rec_t* clust_rec, dict_index_t* clust_index, - ibool referenced, + bool referenced, + upd_node_t* upd_node, + bool pa_disable, Wsrep_service_key_type key_type); #endif /* WITH_WSREP */ @@ -1326,11 +1328,13 @@ row_ins_foreign_check_on_constraint( } #ifdef WITH_WSREP - err = wsrep_append_foreign_key(trx, foreign, clust_rec, clust_index, - FALSE, WSREP_SERVICE_KEY_EXCLUSIVE); - if (err != DB_SUCCESS) { - ib::info() << "WSREP: foreign key append failed: " << err; - goto nonstandard_exit_func; + if (trx->is_wsrep()) { + err = wsrep_append_foreign_key(trx, foreign, clust_rec, clust_index, + false, NULL, true, + WSREP_SERVICE_KEY_EXCLUSIVE); + if (err != DB_SUCCESS) { + goto nonstandard_exit_func; + } } #endif /* WITH_WSREP */ mtr_commit(mtr); @@ -1714,19 +1718,16 @@ row_ins_check_foreign_constraint( if (check_ref) { err = DB_SUCCESS; #ifdef WITH_WSREP - err = wsrep_append_foreign_key( - thr_get_trx(thr), - foreign, - rec, - check_index, - check_ref, - (upd_node != NULL - && wsrep_protocol_version < 4) - ? WSREP_SERVICE_KEY_SHARED - : WSREP_SERVICE_KEY_REFERENCE); - if (err != DB_SUCCESS) { - fprintf(stderr, - "WSREP: foreign key append failed: %d\n", err); + if (trx->is_wsrep()) { + err = wsrep_append_foreign_key( + thr_get_trx(thr), + foreign, + rec, + check_index, + check_ref, + upd_node, + false, + WSREP_SERVICE_KEY_REFERENCE); } #endif /* WITH_WSREP */ goto end_scan; @@ -3370,10 +3371,13 @@ row_ins_index_entry( DBUG_SET("-d,row_ins_index_entry_timeout"); return(DB_LOCK_WAIT);}); - if (auto t= trx->check_bulk_buffer(index->table)) { - /* MDEV-25036 FIXME: check also foreign key constraints */ - ut_ad(!trx->check_foreigns); - return t->bulk_insert_buffered(*entry, *index, trx); + if (index->is_btree()) { + if (auto t= trx->check_bulk_buffer(index->table)) { + /* MDEV-25036 FIXME: check also foreign key + constraints */ + ut_ad(!trx->check_foreigns); + return t->bulk_insert_buffered(*entry, *index, trx); + } } if (index->is_primary()) { diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index 4a5b8ffb271..f693a9ec96e 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -4986,7 +4986,7 @@ row_merge_bulk_t::row_merge_bulk_t(dict_table_t *table) for (dict_index_t *index= UT_LIST_GET_FIRST(table->indexes); index; index= UT_LIST_GET_NEXT(indexes, index)) { - if (index->type & DICT_FTS) + if (!index->is_btree()) continue; n_index++; } @@ -4998,7 +4998,7 @@ row_merge_bulk_t::row_merge_bulk_t(dict_table_t *table) for (dict_index_t *index= UT_LIST_GET_FIRST(table->indexes); index; index= UT_LIST_GET_NEXT(indexes, index)) { - if (index->type & DICT_FTS) + if (!index->is_btree()) continue; mem_heap_t *heap= mem_heap_create(100); @@ -5019,7 +5019,7 @@ row_merge_bulk_t::~row_merge_bulk_t() for (dict_index_t *index= UT_LIST_GET_FIRST(table->indexes); index; index= UT_LIST_GET_NEXT(indexes, index)) { - if (index->type & DICT_FTS) + if (!index->is_btree()) continue; row_merge_buf_free(&m_merge_buf[i]); if (m_merge_files) @@ -5049,7 +5049,7 @@ void row_merge_bulk_t::init_tmp_file() for (dict_index_t *index= UT_LIST_GET_FIRST(table->indexes); index; index= UT_LIST_GET_NEXT(indexes, index)) { - if (index->type & DICT_FTS) + if (!index->is_btree()) continue; n_index++; } @@ -5112,7 +5112,7 @@ dberr_t row_merge_bulk_t::bulk_insert_buffered(const dtuple_t &row, for (dict_index_t *index= UT_LIST_GET_FIRST(ind.table->indexes); index; index= UT_LIST_GET_NEXT(indexes, index)) { - if (index->type & DICT_FTS) + if (!index->is_btree()) continue; if (index != &ind) @@ -5210,7 +5210,7 @@ dberr_t row_merge_bulk_t::write_to_table(dict_table_t *table, trx_t *trx) for (dict_index_t *index= UT_LIST_GET_FIRST(table->indexes); index; index= UT_LIST_GET_NEXT(indexes, index)) { - if (index->type & DICT_FTS) + if (!index->is_btree()) continue; dberr_t err= write_to_index(i, trx); diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc index 9c5aea2a453..595bc4237f0 100644 --- a/storage/innobase/srv/srv0srv.cc +++ b/storage/innobase/srv/srv0srv.cc @@ -562,7 +562,7 @@ char srv_buffer_pool_load_at_startup = TRUE; #ifdef HAVE_PSI_STAGE_INTERFACE /** Performance schema stage event for monitoring ALTER TABLE progress -everything after flush log_make_checkpoint(). */ +in ha_innobase::commit_inplace_alter_table(). */ PSI_stage_info srv_stage_alter_table_end = {0, "alter table (end)", PSI_FLAG_STAGE_PROGRESS}; diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index c93ca053d98..c3059b2a54e 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -238,6 +238,10 @@ static dberr_t create_log_file(bool create_new_db, lsn_t lsn, return DB_READ_ONLY; } + if (!log_set_capacity(srv_log_file_size_requested)) { + return(DB_ERROR); + } + /* Crashing after deleting the first file should be recoverable. The buffer pool was clean, and we can simply create log file from the scratch. */ @@ -290,9 +294,6 @@ static dberr_t create_log_file(bool create_new_db, lsn_t lsn, renamed. */ log_sys.log.create(); - if (!log_set_capacity(srv_log_file_size_requested)) { - return DB_ERROR; - } log_sys.log.open_file(logfile0); if (!fil_system.sys_space->open(create_new_db)) { @@ -325,6 +326,13 @@ static dberr_t create_log_file(bool create_new_db, lsn_t lsn, log_sys.log.write_header_durable(lsn); + ut_ad(srv_startup_is_before_trx_rollback_phase); + if (create_new_db) { + srv_startup_is_before_trx_rollback_phase = false; + } + + /* Enable checkpoints in buf_flush_page_cleaner(). */ + recv_sys.recovery_on = false; mysql_mutex_unlock(&log_sys.mutex); log_make_checkpoint(); @@ -879,92 +887,74 @@ buffer pools. Flush the redo log buffer to the redo log file. @return lsn upto which data pages have been flushed. */ static lsn_t srv_prepare_to_delete_redo_log_file(bool old_exists) { - DBUG_ENTER("srv_prepare_to_delete_redo_log_file"); - - lsn_t flushed_lsn; - ulint count = 0; + DBUG_ENTER("srv_prepare_to_delete_redo_log_file"); - if (log_sys.log.subformat != 2) { - srv_log_file_size = 0; - } + /* Disable checkpoints in the page cleaner. */ + ut_ad(!recv_sys.recovery_on); + recv_sys.recovery_on= true; - for (;;) { - /* Clean the buffer pool. */ - buf_flush_sync(); + /* Clean the buffer pool. */ + buf_flush_sync(); - DBUG_EXECUTE_IF("innodb_log_abort_1", DBUG_RETURN(0);); - DBUG_PRINT("ib_log", ("After innodb_log_abort_1")); + if (log_sys.log.subformat != 2) + srv_log_file_size= 0; - mysql_mutex_lock(&log_sys.mutex); + DBUG_EXECUTE_IF("innodb_log_abort_1", DBUG_RETURN(0);); + DBUG_PRINT("ib_log", ("After innodb_log_abort_1")); - fil_names_clear(log_sys.get_lsn(), false); - - flushed_lsn = log_sys.get_lsn(); - - { - ib::info info; - if (srv_log_file_size == 0 - || (log_sys.log.format & ~log_t::FORMAT_ENCRYPTED) - != log_t::FORMAT_10_5) { - info << "Upgrading redo log: "; - } else if (!old_exists - || srv_log_file_size - != srv_log_file_size_requested) { - if (srv_encrypt_log - == (my_bool)log_sys.is_encrypted()) { - info << (srv_encrypt_log - ? "Resizing encrypted" - : "Resizing"); - } else if (srv_encrypt_log) { - info << "Encrypting and resizing"; - } else { - info << "Removing encryption" - " and resizing"; - } - - info << " redo log from " << srv_log_file_size - << " to "; - } else if (srv_encrypt_log) { - info << "Encrypting redo log: "; - } else { - info << "Removing redo log encryption: "; - } - - info << srv_log_file_size_requested - << " bytes; LSN=" << flushed_lsn; - } + mysql_mutex_lock(&log_sys.mutex); + const bool latest_format= (log_sys.log.format & ~log_t::FORMAT_ENCRYPTED) == + log_t::FORMAT_10_5; + lsn_t flushed_lsn= log_sys.get_lsn(); - mysql_mutex_unlock(&log_sys.mutex); + if (latest_format) + { + fil_names_clear(flushed_lsn, false); + flushed_lsn= log_sys.get_lsn(); + } - if (flushed_lsn != log_sys.get_flushed_lsn()) { - log_write_up_to(flushed_lsn, false); - log_sys.log.flush(); - } + { + const char *msg; + if (!latest_format || srv_log_file_size == 0) + { + msg= "Upgrading redo log: "; +same_size: + ib::info() << msg << srv_log_file_size_requested << " bytes; LSN=" + << flushed_lsn; + } + else if (old_exists && srv_log_file_size == srv_log_file_size_requested) + { + msg= srv_encrypt_log + ? "Encrypting redo log: " : "Removing redo log encryption: "; + goto same_size; + } + else + { + if (srv_encrypt_log == (my_bool)log_sys.is_encrypted()) + msg= srv_encrypt_log ? "Resizing encrypted" : "Resizing"; + else + msg= srv_encrypt_log + ? "Encrypting and resizing" + : "Removing encryption and resizing"; + + ib::info() << msg << " redo log from " << srv_log_file_size << " to " + << srv_log_file_size_requested + << " bytes; LSN=" << flushed_lsn; + } + } - ut_ad(flushed_lsn == log_sys.get_lsn()); - - /* Check if the buffer pools are clean. If not - retry till it is clean. */ - if (ulint pending_io = buf_pool.io_pending()) { - count++; - /* Print a message every 60 seconds if we - are waiting to clean the buffer pools */ - if (srv_print_verbose_log && count > 600) { - ib::info() << "Waiting for " - << pending_io << " buffer " - << "page I/Os to complete"; - count = 0; - } + mysql_mutex_unlock(&log_sys.mutex); - std::this_thread::sleep_for( - std::chrono::milliseconds(100)); - continue; - } + if (flushed_lsn != log_sys.get_flushed_lsn()) + { + log_write_up_to(flushed_lsn, false); + log_sys.log.flush(); + } - break; - } + ut_ad(flushed_lsn == log_sys.get_lsn()); + ut_ad(!buf_pool.any_io_pending()); - DBUG_RETURN(flushed_lsn); + DBUG_RETURN(flushed_lsn); } /** Tries to locate LOG_FILE_NAME and check it's size, etc @@ -1241,7 +1231,7 @@ dberr_t srv_start(bool create_new_db) ut_ad(buf_page_cleaner_is_active); } - srv_startup_is_before_trx_rollback_phase = !create_new_db; + srv_startup_is_before_trx_rollback_phase = true; /* Check if undo tablespaces and redo log files exist before creating a new system tablespace */ @@ -1290,11 +1280,16 @@ dberr_t srv_start(bool create_new_db) if (create_new_db) { flushed_lsn = log_sys.get_lsn(); log_sys.set_flushed_lsn(flushed_lsn); - buf_flush_sync(); err = create_log_file(true, flushed_lsn, logfile0); if (err != DB_SUCCESS) { + for (Tablespace::const_iterator + i = srv_sys_space.begin(); + i != srv_sys_space.end(); i++) { + os_file_delete(innodb_data_file_key, + i->filepath()); + } return(srv_init_abort(err)); } } else { @@ -1347,6 +1342,9 @@ dberr_t srv_start(bool create_new_db) if (!log_set_capacity(srv_log_file_size_requested)) { return(srv_init_abort(DB_ERROR)); } + + /* Enable checkpoints in the page cleaner. */ + recv_sys.recovery_on = false; } file_checked: @@ -1951,11 +1949,8 @@ void innodb_shutdown() break; case SRV_OPERATION_RESTORE: case SRV_OPERATION_RESTORE_EXPORT: - srv_shutdown_state = SRV_SHUTDOWN_CLEANUP; - if (!buf_page_cleaner_is_active) { - break; - } mysql_mutex_lock(&buf_pool.flush_list_mutex); + srv_shutdown_state = SRV_SHUTDOWN_CLEANUP; while (buf_page_cleaner_is_active) { pthread_cond_signal(&buf_pool.do_flush_list); my_cond_wait(&buf_pool.done_flush_list, diff --git a/storage/innobase/trx/trx0i_s.cc b/storage/innobase/trx/trx0i_s.cc index 1232ccc5ad9..2dc39118d3d 100644 --- a/storage/innobase/trx/trx0i_s.cc +++ b/storage/innobase/trx/trx0i_s.cc @@ -1213,7 +1213,7 @@ static void fetch_data_into_cache(trx_i_s_cache_t *cache) /* Capture the state of transactions */ 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) + &trx != (purge_sys.query ? purge_sys.query->trx : nullptr)) { trx.mutex_lock(); if (trx.state != TRX_STATE_NOT_STARTED) diff --git a/storage/innobase/trx/trx0purge.cc b/storage/innobase/trx/trx0purge.cc index 13a5afdfeef..c3af9d79db1 100644 --- a/storage/innobase/trx/trx0purge.cc +++ b/storage/innobase/trx/trx0purge.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2017, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2021, MariaDB Corporation. +Copyright (c) 2017, 2022, 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 @@ -705,7 +705,16 @@ not_free: { auto block= reinterpret_cast<buf_block_t*>(bpage); ut_ad(buf_pool.is_uncompressed(block)); - bpage->lock.x_lock(); + if (!bpage->lock.x_lock_try()) + { + /* Let buf_pool_t::release_freed_page() proceed. */ + mysql_mutex_unlock(&buf_pool.flush_list_mutex); + std::this_thread::yield(); + mysql_mutex_lock(&buf_pool.flush_list_mutex); + rescan: + bpage= UT_LIST_GET_LAST(buf_pool.flush_list); + continue; + } buf_pool.flush_hp.set(prev); mysql_mutex_unlock(&buf_pool.flush_list_mutex); @@ -728,11 +737,8 @@ not_free: } if (prev != buf_pool.flush_hp.get()) - { /* Rescan, because we may have lost the position. */ - bpage= UT_LIST_GET_LAST(buf_pool.flush_list); - continue; - } + goto rescan; } bpage= prev; diff --git a/storage/maria/ma_blockrec.c b/storage/maria/ma_blockrec.c index a89ac966a75..05040d962eb 100644 --- a/storage/maria/ma_blockrec.c +++ b/storage/maria/ma_blockrec.c @@ -6399,16 +6399,19 @@ uint _ma_apply_redo_insert_row_head_or_tail(MARIA_HA *info, LSN lsn, pin_method= PAGECACHE_PIN_LEFT_PINNED; share->pagecache->readwrite_flags&= ~MY_WME; + share->silence_encryption_errors= 1; buff= pagecache_read(share->pagecache, &info->dfile, page, 0, 0, PAGECACHE_PLAIN_PAGE, PAGECACHE_LOCK_WRITE, &page_link.link); share->pagecache->readwrite_flags= share->pagecache->org_readwrite_flags; + share->silence_encryption_errors= 0; if (!buff) { /* Skip errors when reading outside of file and uninitialized pages */ if (!new_page || (my_errno != HA_ERR_FILE_TOO_SHORT && - my_errno != HA_ERR_WRONG_CRC)) + my_errno != HA_ERR_WRONG_CRC && + my_errno != HA_ERR_DECRYPTION_FAILED)) { DBUG_PRINT("error", ("Error %d when reading page", (int) my_errno)); goto err; @@ -6900,6 +6903,7 @@ uint _ma_apply_redo_insert_row_blobs(MARIA_HA *info, else { share->pagecache->readwrite_flags&= ~MY_WME; + share->silence_encryption_errors= 1; buff= pagecache_read(share->pagecache, &info->dfile, page, 0, 0, @@ -6907,10 +6911,12 @@ uint _ma_apply_redo_insert_row_blobs(MARIA_HA *info, PAGECACHE_LOCK_WRITE, &page_link.link); share->pagecache->readwrite_flags= share->pagecache-> org_readwrite_flags; + share->silence_encryption_errors= 0; if (!buff) { if (my_errno != HA_ERR_FILE_TOO_SHORT && - my_errno != HA_ERR_WRONG_CRC) + my_errno != HA_ERR_WRONG_CRC && + my_errno != HA_ERR_DECRYPTION_FAILED) { /* If not read outside of file */ pagecache_unlock_by_link(share->pagecache, page_link.link, diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c index 20baa429d76..8cc2a1829a9 100644 --- a/storage/maria/ma_check.c +++ b/storage/maria/ma_check.c @@ -5031,7 +5031,8 @@ static int sort_get_next_record(MARIA_SORT_PARAM *sort_param) DBUG_RETURN(-1); } /* Retry only if wrong record, not if disk error */ - if (flag != HA_ERR_WRONG_IN_RECORD && flag != HA_ERR_WRONG_CRC) + if (flag != HA_ERR_WRONG_IN_RECORD && flag != HA_ERR_WRONG_CRC && + flag != HA_ERR_DECRYPTION_FAILED) { retry_if_quick(sort_param, flag); DBUG_RETURN(flag); @@ -6851,7 +6852,8 @@ read_next_page: PAGECACHE_READ_UNKNOWN_PAGE, PAGECACHE_LOCK_LEFT_UNLOCKED, 0))) { - if (my_errno == HA_ERR_WRONG_CRC) + if (my_errno == HA_ERR_WRONG_CRC || + my_errno == HA_ERR_DECRYPTION_FAILED) { /* Don't give errors for zero filled blocks. These can diff --git a/storage/maria/ma_control_file.c b/storage/maria/ma_control_file.c index db74ba0af75..bcf9a7041e4 100644 --- a/storage/maria/ma_control_file.c +++ b/storage/maria/ma_control_file.c @@ -314,7 +314,7 @@ CONTROL_FILE_ERROR ma_control_file_open(my_bool create_if_missing, errmsg= "Can't create file"; goto err; } - if (lock_control_file(name, wait_for_lock)) + if (!aria_readonly && lock_control_file(name, wait_for_lock)) { error= CONTROL_FILE_LOCKED; errmsg= lock_failed_errmsg; @@ -332,7 +332,7 @@ CONTROL_FILE_ERROR ma_control_file_open(my_bool create_if_missing, } /* lock it before reading content */ - if (lock_control_file(name, wait_for_lock)) + if (!aria_readonly && lock_control_file(name, wait_for_lock)) { error= CONTROL_FILE_LOCKED; errmsg= lock_failed_errmsg; diff --git a/storage/maria/ma_crypt.c b/storage/maria/ma_crypt.c index 31f16a21841..9282405bae9 100644 --- a/storage/maria/ma_crypt.c +++ b/storage/maria/ma_crypt.c @@ -345,7 +345,14 @@ static my_bool ma_crypt_index_post_read_hook(int res, const uint block_size= share->block_size; const uint page_used= _ma_get_page_used(share, args->page); - if (res == 0 && page_used <= block_size - CRC_SIZE) + if (res || + page_used < share->keypage_header || + page_used >= block_size - CRC_SIZE) + { + res= 1; + my_errno= HA_ERR_DECRYPTION_FAILED; + } + else { const uchar *src= args->page; uchar* dst= args->crypt_buf; @@ -506,10 +513,11 @@ static int ma_decrypt(MARIA_SHARE *share, MARIA_CRYPT_DATA *crypt_data, if (! (rc == MY_AES_OK && dstlen == size)) { my_errno= HA_ERR_DECRYPTION_FAILED; - my_printf_error(HA_ERR_DECRYPTION_FAILED, - "failed to decrypt '%s' rc: %d dstlen: %u size: %u\n", - MYF(ME_FATAL|ME_ERROR_LOG), - share->open_file_name.str, rc, dstlen, size); + if (!share->silence_encryption_errors) + my_printf_error(HA_ERR_DECRYPTION_FAILED, + "failed to decrypt '%s' rc: %d dstlen: %u size: %u\n", + MYF(ME_FATAL|ME_ERROR_LOG), + share->open_file_name.str, rc, dstlen, size); return 1; } return 0; diff --git a/storage/maria/ma_key_recover.c b/storage/maria/ma_key_recover.c index afa69fce444..2f28ec8d175 100644 --- a/storage/maria/ma_key_recover.c +++ b/storage/maria/ma_key_recover.c @@ -767,7 +767,8 @@ uint _ma_apply_redo_index_new_page(MARIA_HA *info, LSN lsn, &page_link.link))) { if (my_errno != HA_ERR_FILE_TOO_SHORT && - my_errno != HA_ERR_WRONG_CRC) + my_errno != HA_ERR_WRONG_CRC && + my_errno != HA_ERR_DECRYPTION_FAILED) { result= 1; goto err; diff --git a/storage/maria/maria_def.h b/storage/maria/maria_def.h index 60b6cc35fbb..d6bdffa0f7e 100644 --- a/storage/maria/maria_def.h +++ b/storage/maria/maria_def.h @@ -803,6 +803,7 @@ typedef struct st_maria_share my_bool key_del_used; /* != 0 if key_del is locked */ my_bool deleting; /* we are going to delete this table */ my_bool redo_error_given; /* Used during recovery */ + my_bool silence_encryption_errors; /* Used during recovery */ THR_LOCK lock; void (*lock_restore_status)(void *); /** diff --git a/storage/perfschema/unittest/pfs_server_stubs.cc b/storage/perfschema/unittest/pfs_server_stubs.cc index 5a855b2c147..ca7b2300797 100644 --- a/storage/perfschema/unittest/pfs_server_stubs.cc +++ b/storage/perfschema/unittest/pfs_server_stubs.cc @@ -51,7 +51,7 @@ void sql_print_warning(const char *format, ...) } class sys_var { public: enum where { AUTO }; }; -void set_sys_var_value_origin(void *ptr, enum sys_var::where here) +void set_sys_var_value_origin(void *, enum sys_var::where, const char *) { } diff --git a/storage/spider/mysql-test/spider/bugfix/r/mdev_27184.result b/storage/spider/mysql-test/spider/bugfix/r/mdev_27184.result new file mode 100644 index 00000000000..8a3d9da1dc4 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/mdev_27184.result @@ -0,0 +1,21 @@ +# +# MDEV-27184 Assertion `(old_top == initial_top (av) && old_size == 0) || +# ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && +# ((unsigned long) old_end & (pagesize - 1)) == 0)' failed, +# Assertion `str.alloced_length() >= str.length() + data_len' failed +# +for master_1 +for child2 +for child3 +connection master_1; +CREATE DATABASE auto_test_remote; +USE auto_test_remote; +CREATE TABLE tbl_a (a FLOAT) ENGINE=SPIDER; +INSERT INTO tbl_a VALUES +(0xF5A7),(0xF5A8),(0xF5A9),(0xF5AA),(0xF5AB),(0xF5AC),(0xF5AD),(0xF5AE), +(0xF5A7),(0xF5A8),(0xF5A9),(0xF5AA),(0xF5AB),(0xF5AC),(0xF5AD),(0xF5AE); +ERROR HY000: Unable to connect to foreign data source: localhost +DROP DATABASE auto_test_remote; +for master_1 +for child2 +for child3 diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_27184.cnf b/storage/spider/mysql-test/spider/bugfix/t/mdev_27184.cnf new file mode 100644 index 00000000000..b0853e32654 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_27184.cnf @@ -0,0 +1,2 @@ +!include include/default_mysqld.cnf +!include ../my_1_1.cnf diff --git a/storage/spider/mysql-test/spider/bugfix/t/mdev_27184.test b/storage/spider/mysql-test/spider/bugfix/t/mdev_27184.test new file mode 100644 index 00000000000..9d3922b2c48 --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/mdev_27184.test @@ -0,0 +1,31 @@ +--echo # +--echo # MDEV-27184 Assertion `(old_top == initial_top (av) && old_size == 0) || +--echo # ((unsigned long) (old_size) >= MINSIZE && prev_inuse (old_top) && +--echo # ((unsigned long) old_end & (pagesize - 1)) == 0)' failed, +--echo # Assertion `str.alloced_length() >= str.length() + data_len' failed +--echo # + +--disable_query_log +--disable_result_log +--source ../../t/test_init.inc +--enable_result_log +--enable_query_log + +--connection master_1 +CREATE DATABASE auto_test_remote; +USE auto_test_remote; + +CREATE TABLE tbl_a (a FLOAT) ENGINE=SPIDER; + +--error ER_CONNECT_TO_FOREIGN_DATA_SOURCE +INSERT INTO tbl_a VALUES + (0xF5A7),(0xF5A8),(0xF5A9),(0xF5AA),(0xF5AB),(0xF5AC),(0xF5AD),(0xF5AE), + (0xF5A7),(0xF5A8),(0xF5A9),(0xF5AA),(0xF5AB),(0xF5AC),(0xF5AD),(0xF5AE); + +DROP DATABASE auto_test_remote; + +--disable_query_log +--disable_result_log +--source ../../t/test_deinit.inc +--enable_result_log +--enable_query_log diff --git a/storage/spider/mysql-test/spider/r/spider_fixes.result b/storage/spider/mysql-test/spider/r/spider_fixes.result index 1db31ca9f95..b2a2fad5238 100644 --- a/storage/spider/mysql-test/spider/r/spider_fixes.result +++ b/storage/spider/mysql-test/spider/r/spider_fixes.result @@ -596,6 +596,13 @@ connection child2_1; DROP DATABASE IF EXISTS auto_test_remote; connection child2_2; DROP DATABASE IF EXISTS auto_test_remote2; +connection master_1; +SET @@global.expire_logs_days=11; +connect master_purge, localhost, root, , , $MASTER_1_MYPORT, $MASTER_1_MYSOCK; +SET @@global.binlog_checksum=NONE; +SET @@global.binlog_checksum=$binlog_checksum; +SET @@global.expire_logs_days=$expire_logs_days; +disconnect master_purge; for slave1_1 for master_1 for child2 diff --git a/storage/spider/mysql-test/spider/t/spider_fixes.test b/storage/spider/mysql-test/spider/t/spider_fixes.test index 9f7ada052ed..56e143060e6 100644 --- a/storage/spider/mysql-test/spider/t/spider_fixes.test +++ b/storage/spider/mysql-test/spider/t/spider_fixes.test @@ -1410,6 +1410,21 @@ if ($USE_CHILD_GROUP2) --connection child2_2 DROP DATABASE IF EXISTS auto_test_remote2; } + + +# MDEV-27039 LOCK_global_system_variables attempted to re-acquire +# The test proves no assert anymore. +--connection master_1 +--let $binlog_checksum=`SELECT @@global.binlog_checksum` +--let $expire_logs_days=`SELECT @@global.expire_logs_days` +SET @@global.expire_logs_days=11; + +--connect (master_purge, localhost, root, , , $MASTER_1_MYPORT, $MASTER_1_MYSOCK) +SET @@global.binlog_checksum=NONE; +--evalp SET @@global.binlog_checksum=$binlog_checksum +--evalp SET @@global.expire_logs_days=$expire_logs_days +--disconnect master_purge + --disable_query_log --disable_result_log --source slave_test_deinit.inc diff --git a/storage/spider/spd_db_mysql.cc b/storage/spider/spd_db_mysql.cc index 62e6e2f1245..03dc1ebd49f 100644 --- a/storage/spider/spd_db_mysql.cc +++ b/storage/spider/spd_db_mysql.cc @@ -4388,7 +4388,7 @@ int spider_db_mariadb_util::append_column_value( } else if (float_value) { if (str->reserve(SPIDER_SQL_CAST_LEN + ptr->length() + - SPIDER_SQL_AS_FLOAT_LEN, SPIDER_SQL_CLOSE_PAREN_LEN)) + SPIDER_SQL_AS_FLOAT_LEN + SPIDER_SQL_CLOSE_PAREN_LEN)) { DBUG_RETURN(HA_ERR_OUT_OF_MEM); } |