From 74904a667e184c2e190e0b6e20dfa7613f4b2723 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 20 May 2019 17:00:21 +0300 Subject: Remove UT_NOT_USED btr_pcur_move_to_last_on_page(): Merge with the only caller. --- storage/innobase/fil/fil0crypt.cc | 7 +------ storage/innobase/include/btr0pcur.h | 10 +--------- storage/innobase/include/btr0pcur.ic | 20 +------------------- storage/innobase/include/ut0dbg.h | 6 +----- storage/innobase/row/row0sel.cc | 5 +++-- 5 files changed, 7 insertions(+), 41 deletions(-) (limited to 'storage') diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc index acf0b5eb1a3..902af66ebe7 100644 --- a/storage/innobase/fil/fil0crypt.cc +++ b/storage/innobase/fil/fil0crypt.cc @@ -2101,13 +2101,8 @@ A thread which monitors global key state and rotates tablespaces accordingly @return a dummy parameter */ extern "C" UNIV_INTERN os_thread_ret_t -DECLARE_THREAD(fil_crypt_thread)( -/*=============================*/ - void* arg __attribute__((unused))) /*!< in: a dummy parameter required - * by os_thread_create */ +DECLARE_THREAD(fil_crypt_thread)(void*) { - UT_NOT_USED(arg); - mutex_enter(&fil_crypt_threads_mutex); uint thread_no = srv_n_fil_crypt_threads_started; srv_n_fil_crypt_threads_started++; diff --git a/storage/innobase/include/btr0pcur.h b/storage/innobase/include/btr0pcur.h index 9eccd9e9636..b79260e5ab6 100644 --- a/storage/innobase/include/btr0pcur.h +++ b/storage/innobase/include/btr0pcur.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2018, MariaDB Corporation. +Copyright (c) 2017, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -328,14 +328,6 @@ btr_pcur_move_to_prev( function may release the page latch */ mtr_t* mtr); /*!< in: mtr */ /*********************************************************//** -Moves the persistent cursor to the last record on the same page. */ -UNIV_INLINE -void -btr_pcur_move_to_last_on_page( -/*==========================*/ - btr_pcur_t* cursor, /*!< in: persistent cursor */ - mtr_t* mtr); /*!< in: mtr */ -/*********************************************************//** Moves the persistent cursor to the next user record in the tree. If no user records are left, the cursor ends up 'after last in tree'. @return TRUE if the cursor moved forward, ending on a user record */ diff --git a/storage/innobase/include/btr0pcur.ic b/storage/innobase/include/btr0pcur.ic index 948eee242b8..51ebcfbb2ee 100644 --- a/storage/innobase/include/btr0pcur.ic +++ b/storage/innobase/include/btr0pcur.ic @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2015, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2015, 2017, MariaDB Corporation. +Copyright (c) 2015, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -280,24 +280,6 @@ btr_pcur_move_to_prev_on_page( cursor->old_stored = false; } -/*********************************************************//** -Moves the persistent cursor to the last record on the same page. */ -UNIV_INLINE -void -btr_pcur_move_to_last_on_page( -/*==========================*/ - btr_pcur_t* cursor, /*!< in: persistent cursor */ - mtr_t* mtr) /*!< in: mtr */ -{ - UT_NOT_USED(mtr); - ut_ad(cursor->latch_mode != BTR_NO_LATCHES); - - page_cur_set_after_last(btr_pcur_get_block(cursor), - btr_pcur_get_page_cur(cursor)); - - cursor->old_stored = false; -} - /*********************************************************//** Moves the persistent cursor to the next user record in the tree. If no user records are left, the cursor ends up 'after last in tree'. diff --git a/storage/innobase/include/ut0dbg.h b/storage/innobase/include/ut0dbg.h index c145b932771..5d3fa1cf987 100644 --- a/storage/innobase/include/ut0dbg.h +++ b/storage/innobase/include/ut0dbg.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1994, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, MariaDB Corporation. +Copyright (c) 2017, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -68,10 +68,6 @@ ut_dbg_assertion_failed( #define ut_d(EXPR) #endif -/** Silence warnings about an unused variable by doing a null assignment. -@param A the unused variable */ -#define UT_NOT_USED(A) A = A - #if defined(HAVE_SYS_TIME_H) && defined(HAVE_SYS_RESOURCE_H) #define HAVE_UT_CHRONO_T diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc index 24e2b52faa6..afdac984cfd 100644 --- a/storage/innobase/row/row0sel.cc +++ b/storage/innobase/row/row0sel.cc @@ -4871,8 +4871,9 @@ wrong_offs: << " of table " << index->table->name << ". We try to skip the rest of the page."; - btr_pcur_move_to_last_on_page(pcur, &mtr); - + page_cur_set_after_last(btr_pcur_get_block(pcur), + btr_pcur_get_page_cur(pcur)); + pcur->old_stored = false; goto next_rec; } } -- cgit v1.2.1 From c8740407297f8bf0339b9e907adccdd43133b7c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 24 May 2019 10:22:34 +0300 Subject: Declare INFORMATION_SCHEMA.INNODB_SYS_VIRTUAL stable The INFORMATION_SCHEMA plugin INNODB_SYS_VIRTUAL, which was introduced in MariaDB 10.2.2 along with the dictionary table SYS_VIRTUAL, is similar to other, much older and already stable plugins that provide access to InnoDB dictionary tables. --- storage/innobase/handler/i_s.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'storage') diff --git a/storage/innobase/handler/i_s.cc b/storage/innobase/handler/i_s.cc index 8eb6b1d3427..fae634630fd 100644 --- a/storage/innobase/handler/i_s.cc +++ b/storage/innobase/handler/i_s.cc @@ -7227,7 +7227,7 @@ struct st_maria_plugin i_s_innodb_sys_virtual = /* Maria extension */ STRUCT_FLD(version_info, INNODB_VERSION_STR), - STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_BETA), + STRUCT_FLD(maturity, MariaDB_PLUGIN_MATURITY_STABLE), }; /** SYS_FIELDS ***************************************************/ /* Fields of the dynamic table INFORMATION_SCHEMA.INNODB_SYS_FIELDS */ -- cgit v1.2.1 From 35522455e0c0d680a68609b2bb82e4321afce32f Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Thu, 22 Nov 2018 14:51:31 +1100 Subject: RocksDB: use crc32c optimised version for POWER --- storage/rocksdb/build_rocksdb.cmake | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'storage') diff --git a/storage/rocksdb/build_rocksdb.cmake b/storage/rocksdb/build_rocksdb.cmake index 93f5fa2d1f3..eb7a7fed6c1 100644 --- a/storage/rocksdb/build_rocksdb.cmake +++ b/storage/rocksdb/build_rocksdb.cmake @@ -112,6 +112,24 @@ if(NOT WIN32) add_definitions(-DROCKSDB_PLATFORM_POSIX -DROCKSDB_LIB_IO_POSIX) endif() +include(CheckCCompilerFlag) +# ppc64 or ppc64le +if(CMAKE_SYSTEM_PROCESSOR MATCHES "ppc64") + CHECK_C_COMPILER_FLAG("-maltivec" HAS_ALTIVEC) + if(HAS_ALTIVEC) + message(STATUS " HAS_ALTIVEC yes") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -maltivec") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -maltivec") + endif(HAS_ALTIVEC) + if(NOT CMAKE_C_FLAGS MATCHES "m(cpu|tune)") + set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -mcpu=power8") + endif() + if(NOT CMAKE_CXX_FLAGS MATCHES "m(cpu|tune)") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -mcpu=power8") + endif() + ADD_DEFINITIONS(-DHAVE_POWER8 -DHAS_ALTIVEC) +endif(CMAKE_SYSTEM_PROCESSOR MATCHES "ppc64") + option(WITH_FALLOCATE "build with fallocate" ON) if(WITH_FALLOCATE AND UNIX) @@ -377,6 +395,13 @@ else() port/port_posix.cc env/env_posix.cc env/io_posix.cc) + # ppc64 or ppc64le + if(CMAKE_SYSTEM_PROCESSOR MATCHES "ppc64") + enable_language(ASM) + list(APPEND ROCKSDB_SOURCES + util/crc32c_ppc.c + util/crc32c_ppc_asm.S) + endif(CMAKE_SYSTEM_PROCESSOR MATCHES "ppc64") endif() SET(SOURCES) FOREACH(s ${ROCKSDB_SOURCES}) -- cgit v1.2.1 From b8b74e141d0aef3f93241ce027af2fb944085fbe Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Mon, 27 May 2019 21:28:33 +0530 Subject: MDEV-19027 create_table_def fails when virtual column is present between stored columns - create_table_def() misconstructs the dict_table_t by ignoring the stored columns of the table if virtual column is present between stored columns. --- storage/innobase/handler/ha_innodb.cc | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'storage') diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index dbb74e4d99f..f2f43f18502 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -11016,7 +11016,6 @@ create_table_info_t::create_table_def() ulint binary_type; ulint long_true_varchar; ulint charset_no; - ulint j = 0; ulint doc_id_col = 0; ibool has_doc_id_col = FALSE; mem_heap_t* heap; @@ -11106,7 +11105,7 @@ error_ret: heap = mem_heap_create(1000); - for (ulint i = 0; i < n_cols; i++) { + for (ulint i = 0, j = 0; j < n_cols; i++) { Field* field = m_form->field[i]; col_type = get_innobase_type_from_mysql_type( @@ -11214,10 +11213,16 @@ err_col: dict_mem_table_add_s_col( table, 0); } + + if (is_virtual && omit_virtual) { + continue; + } + + j++; } if (num_v) { - for (ulint i = 0; i < n_cols; i++) { + for (ulint i = 0, j = 0; i < n_cols; i++) { dict_v_col_t* v_col; const Field* field = m_form->field[i]; -- cgit v1.2.1 From 242a28c320ae8b16144c5e91cbcf8806ce1e5d68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 28 May 2019 08:07:45 +0300 Subject: MDEV-6812: Remove the wrapper my_log2f() --- storage/innobase/row/row0merge.cc | 17 +++-------------- storage/xtradb/row/row0merge.cc | 17 +++-------------- 2 files changed, 6 insertions(+), 28 deletions(-) (limited to 'storage') diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index 5042a9ed170..463be8d229d 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -27,6 +27,7 @@ Completed by Sunny Bains and Marko Makela #include #include #include +#include #include "row0merge.h" #include "row0ext.h" @@ -42,15 +43,8 @@ Completed by Sunny Bains and Marko Makela #include "row0import.h" #include "handler0alter.h" #include "ha_prototypes.h" -#include "math.h" /* log() */ #include "fil0crypt.h" -float my_log2f(float n) -{ - /* log(n) / log(2) is log2. */ - return (float)(log((double)n) / log((double)2)); -} - /* Ignore posix_fadvise() on those platforms where it does not exist */ #if defined __WIN__ # define posix_fadvise(fd, offset, len, advice) /* nothing */ @@ -2503,18 +2497,13 @@ row_merge_sort( /* Record the number of merge runs we need to perform */ num_runs = file->offset; - /* Find the number N which 2^N is greater or equal than num_runs */ - /* N is merge sort running count */ - total_merge_sort_count = ceil(my_log2f(num_runs)); - if(total_merge_sort_count <= 0) { - total_merge_sort_count=1; - } - /* If num_runs are less than 1, nothing to merge */ if (num_runs <= 1) { DBUG_RETURN(error); } + total_merge_sort_count = ceil(log2f(num_runs)); + /* "run_offset" records each run's first offset number */ run_offset = (ulint*) mem_alloc(file->offset * sizeof(ulint)); diff --git a/storage/xtradb/row/row0merge.cc b/storage/xtradb/row/row0merge.cc index cc7c648fe4c..f71a623da20 100644 --- a/storage/xtradb/row/row0merge.cc +++ b/storage/xtradb/row/row0merge.cc @@ -27,6 +27,7 @@ Completed by Sunny Bains and Marko Makela #include #include #include +#include #include "row0merge.h" #include "row0ext.h" @@ -42,15 +43,8 @@ Completed by Sunny Bains and Marko Makela #include "row0import.h" #include "handler0alter.h" #include "ha_prototypes.h" -#include "math.h" /* log2() */ #include "fil0crypt.h" -float my_log2f(float n) -{ - /* log(n) / log(2) is log2. */ - return (float)(log((double)n) / log((double)2)); -} - /* Ignore posix_fadvise() on those platforms where it does not exist */ #if defined __WIN__ # define posix_fadvise(fd, offset, len, advice) /* nothing */ @@ -2516,18 +2510,13 @@ row_merge_sort( /* Record the number of merge runs we need to perform */ num_runs = file->offset; - /* Find the number N which 2^N is greater or equal than num_runs */ - /* N is merge sort running count */ - total_merge_sort_count = ceil(my_log2f(num_runs)); - if(total_merge_sort_count <= 0) { - total_merge_sort_count=1; - } - /* If num_runs are less than 1, nothing to merge */ if (num_runs <= 1) { DBUG_RETURN(error); } + total_merge_sort_count = ceil(log2f(num_runs)); + /* "run_offset" records each run's first offset number */ run_offset = (ulint*) mem_alloc(file->offset * sizeof(ulint)); -- cgit v1.2.1 From 626f2a1c170e615c7866c1041746159dc3f709af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 28 May 2019 10:50:17 +0300 Subject: MDEV-19614 SET GLOBAL innodb_ deadlock due to LOCK_global_system_variables MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The update callback functions for several settable global InnoDB variables are acquiring InnoDB latches while holding LOCK_global_system_variables. On the other hand, some InnoDB code is invoking THDVAR() while holding InnoDB latches. An example of this is thd_lock_wait_timeout() that is called by lock_rec_enqueue_waiting(). In some cases, the intern_sys_var_ptr() that is invoked by THDVAR() may acquire LOCK_global_system_variables, via sync_dynamic_session_variables(). In lock_rec_enqueue_waiting(), we really must be holding some InnoDB latch while invoking THDVAR(). This implies that LOCK_global_system_variables must conceptually reside below any InnoDB latch in the latching order. That in turns implies that the various update callback functions must release LOCK_global_system_variables before acquiring any InnoDB mutexes or rw-locks, and reacquire LOCK_global_system_variables later. The validate functions are being invoked while not holding LOCK_global_system_variables and thus they do not need any changes. The following statements are affected by this: SET GLOBAL innodb_adaptive_hash_index = …; SET GLOBAL innodb_cmp_per_index_enabled = 1; SET GLOBAL innodb_old_blocks_pct = …; SET GLOBAL innodb_fil_make_page_dirty_debug = …; -- debug builds only SET GLOBAL innodb_buffer_pool_evict = uncompressed; -- debug builds only SET GLOBAL innodb_purge_run_now = 1; -- debug builds only SET GLOBAL innodb_purge_stop_now = 1; -- debug builds only SET GLOBAL innodb_log_checkpoint_now = 1; -- debug builds only SET GLOBAL innodb_buf_flush_list_now = 1; -- debug builds only SET GLOBAL innodb_buffer_pool_dump_now = 1; SET GLOBAL innodb_buffer_pool_load_now = 1; SET GLOBAL innodb_buffer_pool_load_abort = 1; SET GLOBAL innodb_status_output = …; SET GLOBAL innodb_status_output_locks = …; SET GLOBAL innodb_encryption_threads = …; SET GLOBAL innodb_encryption_rotate_key_age = …; SET GLOBAL innodb_encryption_rotation_iops = …; SET GLOBAL innodb_encrypt_tables = …; SET GLOBAL innodb_disallow_writes = …; buf_LRU_old_ratio_update(): Correct the return type. --- storage/innobase/buf/buf0lru.cc | 14 ++-- storage/innobase/handler/ha_innodb.cc | 126 ++++++++++++++++++---------------- storage/innobase/include/buf0lru.h | 8 +-- storage/xtradb/buf/buf0lru.cc | 14 ++-- storage/xtradb/handler/ha_innodb.cc | 126 ++++++++++++++++++---------------- storage/xtradb/include/buf0lru.h | 8 +-- 6 files changed, 152 insertions(+), 144 deletions(-) (limited to 'storage') diff --git a/storage/innobase/buf/buf0lru.cc b/storage/innobase/buf/buf0lru.cc index 7edc9520e02..29fe81dc920 100644 --- a/storage/innobase/buf/buf0lru.cc +++ b/storage/innobase/buf/buf0lru.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2018, MariaDB Corporation. +Copyright (c) 2017, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -2243,8 +2243,8 @@ buf_LRU_old_ratio_update_instance( buf_pool_t* buf_pool,/*!< in: buffer pool instance */ uint old_pct,/*!< in: Reserve this percentage of the buffer pool for "old" blocks. */ - ibool adjust) /*!< in: TRUE=adjust the LRU list; - FALSE=just assign buf_pool->LRU_old_ratio + bool adjust) /*!< in: true=adjust the LRU list; + false=just assign buf_pool->LRU_old_ratio during the initialization of InnoDB */ { uint ratio; @@ -2282,17 +2282,17 @@ buf_LRU_old_ratio_update_instance( Updates buf_pool->LRU_old_ratio. @return updated old_pct */ UNIV_INTERN -ulint +uint buf_LRU_old_ratio_update( /*=====================*/ uint old_pct,/*!< in: Reserve this percentage of the buffer pool for "old" blocks. */ - ibool adjust) /*!< in: TRUE=adjust the LRU list; - FALSE=just assign buf_pool->LRU_old_ratio + bool adjust) /*!< in: true=adjust the LRU list; + false=just assign buf_pool->LRU_old_ratio during the initialization of InnoDB */ { ulint i; - ulint new_ratio = 0; + uint new_ratio = 0; for (i = 0; i < srv_buf_pool_instances; i++) { buf_pool_t* buf_pool; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index cb6ec20e0d6..e04d431174a 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -17166,11 +17166,13 @@ innodb_adaptive_hash_index_update( const void* save) /*!< in: immediate result from check function */ { + mysql_mutex_unlock(&LOCK_global_system_variables); if (*(my_bool*) save) { btr_search_enable(); } else { btr_search_disable(); } + mysql_mutex_lock(&LOCK_global_system_variables); } /****************************************************************//** @@ -17191,7 +17193,9 @@ innodb_cmp_per_index_update( /* Reset the stats whenever we enable the table INFORMATION_SCHEMA.innodb_cmp_per_index. */ if (!srv_cmp_per_index_enabled && *(my_bool*) save) { + mysql_mutex_unlock(&LOCK_global_system_variables); page_zip_reset_stat_per_index(); + mysql_mutex_lock(&LOCK_global_system_variables); } srv_cmp_per_index_enabled = !!(*(my_bool*) save); @@ -17212,9 +17216,11 @@ innodb_old_blocks_pct_update( const void* save) /*!< in: immediate result from check function */ { - innobase_old_blocks_pct = static_cast( - buf_LRU_old_ratio_update( - *static_cast(save), TRUE)); + mysql_mutex_unlock(&LOCK_global_system_variables); + uint ratio = buf_LRU_old_ratio_update(*static_cast(save), + true); + mysql_mutex_lock(&LOCK_global_system_variables); + innobase_old_blocks_pct = ratio; } /****************************************************************//** @@ -17232,9 +17238,10 @@ innodb_change_buffer_max_size_update( const void* save) /*!< in: immediate result from check function */ { - innobase_change_buffer_max_size = - (*static_cast(save)); + innobase_change_buffer_max_size = *static_cast(save); + mysql_mutex_unlock(&LOCK_global_system_variables); ibuf_max_size_update(innobase_change_buffer_max_size); + mysql_mutex_lock(&LOCK_global_system_variables); } #ifdef UNIV_DEBUG @@ -17278,6 +17285,7 @@ innodb_make_page_dirty( { mtr_t mtr; ulong space_id = *static_cast(save); + mysql_mutex_unlock(&LOCK_global_system_variables); mtr_start(&mtr); @@ -17295,6 +17303,7 @@ innodb_make_page_dirty( MLOG_2BYTES, &mtr); } mtr_commit(&mtr); + mysql_mutex_lock(&LOCK_global_system_variables); } #endif // UNIV_DEBUG @@ -17933,8 +17942,11 @@ innodb_buffer_pool_evict_update( { if (const char* op = *static_cast(save)) { if (!strcmp(op, "uncompressed")) { + mysql_mutex_unlock(&LOCK_global_system_variables); for (uint tries = 0; tries < 10000; tries++) { if (innodb_buffer_pool_evict_uncompressed()) { + mysql_mutex_lock( + &LOCK_global_system_variables); return; } @@ -18237,7 +18249,9 @@ purge_run_now_set( check function */ { if (*(my_bool*) save && trx_purge_state() != PURGE_STATE_DISABLED) { + mysql_mutex_unlock(&LOCK_global_system_variables); trx_purge_run(); + mysql_mutex_lock(&LOCK_global_system_variables); } } @@ -18260,7 +18274,9 @@ purge_stop_now_set( check function */ { if (*(my_bool*) save && trx_purge_state() != PURGE_STATE_DISABLED) { + mysql_mutex_unlock(&LOCK_global_system_variables); trx_purge_stop(); + mysql_mutex_lock(&LOCK_global_system_variables); } } @@ -18282,6 +18298,8 @@ checkpoint_now_set( check function */ { if (*(my_bool*) save) { + mysql_mutex_unlock(&LOCK_global_system_variables); + while (log_sys->last_checkpoint_lsn < log_sys->lsn) { log_make_checkpoint_at(LSN_MAX, TRUE); fil_flush_file_spaces(FIL_LOG); @@ -18295,6 +18313,8 @@ checkpoint_now_set( "system tablespace at checkpoint err=%s", ut_strerr(err)); } + + mysql_mutex_lock(&LOCK_global_system_variables); } } @@ -18316,8 +18336,10 @@ buf_flush_list_now_set( check function */ { if (*(my_bool*) save) { + mysql_mutex_unlock(&LOCK_global_system_variables); buf_flush_list(ULINT_MAX, LSN_MAX, NULL); buf_flush_wait_batch_end(NULL, BUF_FLUSH_LIST); + mysql_mutex_lock(&LOCK_global_system_variables); } } #endif /* UNIV_DEBUG */ @@ -18419,7 +18441,9 @@ buffer_pool_dump_now( check function */ { if (*(my_bool*) save && !srv_read_only_mode) { + mysql_mutex_unlock(&LOCK_global_system_variables); buf_dump_start(); + mysql_mutex_lock(&LOCK_global_system_variables); } } @@ -18442,7 +18466,9 @@ buffer_pool_load_now( check function */ { if (*(my_bool*) save && !srv_read_only_mode) { + mysql_mutex_unlock(&LOCK_global_system_variables); buf_load_start(); + mysql_mutex_lock(&LOCK_global_system_variables); } } @@ -18465,96 +18491,71 @@ buffer_pool_load_abort( check function */ { if (*(my_bool*) save && !srv_read_only_mode) { + mysql_mutex_unlock(&LOCK_global_system_variables); buf_load_abort(); + mysql_mutex_lock(&LOCK_global_system_variables); } } /** Update innodb_status_output or innodb_status_output_locks, which control InnoDB "status monitor" output to the error log. -@param[in] thd thread handle -@param[in] var system variable -@param[out] var_ptr current value +@param[out] var current value @param[in] save to-be-assigned value */ static void -innodb_status_output_update( -/*========================*/ - THD* thd __attribute__((unused)), - struct st_mysql_sys_var* var __attribute__((unused)), - void* var_ptr __attribute__((unused)), - const void* save __attribute__((unused))) +innodb_status_output_update(THD*,st_mysql_sys_var*,void*var,const void*save) { - *static_cast(var_ptr) = *static_cast(save); + *static_cast(var) = *static_cast(save); + mysql_mutex_unlock(&LOCK_global_system_variables); /* Wakeup server monitor thread. */ os_event_set(srv_monitor_event); + mysql_mutex_lock(&LOCK_global_system_variables); } -/****************************************************************** -Update the system variable innodb_encryption_threads */ +/** Update the system variable innodb_encryption_threads. +@param[in] save to-be-assigned value */ static void -innodb_encryption_threads_update( -/*=============================*/ - THD* thd, /*!< in: thread handle */ - struct st_mysql_sys_var* var, /*!< in: pointer to - system variable */ - void* var_ptr,/*!< out: where the - formal string goes */ - const void* save) /*!< in: immediate result - from check function */ +innodb_encryption_threads_update(THD*,st_mysql_sys_var*,void*,const void*save) { + mysql_mutex_unlock(&LOCK_global_system_variables); fil_crypt_set_thread_cnt(*static_cast(save)); + mysql_mutex_lock(&LOCK_global_system_variables); } -/****************************************************************** -Update the system variable innodb_encryption_rotate_key_age */ +/** Update the system variable innodb_encryption_rotate_key_age. +@param[in] save to-be-assigned value */ static void -innodb_encryption_rotate_key_age_update( -/*====================================*/ - THD* thd, /*!< in: thread handle */ - struct st_mysql_sys_var* var, /*!< in: pointer to - system variable */ - void* var_ptr,/*!< out: where the - formal string goes */ - const void* save) /*!< in: immediate result - from check function */ +innodb_encryption_rotate_key_age_update(THD*,st_mysql_sys_var*,void*, + const void*save) { + mysql_mutex_unlock(&LOCK_global_system_variables); fil_crypt_set_rotate_key_age(*static_cast(save)); + mysql_mutex_lock(&LOCK_global_system_variables); } -/****************************************************************** -Update the system variable innodb_encryption_rotation_iops */ +/** Update the system variable innodb_encryption_rotation_iops. +@param[in] save to-be-assigned value */ static void -innodb_encryption_rotation_iops_update( -/*===================================*/ - THD* thd, /*!< in: thread handle */ - struct st_mysql_sys_var* var, /*!< in: pointer to - system variable */ - void* var_ptr,/*!< out: where the - formal string goes */ - const void* save) /*!< in: immediate result - from check function */ +innodb_encryption_rotation_iops_update(THD*,st_mysql_sys_var*,void*, + const void*save) { + mysql_mutex_unlock(&LOCK_global_system_variables); fil_crypt_set_rotation_iops(*static_cast(save)); + mysql_mutex_lock(&LOCK_global_system_variables); } -/****************************************************************** -Update the system variable innodb_encrypt_tables*/ +/** Update the system variable innodb_encrypt_tables. +@param[in] save to-be-assigned value */ static void -innodb_encrypt_tables_update( -/*=========================*/ - THD* thd, /*!< in: thread handle */ - struct st_mysql_sys_var* var, /*!< in: pointer to - system variable */ - void* var_ptr,/*!< out: where the - formal string goes */ - const void* save) /*!< in: immediate result - from check function */ +innodb_encrypt_tables_update(THD*,st_mysql_sys_var*,void*,const void*save) { + mysql_mutex_unlock(&LOCK_global_system_variables); fil_crypt_set_encrypt_tables(*static_cast(save)); + mysql_mutex_lock(&LOCK_global_system_variables); } static SHOW_VAR innodb_status_variables_export[]= { @@ -19736,12 +19737,15 @@ innobase_disallow_writes_update( variable */ const void* save) /* in: temporary storage */ { - *(my_bool*)var_ptr = *(my_bool*)save; + const my_bool val = *static_cast(save); + *static_cast(var_ptr) = val; ut_a(srv_allow_writes_event); - if (*(my_bool*)var_ptr) + mysql_mutex_unlock(&LOCK_global_system_variables); + if (val) os_event_reset(srv_allow_writes_event); else os_event_set(srv_allow_writes_event); + mysql_mutex_lock(&LOCK_global_system_variables); } static MYSQL_SYSVAR_BOOL(disallow_writes, innobase_disallow_writes, diff --git a/storage/innobase/include/buf0lru.h b/storage/innobase/include/buf0lru.h index 948c6f25503..09100b35e68 100644 --- a/storage/innobase/include/buf0lru.h +++ b/storage/innobase/include/buf0lru.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2018, MariaDB Corporation. +Copyright (c) 2017, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -202,13 +202,13 @@ buf_LRU_make_block_old( Updates buf_pool->LRU_old_ratio. @return updated old_pct */ UNIV_INTERN -ulint +uint buf_LRU_old_ratio_update( /*=====================*/ uint old_pct,/*!< in: Reserve this percentage of the buffer pool for "old" blocks. */ - ibool adjust);/*!< in: TRUE=adjust the LRU list; - FALSE=just assign buf_pool->LRU_old_ratio + bool adjust);/*!< in: true=adjust the LRU list; + false=just assign buf_pool->LRU_old_ratio during the initialization of InnoDB */ /********************************************************************//** Update the historical stats that we are collecting for LRU eviction diff --git a/storage/xtradb/buf/buf0lru.cc b/storage/xtradb/buf/buf0lru.cc index 5f3a8627055..13bf5e79f2d 100644 --- a/storage/xtradb/buf/buf0lru.cc +++ b/storage/xtradb/buf/buf0lru.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2018, MariaDB Corporation. +Copyright (c) 2017, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -2408,8 +2408,8 @@ buf_LRU_old_ratio_update_instance( buf_pool_t* buf_pool,/*!< in: buffer pool instance */ uint old_pct,/*!< in: Reserve this percentage of the buffer pool for "old" blocks. */ - ibool adjust) /*!< in: TRUE=adjust the LRU list; - FALSE=just assign buf_pool->LRU_old_ratio + bool adjust) /*!< in: true=adjust the LRU list; + false=just assign buf_pool->LRU_old_ratio during the initialization of InnoDB */ { uint ratio; @@ -2447,17 +2447,17 @@ buf_LRU_old_ratio_update_instance( Updates buf_pool->LRU_old_ratio. @return updated old_pct */ UNIV_INTERN -ulint +uint buf_LRU_old_ratio_update( /*=====================*/ uint old_pct,/*!< in: Reserve this percentage of the buffer pool for "old" blocks. */ - ibool adjust) /*!< in: TRUE=adjust the LRU list; - FALSE=just assign buf_pool->LRU_old_ratio + bool adjust) /*!< in: true=adjust the LRU list; + false=just assign buf_pool->LRU_old_ratio during the initialization of InnoDB */ { ulint i; - ulint new_ratio = 0; + uint new_ratio = 0; for (i = 0; i < srv_buf_pool_instances; i++) { buf_pool_t* buf_pool; diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index aa17eb6a5ea..0cdd5ac2452 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -17887,11 +17887,13 @@ innodb_adaptive_hash_index_update( const void* save) /*!< in: immediate result from check function */ { + mysql_mutex_unlock(&LOCK_global_system_variables); if (*(my_bool*) save) { btr_search_enable(); } else { btr_search_disable(); } + mysql_mutex_lock(&LOCK_global_system_variables); } /****************************************************************//** @@ -17912,7 +17914,9 @@ innodb_cmp_per_index_update( /* Reset the stats whenever we enable the table INFORMATION_SCHEMA.innodb_cmp_per_index. */ if (!srv_cmp_per_index_enabled && *(my_bool*) save) { + mysql_mutex_unlock(&LOCK_global_system_variables); page_zip_reset_stat_per_index(); + mysql_mutex_lock(&LOCK_global_system_variables); } srv_cmp_per_index_enabled = !!(*(my_bool*) save); @@ -17933,9 +17937,11 @@ innodb_old_blocks_pct_update( const void* save) /*!< in: immediate result from check function */ { - innobase_old_blocks_pct = static_cast( - buf_LRU_old_ratio_update( - *static_cast(save), TRUE)); + mysql_mutex_unlock(&LOCK_global_system_variables); + uint ratio = buf_LRU_old_ratio_update(*static_cast(save), + true); + mysql_mutex_lock(&LOCK_global_system_variables); + innobase_old_blocks_pct = ratio; } /****************************************************************//** @@ -17953,9 +17959,10 @@ innodb_change_buffer_max_size_update( const void* save) /*!< in: immediate result from check function */ { - innobase_change_buffer_max_size = - (*static_cast(save)); + innobase_change_buffer_max_size = *static_cast(save); + mysql_mutex_unlock(&LOCK_global_system_variables); ibuf_max_size_update(innobase_change_buffer_max_size); + mysql_mutex_lock(&LOCK_global_system_variables); } #ifdef UNIV_DEBUG @@ -17999,6 +18006,7 @@ innodb_make_page_dirty( { mtr_t mtr; ulong space_id = *static_cast(save); + mysql_mutex_unlock(&LOCK_global_system_variables); mtr_start(&mtr); @@ -18016,6 +18024,7 @@ innodb_make_page_dirty( MLOG_2BYTES, &mtr); } mtr_commit(&mtr); + mysql_mutex_lock(&LOCK_global_system_variables); } #endif // UNIV_DEBUG @@ -18661,8 +18670,11 @@ innodb_buffer_pool_evict_update( { if (const char* op = *static_cast(save)) { if (!strcmp(op, "uncompressed")) { + mysql_mutex_unlock(&LOCK_global_system_variables); for (uint tries = 0; tries < 10000; tries++) { if (innodb_buffer_pool_evict_uncompressed()) { + mysql_mutex_lock( + &LOCK_global_system_variables); return; } @@ -19199,7 +19211,9 @@ purge_run_now_set( check function */ { if (*(my_bool*) save && trx_purge_state() != PURGE_STATE_DISABLED) { + mysql_mutex_unlock(&LOCK_global_system_variables); trx_purge_run(); + mysql_mutex_lock(&LOCK_global_system_variables); } } @@ -19222,7 +19236,9 @@ purge_stop_now_set( check function */ { if (*(my_bool*) save && trx_purge_state() != PURGE_STATE_DISABLED) { + mysql_mutex_unlock(&LOCK_global_system_variables); trx_purge_stop(); + mysql_mutex_lock(&LOCK_global_system_variables); } } @@ -19244,6 +19260,8 @@ checkpoint_now_set( check function */ { if (*(my_bool*) save) { + mysql_mutex_unlock(&LOCK_global_system_variables); + while (log_sys->last_checkpoint_lsn < log_sys->lsn) { log_make_checkpoint_at(LSN_MAX, TRUE); fil_flush_file_spaces(FIL_LOG); @@ -19257,6 +19275,8 @@ checkpoint_now_set( "system tablespace at checkpoint err=%s", ut_strerr(err)); } + + mysql_mutex_lock(&LOCK_global_system_variables); } } @@ -19278,8 +19298,10 @@ buf_flush_list_now_set( check function */ { if (*(my_bool*) save) { + mysql_mutex_unlock(&LOCK_global_system_variables); buf_flush_list(ULINT_MAX, LSN_MAX, NULL); buf_flush_wait_batch_end(NULL, BUF_FLUSH_LIST); + mysql_mutex_lock(&LOCK_global_system_variables); } } @@ -19406,7 +19428,9 @@ buffer_pool_dump_now( check function */ { if (*(my_bool*) save && !srv_read_only_mode) { + mysql_mutex_unlock(&LOCK_global_system_variables); buf_dump_start(); + mysql_mutex_lock(&LOCK_global_system_variables); } } @@ -19429,7 +19453,9 @@ buffer_pool_load_now( check function */ { if (*(my_bool*) save && !srv_read_only_mode) { + mysql_mutex_unlock(&LOCK_global_system_variables); buf_load_start(); + mysql_mutex_lock(&LOCK_global_system_variables); } } @@ -19452,96 +19478,71 @@ buffer_pool_load_abort( check function */ { if (*(my_bool*) save && !srv_read_only_mode) { + mysql_mutex_unlock(&LOCK_global_system_variables); buf_load_abort(); + mysql_mutex_lock(&LOCK_global_system_variables); } } /** Update innodb_status_output or innodb_status_output_locks, which control InnoDB "status monitor" output to the error log. -@param[in] thd thread handle -@param[in] var system variable -@param[out] var_ptr current value +@param[out] var current value @param[in] save to-be-assigned value */ static void -innodb_status_output_update( -/*========================*/ - THD* thd __attribute__((unused)), - struct st_mysql_sys_var* var __attribute__((unused)), - void* var_ptr __attribute__((unused)), - const void* save __attribute__((unused))) +innodb_status_output_update(THD*,st_mysql_sys_var*,void*var,const void*save) { - *static_cast(var_ptr) = *static_cast(save); + *static_cast(var) = *static_cast(save); + mysql_mutex_unlock(&LOCK_global_system_variables); /* Wakeup server monitor thread. */ os_event_set(srv_monitor_event); + mysql_mutex_lock(&LOCK_global_system_variables); } -/****************************************************************** -Update the system variable innodb_encryption_threads */ +/** Update the system variable innodb_encryption_threads. +@param[in] save to-be-assigned value */ static void -innodb_encryption_threads_update( -/*=============================*/ - THD* thd, /*!< in: thread handle */ - struct st_mysql_sys_var* var, /*!< in: pointer to - system variable */ - void* var_ptr,/*!< out: where the - formal string goes */ - const void* save) /*!< in: immediate result - from check function */ +innodb_encryption_threads_update(THD*,st_mysql_sys_var*,void*,const void*save) { + mysql_mutex_unlock(&LOCK_global_system_variables); fil_crypt_set_thread_cnt(*static_cast(save)); + mysql_mutex_lock(&LOCK_global_system_variables); } -/****************************************************************** -Update the system variable innodb_encryption_rotate_key_age */ +/** Update the system variable innodb_encryption_rotate_key_age. +@param[in] save to-be-assigned value */ static void -innodb_encryption_rotate_key_age_update( -/*====================================*/ - THD* thd, /*!< in: thread handle */ - struct st_mysql_sys_var* var, /*!< in: pointer to - system variable */ - void* var_ptr,/*!< out: where the - formal string goes */ - const void* save) /*!< in: immediate result - from check function */ +innodb_encryption_rotate_key_age_update(THD*,st_mysql_sys_var*,void*, + const void*save) { + mysql_mutex_unlock(&LOCK_global_system_variables); fil_crypt_set_rotate_key_age(*static_cast(save)); + mysql_mutex_lock(&LOCK_global_system_variables); } -/****************************************************************** -Update the system variable innodb_encryption_rotation_iops */ +/** Update the system variable innodb_encryption_rotation_iops. +@param[in] save to-be-assigned value */ static void -innodb_encryption_rotation_iops_update( -/*===================================*/ - THD* thd, /*!< in: thread handle */ - struct st_mysql_sys_var* var, /*!< in: pointer to - system variable */ - void* var_ptr,/*!< out: where the - formal string goes */ - const void* save) /*!< in: immediate result - from check function */ +innodb_encryption_rotation_iops_update(THD*,st_mysql_sys_var*,void*, + const void*save) { + mysql_mutex_unlock(&LOCK_global_system_variables); fil_crypt_set_rotation_iops(*static_cast(save)); + mysql_mutex_lock(&LOCK_global_system_variables); } -/****************************************************************** -Update the system variable innodb_encrypt_tables*/ +/** Update the system variable innodb_encrypt_tables. +@param[in] save to-be-assigned value */ static void -innodb_encrypt_tables_update( -/*=========================*/ - THD* thd, /*!< in: thread handle */ - struct st_mysql_sys_var* var, /*!< in: pointer to - system variable */ - void* var_ptr,/*!< out: where the - formal string goes */ - const void* save) /*!< in: immediate result - from check function */ +innodb_encrypt_tables_update(THD*,st_mysql_sys_var*,void*,const void*save) { + mysql_mutex_unlock(&LOCK_global_system_variables); fil_crypt_set_encrypt_tables(*static_cast(save)); + mysql_mutex_lock(&LOCK_global_system_variables); } static SHOW_VAR innodb_status_variables_export[]= { @@ -20979,12 +20980,15 @@ innobase_disallow_writes_update( variable */ const void* save) /* in: temporary storage */ { - *(my_bool*)var_ptr = *(my_bool*)save; + const my_bool val = *static_cast(save); + *static_cast(var_ptr) = val; ut_a(srv_allow_writes_event); - if (*(my_bool*)var_ptr) + mysql_mutex_unlock(&LOCK_global_system_variables); + if (val) os_event_reset(srv_allow_writes_event); else os_event_set(srv_allow_writes_event); + mysql_mutex_lock(&LOCK_global_system_variables); } static MYSQL_SYSVAR_BOOL(disallow_writes, innobase_disallow_writes, diff --git a/storage/xtradb/include/buf0lru.h b/storage/xtradb/include/buf0lru.h index e0f2277b6a2..69ada4abb70 100644 --- a/storage/xtradb/include/buf0lru.h +++ b/storage/xtradb/include/buf0lru.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2017, 2018, MariaDB Corporation. +Copyright (c) 2017, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -208,13 +208,13 @@ buf_LRU_make_block_old( Updates buf_pool->LRU_old_ratio. @return updated old_pct */ UNIV_INTERN -ulint +uint buf_LRU_old_ratio_update( /*=====================*/ uint old_pct,/*!< in: Reserve this percentage of the buffer pool for "old" blocks. */ - ibool adjust);/*!< in: TRUE=adjust the LRU list; - FALSE=just assign buf_pool->LRU_old_ratio + bool adjust);/*!< in: true=adjust the LRU list; + false=just assign buf_pool->LRU_old_ratio during the initialization of InnoDB */ /********************************************************************//** Update the historical stats that we are collecting for LRU eviction -- cgit v1.2.1 From 79b46ab2a6eae493b89ab0fcfc03fcf6b585244c Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Thu, 23 May 2019 14:25:54 +0530 Subject: MDEV-19541 InnoDB crashes when trying to recover a corrupted page - Don't apply redo log for the corrupted page when innodb_force_recovery > 0. - Allow the table to be dropped when index root page is corrupted when innodb_force_recovery > 0. --- storage/innobase/buf/buf0buf.cc | 57 +++++++++++++++++++++++++++---------- storage/innobase/include/log0recv.h | 5 ++++ storage/innobase/log/log0recv.cc | 26 +++++++++++++++++ 3 files changed, 73 insertions(+), 15 deletions(-) (limited to 'storage') diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 41d9efe25cc..756caac1f54 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -4378,6 +4378,11 @@ loop: return (NULL); } + if (local_err == DB_PAGE_CORRUPTED + && srv_force_recovery) { + return NULL; + } + /* Try to set table as corrupted instead of asserting. */ if (page_id.space() != TRX_SYS_SPACE && @@ -5743,18 +5748,33 @@ buf_page_monitor( MONITOR_INC_NOCHECK(counter); } -/********************************************************************//** -Mark a table with the specified space pointed by bpage->id.space() corrupted. -Also remove the bpage from LRU list. -@param[in,out] bpage Block */ +/** Mark a table corrupted. +@param[in] bpage Corrupted page. */ static void buf_mark_space_corrupt(buf_page_t* bpage) +{ + /* If block is not encrypted find the table with specified + space id, and mark it corrupted. Encrypted tables + are marked unusable later e.g. in ::open(). */ + if (!bpage->encrypted) { + dict_set_corrupted_by_space(bpage->id.space()); + } else { + dict_set_encrypted_by_space(bpage->id.space()); + } +} + +/** Mark a table corrupted. +@param[in] bpage Corrupted page +@param[in] space Corrupted page belongs to tablespace +Also remove the bpage from LRU list. */ +static +void +buf_corrupt_page_release(buf_page_t* bpage, const fil_space_t* space) { buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); const ibool uncompressed = (buf_page_get_state(bpage) == BUF_BLOCK_FILE_PAGE); - uint32_t space = bpage->id.space(); /* First unfix and release lock on the bpage */ buf_pool_mutex_enter(buf_pool); @@ -5773,13 +5793,8 @@ buf_mark_space_corrupt(buf_page_t* bpage) mutex_exit(buf_page_get_mutex(bpage)); - /* If block is not encrypted find the table with specified - space id, and mark it corrupted. Encrypted tables - are marked unusable later e.g. in ::open(). */ - if (!bpage->encrypted) { - dict_set_corrupted_by_space(space); - } else { - dict_set_encrypted_by_space(space); + if (!srv_force_recovery) { + buf_mark_space_corrupt(bpage); } /* After this point bpage can't be referenced. */ @@ -5981,7 +5996,7 @@ database_corrupted: "buf_page_import_corrupt_failure", if (!is_predefined_tablespace( bpage->id.space())) { - buf_mark_space_corrupt(bpage); + buf_corrupt_page_release(bpage, space); ib::info() << "Simulated IMPORT " "corruption"; fil_space_release_for_io(space); @@ -6015,7 +6030,7 @@ database_corrupted: << FORCE_RECOVERY_MSG; } - if (srv_force_recovery < SRV_FORCE_IGNORE_CORRUPT) { + if (!srv_force_recovery) { /* If page space id is larger than TRX_SYS_SPACE (0), we will attempt to mark the corresponding @@ -6025,7 +6040,7 @@ database_corrupted: " a corrupt database page."; } - buf_mark_space_corrupt(bpage); + buf_corrupt_page_release(bpage, space); fil_space_release_for_io(space); return(err); } @@ -6034,6 +6049,18 @@ database_corrupted: DBUG_EXECUTE_IF("buf_page_import_corrupt_failure", page_not_corrupt: bpage = bpage; ); + if (err == DB_PAGE_CORRUPTED + || err == DB_DECRYPTION_FAILED) { + buf_corrupt_page_release(bpage, space); + + if (recv_recovery_is_on()) { + recv_recover_corrupt_page(bpage); + } + + fil_space_release_for_io(space); + return err; + } + if (recv_recovery_is_on()) { recv_recover_page(bpage); } diff --git a/storage/innobase/include/log0recv.h b/storage/innobase/include/log0recv.h index 0b04e1642cf..9bb54960058 100644 --- a/storage/innobase/include/log0recv.h +++ b/storage/innobase/include/log0recv.h @@ -49,6 +49,11 @@ dberr_t recv_find_max_checkpoint(ulint* max_field) MY_ATTRIBUTE((nonnull, warn_unused_result)); +/** Reduces recv_sys->n_addrs for the corrupted page. +This function should called when srv_force_recovery > 0. +@param[in] bpage buffer pool page */ +void recv_recover_corrupt_page(buf_page_t* bpage); + /** Apply any buffered redo log to a page that was just read from a data file. @param[in,out] bpage buffer pool page */ ATTRIBUTE_COLD void recv_recover_page(buf_page_t* bpage); diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index 9484901c90f..c0521f1dba4 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -2212,6 +2212,32 @@ skip_log: } } +/** Reduces recv_sys->n_addrs for the corrupted page. +This function should called when srv_force_recovery > 0. +@param[in] bpage buffer pool page */ +void recv_recover_corrupt_page(buf_page_t* bpage) +{ + ut_ad(srv_force_recovery); + mutex_enter(&recv_sys->mutex); + + if (!recv_sys->apply_log_recs) { + mutex_exit(&recv_sys->mutex); + return; + } + + recv_addr_t* recv_addr = recv_get_fil_addr_struct( + bpage->id.space(), bpage->id.page_no()); + + ut_ad(recv_addr->state != RECV_WILL_NOT_READ); + + if (recv_addr->state != RECV_BEING_PROCESSED + && recv_addr->state != RECV_PROCESSED) { + recv_sys->n_addrs--; + } + + mutex_exit(&recv_sys->mutex); +} + /** Apply any buffered redo log to a page that was just read from a data file. @param[in,out] bpage buffer pool page */ void recv_recover_page(buf_page_t* bpage) -- cgit v1.2.1 From 88157247fc5920ef77cfa96aebd33460d86b3905 Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Fri, 17 May 2019 20:32:51 +0530 Subject: MDEV-19509 InnoDB skips the tablespace in rotation list - If one of the encryption threads already started the initialization of the tablespace then don't remove the other uninitialized tablespace from the rotation list. - If there is a change in innodb_encrypt_tables then don't remove the processed tablespace from rotation list. --- storage/innobase/fil/fil0crypt.cc | 32 ++++++++++----------- storage/innobase/fil/fil0fil.cc | 58 ++++++++++++++++++-------------------- storage/innobase/include/fil0fil.h | 27 ++++++++++++++++-- 3 files changed, 67 insertions(+), 50 deletions(-) (limited to 'storage') diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc index 902af66ebe7..635ed619df0 100644 --- a/storage/innobase/fil/fil0crypt.cc +++ b/storage/innobase/fil/fil0crypt.cc @@ -943,14 +943,10 @@ fil_crypt_read_crypt_data(fil_space_t* space) mtr.commit(); } -/*********************************************************************** -Start encrypting a space +/** Start encrypting a space @param[in,out] space Tablespace -@return true if a recheck is needed */ -static -bool -fil_crypt_start_encrypting_space( - fil_space_t* space) +@return true if a recheck of tablespace is needed by encryption thread. */ +static bool fil_crypt_start_encrypting_space(fil_space_t* space) { bool recheck = false; @@ -1408,14 +1404,12 @@ fil_crypt_return_iops( fil_crypt_update_total_stat(state); } -/*********************************************************************** -Search for a space needing rotation -@param[in,out] key_state Key state -@param[in,out] state Rotation state -@param[in,out] recheck recheck ? */ -static -bool -fil_crypt_find_space_to_rotate( +/** Search for a space needing rotation +@param[in,out] key_state Key state +@param[in,out] state Rotation state +@param[in,out] recheck recheck of the tablespace is needed or + still encryption thread does write page 0 */ +static bool fil_crypt_find_space_to_rotate( key_state_t* key_state, rotate_thread_t* state, bool* recheck) @@ -1448,7 +1442,9 @@ fil_crypt_find_space_to_rotate( if (srv_fil_crypt_rotate_key_age) { state->space = fil_space_next(state->space); } else { - state->space = fil_space_keyrotate_next(state->space); + state->space = fil_system->keyrotate_next( + state->space, *recheck, + key_state->key_version); } while (!state->should_shutdown() && state->space) { @@ -1470,7 +1466,9 @@ fil_crypt_find_space_to_rotate( if (srv_fil_crypt_rotate_key_age) { state->space = fil_space_next(state->space); } else { - state->space = fil_space_keyrotate_next(state->space); + state->space = fil_system->keyrotate_next( + state->space, *recheck, + key_state->key_version); } } diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index 595f9c3e729..08c3a699a04 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -5983,28 +5983,32 @@ fil_space_remove_from_keyrotation(fil_space_t* space) Once started, the caller must keep calling this until it returns NULL. fil_space_acquire() and fil_space_release() are invoked here which blocks a concurrent operation from dropping the tablespace. -@param[in] prev_space Pointer to the previous fil_space_t. +@param[in] prev_space Previous tablespace or NULL to start + from beginning of fil_system->rotation list +@param[in] recheck recheck of the tablespace is needed or + still encryption thread does write page0 for it +@param[in] key_version key version of the key state thread If NULL, use the first fil_space_t on fil_system->space_list. @return pointer to the next fil_space_t. -@retval NULL if this was the last*/ +@retval NULL if this was the last */ fil_space_t* -fil_space_keyrotate_next( - fil_space_t* prev_space) +fil_system_t::keyrotate_next( + fil_space_t* prev_space, + bool recheck, + uint key_version) { - fil_space_t* space = prev_space; - fil_space_t* old = NULL; - mutex_enter(&fil_system->mutex); - if (UT_LIST_GET_LEN(fil_system->rotation_list) == 0) { - if (space) { - ut_ad(space->n_pending_ops > 0); - space->n_pending_ops--; - fil_space_remove_from_keyrotation(space); - } - mutex_exit(&fil_system->mutex); - return(NULL); - } + /* If one of the encryption threads already started the encryption + of the table then don't remove the unencrypted spaces from + rotation list + + If there is a change in innodb_encrypt_tables variables value then + don't remove the last processed tablespace from the rotation list. */ + const bool remove = ((!recheck || prev_space->crypt_data) + && (!key_version == !srv_encrypt_tables)); + + fil_space_t* space = prev_space; if (prev_space == NULL) { space = UT_LIST_GET_FIRST(fil_system->rotation_list); @@ -6017,22 +6021,17 @@ fil_space_keyrotate_next( /* Move on to the next fil_space_t */ space->n_pending_ops--; - old = space; space = UT_LIST_GET_NEXT(rotation_list, space); - fil_space_remove_from_keyrotation(old); - } - - /* Skip spaces that are being created by fil_ibd_create(), - or dropped. Note that rotation_list contains only - space->purpose == FIL_TYPE_TABLESPACE. */ - while (space != NULL - && (UT_LIST_GET_LEN(space->chain) == 0 - || space->is_stopping())) { + while (space != NULL + && (UT_LIST_GET_LEN(space->chain) == 0 + || space->is_stopping())) { + space = UT_LIST_GET_NEXT(rotation_list, space); + } - old = space; - space = UT_LIST_GET_NEXT(rotation_list, space); - fil_space_remove_from_keyrotation(old); + if (remove) { + fil_space_remove_from_keyrotation(prev_space); + } } if (space != NULL) { @@ -6040,7 +6039,6 @@ fil_space_keyrotate_next( } mutex_exit(&fil_system->mutex); - return(space); } diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h index a892736f5c4..386f574a59f 100644 --- a/storage/innobase/include/fil0fil.h +++ b/storage/innobase/include/fil0fil.h @@ -538,6 +538,25 @@ struct fil_system_t { @return tablespace @retval NULL if the tablespace does not exist or cannot be read */ fil_space_t* read_page0(ulint id); + + /** Return the next fil_space_t from key rotation list. + Once started, the caller must keep calling this until it returns NULL. + fil_space_acquire() and fil_space_release() are invoked here which + blocks a concurrent operation from dropping the tablespace. + @param[in] prev_space Previous tablespace or NULL to start + from beginning of fil_system->rotation + list + @param[in] recheck recheck of the tablespace is needed or + still encryption thread does write page0 + for it + @param[in] key_version key version of the key state thread + If NULL, use the first fil_space_t on fil_system->space_list. + @return pointer to the next fil_space_t. + @retval NULL if this was the last */ + fil_space_t* keyrotate_next( + fil_space_t* prev_space, + bool remove, + uint key_version); }; /** The tablespace memory cache. This variable is NULL before the module is @@ -793,13 +812,15 @@ fil_space_next( Once started, the caller must keep calling this until it returns NULL. fil_space_acquire() and fil_space_release() are invoked here which blocks a concurrent operation from dropping the tablespace. -@param[in,out] prev_space Pointer to the previous fil_space_t. +@param[in] prev_space Previous tablespace or NULL to start + from beginning of fil_system->rotation list +@param[in] remove Whether to remove the previous tablespace from + the rotation list If NULL, use the first fil_space_t on fil_system->space_list. @return pointer to the next fil_space_t. @retval NULL if this was the last*/ fil_space_t* -fil_space_keyrotate_next( - fil_space_t* prev_space) +fil_space_keyrotate_next(fil_space_t* prev_space, bool remove) MY_ATTRIBUTE((warn_unused_result)); /** Wrapper with reference-counting for a fil_space_t. */ -- cgit v1.2.1 From 96d9f03328a737439dc81c5b85584db55449ca6b Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Tue, 28 May 2019 18:31:20 +0530 Subject: MDEV-19602 Replace mysql_version check with frm_version for virtual columns inside InnoDB - Replace mysql_version check with omit_virtual_cols() in ha_innobase::check_if_supported_inplace_alter(). --- storage/innobase/handler/handler0alter.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'storage') diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index c0c002e3042..ffb7d498453 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -593,7 +593,7 @@ ha_innobase::check_if_supported_inplace_alter( /* Before 10.2.2 information about virtual columns was not stored in system tables. We need to do a full alter to rebuild proper 10.2.2+ metadata with the information about virtual columns */ - if (table->s->mysql_version < 100202 && table->s->virtual_fields) { + if (omits_virtual_cols(*table_share)) { DBUG_RETURN(HA_ALTER_INPLACE_NOT_SUPPORTED); } -- cgit v1.2.1 From 1ca75ae1c881bf0afae00f4acac0d668446a15d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 28 May 2019 16:43:02 +0300 Subject: MDEV-19587 innodb_force_recovery=5 crash on DROP SCHEMA At higher levels of innodb_force_recovery, the InnoDB transaction subsystem will not be set up at all. At slightly lower levels, recovered transactions will not be rolled back, and DDL operations could hang due to locks being held at all. Let us consistently refuse all writes if the predicate high_level_read_only holds. We failed to refuse DROP TABLE and DROP DATABASE. (Refusing DROP TABLE is a partial backport from MDEV-19570 in the 10.5 branch.) --- storage/innobase/handler/ha_innodb.cc | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) (limited to 'storage') diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index ef3f9617069..a511a3d175e 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -13118,8 +13118,7 @@ inline int ha_innobase::delete_table(const char* name, enum_sql_command sqlcom) extension, in contrast to ::create */ normalize_table_name(norm_name, name); - if (srv_read_only_mode - || srv_force_recovery >= SRV_FORCE_NO_UNDO_LOG_SCAN) { + if (high_level_read_only) { DBUG_RETURN(HA_ERR_TABLE_READONLY); } @@ -13308,7 +13307,7 @@ innobase_drop_database( DBUG_ASSERT(hton == innodb_hton_ptr); - if (srv_read_only_mode) { + if (high_level_read_only) { return; } -- cgit v1.2.1 From 6eefeb6fea05ff17d010d173ef244a1d92078d71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 29 May 2019 11:20:56 +0300 Subject: MDEV-19541: Avoid infinite loop of reading a corrupted page row_search_mvcc(): Duplicate the logic of btr_pcur_move_to_next() so that an infinite loop can be avoided when advancing to the next page fails due to a corrupted page. --- storage/innobase/row/row0sel.cc | 54 +++++++++++++++++++++++++---------------- 1 file changed, 33 insertions(+), 21 deletions(-) (limited to 'storage') diff --git a/storage/innobase/row/row0sel.cc b/storage/innobase/row/row0sel.cc index afdac984cfd..877d9c3ef78 100644 --- a/storage/innobase/row/row0sel.cc +++ b/storage/innobase/row/row0sel.cc @@ -5636,36 +5636,48 @@ next_rec: } if (moves_up) { - bool move; - - if (spatial_search) { - move = rtr_pcur_move_to_next( - search_tuple, mode, pcur, 0, &mtr); - } else { - move = btr_pcur_move_to_next(pcur, &mtr); - } - - if (!move) { -not_moved: - if (!spatial_search) { - btr_pcur_store_position(pcur, &mtr); + if (UNIV_UNLIKELY(spatial_search)) { + if (rtr_pcur_move_to_next( + search_tuple, mode, pcur, 0, &mtr)) { + goto rec_loop; } - - if (match_mode != 0) { - err = DB_RECORD_NOT_FOUND; + } else { + const buf_block_t* block = btr_pcur_get_block(pcur); + /* This is based on btr_pcur_move_to_next(), + but avoids infinite read loop of a corrupted page. */ + ut_ad(pcur->pos_state == BTR_PCUR_IS_POSITIONED); + ut_ad(pcur->latch_mode != BTR_NO_LATCHES); + pcur->old_stored = false; + if (btr_pcur_is_after_last_on_page(pcur)) { + if (btr_pcur_is_after_last_in_tree(pcur, + &mtr)) { + goto not_moved; + } + btr_pcur_move_to_next_page(pcur, &mtr); + if (UNIV_UNLIKELY(btr_pcur_get_block(pcur) + == block)) { + err = DB_CORRUPTION; + goto lock_wait_or_error; + } } else { - err = DB_END_OF_INDEX; + btr_pcur_move_to_next_on_page(pcur); } - goto normal_return; + goto rec_loop; } } else { - if (UNIV_UNLIKELY(!btr_pcur_move_to_prev(pcur, &mtr))) { - goto not_moved; + if (btr_pcur_move_to_prev(pcur, &mtr)) { + goto rec_loop; } } - goto rec_loop; +not_moved: + if (!spatial_search) { + btr_pcur_store_position(pcur, &mtr); + } + + err = match_mode ? DB_RECORD_NOT_FOUND : DB_END_OF_INDEX; + goto normal_return; lock_wait_or_error: /* Reset the old and new "did semi-consistent read" flags. */ -- cgit v1.2.1