summaryrefslogtreecommitdiff
path: root/storage
diff options
context:
space:
mode:
Diffstat (limited to 'storage')
-rw-r--r--storage/innobase/buf/buf0buf.cc7
-rw-r--r--storage/innobase/buf/buf0dblwr.cc3
-rw-r--r--storage/innobase/buf/buf0flu.cc109
-rw-r--r--storage/innobase/eval/eval0eval.cc15
-rw-r--r--storage/innobase/fil/fil0crypt.cc3
-rw-r--r--storage/innobase/handler/ha_innodb.cc29
-rw-r--r--storage/innobase/include/buf0flu.h11
-rw-r--r--storage/innobase/include/dict0mem.h7
-rw-r--r--storage/innobase/include/mtr0mtr.h3
-rw-r--r--storage/innobase/include/os0file.h3
-rw-r--r--storage/innobase/include/page0zip.ic3
-rw-r--r--storage/innobase/include/srv0srv.h2
-rw-r--r--storage/innobase/log/log0recv.cc25
-rw-r--r--storage/innobase/os/os0file.cc3
-rw-r--r--storage/innobase/row/row0import.cc2
-rw-r--r--storage/innobase/row/row0ins.cc50
-rw-r--r--storage/innobase/row/row0merge.cc12
-rw-r--r--storage/innobase/srv/srv0srv.cc2
-rw-r--r--storage/innobase/srv/srv0start.cc163
-rw-r--r--storage/innobase/trx/trx0i_s.cc2
-rw-r--r--storage/innobase/trx/trx0purge.cc18
-rw-r--r--storage/maria/ma_blockrec.c10
-rw-r--r--storage/maria/ma_check.c6
-rw-r--r--storage/maria/ma_control_file.c4
-rw-r--r--storage/maria/ma_crypt.c18
-rw-r--r--storage/maria/ma_key_recover.c3
-rw-r--r--storage/maria/maria_def.h1
-rw-r--r--storage/perfschema/unittest/pfs_server_stubs.cc2
-rw-r--r--storage/spider/mysql-test/spider/bugfix/r/mdev_27184.result21
-rw-r--r--storage/spider/mysql-test/spider/bugfix/t/mdev_27184.cnf2
-rw-r--r--storage/spider/mysql-test/spider/bugfix/t/mdev_27184.test31
-rw-r--r--storage/spider/mysql-test/spider/r/spider_fixes.result7
-rw-r--r--storage/spider/mysql-test/spider/t/spider_fixes.test15
-rw-r--r--storage/spider/spd_db_mysql.cc2
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);
}