From c62bb9c3b40decdcd3d2cdbff6616107e9434e33 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Sun, 9 Jan 2022 23:52:24 +0100 Subject: [PATCH 1/4] Silence CMake warning from exteral cmake project (pcre2) The warning reads: CMake Deprecation Warning at CMakeLists.txt:101 (CMAKE_MINIMUM_REQUIRED): Compatibility with CMake < 2.8.12 will be removed from a future version of CMake. --- cmake/pcre.cmake | 1 + 1 file changed, 1 insertion(+) diff --git a/cmake/pcre.cmake b/cmake/pcre.cmake index 42f22d9fe19..678556c9a59 100644 --- a/cmake/pcre.cmake +++ b/cmake/pcre.cmake @@ -48,6 +48,7 @@ MACRO(BUNDLE_PCRE2) URL_MD5 8c1699a725d4b28410adf4b964ebbcb7 INSTALL_COMMAND "" CMAKE_ARGS + "-DCMAKE_WARN_DEPRECATED=FALSE" "-DPCRE2_BUILD_TESTS=OFF" "-DPCRE2_BUILD_PCRE2GREP=OFF" "-DBUILD_SHARED_LIBS=OFF" From 81e00485c3eb4be044bbca398f1a4e479ebcc3ac Mon Sep 17 00:00:00 2001 From: Rucha Deodhar Date: Fri, 16 Oct 2020 20:19:09 +0530 Subject: [PATCH 2/4] MDEV-23836: Assertion `! is_set() || m_can_overwrite_status' in Diagnostics_area::set_error_status (interrupted ALTER TABLE under LOCK) Analysis: KILL_QUERY is not ignored when local memory used exceeds maximum session memory. Hence the query proceeds, OK is sent and we end up reopening tables that are marked for reopen. During this, kill status is eventually checked and assertion failure happens during trying to send error message because OK has already been sent. Fix: Ok is already sent so statement has already executed. It is too late to give error. So ignore kill. --- mysql-test/main/alter_table.result | 18 ++++++++++++++++++ mysql-test/main/alter_table.test | 22 ++++++++++++++++++++++ sql/lock.cc | 2 +- sql/sql_base.cc | 4 +++- 4 files changed, 44 insertions(+), 2 deletions(-) diff --git a/mysql-test/main/alter_table.result b/mysql-test/main/alter_table.result index 755de4336b9..682f2cc9d82 100644 --- a/mysql-test/main/alter_table.result +++ b/mysql-test/main/alter_table.result @@ -3415,5 +3415,23 @@ ERROR 0A000: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITH delete from t1 where a = 11; drop table t1; # +# MDEV-23836: Assertion `! is_set() || m_can_overwrite_status' in +# Diagnostics_area::set_error_status (interrupted ALTER TABLE under LOCK) +# +SET @max_session_mem_used_save= @@max_session_mem_used; +CREATE TABLE t1 (a INT); +SELECT * FROM t1; +a +ALTER TABLE x MODIFY xx INT; +ERROR 42S02: Table 'test.x' doesn't exist +SET SESSION max_session_mem_used= 8192; +LOCK TABLE t1 WRITE; +ALTER TABLE t1 CHANGE COLUMN IF EXISTS b c INT; +Warnings: +Note 1054 Unknown column 'b' in 't1' +SET SESSION max_session_mem_used = @max_session_mem_used_save; +UNLOCK TABLES; +DROP TABLE t1; +# # End of 10.5 tests # diff --git a/mysql-test/main/alter_table.test b/mysql-test/main/alter_table.test index 1bff20a7bd7..cc17c3efec9 100644 --- a/mysql-test/main/alter_table.test +++ b/mysql-test/main/alter_table.test @@ -2661,6 +2661,28 @@ delete from t1 where a = 11; # cleanup drop table t1; +--echo # +--echo # MDEV-23836: Assertion `! is_set() || m_can_overwrite_status' in +--echo # Diagnostics_area::set_error_status (interrupted ALTER TABLE under LOCK) +--echo # + +SET @max_session_mem_used_save= @@max_session_mem_used; + +CREATE TABLE t1 (a INT); +SELECT * FROM t1; + +--error ER_NO_SUCH_TABLE +ALTER TABLE x MODIFY xx INT; + +SET SESSION max_session_mem_used= 8192; +LOCK TABLE t1 WRITE; + +ALTER TABLE t1 CHANGE COLUMN IF EXISTS b c INT; + +SET SESSION max_session_mem_used = @max_session_mem_used_save; +UNLOCK TABLES; +DROP TABLE t1; + --echo # --echo # End of 10.5 tests --echo # diff --git a/sql/lock.cc b/sql/lock.cc index 559f1195b32..ec91655375e 100644 --- a/sql/lock.cc +++ b/sql/lock.cc @@ -356,7 +356,7 @@ bool mysql_lock_tables(THD *thd, MYSQL_LOCK *sql_lock, uint flags) end: THD_STAGE_INFO(thd, org_stage); - if (thd->killed) + if (thd->killed && !thd->get_stmt_da()->is_ok()) { thd->send_kill_message(); if (!rc) diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 01e8a65fda4..87d7f65fed5 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -2609,7 +2609,9 @@ void Locked_tables_list::mark_table_for_reopen(THD *thd, TABLE *table) bool Locked_tables_list::reopen_tables(THD *thd, bool need_reopen) { - Open_table_context ot_ctx(thd, MYSQL_OPEN_REOPEN); + bool is_ok= thd->get_stmt_da()->is_ok(); + Open_table_context ot_ctx(thd, !is_ok ? MYSQL_OPEN_REOPEN: + MYSQL_OPEN_IGNORE_KILLED | MYSQL_OPEN_REOPEN); uint reopen_count= 0; MYSQL_LOCK *lock; MYSQL_LOCK *merged_lock; From f443cd11007ab89512d4141472cbd9d3b524bad6 Mon Sep 17 00:00:00 2001 From: Eugene Kosov Date: Thu, 11 Nov 2021 15:22:20 +0600 Subject: [PATCH 3/4] MDEV-27022 Buffer pool is being flushed during recovery The problem was introduced by the removal of buf_pool.flush_rbt in commit 46b1f500983d45e89dc84bb9820023bd51a4cda8 (MDEV-23399) recv_sys_t::apply(): don't write to disc and fsync() the last batch. Insead, sort it by oldest_modification for MariaDB server and some mariabackup operations. log_sort_flush_list(): a thread-safe function which sorts buf_pool::flush_list --- storage/innobase/log/log0recv.cc | 38 +++++++++++++++++++++++++++++--- 1 file changed, 35 insertions(+), 3 deletions(-) diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index 9474cd31793..fdd9314b9b8 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -2616,6 +2616,32 @@ buf_block_t *recv_sys_t::recover_low(const page_id_t page_id) return block; } +/** Thread-safe function which sorts flush_list by oldest_modification */ +static void log_sort_flush_list() +{ + mysql_mutex_lock(&buf_pool.flush_list_mutex); + + const size_t size= UT_LIST_GET_LEN(buf_pool.flush_list); + std::unique_ptr list(new buf_page_t *[size]); + + size_t idx= 0; + for (buf_page_t *p= UT_LIST_GET_FIRST(buf_pool.flush_list); p; + p= UT_LIST_GET_NEXT(list, p)) + list.get()[idx++]= p; + + std::sort(list.get(), list.get() + size, + [](const buf_page_t *lhs, const buf_page_t *rhs) { + return rhs->oldest_modification() < lhs->oldest_modification(); + }); + + UT_LIST_INIT(buf_pool.flush_list, &buf_page_t::list); + + for (size_t i= 0; i < size; i++) + UT_LIST_ADD_LAST(buf_pool.flush_list, list[i]); + + mysql_mutex_unlock(&buf_pool.flush_list_mutex); +} + /** Apply buffered log to persistent data pages. @param last_batch whether it is possible to write more redo log */ void recv_sys_t::apply(bool last_batch) @@ -2750,9 +2776,15 @@ next_page: mysql_mutex_assert_not_owner(&log_sys.mutex); mutex_exit(&mutex); - /* Instead of flushing, last_batch could sort the buf_pool.flush_list - in ascending order of buf_page_t::oldest_modification. */ - buf_flush_sync_batch(recovered_lsn); + if (last_batch && srv_operation != SRV_OPERATION_RESTORE && + srv_operation != SRV_OPERATION_RESTORE_EXPORT) + log_sort_flush_list(); + else + { + /* Instead of flushing, last_batch could sort the buf_pool.flush_list + in ascending order of buf_page_t::oldest_modification. */ + buf_flush_sync_batch(recovered_lsn); + } if (!last_batch) { From 017d1b867b12ff36b3b871c3d57719907a905659 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 12 Jan 2022 12:29:16 +0200 Subject: [PATCH 4/4] MDEV-27476 heap-use-after-free in buf_pool_t::is_block_field() mtr_t::modify(): Remove a debug assertion that had been added in commit 05fa4558e0e82302ece981deabce764491464eb2 (MDEV-22110). The function buf_pool_t::is_uncompressed() is only safe to invoke while holding a buf_pool.page_hash latch so that buf_pool_t::resize() cannot concurrently invoke free() on any chunks. --- storage/innobase/mtr/mtr0mtr.cc | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/storage/innobase/mtr/mtr0mtr.cc b/storage/innobase/mtr/mtr0mtr.cc index 37a75ce4c94..a8dffa48c35 100644 --- a/storage/innobase/mtr/mtr0mtr.cc +++ b/storage/innobase/mtr/mtr0mtr.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 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 @@ -1217,7 +1217,6 @@ void mtr_t::modify(const buf_block_t &block) { /* This must be PageConverter::update_page() in IMPORT TABLESPACE. */ ut_ad(!block.page.in_LRU_list); - ut_ad(!buf_pool.is_uncompressed(&block)); return; }