From edda2fd149e4fcb7c9640be4d05d2c25013b2b71 Mon Sep 17 00:00:00 2001 From: Vlad Lesin Date: Tue, 1 Oct 2019 03:23:33 +0300 Subject: [PATCH 01/44] MDEV-20703: mariabackup creates binlog files in server binlog directory on --prepare --export step When "--export" mariabackup option is used, mariabackup starts the server in bootstrap mode to generate *.cfg files for the certain innodb tables. The started instance of the server reads options from the file, pointed out in "--defaults-file" mariabackup option. If the server uses the same config file as mariabackup, and binlog is switched on in that config file, then "mariabackup --prepare --export" will create binary log files in the server's binary log directory, what can cause issues. The fix is to add "--skip-log-bin" in mysld options when the server is started to generate *.cfg files. --- extra/mariabackup/xtrabackup.cc | 6 ++++-- mysql-test/suite/mariabackup/partial.test | 18 ++++++++++++++++-- 2 files changed, 20 insertions(+), 4 deletions(-) diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc index 46b67705700..ec53554e2d8 100644 --- a/extra/mariabackup/xtrabackup.cc +++ b/extra/mariabackup/xtrabackup.cc @@ -1535,7 +1535,8 @@ static int prepare_export() " --defaults-extra-file=./backup-my.cnf --defaults-group-suffix=%s --datadir=." " --innodb --innodb-fast-shutdown=0 --loose-partition" " --innodb_purge_rseg_truncate_frequency=1 --innodb-buffer-pool-size=%llu" - " --console --skip-log-error --bootstrap < " BOOTSTRAP_FILENAME IF_WIN("\"",""), + " --console --skip-log-error --skip-log-bin --bootstrap < " + BOOTSTRAP_FILENAME IF_WIN("\"",""), mariabackup_exe, orig_argv1, (my_defaults_group_suffix?my_defaults_group_suffix:""), xtrabackup_use_memory); @@ -1547,7 +1548,8 @@ static int prepare_export() " --defaults-file=./backup-my.cnf --defaults-group-suffix=%s --datadir=." " --innodb --innodb-fast-shutdown=0 --loose-partition" " --innodb_purge_rseg_truncate_frequency=1 --innodb-buffer-pool-size=%llu" - " --console --log-error= --bootstrap < " BOOTSTRAP_FILENAME IF_WIN("\"",""), + " --console --log-error= --skip-log-bin --bootstrap < " + BOOTSTRAP_FILENAME IF_WIN("\"",""), mariabackup_exe, (my_defaults_group_suffix?my_defaults_group_suffix:""), xtrabackup_use_memory); diff --git a/mysql-test/suite/mariabackup/partial.test b/mysql-test/suite/mariabackup/partial.test index 559ba155972..53388b1947f 100644 --- a/mysql-test/suite/mariabackup/partial.test +++ b/mysql-test/suite/mariabackup/partial.test @@ -12,7 +12,7 @@ CREATE TABLE t2(i int) ENGINE INNODB; echo # xtrabackup backup; -let $targetdir=$MYSQLTEST_VARDIR/tmp/backup; +let targetdir=$MYSQLTEST_VARDIR/tmp/backup; --disable_result_log exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup "--tables=test.*1" --target-dir=$targetdir; --enable_result_log @@ -25,13 +25,27 @@ EOF write_file $targetdir/test/junk.frm; EOF +let server_cnf=$targetdir/server.cnf; +copy_file $MYSQLTEST_VARDIR/my.cnf $server_cnf; + +# Emulate server config file turnes on binary logs +perl; +my $binlog_path="$ENV{'targetdir'}/mysqld-bin"; +my $config_path=$ENV{'server_cnf'}; +open(my $fd, '>>', "$config_path"); +print $fd "\n[mysqld]\n"; +print $fd "log-bin=$binlog_path\n"; +close $fd; +EOF echo # xtrabackup prepare; --disable_result_log -exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --defaults-group-suffix=.1 --prepare --export --target-dir=$targetdir; +exec $XTRABACKUP --defaults-file=$server_cnf --defaults-group-suffix=.1 --prepare --export --target-dir=$targetdir; --enable_result_log list_files $targetdir/test *.cfg; +# There must not be binary logs created on --prepare step +list_files $targetdir/ mysqld-bin.*; let $MYSQLD_DATADIR= `select @@datadir`; ALTER TABLE t1 DISCARD TABLESPACE; From e43791d4dc8feb2c02a08ce73c0bb0e2c320018c Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Wed, 2 Oct 2019 15:23:59 +0400 Subject: [PATCH 02/44] Cleanup EITS Moved EITS allocation inside read_statistics_for_tables_if_needed(). Removed redundant is_safe argument. --- sql/sql_base.cc | 26 --------------------- sql/sql_statistics.cc | 53 +++++++++++++++++++++++++++---------------- sql/sql_statistics.h | 2 -- 3 files changed, 34 insertions(+), 47 deletions(-) diff --git a/sql/sql_base.cc b/sql/sql_base.cc index e8bdff8b48f..1c4e7600d87 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -4245,32 +4245,6 @@ open_and_process_table(THD *thd, TABLE_LIST *tables, uint *counter, uint flags, goto end; } - if (get_use_stat_tables_mode(thd) > NEVER && tables->table) - { - TABLE_SHARE *table_share= tables->table->s; - if (table_share && table_share->table_category == TABLE_CATEGORY_USER && - table_share->tmp_table == NO_TMP_TABLE) - { - if (table_share->stats_cb.stats_can_be_read || - !alloc_statistics_for_table_share(thd, table_share, FALSE)) - { - if (table_share->stats_cb.stats_can_be_read) - { - KEY *key_info= table_share->key_info; - KEY *key_info_end= key_info + table_share->keys; - KEY *table_key_info= tables->table->key_info; - for ( ; key_info < key_info_end; key_info++, table_key_info++) - table_key_info->read_stats= key_info->read_stats; - Field **field_ptr= table_share->field; - Field **table_field_ptr= tables->table->field; - for ( ; *field_ptr; field_ptr++, table_field_ptr++) - (*table_field_ptr)->read_stats= (*field_ptr)->read_stats; - tables->table->stats_is_read= table_share->stats_cb.stats_is_read; - } - } - } - } - process_view_routines: /* Again we may need cache all routines used by this view and add diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index 52b3811e60d..e18cec589be 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -2216,8 +2216,6 @@ inline bool statistics_for_command_is_needed(THD *thd) thd Thread handler @param table_share Table share for which the memory for statistical data is allocated - @param - is_safe TRUE <-> at any time only one thread can perform the function @note The function allocates the memory for the statistical data on a table in the @@ -2226,8 +2224,6 @@ inline bool statistics_for_command_is_needed(THD *thd) mysql.index_stats. The memory is allocated for the statistics on the table, on the tables's columns, and on the table's indexes. The memory is allocated in the table_share's mem_root. - If the parameter is_safe is TRUE then it is guaranteed that at any given time - only one thread is executed the code of the function. @retval 0 If the memory for all statistical data has been successfully allocated @@ -2246,16 +2242,10 @@ inline bool statistics_for_command_is_needed(THD *thd) Here the second and the third threads try to allocate the memory for statistical data at the same time. The precautions are taken to guarantee the correctness of the allocation. - - @note - Currently the function always is called with the parameter is_safe set - to FALSE. */ -int alloc_statistics_for_table_share(THD* thd, TABLE_SHARE *table_share, - bool is_safe) +static int alloc_statistics_for_table_share(THD* thd, TABLE_SHARE *table_share) { - Field **field_ptr; KEY *key_info, *end; TABLE_STATISTICS_CB *stats_cb= &table_share->stats_cb; @@ -2268,13 +2258,11 @@ int alloc_statistics_for_table_share(THD* thd, TABLE_SHARE *table_share, if (!statistics_for_command_is_needed(thd)) DBUG_RETURN(1); - if (!is_safe) - mysql_mutex_lock(&table_share->LOCK_share); + mysql_mutex_lock(&table_share->LOCK_share); if (stats_cb->stats_can_be_read) { - if (!is_safe) - mysql_mutex_unlock(&table_share->LOCK_share); + mysql_mutex_unlock(&table_share->LOCK_share); DBUG_RETURN(0); } @@ -2285,8 +2273,7 @@ int alloc_statistics_for_table_share(THD* thd, TABLE_SHARE *table_share, sizeof(Table_statistics)); if (!table_stats) { - if (!is_safe) - mysql_mutex_unlock(&table_share->LOCK_share); + mysql_mutex_unlock(&table_share->LOCK_share); DBUG_RETURN(1); } memset(table_stats, 0, sizeof(Table_statistics)); @@ -2358,8 +2345,7 @@ int alloc_statistics_for_table_share(THD* thd, TABLE_SHARE *table_share, if (column_stats && index_stats && idx_avg_frequency) stats_cb->stats_can_be_read= TRUE; - if (!is_safe) - mysql_mutex_unlock(&table_share->LOCK_share); + mysql_mutex_unlock(&table_share->LOCK_share); DBUG_RETURN(0); } @@ -3264,6 +3250,35 @@ int read_statistics_for_tables_if_needed(THD *thd, TABLE_LIST *tables) DBUG_ENTER("read_statistics_for_tables_if_needed"); + for (TABLE_LIST *tl= tables; tl; tl= tl->next_global) + { + if (get_use_stat_tables_mode(thd) > NEVER && tl->table) + { + TABLE_SHARE *table_share= tl->table->s; + if (table_share && table_share->table_category == TABLE_CATEGORY_USER && + table_share->tmp_table == NO_TMP_TABLE) + { + if (table_share->stats_cb.stats_can_be_read || + !alloc_statistics_for_table_share(thd, table_share)) + { + if (table_share->stats_cb.stats_can_be_read) + { + KEY *key_info= table_share->key_info; + KEY *key_info_end= key_info + table_share->keys; + KEY *table_key_info= tl->table->key_info; + for ( ; key_info < key_info_end; key_info++, table_key_info++) + table_key_info->read_stats= key_info->read_stats; + Field **field_ptr= table_share->field; + Field **table_field_ptr= tl->table->field; + for ( ; *field_ptr; field_ptr++, table_field_ptr++) + (*table_field_ptr)->read_stats= (*field_ptr)->read_stats; + tl->table->stats_is_read= table_share->stats_cb.stats_is_read; + } + } + } + } + } + DEBUG_SYNC(thd, "statistics_read_start"); if (!statistics_for_tables_is_needed(thd, tables)) diff --git a/sql/sql_statistics.h b/sql/sql_statistics.h index 16325220e84..968f77cd2ca 100644 --- a/sql/sql_statistics.h +++ b/sql/sql_statistics.h @@ -90,8 +90,6 @@ Use_stat_tables_mode get_use_stat_tables_mode(THD *thd) int read_statistics_for_tables_if_needed(THD *thd, TABLE_LIST *tables); int collect_statistics_for_table(THD *thd, TABLE *table); -int alloc_statistics_for_table_share(THD* thd, TABLE_SHARE *share, - bool is_safe); void delete_stat_values_for_table_share(TABLE_SHARE *table_share); int alloc_statistics_for_table(THD *thd, TABLE *table); int update_statistics_for_table(THD *thd, TABLE *table); From 716c748f97d8f7cb7caaf39dd7b9cdaf79b2229a Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Mon, 23 Sep 2019 18:28:55 +1000 Subject: [PATCH 03/44] MDEV-20684: innodb/query cache use madvise CORE/NOCORE on FreeBSD This applies to large allocations. This maps to the way Linux does it in MDEV-10814 except FreeBSD uses different constants. Adjust error string to match to implementation. Tested on FreeBSD-12.0 --- include/my_global.h | 14 ++++++++++++++ sql/sql_cache.cc | 4 ++-- storage/innobase/include/ut0new.h | 4 ++-- 3 files changed, 18 insertions(+), 4 deletions(-) diff --git a/include/my_global.h b/include/my_global.h index 819d388f367..a1cecdd8a6f 100644 --- a/include/my_global.h +++ b/include/my_global.h @@ -445,6 +445,20 @@ C_MODE_END #if HAVE_MADVISE && !HAVE_DECL_MADVISE && defined(__cplusplus) extern "C" int madvise(void *addr, size_t len, int behav); #endif +#ifdef HAVE_SYS_MMAN_H +#include +#endif +/** FreeBSD equivalent */ +#if defined(MADV_CORE) && !defined(MADV_DODUMP) +#define MADV_DODUMP MADV_CORE +#define MADV_DONTDUMP MADV_NOCORE +#define DODUMP_STR "MADV_CORE" +#define DONTDUMP_STR "MADV_NOCORE" +#else +#define DODUMP_STR "MADV_DODUMP" +#define DONTDUMP_STR "MADV_DONTDUMP" +#endif + #define QUOTE_ARG(x) #x /* Quote argument (before cpp) */ #define STRINGIFY_ARG(x) QUOTE_ARG(x) /* Quote argument, after cpp */ diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index c44be9a11f5..70525725689 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -2662,7 +2662,7 @@ size_t Query_cache::init_cache() #if defined(DBUG_OFF) && defined(HAVE_MADVISE) && defined(MADV_DONTDUMP) if (madvise(cache, query_cache_size+additional_data_size, MADV_DONTDUMP)) { - DBUG_PRINT("warning", ("coudn't mark query cache memory as MADV_DONTDUMP: %s", + DBUG_PRINT("warning", ("coudn't mark query cache memory as " DONTDUMP_STR ": %s", strerror(errno))); } #endif @@ -2831,7 +2831,7 @@ void Query_cache::free_cache() #if defined(DBUG_OFF) && defined(HAVE_MADVISE) && defined(MADV_DODUMP) if (madvise(cache, query_cache_size+additional_data_size, MADV_DODUMP)) { - DBUG_PRINT("warning", ("coudn't mark query cache memory as MADV_DODUMP: %s", + DBUG_PRINT("warning", ("coudn't mark query cache memory as " DODUMP_STR ": %s", strerror(errno))); } #endif diff --git a/storage/innobase/include/ut0new.h b/storage/innobase/include/ut0new.h index 6732a12ecf1..46867a60023 100644 --- a/storage/innobase/include/ut0new.h +++ b/storage/innobase/include/ut0new.h @@ -252,7 +252,7 @@ static inline void ut_allocate_trace_dontdump(void *ptr, size_t bytes, #if defined(DBUG_OFF) && defined(HAVE_MADVISE) && defined(MADV_DONTDUMP) if (dontdump && madvise(ptr, bytes, MADV_DONTDUMP)) { - ib::warn() << "Failed to set memory to DONTDUMP: " + ib::warn() << "Failed to set memory to " DONTDUMP_STR ": " << strerror(errno) << " ptr " << ptr << " size " << bytes; @@ -270,7 +270,7 @@ static inline void ut_allocate_trace_dontdump(void *ptr, size_t bytes, static inline void ut_dodump(void* ptr, size_t m_size) { if (ptr && madvise(ptr, m_size, MADV_DODUMP)) { - ib::warn() << "Failed to set memory to DODUMP: " + ib::warn() << "Failed to set memory to " DODUMP_STR ": " << strerror(errno) << " ptr " << ptr << " size " << m_size; From 5b2fa078e8aee75a180461963bd54ce885445c17 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Wed, 2 Oct 2019 20:17:00 +0400 Subject: [PATCH 04/44] Cleanup mman.h includes As it is included from my_global.h already. --- include/my_sys.h | 2 -- mysys/my_lockmem.c | 1 - sql/mysqld.cc | 5 ----- sql/sql_cache.cc | 3 --- storage/innobase/include/univ.i | 1 - storage/innobase/include/ut0new.h | 3 --- storage/maria/ma_check.c | 3 --- storage/maria/ma_extra.c | 3 --- storage/maria/ma_packrec.c | 3 --- storage/maria/maria_chk.c | 3 --- storage/myisam/mi_check.c | 3 --- storage/myisam/mi_extra.c | 3 --- storage/myisam/mi_packrec.c | 3 --- storage/myisam/myisamchk.c | 3 --- 14 files changed, 39 deletions(-) diff --git a/include/my_sys.h b/include/my_sys.h index 90f37f8ca81..61551d38337 100644 --- a/include/my_sys.h +++ b/include/my_sys.h @@ -964,8 +964,6 @@ extern ulonglong my_getcputime(void); #endif #ifdef HAVE_SYS_MMAN_H -#include - #ifndef MAP_NOSYNC #define MAP_NOSYNC 0 #endif diff --git a/mysys/my_lockmem.c b/mysys/my_lockmem.c index ce569b78c73..3ce0f07af58 100644 --- a/mysys/my_lockmem.c +++ b/mysys/my_lockmem.c @@ -20,7 +20,6 @@ #include #ifdef HAVE_MLOCK -#include struct st_mem_list { diff --git a/sql/mysqld.cc b/sql/mysqld.cc index fa10d4af3a1..bc804598cd5 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -157,16 +157,11 @@ extern "C" { // Because of SCO 3.2V4.2 #include -#ifdef HAVE_SYS_MMAN_H -#include -#endif - #ifdef __WIN__ #include #endif #ifdef HAVE_SOLARIS_LARGE_PAGES -#include #if defined(__sun__) && defined(__GNUC__) && defined(__cplusplus) \ && defined(_XOPEN_SOURCE) extern int getpagesizes(size_t *, int); diff --git a/sql/sql_cache.cc b/sql/sql_cache.cc index 70525725689..3842b7c4dc1 100644 --- a/sql/sql_cache.cc +++ b/sql/sql_cache.cc @@ -329,9 +329,6 @@ TODO list: */ #include "mariadb.h" /* NO_EMBEDDED_ACCESS_CHECKS */ -#if defined(DBUG_OFF) && defined(HAVE_MADVISE) -#include -#endif #include "sql_priv.h" #include "sql_basic_types.h" #include "sql_cache.h" diff --git a/storage/innobase/include/univ.i b/storage/innobase/include/univ.i index b1271ec85d1..19a03009ad5 100644 --- a/storage/innobase/include/univ.i +++ b/storage/innobase/include/univ.i @@ -92,7 +92,6 @@ support cross-platform development and expose comonly used SQL names. */ #include #ifndef _WIN32 -# include /* mmap() for os0proc.cc */ # include # include "my_config.h" #endif diff --git a/storage/innobase/include/ut0new.h b/storage/innobase/include/ut0new.h index 46867a60023..a190b872549 100644 --- a/storage/innobase/include/ut0new.h +++ b/storage/innobase/include/ut0new.h @@ -129,9 +129,6 @@ InnoDB: #include /* strlen(), strrchr(), strncmp() */ #include "my_global.h" /* needed for headers from mysql/psi/ */ -#if !defined(DBUG_OFF) && defined(HAVE_MADVISE) -#include -#endif /* JAN: TODO: missing 5.7 header */ #ifdef HAVE_MYSQL_MEMORY_H diff --git a/storage/maria/ma_check.c b/storage/maria/ma_check.c index bfed6698428..eadac5b04eb 100644 --- a/storage/maria/ma_check.c +++ b/storage/maria/ma_check.c @@ -52,9 +52,6 @@ #ifdef HAVE_SYS_VADVISE_H #include #endif -#ifdef HAVE_SYS_MMAN_H -#include -#endif /* Functions defined in this file */ diff --git a/storage/maria/ma_extra.c b/storage/maria/ma_extra.c index 2697c72f2b8..c2ac4d588a9 100644 --- a/storage/maria/ma_extra.c +++ b/storage/maria/ma_extra.c @@ -14,9 +14,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1335 USA */ #include "maria_def.h" -#ifdef HAVE_SYS_MMAN_H -#include -#endif #include "ma_blockrec.h" static void maria_extra_keyflag(MARIA_HA *info, diff --git a/storage/maria/ma_packrec.c b/storage/maria/ma_packrec.c index e2c1e353616..2e7add8f61d 100644 --- a/storage/maria/ma_packrec.c +++ b/storage/maria/ma_packrec.c @@ -1528,9 +1528,6 @@ static uint max_bit(register uint value) /***************************************************************************** Some redefined functions to handle files when we are using memmap *****************************************************************************/ -#ifdef HAVE_SYS_MMAN_H -#include -#endif #ifdef HAVE_MMAP diff --git a/storage/maria/maria_chk.c b/storage/maria/maria_chk.c index 6ea40e65b29..85cdaa06701 100644 --- a/storage/maria/maria_chk.c +++ b/storage/maria/maria_chk.c @@ -23,9 +23,6 @@ #include #include #include -#ifdef HAVE_SYS_MMAN_H -#include -#endif static uint decode_bits; static char **default_argv; diff --git a/storage/myisam/mi_check.c b/storage/myisam/mi_check.c index 76accc0978e..eac50c4a04c 100644 --- a/storage/myisam/mi_check.c +++ b/storage/myisam/mi_check.c @@ -46,9 +46,6 @@ #ifdef HAVE_SYS_VADVISE_H #include #endif -#ifdef HAVE_SYS_MMAN_H -#include -#endif #include "rt_index.h" #include diff --git a/storage/myisam/mi_extra.c b/storage/myisam/mi_extra.c index 27e08f093ff..07592ced5db 100644 --- a/storage/myisam/mi_extra.c +++ b/storage/myisam/mi_extra.c @@ -15,9 +15,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */ #include "myisamdef.h" -#ifdef HAVE_SYS_MMAN_H -#include -#endif static void mi_extra_keyflag(MI_INFO *info, enum ha_extra_function function); diff --git a/storage/myisam/mi_packrec.c b/storage/myisam/mi_packrec.c index 72ce17b6a78..b28eaf21090 100644 --- a/storage/myisam/mi_packrec.c +++ b/storage/myisam/mi_packrec.c @@ -1479,9 +1479,6 @@ static uint max_bit(register uint value) /***************************************************************************** Some redefined functions to handle files when we are using memmap *****************************************************************************/ -#ifdef HAVE_SYS_MMAN_H -#include -#endif #ifdef HAVE_MMAP diff --git a/storage/myisam/myisamchk.c b/storage/myisam/myisamchk.c index a3021ed72a7..f616a9f9b1a 100644 --- a/storage/myisam/myisamchk.c +++ b/storage/myisam/myisamchk.c @@ -21,9 +21,6 @@ #include #include #include -#ifdef HAVE_SYS_MMAN_H -#include -#endif static uint decode_bits; static char **default_argv; From 5e65c67cfcc79c48c22798babee7555b04f40d18 Mon Sep 17 00:00:00 2001 From: Eugene Kosov Date: Thu, 3 Oct 2019 17:45:36 +0300 Subject: [PATCH 05/44] fix clang warning --- storage/connect/inihandl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/connect/inihandl.cpp b/storage/connect/inihandl.cpp index 8e79aeac7ef..dacab3c485c 100644 --- a/storage/connect/inihandl.cpp +++ b/storage/connect/inihandl.cpp @@ -194,7 +194,7 @@ static void PROFILE_Save( FILE *file, PROFILESECTION *section ) } for (key = section->key; key; key = key->next) - if (key->name && key->name[0]) { + if (key->name[0]) { fprintf(file, "%s", SVP(key->name)); if (key->value) From 13535b2713aa78636e7c93059c30a298a72b627f Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Mon, 30 Sep 2019 09:08:17 +0200 Subject: [PATCH 06/44] Fix problem with warnings of new compilers. --- libmariadb | 2 +- sql-common/client_plugin.c | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/libmariadb b/libmariadb index 544b6f1d12f..c6403c4c847 160000 --- a/libmariadb +++ b/libmariadb @@ -1 +1 @@ -Subproject commit 544b6f1d12f0e5b2a141129075ff2d64feb0e4c9 +Subproject commit c6403c4c847d94ed6b40d3fd128e729271867e75 diff --git a/sql-common/client_plugin.c b/sql-common/client_plugin.c index 52e0ae03ee1..a4de02b9f41 100644 --- a/sql-common/client_plugin.c +++ b/sql-common/client_plugin.c @@ -28,10 +28,8 @@ There is no reference counting and no unloading either. */ -#if _MSC_VER /* Silence warnings about variable 'unused' being used. */ #define FORCE_INIT_OF_VARS 1 -#endif #include #include "mysql.h" From fe4f766e81fb96bb1c6dbeb6a76b7a379b4449ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Fri, 4 Oct 2019 14:44:16 +0300 Subject: [PATCH 07/44] Add wait_condition to wait that node returns to ready state before accessing it. --- .../r/galera_var_ignore_apply_errors.result | 80 +++++++++---------- .../t/galera_var_ignore_apply_errors.test | 41 ++++++---- 2 files changed, 67 insertions(+), 54 deletions(-) diff --git a/mysql-test/suite/galera/r/galera_var_ignore_apply_errors.result b/mysql-test/suite/galera/r/galera_var_ignore_apply_errors.result index 48c845a4c2b..082d2e8eb1d 100644 --- a/mysql-test/suite/galera/r/galera_var_ignore_apply_errors.result +++ b/mysql-test/suite/galera/r/galera_var_ignore_apply_errors.result @@ -38,13 +38,13 @@ INSERT INTO t1 VALUES (1); SET GLOBAL wsrep_on = ON; DELETE FROM t1 WHERE f1 = 1; connection node_1; -SELECT COUNT(*) = 0 FROM t1; -COUNT(*) = 0 -1 +SELECT COUNT(*) as expect_0 FROM t1; +expect_0 +0 connection node_2; -SELECT COUNT(*) = 0 FROM t1; -COUNT(*) = 0 -1 +SELECT COUNT(*) as expect_0 FROM t1; +expect_0 +0 DROP TABLE t1; connection node_1; CREATE TABLE t1 (f1 INTEGER); @@ -58,12 +58,12 @@ DELETE FROM t1 WHERE f1 = 1; DELETE FROM t1 WHERE f1 = 2; COMMIT; connection node_1; -SELECT COUNT(*) = 1 FROM t1; -COUNT(*) = 1 +SELECT COUNT(*) as expect_1 FROM t1; +expect_1 1 connection node_2; -SELECT COUNT(*) = 1 FROM t1; -COUNT(*) = 1 +SELECT COUNT(*) as expect_1 FROM t1; +expect_1 1 DROP TABLE t1; connection node_1; @@ -75,16 +75,16 @@ DELETE FROM t1 WHERE f1 = 3; SET SESSION wsrep_on = ON; connection node_1; DELETE FROM t1; -SELECT COUNT(*) = 0 FROM t1; -COUNT(*) = 0 -1 +SELECT COUNT(*) as expect_0 FROM t1; +expect_0 +0 connection node_2; SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; VARIABLE_VALUE = 'Primary' 1 -SELECT COUNT(*) = 0 FROM t1; -COUNT(*) = 0 -1 +SELECT COUNT(*) as expect_0 FROM t1; +expect_0 +0 DROP TABLE t1; connection node_1; CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB; @@ -103,16 +103,16 @@ DELETE FROM t1 WHERE f1 = 4; DELETE FROM t1 WHERE f1 = 5; COMMIT; SET AUTOCOMMIT=ON; -SELECT COUNT(*) = 0 FROM t1; -COUNT(*) = 0 -1 +SELECT COUNT(*) as expect_0 FROM t1; +expect_0 +0 connection node_2; SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; VARIABLE_VALUE = 'Primary' 1 -SELECT COUNT(*) = 0 FROM t1; -COUNT(*) = 0 -1 +SELECT COUNT(*) as expect_0 FROM t1; +expect_0 +0 DROP TABLE t1; connection node_1; CREATE TABLE t1 (f1 INTEGER PRIMARY KEY) ENGINE=InnoDB; @@ -126,16 +126,16 @@ DELETE FROM t1 WHERE f1 = 3; SET SESSION wsrep_on = ON; connection node_1; DELETE t1, t2 FROM t1 JOIN t2 WHERE t1.f1 = t2.f1; -SELECT COUNT(*) = 0 FROM t1; -COUNT(*) = 0 -1 +SELECT COUNT(*) as expect_0 FROM t1; +expect_0 +0 connection node_2; SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; VARIABLE_VALUE = 'Primary' 1 -SELECT COUNT(*) = 0 FROM t1; -COUNT(*) = 0 -1 +SELECT COUNT(*) as expect_0 FROM t1; +expect_0 +0 DROP TABLE t1,t2; connection node_1; CREATE TABLE parent (id INT NOT NULL, PRIMARY KEY (id)) ENGINE=INNODB; @@ -148,22 +148,22 @@ DELETE FROM child WHERE parent_id = 2; SET SESSION wsrep_on = ON; connection node_1; DELETE FROM parent; -SELECT COUNT(*) = 0 FROM parent; -COUNT(*) = 0 -1 -SELECT COUNT(*) = 0 FROM child; -COUNT(*) = 0 -1 +SELECT COUNT(*) as expect_0 FROM parent; +expect_0 +0 +SELECT COUNT(*) as expect_0 FROM child; +expect_0 +0 connection node_2; SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; VARIABLE_VALUE = 'Primary' 1 -SELECT COUNT(*) = 0 FROM parent; -COUNT(*) = 0 -1 -SELECT COUNT(*) = 0 FROM child; -COUNT(*) = 0 -1 +SELECT COUNT(*) as expect_0 FROM parent; +expect_0 +0 +SELECT COUNT(*) as expect_0 FROM child; +expect_0 +0 DROP TABLE child, parent; connection node_2; SET GLOBAL wsrep_ignore_apply_errors = 4; diff --git a/mysql-test/suite/galera/t/galera_var_ignore_apply_errors.test b/mysql-test/suite/galera/t/galera_var_ignore_apply_errors.test index ddf561c8784..5232d4236e6 100644 --- a/mysql-test/suite/galera/t/galera_var_ignore_apply_errors.test +++ b/mysql-test/suite/galera/t/galera_var_ignore_apply_errors.test @@ -18,12 +18,14 @@ SET GLOBAL wsrep_ignore_apply_errors = 1; SET GLOBAL wsrep_on = OFF; CREATE TABLE t1 (f1 INTEGER); SET GLOBAL wsrep_on = ON; +--source include/galera_wait_ready.inc DROP TABLE t1; # Drop schema that does not exist SET GLOBAL wsrep_on = OFF; CREATE SCHEMA s1; SET GLOBAL wsrep_on = ON; +--source include/galera_wait_ready.inc DROP SCHEMA s1; # Drop index that does not exist using DROP INDEX @@ -31,6 +33,7 @@ CREATE TABLE t1 (f1 INTEGER); SET GLOBAL wsrep_on = OFF; CREATE INDEX idx1 ON t1 (f1); SET GLOBAL wsrep_on = ON; +--source include/galera_wait_ready.inc DROP INDEX idx1 ON t1; DROP TABLE t1; @@ -39,6 +42,7 @@ CREATE TABLE t1 (f1 INTEGER); SET GLOBAL wsrep_on = OFF; CREATE INDEX idx1 ON t1 (f1); SET GLOBAL wsrep_on = ON; +--source include/galera_wait_ready.inc ALTER TABLE t1 DROP INDEX idx1; DROP TABLE t1; @@ -47,6 +51,7 @@ CREATE TABLE t1 (f1 INTEGER); SET GLOBAL wsrep_on = OFF; ALTER TABLE t1 ADD COLUMN f2 INTEGER; SET GLOBAL wsrep_on = ON; +--source include/galera_wait_ready.inc ALTER TABLE t1 DROP COLUMN f2; DROP TABLE t1; @@ -64,12 +69,13 @@ CREATE TABLE t1 (f1 INTEGER); SET GLOBAL wsrep_on = OFF; INSERT INTO t1 VALUES (1); SET GLOBAL wsrep_on = ON; +--source include/galera_wait_ready.inc DELETE FROM t1 WHERE f1 = 1; --connection node_1 -SELECT COUNT(*) = 0 FROM t1; +SELECT COUNT(*) as expect_0 FROM t1; --connection node_2 -SELECT COUNT(*) = 0 FROM t1; +SELECT COUNT(*) as expect_0 FROM t1; DROP TABLE t1; @@ -80,6 +86,7 @@ INSERT INTO t1 VALUES (2); SET GLOBAL wsrep_on = OFF; INSERT INTO t1 VALUES (1); SET GLOBAL wsrep_on = ON; +--source include/galera_wait_ready.inc START TRANSACTION; INSERT INTO t1 VALUES (3); DELETE FROM t1 WHERE f1 = 1; @@ -87,9 +94,9 @@ DELETE FROM t1 WHERE f1 = 2; COMMIT; --connection node_1 -SELECT COUNT(*) = 1 FROM t1; +SELECT COUNT(*) as expect_1 FROM t1; --connection node_2 -SELECT COUNT(*) = 1 FROM t1; +SELECT COUNT(*) as expect_1 FROM t1; DROP TABLE t1; @@ -107,13 +114,14 @@ INSERT INTO t1 VALUES (1),(2),(3),(4),(5); SET SESSION wsrep_on = OFF; DELETE FROM t1 WHERE f1 = 3; SET SESSION wsrep_on = ON; +--source include/galera_wait_ready.inc --connection node_1 DELETE FROM t1; -SELECT COUNT(*) = 0 FROM t1; +SELECT COUNT(*) as expect_0 FROM t1; --connection node_2 SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; -SELECT COUNT(*) = 0 FROM t1; +SELECT COUNT(*) as expect_0 FROM t1; DROP TABLE t1; # @@ -130,6 +138,8 @@ INSERT INTO t1 VALUES (1),(2),(3),(4),(5); SET SESSION wsrep_on = OFF; DELETE FROM t1 WHERE f1 = 3; SET SESSION wsrep_on = ON; +--source include/galera_wait_ready.inc + --connection node_1 SET AUTOCOMMIT=OFF; @@ -142,10 +152,10 @@ DELETE FROM t1 WHERE f1 = 5; COMMIT; SET AUTOCOMMIT=ON; -SELECT COUNT(*) = 0 FROM t1; +SELECT COUNT(*) as expect_0 FROM t1; --connection node_2 SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; -SELECT COUNT(*) = 0 FROM t1; +SELECT COUNT(*) as expect_0 FROM t1; DROP TABLE t1; # @@ -166,14 +176,15 @@ SET SESSION wsrep_on = OFF; DELETE FROM t2 WHERE f1 = 2; DELETE FROM t1 WHERE f1 = 3; SET SESSION wsrep_on = ON; +--source include/galera_wait_ready.inc --connection node_1 DELETE t1, t2 FROM t1 JOIN t2 WHERE t1.f1 = t2.f1; -SELECT COUNT(*) = 0 FROM t1; +SELECT COUNT(*) as expect_0 FROM t1; --connection node_2 SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; -SELECT COUNT(*) = 0 FROM t1; +SELECT COUNT(*) as expect_0 FROM t1; DROP TABLE t1,t2; # @@ -193,16 +204,17 @@ INSERT INTO child VALUES (1,1),(2,2),(3,3); SET SESSION wsrep_on = OFF; DELETE FROM child WHERE parent_id = 2; SET SESSION wsrep_on = ON; +--source include/galera_wait_ready.inc --connection node_1 DELETE FROM parent; -SELECT COUNT(*) = 0 FROM parent; -SELECT COUNT(*) = 0 FROM child; +SELECT COUNT(*) as expect_0 FROM parent; +SELECT COUNT(*) as expect_0 FROM child; --connection node_2 SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; -SELECT COUNT(*) = 0 FROM parent; -SELECT COUNT(*) = 0 FROM child; +SELECT COUNT(*) as expect_0 FROM parent; +SELECT COUNT(*) as expect_0 FROM child; DROP TABLE child, parent; # @@ -217,6 +229,7 @@ SET GLOBAL wsrep_ignore_apply_errors = 4; SET GLOBAL wsrep_on = OFF; CREATE TABLE t1 (f1 INTEGER); SET GLOBAL wsrep_on = ON; +--source include/galera_wait_ready.inc --connection node_1 CREATE TABLE t1 (f1 INTEGER, f2 INTEGER); DROP TABLE t1; From b710d01dc783b53ae3385492b893d8569399462d Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 25 Sep 2019 16:57:05 +0200 Subject: [PATCH 08/44] mark PAMv2 plugin stable --- plugin/auth_pam/auth_pam.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugin/auth_pam/auth_pam.c b/plugin/auth_pam/auth_pam.c index 65d71a81080..4ce9eb4c2fa 100644 --- a/plugin/auth_pam/auth_pam.c +++ b/plugin/auth_pam/auth_pam.c @@ -221,6 +221,6 @@ maria_declare_plugin(pam) NULL, vars, "2.0", - MariaDB_PLUGIN_MATURITY_GAMMA + MariaDB_PLUGIN_MATURITY_STABLE } maria_declare_plugin_end; From a5c34bc200eb38791fdba170968b72bf9139789e Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Fri, 4 Oct 2019 10:11:47 +0200 Subject: [PATCH 09/44] if the test uses example plugin, it has to check whether plugin exists --- mysql-test/include/install_plugin_if_exists.inc | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/mysql-test/include/install_plugin_if_exists.inc b/mysql-test/include/install_plugin_if_exists.inc index 93f968e8a39..c641f020deb 100644 --- a/mysql-test/include/install_plugin_if_exists.inc +++ b/mysql-test/include/install_plugin_if_exists.inc @@ -5,6 +5,10 @@ --echo # UNINSTALL IF EXISTS PLUGIN|SONAME name --echo # +if (!$HA_EXAMPLE_SO) { + skip Needs ha_example plugin; +} + select PLUGIN_NAME,PLUGIN_STATUS,PLUGIN_TYPE from information_schema.plugins where plugin_library like 'ha_example%'; INSTALL PLUGIN IF NOT EXISTS example SONAME 'ha_example'; select PLUGIN_NAME,PLUGIN_STATUS,PLUGIN_TYPE from information_schema.plugins where plugin_library like 'ha_example%'; From 37570e845bc5eb20e277340015c5fd36feb7a823 Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Fri, 4 Oct 2019 20:16:39 +0300 Subject: [PATCH 10/44] MDEV-20740: Odd computations in calculate_cond_selectivity_for_table Make SEL_ARG graph traversal code in sel_arg_range_seq_next() set max_key_parts first. (Pushing to 10.4 first) --- mysql-test/main/index_intersect_innodb.result | 8 ++++---- sql/opt_range.cc | 16 ++++++++++------ sql/opt_range_mrr.cc | 5 ++++- 3 files changed, 18 insertions(+), 11 deletions(-) diff --git a/mysql-test/main/index_intersect_innodb.result b/mysql-test/main/index_intersect_innodb.result index 854bcd75e5c..fd07f6b41c6 100644 --- a/mysql-test/main/index_intersect_innodb.result +++ b/mysql-test/main/index_intersect_innodb.result @@ -470,17 +470,17 @@ EXPLAIN SELECT * FROM City WHERE ID BETWEEN 501 AND 1000 AND Population > 700000 AND Country LIKE 'C%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City index_merge PRIMARY,Population,Country PRIMARY,Country,Population 4,7,4 NULL # Using sort_intersect(PRIMARY,Country,Population); Using where +1 SIMPLE City index_merge PRIMARY,Population,Country PRIMARY,Population,Country 4,4,7 NULL # Using sort_intersect(PRIMARY,Population,Country); Using where EXPLAIN SELECT * FROM City WHERE ID BETWEEN 1 AND 500 AND Population > 700000 AND Country LIKE 'C%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City index_merge PRIMARY,Population,Country PRIMARY,Country,Population 4,7,4 NULL # Using sort_intersect(PRIMARY,Country,Population); Using where +1 SIMPLE City index_merge PRIMARY,Population,Country PRIMARY,Population,Country 4,4,7 NULL # Using sort_intersect(PRIMARY,Population,Country); Using where EXPLAIN SELECT * FROM City WHERE ID BETWEEN 2001 AND 2500 AND Population > 300000 AND Country LIKE 'H%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City index_merge PRIMARY,Population,Country PRIMARY,Country 4,7 NULL # Using sort_intersect(PRIMARY,Country); Using where +1 SIMPLE City range PRIMARY,Population,Country Country 7 NULL # Using index condition; Using where EXPLAIN SELECT * FROM City WHERE ID BETWEEN 3701 AND 4000 AND Population > 1000000 @@ -724,7 +724,7 @@ EXPLAIN SELECT * FROM City WHERE ID BETWEEN 1 AND 500 AND Population > 700000 AND Country LIKE 'C%'; id select_type table type possible_keys key key_len ref rows Extra -1 SIMPLE City index_merge PRIMARY,Population,Country PRIMARY,Country,Population 4,7,4 NULL # Using sort_intersect(PRIMARY,Country,Population); Using where +1 SIMPLE City index_merge PRIMARY,Population,Country PRIMARY,Population,Country 4,4,7 NULL # Using sort_intersect(PRIMARY,Population,Country); Using where EXPLAIN SELECT * FROM City WHERE ID BETWEEN 3001 AND 4000 AND Population > 600000 diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 654fab7810a..c47da283e9c 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -315,7 +315,7 @@ public: */ key_map possible_keys; longlong baseflag; - uint max_key_part, range_count; + uint max_key_parts, range_count; bool quick; // Don't calulate possible keys @@ -7387,7 +7387,7 @@ static TRP_RANGE *get_key_scans_params(PARAM *param, SEL_TREE *tree, index_scan->idx= idx; index_scan->keynr= keynr; index_scan->key_info= ¶m->table->key_info[keynr]; - index_scan->used_key_parts= param->max_key_part+1; + index_scan->used_key_parts= param->max_key_parts; index_scan->range_count= param->range_count; index_scan->records= found_records; index_scan->sel_arg= key; @@ -11042,7 +11042,7 @@ ha_rows check_quick_select(PARAM *param, uint idx, bool index_only, seq.start= tree; param->range_count=0; - param->max_key_part=0; + param->max_key_parts=0; seq.is_ror_scan= TRUE; if (file->index_flags(keynr, 0, TRUE) & HA_KEY_SCAN_NOT_ROR) @@ -11055,9 +11055,13 @@ ha_rows check_quick_select(PARAM *param, uint idx, bool index_only, *mrr_flags|= HA_MRR_NO_ASSOCIATION | HA_MRR_SORTED; bool pk_is_clustered= file->primary_key_is_clustered(); + // TODO: param->max_key_parts holds 0 now, and not the #keyparts used. + // Passing wrong second argument to index_flags() makes no difference for + // most storage engines but might be an issue for MyRocks with certain + // datatypes. if (index_only && - (file->index_flags(keynr, param->max_key_part, 1) & HA_KEYREAD_ONLY) && - !(file->index_flags(keynr, param->max_key_part, 1) & HA_CLUSTERED_INDEX)) + (file->index_flags(keynr, param->max_key_parts, 1) & HA_KEYREAD_ONLY) && + !(file->index_flags(keynr, param->max_key_parts, 1) & HA_CLUSTERED_INDEX)) *mrr_flags |= HA_MRR_INDEX_ONLY; if (param->thd->lex->sql_command != SQLCOM_SELECT) @@ -11088,7 +11092,7 @@ ha_rows check_quick_select(PARAM *param, uint idx, bool index_only, if (update_tbl_stats) { param->table->quick_keys.set_bit(keynr); - param->table->quick_key_parts[keynr]= param->max_key_part+1; + param->table->quick_key_parts[keynr]= param->max_key_parts; param->table->quick_n_ranges[keynr]= param->range_count; param->table->quick_condition_rows= MY_MIN(param->table->quick_condition_rows, rows); diff --git a/sql/opt_range_mrr.cc b/sql/opt_range_mrr.cc index d3a1e155fb7..4afa06a7ca0 100644 --- a/sql/opt_range_mrr.cc +++ b/sql/opt_range_mrr.cc @@ -247,6 +247,7 @@ walk_up_n_right: uint min_key_length= (uint)(cur->min_key - seq->param->min_key); range->ptr= (char*)(intptr)(key_tree->part); + uint max_key_parts; if (cur->min_key_flag & GEOM_FLAG) { range->range_flag= cur->min_key_flag; @@ -256,9 +257,11 @@ walk_up_n_right: range->start_key.length= min_key_length; range->start_key.keypart_map= make_prev_keypart_map(cur->min_key_parts); range->start_key.flag= (ha_rkey_function) (cur->min_key_flag ^ GEOM_FLAG); + max_key_parts= cur->min_key_parts; } else { + max_key_parts= MY_MAX(cur->min_key_parts, cur->max_key_parts); range->range_flag= cur->min_key_flag | cur->max_key_flag; range->start_key.key= seq->param->min_key; @@ -336,7 +339,7 @@ walk_up_n_right: } } seq->param->range_count++; - seq->param->max_key_part=MY_MAX(seq->param->max_key_part,key_tree->part); + seq->param->max_key_parts= MY_MAX(seq->param->max_key_parts, max_key_parts); return 0; } From c3394870303090e3e58ec68f425cc46cc4762370 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Mon, 7 Oct 2019 08:47:42 +0300 Subject: [PATCH 11/44] Try to fix galera_parallel_simple test case. --- .../galera/r/galera_parallel_simple.result | 20 ++++++++++--------- .../galera/t/galera_parallel_simple.test | 14 ++++++++----- 2 files changed, 20 insertions(+), 14 deletions(-) diff --git a/mysql-test/suite/galera/r/galera_parallel_simple.result b/mysql-test/suite/galera/r/galera_parallel_simple.result index d95abefdc24..cac784cd16f 100644 --- a/mysql-test/suite/galera/r/galera_parallel_simple.result +++ b/mysql-test/suite/galera/r/galera_parallel_simple.result @@ -3,11 +3,11 @@ connection node_1; CREATE TABLE t1 (id INT) ENGINE=InnoDB; CREATE TABLE t2 (id INT) ENGINE=InnoDB; connection node_2; -SET GLOBAL wsrep_slave_threads = 2; SELECT NAME FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE 'test/t%'; NAME test/t1 test/t2 +SET GLOBAL wsrep_slave_threads = 2; LOCK TABLE t1 WRITE; connection node_1; INSERT INTO t1 VALUES (1); @@ -20,18 +20,20 @@ INSERT INTO t1 VALUES (1); INSERT INTO t2 VALUES (1); INSERT INTO t1 VALUES (1); INSERT INTO t2 VALUES (1); -INSERT INTO t1 VALUES (1); -INSERT INTO t2 VALUES (1); +INSERT INTO t1 select * from t1; +INSERT INTO t2 select * from t2; +INSERT INTO t1 select * from t1; +INSERT INTO t2 select * from t2; connection node_2; SET SESSION wsrep_sync_wait = 0; UNLOCK TABLES; SET SESSION wsrep_sync_wait = 15; -SELECT COUNT(*) = 10 FROM t1; -COUNT(*) = 10 -0 -SELECT COUNT(*) = 10 FROM t2; -COUNT(*) = 10 -0 +SELECT COUNT(*) as expect_20 FROM t1; +expect_20 +20 +SELECT COUNT(*) as expect_20 FROM t2; +expect_20 +20 SET GLOBAL wsrep_slave_threads = 1;; DROP TABLE t1; DROP TABLE t2; diff --git a/mysql-test/suite/galera/t/galera_parallel_simple.test b/mysql-test/suite/galera/t/galera_parallel_simple.test index 51bb1355ba4..d49dc0ae876 100644 --- a/mysql-test/suite/galera/t/galera_parallel_simple.test +++ b/mysql-test/suite/galera/t/galera_parallel_simple.test @@ -12,7 +12,6 @@ CREATE TABLE t1 (id INT) ENGINE=InnoDB; CREATE TABLE t2 (id INT) ENGINE=InnoDB; --connection node_2 -SET GLOBAL wsrep_slave_threads = 2; # Wait until above DDL's are replicated --let $wait_condition = SELECT COUNT(*) = 2 FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE 'test/t%'; @@ -20,6 +19,8 @@ SET GLOBAL wsrep_slave_threads = 2; SELECT NAME FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES WHERE NAME LIKE 'test/t%'; +SET GLOBAL wsrep_slave_threads = 2; + LOCK TABLE t1 WRITE; --connection node_1 @@ -38,8 +39,11 @@ INSERT INTO t2 VALUES (1); INSERT INTO t1 VALUES (1); INSERT INTO t2 VALUES (1); -INSERT INTO t1 VALUES (1); -INSERT INTO t2 VALUES (1); +INSERT INTO t1 select * from t1; +INSERT INTO t2 select * from t2; + +INSERT INTO t1 select * from t1; +INSERT INTO t2 select * from t2; --connection node_2 SET SESSION wsrep_sync_wait = 0; @@ -54,8 +58,8 @@ UNLOCK TABLES; SET SESSION wsrep_sync_wait = 15; -SELECT COUNT(*) = 10 FROM t1; -SELECT COUNT(*) = 10 FROM t2; +SELECT COUNT(*) as expect_20 FROM t1; +SELECT COUNT(*) as expect_20 FROM t2; --eval SET GLOBAL wsrep_slave_threads = $wsrep_slave_threads_orig; From adefaeffcce7c4ae0844f72dd920603b35285d40 Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Wed, 2 Oct 2019 16:04:52 +0400 Subject: [PATCH 12/44] MDEV-19536 - Server crash or ASAN heap-use-after-free in is_temporary_table / read_statistics_for_tables_if_needed Regression after 279a907, read_statistics_for_tables_if_needed() was called after open_normal_and_derived_tables() failure. Fixed by moving read_statistics_for_tables() call to a branch of get_schema_stat_record() where result of open_normal_and_derived_tables() is checked. Removed THD::force_read_stats, added read_statistics_for_tables() instead. Simplified away statistics_for_command_is_needed(). --- sql/sql_class.cc | 1 - sql/sql_class.h | 3 -- sql/sql_show.cc | 5 +-- sql/sql_statistics.cc | 83 ++++++++++++++----------------------------- sql/sql_statistics.h | 1 + 5 files changed, 29 insertions(+), 64 deletions(-) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 1a3ca54abf8..ab105c67507 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -986,7 +986,6 @@ THD::THD(bool is_wsrep_applier) memset(&invoker_host, 0, sizeof(invoker_host)); prepare_derived_at_open= FALSE; create_tmp_table_for_derived= FALSE; - force_read_stats= FALSE; save_prep_leaf_list= FALSE; /* Restore THR_THD */ set_current_thd(old_THR_THD); diff --git a/sql/sql_class.h b/sql/sql_class.h index 8a4d8ff06a3..6c622648ac7 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -2200,9 +2200,6 @@ public: */ bool create_tmp_table_for_derived; - /* The flag to force reading statistics from EITS tables */ - bool force_read_stats; - bool save_prep_leaf_list; /* container for handler's private per-connection data */ diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 71bfc644441..c154f5da472 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -4272,7 +4272,6 @@ fill_schema_table_by_open(THD *thd, bool is_show_fields_or_keys, SQLCOM_SHOW_FIELDS is used because it satisfies 'only_view_structure()'. */ - thd->force_read_stats= get_schema_table_idx(schema_table) == SCH_STATISTICS; lex->sql_command= SQLCOM_SHOW_FIELDS; result= (open_temporary_tables(thd, table_list) || open_normal_and_derived_tables(thd, table_list, @@ -4287,9 +4286,6 @@ fill_schema_table_by_open(THD *thd, bool is_show_fields_or_keys, */ lex->sql_command= old_lex->sql_command; - (void) read_statistics_for_tables_if_needed(thd, table_list); - thd->force_read_stats= false; - DEBUG_SYNC(thd, "after_open_table_ignore_flush"); /* @@ -6165,6 +6161,7 @@ static int get_schema_stat_record(THD *thd, TABLE_LIST *tables, KEY *key_info=show_table->s->key_info; if (show_table->file) { + (void) read_statistics_for_tables(thd, tables); show_table->file->info(HA_STATUS_VARIABLE | HA_STATUS_NO_LOCK | HA_STATUS_TIME); diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index e18cec589be..4a1ed9cde4e 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -2160,54 +2160,6 @@ int alloc_statistics_for_table(THD* thd, TABLE *table) } -/** - @brief - Check whether any persistent statistics for the processed command is needed - - @param - thd The thread handle - - @details - The function checks whether any persitent statistics for the processed - command is needed to be read. - - @retval - TRUE statistics is needed to be read - @retval - FALSE Otherwise -*/ - -static -inline bool statistics_for_command_is_needed(THD *thd) -{ - if (thd->bootstrap || thd->variables.use_stat_tables == NEVER) - return FALSE; - - if (thd->force_read_stats) - return TRUE; - - switch(thd->lex->sql_command) { - case SQLCOM_SELECT: - case SQLCOM_INSERT: - case SQLCOM_INSERT_SELECT: - case SQLCOM_UPDATE: - case SQLCOM_UPDATE_MULTI: - case SQLCOM_DELETE: - case SQLCOM_DELETE_MULTI: - case SQLCOM_REPLACE: - case SQLCOM_REPLACE_SELECT: - case SQLCOM_CREATE_TABLE: - case SQLCOM_SET_OPTION: - case SQLCOM_DO: - break; - default: - return FALSE; - } - - return TRUE; -} - - /** @brief Allocate memory for the statistical data used by a table share @@ -2255,9 +2207,6 @@ static int alloc_statistics_for_table_share(THD* thd, TABLE_SHARE *table_share) DEBUG_SYNC(thd, "statistics_mem_alloc_start1"); DEBUG_SYNC(thd, "statistics_mem_alloc_start2"); - if (!statistics_for_command_is_needed(thd)) - DBUG_RETURN(1); - mysql_mutex_lock(&table_share->LOCK_share); if (stats_cb->stats_can_be_read) @@ -3110,9 +3059,6 @@ bool statistics_for_tables_is_needed(THD *thd, TABLE_LIST *tables) { if (!tables) return FALSE; - - if (!statistics_for_command_is_needed(thd)) - return FALSE; /* Do not read statistics for any query that explicity involves @@ -3244,15 +3190,40 @@ int read_histograms_for_table(THD *thd, TABLE *table, TABLE_LIST *stat_tables) */ int read_statistics_for_tables_if_needed(THD *thd, TABLE_LIST *tables) +{ + switch (thd->lex->sql_command) { + case SQLCOM_SELECT: + case SQLCOM_INSERT: + case SQLCOM_INSERT_SELECT: + case SQLCOM_UPDATE: + case SQLCOM_UPDATE_MULTI: + case SQLCOM_DELETE: + case SQLCOM_DELETE_MULTI: + case SQLCOM_REPLACE: + case SQLCOM_REPLACE_SELECT: + case SQLCOM_CREATE_TABLE: + case SQLCOM_SET_OPTION: + case SQLCOM_DO: + return read_statistics_for_tables(thd, tables); + default: + return 0; + } +} + + +int read_statistics_for_tables(THD *thd, TABLE_LIST *tables) { TABLE_LIST stat_tables[STATISTICS_TABLES]; Open_tables_backup open_tables_backup; - DBUG_ENTER("read_statistics_for_tables_if_needed"); + DBUG_ENTER("read_statistics_for_tables"); + + if (thd->bootstrap || thd->variables.use_stat_tables == NEVER) + DBUG_RETURN(0); for (TABLE_LIST *tl= tables; tl; tl= tl->next_global) { - if (get_use_stat_tables_mode(thd) > NEVER && tl->table) + if (tl->table) { TABLE_SHARE *table_share= tl->table->s; if (table_share && table_share->table_category == TABLE_CATEGORY_USER && diff --git a/sql/sql_statistics.h b/sql/sql_statistics.h index 968f77cd2ca..71d727eab07 100644 --- a/sql/sql_statistics.h +++ b/sql/sql_statistics.h @@ -89,6 +89,7 @@ Use_stat_tables_mode get_use_stat_tables_mode(THD *thd) } int read_statistics_for_tables_if_needed(THD *thd, TABLE_LIST *tables); +int read_statistics_for_tables(THD *thd, TABLE_LIST *tables); int collect_statistics_for_table(THD *thd, TABLE *table); void delete_stat_values_for_table_share(TABLE_SHARE *table_share); int alloc_statistics_for_table(THD *thd, TABLE *table); From db9a4d928dc8e81ce449b54ef0bf02c248d931d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 7 Oct 2019 17:18:10 +0300 Subject: [PATCH 13/44] Remove orphan declaration buf_flush_wait_batch_end_wait_only() The function was declared but not defined in commit 9d6d1902e091c868bb288e0ccf9f975ccb474db9 --- storage/innobase/include/buf0flu.h | 11 ----------- storage/xtradb/include/buf0flu.h | 11 ----------- 2 files changed, 22 deletions(-) diff --git a/storage/innobase/include/buf0flu.h b/storage/innobase/include/buf0flu.h index b5cfcb125e6..4cc26be3918 100644 --- a/storage/innobase/include/buf0flu.h +++ b/storage/innobase/include/buf0flu.h @@ -141,17 +141,6 @@ buf_flush_wait_batch_end( buf_pool_t* buf_pool, /*!< in: buffer pool instance */ enum buf_flush type); /*!< in: BUF_FLUSH_LRU or BUF_FLUSH_LIST */ -/******************************************************************//** -Waits until a flush batch of the given type ends. This is called by -a thread that only wants to wait for a flush to end but doesn't do -any flushing itself. */ -UNIV_INTERN -void -buf_flush_wait_batch_end_wait_only( -/*===============================*/ - buf_pool_t* buf_pool, /*!< in: buffer pool instance */ - enum buf_flush type); /*!< in: BUF_FLUSH_LRU - or BUF_FLUSH_LIST */ /********************************************************************//** This function should be called at a mini-transaction commit, if a page was modified in it. Puts the block to the list of modified blocks, if it not diff --git a/storage/xtradb/include/buf0flu.h b/storage/xtradb/include/buf0flu.h index ed01b627bf4..83d4dae7f1c 100644 --- a/storage/xtradb/include/buf0flu.h +++ b/storage/xtradb/include/buf0flu.h @@ -143,17 +143,6 @@ buf_flush_wait_batch_end( buf_pool_t* buf_pool, /*!< in: buffer pool instance */ enum buf_flush type); /*!< in: BUF_FLUSH_LRU or BUF_FLUSH_LIST */ -/******************************************************************//** -Waits until a flush batch of the given type ends. This is called by -a thread that only wants to wait for a flush to end but doesn't do -any flushing itself. */ -UNIV_INTERN -void -buf_flush_wait_batch_end_wait_only( -/*===============================*/ - buf_pool_t* buf_pool, /*!< in: buffer pool instance */ - enum buf_flush type); /*!< in: BUF_FLUSH_LRU - or BUF_FLUSH_LIST */ /********************************************************************//** This function should be called at a mini-transaction commit, if a page was modified in it. Puts the block to the list of modified blocks, if it not From 01bf9f8c3da905e0920a9b1f7cc5a0e0ee6eef2f Mon Sep 17 00:00:00 2001 From: Sachin Date: Sat, 14 Sep 2019 12:53:36 +0530 Subject: [PATCH 14/44] MDEV-20591 Wrong Number of rows in mysqlbinlog output calc_field_event_length should accurately calculate the size of BLOB type fields, Instead of returning just the bytes taken by length it should return length bytes + actual length. --- .../binlog/r/binlog_mysqlbinlog_row.result | 55 ++++++++++++++++++- .../binlog/t/binlog_mysqlbinlog_row.test | 13 +++++ sql/log_event.cc | 11 +++- 3 files changed, 75 insertions(+), 4 deletions(-) diff --git a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row.result b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row.result index 2af8b805be8..0cc1805eadc 100644 --- a/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row.result +++ b/mysql-test/suite/binlog/r/binlog_mysqlbinlog_row.result @@ -327,6 +327,14 @@ INSERT INTO t2 SET a=1; INSERT INTO t2 SET b=1; UPDATE t1, t2 SET t1.a=10, t2.a=20; DROP TABLE t1,t2; +# +# MDEV-20591 Wrong Number of rows in mysqlbinlog output. +# +CREATE TABLE t1(c_char_utf8 CHAR(10) , +c_varchar_utf8 char(10) , +c_text_utf8 blob ); +INSERT into t1 values("B", "B", REPEAT("#", 2000)); +drop table t1; flush logs; INSERT INTO t1dec102 VALUES (-999.99); INSERT INTO t1dec102 VALUES (0); @@ -5274,6 +5282,47 @@ SET TIMESTAMP=1000000000/*!*/; DROP TABLE `t1`,`t2` /* generated by server */ /*!*/; # at # +#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX GTID 0-1-317 ddl +/*!100001 SET @@session.gtid_seq_no=317*//*!*/; +# at # +#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +CREATE TABLE t1(c_char_utf8 CHAR(10) , +c_varchar_utf8 char(10) , +c_text_utf8 blob ) +/*!*/; +# at # +#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX GTID 0-1-318 +/*!100001 SET @@session.gtid_seq_no=318*//*!*/; +BEGIN +/*!*/; +# at # +# at # +#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Annotate_rows: +#Q> INSERT into t1 values("B", "B", REPEAT("#", 2000)) +#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Table_map: `test`.`t1` mapped to number # +# at # +#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Write_rows: table id # flags: STMT_END_F +### INSERT INTO `test`.`t1` +### SET +### @1='B' /* STRING(10) meta=65034 nullable=1 is_null=0 */ +### @2='B' /* STRING(10) meta=65034 nullable=1 is_null=0 */ +### @3='################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################################' /* BLOB/TEXT meta=2 nullable=1 is_null=0 */ +# Number of rows: 1 +# at # +#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +COMMIT +/*!*/; +# at # +#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX GTID 0-1-319 ddl +/*!100001 SET @@session.gtid_seq_no=319*//*!*/; +# at # +#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Query thread_id=# exec_time=# error_code=0 +SET TIMESTAMP=1000000000/*!*/; +DROP TABLE `t1` /* generated by server */ +/*!*/; +# at # #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Rotate to master-bin.000002 pos: 4 DELIMITER ; # End of log file @@ -5287,17 +5336,17 @@ DELIMITER /*!*/; # at # #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Start: binlog v 4, server v #.##.## created 010909 4:46:40 # at # -#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Gtid list [0-1-316] +#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Gtid list [0-1-319] # at # #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Binlog checkpoint master-bin.000001 # at # #010909 4:46:40 server id 1 end_log_pos # CRC32 XXX Binlog checkpoint master-bin.000002 # at # -#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX GTID 0-1-317 +#010909 4:46:40 server id 1 end_log_pos # CRC32 XXX GTID 0-1-320 /*!100101 SET @@session.skip_parallel_replication=0*//*!*/; /*!100001 SET @@session.gtid_domain_id=0*//*!*/; /*!100001 SET @@session.server_id=1*//*!*/; -/*!100001 SET @@session.gtid_seq_no=317*//*!*/; +/*!100001 SET @@session.gtid_seq_no=320*//*!*/; BEGIN /*!*/; # at # diff --git a/mysql-test/suite/binlog/t/binlog_mysqlbinlog_row.test b/mysql-test/suite/binlog/t/binlog_mysqlbinlog_row.test index 3146330f0cd..add977bf07a 100644 --- a/mysql-test/suite/binlog/t/binlog_mysqlbinlog_row.test +++ b/mysql-test/suite/binlog/t/binlog_mysqlbinlog_row.test @@ -438,6 +438,18 @@ INSERT INTO t2 SET b=1; UPDATE t1, t2 SET t1.a=10, t2.a=20; DROP TABLE t1,t2; +--echo # +--echo # MDEV-20591 Wrong Number of rows in mysqlbinlog output. +--echo # + +CREATE TABLE t1(c_char_utf8 CHAR(10) , + c_varchar_utf8 char(10) , + c_text_utf8 blob ); + +INSERT into t1 values("B", "B", REPEAT("#", 2000)); + +drop table t1; + flush logs; let $MYSQLD_DATADIR= `select @@datadir`; @@ -462,3 +474,4 @@ flush logs; --replace_regex /SQL_LOAD_MB-[0-9]-[0-9]/SQL_LOAD_MB-#-#/ /exec_time=[0-9]*/exec_time=#/ /end_log_pos [0-9]*/end_log_pos #/ /# at [0-9]*/# at #/ /thread_id=[0-9]*/thread_id=#/ /table id [0-9]*/table id #/ /mapped to number [0-9]*/mapped to number #/ /server v [^ ]*/server v #.##.##/ /(@[0-9]*=[0-9]*[.][0-9]{1,3})[0-9e+-]*[^ ]*(.*(FLOAT|DOUBLE).*[*].)/\1...\2/ /CRC32 0x[0-9a-f]*/CRC32 XXX/ --error 1 --exec $MYSQL_BINLOG --base64-output=decode-rows -v -v $MYSQLD_DATADIR/master-bin.000002 2>&1 + diff --git a/sql/log_event.cc b/sql/log_event.cc index ce4d57329c7..369e9229d03 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -3423,7 +3423,16 @@ static size_t calc_field_event_length(const uchar *ptr, uint type, uint meta) case MYSQL_TYPE_SET: return meta & 0xFF; case MYSQL_TYPE_BLOB: - return (meta <= 4 ? meta : 0); + if (meta > 4 ) + return 0; + if (meta == 1) + return *ptr + 1; + if (meta == 2) + return uint2korr(ptr) + 2; + if (meta == 3) + return uint3korr(ptr) + 3; + if (meta == 4) + return uint4korr(ptr) + 4; case MYSQL_TYPE_VARCHAR: case MYSQL_TYPE_VAR_STRING: length= meta; From 1e0f09cacbb05eec95078e10df1ea610736b9c1a Mon Sep 17 00:00:00 2001 From: sachin Date: Thu, 17 May 2018 14:40:55 +0530 Subject: [PATCH 15/44] MDEV-16239 Many test in rpl suite fails Fix rpl_skip_error test. We cant reset Slave_skipped_errors(even with FLUSH STATUS), So instead of absolute slave_skipped_errors we look for delta of slave_skipped_errors Fix rpl.rpl_binlog_errors and binlog_encryption.rpl_binlog_errors We create the $load_file and $load_file2 but we never remove them. Fix rpl_000011.test Instead of real value use delta value , Since flush status wont flush LONGLONG variable. Fix rpl_row_find_row_debug Instead of searching whole log_error_ file we will use search_pattern_in_file which runs pattern search only on latest test run , instead of full file. Fix rpl_ip_mix rpl_ip_mix2 We should call reset slave all because we also want to reset master_host otherwise show slave status wont be empty and making repeat N a failure. Fix rpl_rotate_logs First we have to remove master.info file (cleanup) and second we have to call reset slave all because if we do not call reset slave all then we wont read master.info file beacuse we already have master config in memory. And this makes start slave to pass , which shoud fail becuase its permision is 000 Fix circular_serverid0 test The reason is that ++dbug_rows_event_count == 2 in queue_event does not take --repeat into account. So I have reseted the dbug_rows_event_count in if body. --- .../suite/rpl/include/rpl_binlog_errors.inc | 2 ++ mysql-test/suite/rpl/r/rpl_000011.result | 10 ++++------ mysql-test/suite/rpl/r/rpl_ip_mix.result | 2 ++ mysql-test/suite/rpl/r/rpl_ip_mix2.result | 2 ++ mysql-test/suite/rpl/r/rpl_rotate_logs.result | 2 ++ .../suite/rpl/r/rpl_row_find_row_debug.result | 3 ++- mysql-test/suite/rpl/r/rpl_skip_error.result | 10 ++++------ mysql-test/suite/rpl/t/rpl_000011.test | 20 +++++++++---------- mysql-test/suite/rpl/t/rpl_ip_mix.test | 2 ++ mysql-test/suite/rpl/t/rpl_ip_mix2.test | 2 ++ mysql-test/suite/rpl/t/rpl_rotate_logs.test | 4 ++++ .../suite/rpl/t/rpl_row_find_row_debug.test | 15 +++++--------- mysql-test/suite/rpl/t/rpl_skip_error.test | 14 ++++++++++--- sql/slave.cc | 1 + 14 files changed, 53 insertions(+), 36 deletions(-) diff --git a/mysql-test/suite/rpl/include/rpl_binlog_errors.inc b/mysql-test/suite/rpl/include/rpl_binlog_errors.inc index 46c76f2b04c..72f8bc053e3 100644 --- a/mysql-test/suite/rpl/include/rpl_binlog_errors.inc +++ b/mysql-test/suite/rpl/include/rpl_binlog_errors.inc @@ -431,5 +431,7 @@ call mtr.add_suppression("Can't generate a unique log-filename .*"); -- source include/stop_slave_sql.inc RESET SLAVE; RESET MASTER; +--remove_file $load_file +--remove_file $load_file2 --let $rpl_only_running_threads= 1 --source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_000011.result b/mysql-test/suite/rpl/r/rpl_000011.result index 136a6a3aacb..eb0d89bd3cb 100644 --- a/mysql-test/suite/rpl/r/rpl_000011.result +++ b/mysql-test/suite/rpl/r/rpl_000011.result @@ -1,15 +1,13 @@ include/master-slave.inc [connection master] +connection slave; +connection master; create table t1 (n int); insert into t1 values(1); connection slave; -show global status like 'com_insert'; -Variable_name Value -Com_insert 1 +# Com_insert = 1 stop slave; -show global status like 'com_insert'; -Variable_name Value -Com_insert 1 +# Com_insert = 1 include/wait_for_slave_to_stop.inc start slave; include/wait_for_slave_to_start.inc diff --git a/mysql-test/suite/rpl/r/rpl_ip_mix.result b/mysql-test/suite/rpl/r/rpl_ip_mix.result index e139f863c8a..cc11f481991 100644 --- a/mysql-test/suite/rpl/r/rpl_ip_mix.result +++ b/mysql-test/suite/rpl/r/rpl_ip_mix.result @@ -64,3 +64,5 @@ Master-Host: 127.0.0.1 change master to master_host='0:0:0:0:0:0:0:1'; Master-Host: 0:0:0:0:0:0:0:1 CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root'; +connection slave; +reset slave all; diff --git a/mysql-test/suite/rpl/r/rpl_ip_mix2.result b/mysql-test/suite/rpl/r/rpl_ip_mix2.result index 70599d097a7..d304eff9ab4 100644 --- a/mysql-test/suite/rpl/r/rpl_ip_mix2.result +++ b/mysql-test/suite/rpl/r/rpl_ip_mix2.result @@ -64,3 +64,5 @@ Master-Host: 127.0.0.1 change master to master_host='0:0:0:0:0:0:0:1'; Master-Host: 0:0:0:0:0:0:0:1 CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root'; +connection slave; +reset slave all; diff --git a/mysql-test/suite/rpl/r/rpl_rotate_logs.result b/mysql-test/suite/rpl/r/rpl_rotate_logs.result index 82f6f537329..2518b207111 100644 --- a/mysql-test/suite/rpl/r/rpl_rotate_logs.result +++ b/mysql-test/suite/rpl/r/rpl_rotate_logs.result @@ -128,4 +128,6 @@ show binlog events in ''; ERROR HY000: Error when executing command SHOW BINLOG EVENTS: Could not find target log purge master logs before now(); End of 5.0 tests +#cleanup include/stop_slave.inc +reset slave all; diff --git a/mysql-test/suite/rpl/r/rpl_row_find_row_debug.result b/mysql-test/suite/rpl/r/rpl_row_find_row_debug.result index 491fb68615c..269dc16733a 100644 --- a/mysql-test/suite/rpl/r/rpl_row_find_row_debug.result +++ b/mysql-test/suite/rpl/r/rpl_row_find_row_debug.result @@ -15,7 +15,8 @@ DELETE FROM t1; DROP TABLE t1; connection slave; # Check if any note related to long DELETE_ROWS and UPDATE_ROWS appears in the error log -Occurrences: update=1, delete=1 +FOUND 1 /The slave is applying a ROW event on behalf of an UPDATE statement on table t1 and is currently taking a considerable amount/ in mysqld.2.err +FOUND 1 /The slave is applying a ROW event on behalf of a DELETE statement on table t1 and is currently taking a considerable amount/ in mysqld.2.err include/stop_slave.inc SET GLOBAL debug_dbug = ''; SET GLOBAL log_warnings = 2; diff --git a/mysql-test/suite/rpl/r/rpl_skip_error.result b/mysql-test/suite/rpl/r/rpl_skip_error.result index 7d351339925..0172336a99c 100644 --- a/mysql-test/suite/rpl/r/rpl_skip_error.result +++ b/mysql-test/suite/rpl/r/rpl_skip_error.result @@ -1,5 +1,7 @@ include/master-slave.inc [connection master] +connection slave; +connection master; ==== Test Without sql_mode=strict_trans_tables ==== create table t1 (n int not null primary key); connection slave; @@ -105,9 +107,7 @@ t2 CREATE TABLE `t2` ( `data` int(11) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=MyISAM DEFAULT CHARSET=latin1 -show global status like 'slave_skipped_errors'; -Variable_name Value -Slave_skipped_errors 4 +# Slave_skipped_errros = 4 connection master; INSERT INTO t2 VALUES(1, 1); INSERT INTO t2 VALUES(2, 1); @@ -119,9 +119,7 @@ SET SQL_LOG_BIN=1; UPDATE t2 SET id= id + 3, data = 2; connection slave; -show global status like 'slave_skipped_errors'; -Variable_name Value -Slave_skipped_errors 5 +# Slave_skipped_errros = 5 **** We cannot execute a select as there are differences in the **** behavior between STMT and RBR. ==== Clean Up ==== diff --git a/mysql-test/suite/rpl/t/rpl_000011.test b/mysql-test/suite/rpl/t/rpl_000011.test index 216e568fc42..289b79f7de8 100644 --- a/mysql-test/suite/rpl/t/rpl_000011.test +++ b/mysql-test/suite/rpl/t/rpl_000011.test @@ -5,19 +5,19 @@ # source include/master-slave.inc; - +--connection slave +let $initial_com_insert= query_get_value(show global status like "Com_insert", Value, 1); +--connection master create table t1 (n int); insert into t1 values(1); -sync_slave_with_master; -show global status like 'com_insert'; +sync_slave_with_master; +let $current_com_insert= query_get_value(show global status like "Com_insert", Value, 1); +--let $delta_com_insert= `select $current_com_insert - $initial_com_insert from dual` +--echo # Com_insert = $delta_com_insert stop slave; -# Temporary work-around for bug MDEV-8301. There is a small window during -# thread exit where the local status values of a thread are counted twice -# in the global status. Remove this wait_condition.inc once MDEV-8301 is -# fixed. ---let $wait_condition= SELECT variable_value=1 FROM information_schema.global_status WHERE variable_name="Com_insert"; ---source include/wait_condition.inc -show global status like 'com_insert'; +let $current_com_insert= query_get_value(show global status like "Com_insert", Value, 1); +--let $delta_com_insert= `select $current_com_insert - $initial_com_insert from dual` +--echo # Com_insert = $delta_com_insert --source include/wait_for_slave_to_stop.inc start slave; --source include/wait_for_slave_to_start.inc diff --git a/mysql-test/suite/rpl/t/rpl_ip_mix.test b/mysql-test/suite/rpl/t/rpl_ip_mix.test index 3ddbd598334..63c5fa9251c 100644 --- a/mysql-test/suite/rpl/t/rpl_ip_mix.test +++ b/mysql-test/suite/rpl/t/rpl_ip_mix.test @@ -44,3 +44,5 @@ let $master_host= query_get_value(SHOW SLAVE STATUS, Master_Host, 1); # clean up CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root'; +--connection slave +reset slave all; diff --git a/mysql-test/suite/rpl/t/rpl_ip_mix2.test b/mysql-test/suite/rpl/t/rpl_ip_mix2.test index feaf4af44cf..3fff54e52bf 100644 --- a/mysql-test/suite/rpl/t/rpl_ip_mix2.test +++ b/mysql-test/suite/rpl/t/rpl_ip_mix2.test @@ -45,3 +45,5 @@ let $master_host= query_get_value(SHOW SLAVE STATUS, Master_Host, 1); # clean up CHANGE MASTER TO MASTER_HOST='127.0.0.1', MASTER_USER='root'; +connection slave; +reset slave all; diff --git a/mysql-test/suite/rpl/t/rpl_rotate_logs.test b/mysql-test/suite/rpl/t/rpl_rotate_logs.test index 358c0be5b3b..0d65a05bf50 100644 --- a/mysql-test/suite/rpl/t/rpl_rotate_logs.test +++ b/mysql-test/suite/rpl/t/rpl_rotate_logs.test @@ -193,4 +193,8 @@ show binlog events in ''; purge master logs before now(); --echo End of 5.0 tests +--echo #cleanup + +--remove_file $MYSQLD_SLAVE_DATADIR/master.info --source include/stop_slave.inc +reset slave all; diff --git a/mysql-test/suite/rpl/t/rpl_row_find_row_debug.test b/mysql-test/suite/rpl/t/rpl_row_find_row_debug.test index fb7491b0077..9c0ee1cdbbb 100644 --- a/mysql-test/suite/rpl/t/rpl_row_find_row_debug.test +++ b/mysql-test/suite/rpl/t/rpl_row_find_row_debug.test @@ -42,16 +42,11 @@ DROP TABLE t1; --sync_slave_with_master --echo # Check if any note related to long DELETE_ROWS and UPDATE_ROWS appears in the error log -perl; - use strict; - my $log_error= $ENV{'LOG_ERROR'} or die "LOG_ERROR not set"; - open(FILE, "$log_error") or die("Unable to open $log_error: $!\n"); - my $upd_count = () = grep(/The slave is applying a ROW event on behalf of an UPDATE statement on table t1 and is currently taking a considerable amount/g,); - seek(FILE, 0, 0) or die "Can't seek to beginning of file: $!"; - my $del_count = () = grep(/The slave is applying a ROW event on behalf of a DELETE statement on table t1 and is currently taking a considerable amount/g,); - print "Occurrences: update=$upd_count, delete=$del_count\n"; - close(FILE); -EOF +--let SEARCH_FILE=$log_error_ +--let SEARCH_PATTERN=The slave is applying a ROW event on behalf of an UPDATE statement on table t1 and is currently taking a considerable amount +--source include/search_pattern_in_file.inc +--let SEARCH_PATTERN=The slave is applying a ROW event on behalf of a DELETE statement on table t1 and is currently taking a considerable amount +--source include/search_pattern_in_file.inc # cleanup --source include/stop_slave.inc diff --git a/mysql-test/suite/rpl/t/rpl_skip_error.test b/mysql-test/suite/rpl/t/rpl_skip_error.test index fa8eeb73fba..d3ef834e8ec 100644 --- a/mysql-test/suite/rpl/t/rpl_skip_error.test +++ b/mysql-test/suite/rpl/t/rpl_skip_error.test @@ -26,6 +26,10 @@ source include/have_innodb.inc; source include/master-slave.inc; +--connection slave +let $initial_skipped_error= query_get_value(show global status like "Slave_skipped_errors", Value, 1); + +connection master; --echo ==== Test Without sql_mode=strict_trans_tables ==== create table t1 (n int not null primary key); @@ -133,8 +137,9 @@ connection slave; CREATE TABLE t2(id INT NOT NULL PRIMARY KEY, data INT) Engine=MyIsam; SHOW CREATE TABLE t2; -show global status like 'slave_skipped_errors'; - +let $current_skipped_error= query_get_value(show global status like "Slave_skipped_errors", Value, 1); +--let $delta_skipped_error= `select $current_skipped_error - $initial_skipped_error from dual` +--echo # Slave_skipped_errros = $delta_skipped_error connection master; INSERT INTO t2 VALUES(1, 1); @@ -151,7 +156,10 @@ sync_slave_with_master; let $error= query_get_value("SHOW SLAVE STATUS", Last_SQL_Error, 1); echo $error; -show global status like 'slave_skipped_errors'; + +let $current_skipped_error= query_get_value(show global status like "Slave_skipped_errors", Value, 1); +--let $delta_skipped_error= `select $current_skipped_error - $initial_skipped_error from dual` +--echo # Slave_skipped_errros = $delta_skipped_error --echo **** We cannot execute a select as there are differences in the --echo **** behavior between STMT and RBR. diff --git a/sql/slave.cc b/sql/slave.cc index 165aa20b1ee..7a9882de507 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -6214,6 +6214,7 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len) DBUG_ASSERT(debug_sync_service); DBUG_ASSERT(!debug_sync_set_action(current_thd, STRING_WITH_LEN(act))); + dbug_rows_event_count = 0; };); #endif mysql_mutex_lock(&mi->data_lock); From 27664ef29d97be2973982aedcc0c8c90d18b20a4 Mon Sep 17 00:00:00 2001 From: Sachin Setiya Date: Thu, 26 Sep 2019 15:05:55 +0530 Subject: [PATCH 16/44] MDEV-20574 Position of events reported by mysqlbinlog is wrong with encrypted binlogs, SHOW BINLOG EVENTS reports the correct one. Analysis Mysqlbinlog output for encrypted binary log #Q> insert into tab1 values (3,'row 003') #190912 17:36:35 server id 10221 end_log_pos 980 CRC32 0x53bcb3d3 Table_map: `test`.`tab1` mapped to number 19 # at 940 #190912 17:36:35 server id 10221 end_log_pos 1026 CRC32 0xf2ae5136 Write_rows: table id 19 flags: STMT_END_F Here we can see Table_map_log_event ends at 980 but Next event starts at 940. And the reason for that is we do not send START_ENCRYPTION_EVENT to the slave Solution:- Send Start_encryption_log_event as Ignorable_log_event to slave(mysqlbinlog), So that mysqlbinlog can update its log_pos. Since Slave can request multiple FORMAT_DESCRIPTION_EVENT while master does not have so We only update slave master pos when master actually have the FORMAT_DESCRIPTION_EVENT. Similar logic should be applied for START_ENCRYPTION_EVENT. Also added the test case when new server reads the data from old server which does not send START_ENCRYPTION_EVENT to slave. Master Slave Upgrade Scenario. When Slave is updated first, Slave will have extra logic of handling START_ENCRYPTION_EVENT But master willnot be sending START_ENCRYPTION_EVENT. So there will be no issue. When Master is updated first, It will send START_ENCRYPTION_EVENT to slave , But slave will ignore this event in queue_event. --- mysql-test/std_data/binlog_before_20574.bin | Bin 0 -> 1022 bytes .../binlog_mdev_20574_old_binlog.result | 27 ++++++++ .../binlog_mdev_20574_old_binlog.test | 46 +++++++++++++ .../binlog_row_annotate.result | 9 +++ .../binlog_encryption/mysqlbinlog.result | 1 + .../suite/binlog_encryption/mysqlbinlog.test | 3 + sql/log_event.cc | 34 +++++----- sql/slave.cc | 11 +++ sql/sql_repl.cc | 63 ++++++++++++------ 9 files changed, 159 insertions(+), 35 deletions(-) create mode 100644 mysql-test/std_data/binlog_before_20574.bin create mode 100644 mysql-test/suite/binlog_encryption/binlog_mdev_20574_old_binlog.result create mode 100644 mysql-test/suite/binlog_encryption/binlog_mdev_20574_old_binlog.test diff --git a/mysql-test/std_data/binlog_before_20574.bin b/mysql-test/std_data/binlog_before_20574.bin new file mode 100644 index 0000000000000000000000000000000000000000..596a883dc71f71a807047ec0073578dbe60eee43 GIT binary patch literal 1022 zcmeyDl$pmQJ~@`3k%58X4-hi|8H@}p42A}JMtVjTy1t1;nTak=x+$qirRlmk`RO1v zSOLfwVGCXc4hA6x79bE}V0gm7BEwZ$*Vk|hV+bAwx{eiV?(p0s@d%Oiz&$qAN{q;@W?_F-X zKz$c?ED>B1bfIR>z1t}Q%KL4~c&cPW>fM-9_MJD$Zs-xrd@+&j&3Y>lPXnOhTB!vy zmd|7|V8fmEtJ2%pl8#Bz4Zn{%z6K=qrC`hA`J zfQc^sqCU(a3i&g^(Xb63H=>zjKXulPR2pfSC5 z%|VuB>w*n|DsLVv-k$x^?^?CR=?-Vb^A{$sTGP4etG&#NHKCWc@?~fg+FfqT$o9;Y zHn@K+5*z>mN1LA>aW$O~zTsx~7W=;FZO^VITiWwo@j9e=Pip@Mo0g}`mntj!*Qo(b zUuL+SA>sKS$1~>Zzx==d!_y^ZRmi96o CKX*0& literal 0 HcmV?d00001 diff --git a/mysql-test/suite/binlog_encryption/binlog_mdev_20574_old_binlog.result b/mysql-test/suite/binlog_encryption/binlog_mdev_20574_old_binlog.result new file mode 100644 index 00000000000..cf660297640 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/binlog_mdev_20574_old_binlog.result @@ -0,0 +1,27 @@ +include/master-slave.inc +[connection master] +connection slave; +include/stop_slave.inc +connection master; +include/rpl_stop_server.inc [server_number=1] +# Data in binlog +# CREATE TABLE t1 (a INT); +# INSERT INTO t1 VALUES (1),(2),(3); +# REPLACE INTO t1 VALUES (4); +include/rpl_start_server.inc [server_number=1] +connection slave; +RESET SLAVE; +RESET MASTER; +CHANGE MASTER TO master_host='127.0.0.1', master_port=SERVER_MYPORT_1, master_user='root', master_log_file='master-bin.000001', master_log_pos=4; +include/start_slave.inc +DESC t1; +Field Type Null Key Default Extra +a int(11) YES NULL +SELECT * FROM t1 ORDER BY a; +a +1 +2 +3 +4 +DROP TABLE t1; +include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/binlog_mdev_20574_old_binlog.test b/mysql-test/suite/binlog_encryption/binlog_mdev_20574_old_binlog.test new file mode 100644 index 00000000000..417df631878 --- /dev/null +++ b/mysql-test/suite/binlog_encryption/binlog_mdev_20574_old_binlog.test @@ -0,0 +1,46 @@ +# MDEV-20574 Position of events reported by mysqlbinlog is wrong with encrypted binlogs, SHOW BINLOG EVENTS reports the correct one. +# Test replicating off old master. +# Test case Desc:- When new server reads the data from old server binlog which +# does not send START_ENCRYPTION_EVENT to slave. +# We simulate old master by copying in pre-generated binlog files from earlier +# server versions with encrypted binlog. +--source include/have_binlog_format_row.inc +--source include/master-slave.inc +--source include/have_innodb.inc + +--connection slave +--source include/stop_slave.inc + +--connection master +--let $datadir= `SELECT @@datadir` + +--let $rpl_server_number= 1 +--source include/rpl_stop_server.inc + +--remove_file $datadir/master-bin.000001 +--remove_file $datadir/master-bin.state +--echo # Data in binlog +--echo # CREATE TABLE t1 (a INT); +--echo # INSERT INTO t1 VALUES (1),(2),(3); +--echo # REPLACE INTO t1 VALUES (4); + +--copy_file $MYSQL_TEST_DIR/std_data/binlog_before_20574.bin $datadir/master-bin.000001 + +--let $rpl_server_number= 1 +--source include/rpl_start_server.inc + +--source include/wait_until_connected_again.inc +--save_master_pos + +--connection slave +RESET SLAVE; +RESET MASTER; +--replace_result $SERVER_MYPORT_1 SERVER_MYPORT_1 +eval CHANGE MASTER TO master_host='127.0.0.1', master_port=$SERVER_MYPORT_1, master_user='root', master_log_file='master-bin.000001', master_log_pos=4; +--source include/start_slave.inc +--sync_with_master +DESC t1; +SELECT * FROM t1 ORDER BY a; + +DROP TABLE t1; +--source include/rpl_end.inc diff --git a/mysql-test/suite/binlog_encryption/binlog_row_annotate.result b/mysql-test/suite/binlog_encryption/binlog_row_annotate.result index 88c690a8bb7..9b843dc8a6b 100644 --- a/mysql-test/suite/binlog_encryption/binlog_row_annotate.result +++ b/mysql-test/suite/binlog_encryption/binlog_row_annotate.result @@ -104,6 +104,9 @@ DELIMITER /*!*/; #010909 4:46:40 server id # end_log_pos # Start: binlog v 4, server v #.##.## created 010909 4:46:40 at startup ROLLBACK/*!*/; # at # +#010909 4:46:40 server id # end_log_pos # Ignorable +# Ignorable event type 164 (Start_encryption) +# at # #010909 4:46:40 server id # end_log_pos # Gtid list [] # at # #010909 4:46:40 server id # end_log_pos # Binlog checkpoint master-bin.000001 @@ -336,6 +339,9 @@ DELIMITER /*!*/; #010909 4:46:40 server id # end_log_pos # Start: binlog v 4, server v #.##.## created 010909 4:46:40 at startup ROLLBACK/*!*/; # at # +#010909 4:46:40 server id # end_log_pos # Ignorable +# Ignorable event type 164 (Start_encryption) +# at # #010909 4:46:40 server id # end_log_pos # Gtid list [] # at # #010909 4:46:40 server id # end_log_pos # Binlog checkpoint master-bin.000001 @@ -495,6 +501,9 @@ DELIMITER /*!*/; #010909 4:46:40 server id # end_log_pos # Start: binlog v 4, server v #.##.## created 010909 4:46:40 at startup ROLLBACK/*!*/; # at # +#010909 4:46:40 server id # end_log_pos # Ignorable +# Ignorable event type 164 (Start_encryption) +# at # #010909 4:46:40 server id # end_log_pos # Gtid list [] # at # #010909 4:46:40 server id # end_log_pos # Binlog checkpoint master-bin.000001 diff --git a/mysql-test/suite/binlog_encryption/mysqlbinlog.result b/mysql-test/suite/binlog_encryption/mysqlbinlog.result index 71758f7d6e7..e97e0569571 100644 --- a/mysql-test/suite/binlog_encryption/mysqlbinlog.result +++ b/mysql-test/suite/binlog_encryption/mysqlbinlog.result @@ -4,3 +4,4 @@ INSERT INTO t1 VALUES (1),(2),(3); REPLACE INTO t1 VALUES (4); DROP TABLE t1; FLUSH LOGS; +FOUND 1 /Ignorable event type 164.*/ in binlog_enc.sql diff --git a/mysql-test/suite/binlog_encryption/mysqlbinlog.test b/mysql-test/suite/binlog_encryption/mysqlbinlog.test index b80388aaa45..108dbd8782f 100644 --- a/mysql-test/suite/binlog_encryption/mysqlbinlog.test +++ b/mysql-test/suite/binlog_encryption/mysqlbinlog.test @@ -17,5 +17,8 @@ let outfile=$MYSQLTEST_VARDIR/tmp/binlog_enc.sql; exec $MYSQL_BINLOG $local > $outfile; exec $MYSQL_BINLOG $local --force-read >> $outfile; exec $MYSQL_BINLOG $remote >> $outfile; +--let SEARCH_FILE= $outfile +--let SEARCH_PATTERN= Ignorable event type 164.* +--source include/search_pattern_in_file.inc remove_file $outfile; diff --git a/sql/log_event.cc b/sql/log_event.cc index 0e0d69b515c..66f1d6bc790 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -2077,6 +2077,19 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len, alg != BINLOG_CHECKSUM_ALG_OFF)) event_len= event_len - BINLOG_CHECKSUM_LEN; + /* + Create an object of Ignorable_log_event for unrecognized sub-class. + So that SLAVE SQL THREAD will only update the position and continue. + We should look for this flag first instead of judging by event_type + Any event can be Ignorable_log_event if it has this flag on. + look into @note of Ignorable_log_event + */ + if (uint2korr(buf + FLAGS_OFFSET) & LOG_EVENT_IGNORABLE_F) + { + ev= new Ignorable_log_event(buf, fdle, + get_type_str((Log_event_type) event_type)); + goto exit; + } switch(event_type) { case QUERY_EVENT: ev = new Query_log_event(buf, event_len, fdle, QUERY_EVENT); @@ -2203,24 +2216,13 @@ Log_event* Log_event::read_log_event(const char* buf, uint event_len, ev = new Start_encryption_log_event(buf, event_len, fdle); break; default: - /* - Create an object of Ignorable_log_event for unrecognized sub-class. - So that SLAVE SQL THREAD will only update the position and continue. - */ - if (uint2korr(buf + FLAGS_OFFSET) & LOG_EVENT_IGNORABLE_F) - { - ev= new Ignorable_log_event(buf, fdle, - get_type_str((Log_event_type) event_type)); - } - else - { - DBUG_PRINT("error",("Unknown event code: %d", - (uchar) buf[EVENT_TYPE_OFFSET])); - ev= NULL; - break; - } + DBUG_PRINT("error",("Unknown event code: %d", + (uchar) buf[EVENT_TYPE_OFFSET])); + ev= NULL; + break; } } +exit: if (ev) { diff --git a/sql/slave.cc b/sql/slave.cc index 88a80029bba..1bc21f8895b 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -6317,7 +6317,18 @@ static int queue_event(Master_info* mi,const char* buf, ulong event_len) mi->last_queued_gtid.seq_no == 1000) goto skip_relay_logging; }); + goto default_action; #endif + case START_ENCRYPTION_EVENT: + if (uint2korr(buf + FLAGS_OFFSET) & LOG_EVENT_IGNORABLE_F) + { + /* + If the event was not requested by the slave (the slave did not ask for + it), i.e. has end_log_pos=0, we do not increment mi->master_log_pos + */ + inc_pos= uint4korr(buf+LOG_POS_OFFSET) ? event_len : 0; + break; + } /* fall through */ default: default_action: diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index edff750a9a3..8a6bea34fb4 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -399,16 +399,27 @@ static int send_file(THD *thd) /** Internal to mysql_binlog_send() routine that recalculates checksum for - a FD event (asserted) that needs additional arranment prior sending to slave. + 1. FD event (asserted) that needs additional arranment prior sending to slave. + 2. Start_encryption_log_event whose Ignored flag is set +TODO DBUG_ASSERT can be removed if this function is used for more general cases */ -inline void fix_checksum(String *packet, ulong ev_offset) + +inline void fix_checksum(enum_binlog_checksum_alg checksum_alg, String *packet, + ulong ev_offset) { + if (checksum_alg == BINLOG_CHECKSUM_ALG_OFF || + checksum_alg == BINLOG_CHECKSUM_ALG_UNDEF) + return; /* recalculate the crc for this event */ uint data_len = uint4korr(packet->ptr() + ev_offset + EVENT_LEN_OFFSET); ha_checksum crc; - DBUG_ASSERT(data_len == + DBUG_ASSERT((data_len == LOG_EVENT_MINIMAL_HEADER_LEN + FORMAT_DESCRIPTION_HEADER_LEN + - BINLOG_CHECKSUM_ALG_DESC_LEN + BINLOG_CHECKSUM_LEN); + BINLOG_CHECKSUM_ALG_DESC_LEN + BINLOG_CHECKSUM_LEN) || + (data_len == + LOG_EVENT_MINIMAL_HEADER_LEN + BINLOG_CRYPTO_SCHEME_LENGTH + + BINLOG_KEY_VERSION_LENGTH + BINLOG_NONCE_LENGTH + + BINLOG_CHECKSUM_LEN)); crc= my_checksum(0, (uchar *)packet->ptr() + ev_offset, data_len - BINLOG_CHECKSUM_LEN); int4store(packet->ptr() + ev_offset + data_len - BINLOG_CHECKSUM_LEN, crc); @@ -2135,6 +2146,7 @@ static int send_format_descriptor_event(binlog_send_info *info, IO_CACHE *log, THD *thd= info->thd; String *packet= info->packet; Log_event_type event_type; + bool initial_log_pos= info->clear_initial_log_pos; DBUG_ENTER("send_format_descriptor_event"); /** @@ -2233,7 +2245,7 @@ static int send_format_descriptor_event(binlog_send_info *info, IO_CACHE *log, (*packet)[FLAGS_OFFSET+ev_offset] &= ~LOG_EVENT_BINLOG_IN_USE_F; - if (info->clear_initial_log_pos) + if (initial_log_pos) { info->clear_initial_log_pos= false; /* @@ -2251,9 +2263,7 @@ static int send_format_descriptor_event(binlog_send_info *info, IO_CACHE *log, ST_CREATED_OFFSET+ev_offset, (ulong) 0); /* fix the checksum due to latest changes in header */ - if (info->current_checksum_alg != BINLOG_CHECKSUM_ALG_OFF && - info->current_checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF) - fix_checksum(packet, ev_offset); + fix_checksum(info->current_checksum_alg, packet, ev_offset); } else if (info->using_gtid_state) { @@ -2274,9 +2284,7 @@ static int send_format_descriptor_event(binlog_send_info *info, IO_CACHE *log, { int4store((char*) packet->ptr()+LOG_EVENT_MINIMAL_HEADER_LEN+ ST_CREATED_OFFSET+ev_offset, (ulong) 0); - if (info->current_checksum_alg != BINLOG_CHECKSUM_ALG_OFF && - info->current_checksum_alg != BINLOG_CHECKSUM_ALG_UNDEF) - fix_checksum(packet, ev_offset); + fix_checksum(info->current_checksum_alg, packet, ev_offset); } } @@ -2289,12 +2297,16 @@ static int send_format_descriptor_event(binlog_send_info *info, IO_CACHE *log, } /* - Read the following Start_encryption_log_event but don't send it to slave. - Slave doesn't need to know whether master's binlog is encrypted, - and if it'll want to encrypt its logs, it should generate its own - random nonce, not use the one from the master. + Read the following Start_encryption_log_event and send it to slave as + Ignorable_log_event. Although Slave doesn't need to know whether master's + binlog is encrypted but it needs to update slave log pos (for mysqlbinlog). + + If slave want to encrypt its logs, it should generate its own + random nonce, it should not use the one from the master. */ - packet->length(0); + /* reset transmit packet for the event read from binary log file */ + if (reset_transmit_packet(info, info->flags, &ev_offset, &info->errmsg)) + DBUG_RETURN(1); info->last_pos= linfo->pos; error= Log_event::read_log_event(log, packet, info->fdev, opt_master_verify_checksum @@ -2308,12 +2320,13 @@ static int send_format_descriptor_event(binlog_send_info *info, IO_CACHE *log, DBUG_RETURN(1); } - event_type= (Log_event_type)((uchar)(*packet)[LOG_EVENT_OFFSET]); + event_type= (Log_event_type)((uchar)(*packet)[LOG_EVENT_OFFSET + ev_offset]); if (event_type == START_ENCRYPTION_EVENT) { Start_encryption_log_event *sele= (Start_encryption_log_event *) - Log_event::read_log_event(packet->ptr(), packet->length(), &info->errmsg, - info->fdev, BINLOG_CHECKSUM_ALG_OFF); + Log_event::read_log_event(packet->ptr() + ev_offset, packet->length() + - ev_offset, &info->errmsg, info->fdev, + BINLOG_CHECKSUM_ALG_OFF); if (!sele) { info->error= ER_MASTER_FATAL_ERROR_READING_BINLOG; @@ -2327,6 +2340,18 @@ static int send_format_descriptor_event(binlog_send_info *info, IO_CACHE *log, delete sele; DBUG_RETURN(1); } + /* Make it Ignorable_log_event and send it */ + (*packet)[FLAGS_OFFSET+ev_offset] |= LOG_EVENT_IGNORABLE_F; + if (initial_log_pos) + int4store((char*) packet->ptr()+LOG_POS_OFFSET+ev_offset, (ulong) 0); + /* fix the checksum due to latest changes in header */ + fix_checksum(info->current_checksum_alg, packet, ev_offset); + if (my_net_write(info->net, (uchar*) packet->ptr(), packet->length())) + { + info->errmsg= "Failed on my_net_write()"; + info->error= ER_UNKNOWN_ERROR; + DBUG_RETURN(1); + } delete sele; } else if (start_pos == BIN_LOG_HEADER_SIZE) From 6bc75a42533f8facb25ebef7d56b020a0342e5e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 8 Oct 2019 13:05:35 +0300 Subject: [PATCH 17/44] MDEV-15528 preparation: Remove a constant parameter fsp_free_seg_inode(): Remove the constant parameter log=true. Only fsp_free_page() could also be called with log=false. The dead code was introduced in commit 304ae942f78f231a1f382624cdef9be80b3f5b84 by me, and spotted by Thirunarayanan Balathandayuthapani. --- storage/innobase/fsp/fsp0fsp.cc | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/storage/innobase/fsp/fsp0fsp.cc b/storage/innobase/fsp/fsp0fsp.cc index 1f410f7af0e..dec1f0cecca 100644 --- a/storage/innobase/fsp/fsp0fsp.cc +++ b/storage/innobase/fsp/fsp0fsp.cc @@ -1644,12 +1644,10 @@ fsp_alloc_seg_inode( /** Frees a file segment inode. @param[in,out] space tablespace @param[in,out] inode segment inode -@param[in] log whether to write MLOG_INIT_FREE_PAGE record @param[in,out] mtr mini-transaction */ static void fsp_free_seg_inode( fil_space_t* space, fseg_inode_t* inode, - bool log, mtr_t* mtr) { page_t* page; @@ -1688,7 +1686,7 @@ static void fsp_free_seg_inode( flst_remove(space_header + FSP_SEG_INODES_FREE, page + FSEG_INODE_PAGE_NODE, mtr); - fsp_free_page(space, page_get_page_no(page), log, mtr); + fsp_free_page(space, page_get_page_no(page), true, mtr); } } @@ -1971,7 +1969,7 @@ fseg_create( ut_ad(!has_done_reservation || block != NULL); if (block == NULL) { - fsp_free_seg_inode(space, inode, true, mtr); + fsp_free_seg_inode(space, inode, mtr); goto funct_exit; } @@ -3083,7 +3081,7 @@ fseg_free_step_func( if (n == ULINT_UNDEFINED) { /* Freeing completed: free the segment inode */ - fsp_free_seg_inode(space, inode, true, mtr); + fsp_free_seg_inode(space, inode, mtr); DBUG_RETURN(TRUE); } @@ -3097,7 +3095,7 @@ fseg_free_step_func( if (n == ULINT_UNDEFINED) { /* Freeing completed: free the segment inode */ - fsp_free_seg_inode(space, inode, true, mtr); + fsp_free_seg_inode(space, inode, mtr); DBUG_RETURN(TRUE); } From 57b666b2e56f3ca5b90d01ace655f9122d0d9e8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Tue, 8 Oct 2019 15:04:39 +0300 Subject: [PATCH 18/44] Fix test case wsrep.mdev_6832 we need to wait until wsrep_ready is ON before test can end. --- mysql-test/suite/wsrep/t/mdev_6832.test | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/wsrep/t/mdev_6832.test b/mysql-test/suite/wsrep/t/mdev_6832.test index 226be1b788c..d5303ce3fcf 100644 --- a/mysql-test/suite/wsrep/t/mdev_6832.test +++ b/mysql-test/suite/wsrep/t/mdev_6832.test @@ -12,5 +12,6 @@ eval SET @@global.wsrep_provider='$WSREP_PROVIDER'; --enable_query_log SHOW STATUS LIKE 'wsrep_ready'; SET @@global.wsrep_cluster_address='gcomm://'; - +--let $wait_condition = SELECT VARIABLE_VALUE = 'ON' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_ready'; +--source include/wait_condition.inc --echo # End of test. From b1ac1742791ad72695f76cab27e45b3f37cc39bc Mon Sep 17 00:00:00 2001 From: Seth Shelnutt Date: Mon, 7 Oct 2019 12:49:57 -0400 Subject: [PATCH 19/44] Cast string literal to char* MDEV-20767 --- client/mysql.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/client/mysql.cc b/client/mysql.cc index 6c8485a5143..d5001d335b6 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -2671,7 +2671,7 @@ static int fake_magic_space(const char *, int) static void initialize_readline () { /* Allow conditional parsing of the ~/.inputrc file. */ - rl_readline_name= "mysql"; + rl_readline_name= (char *) "mysql"; rl_terminal_name= getenv("TERM"); /* Tell the completer that we want a crack first. */ From d480d28f4f389d34248e3889cc059238a803008e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 8 Oct 2019 18:18:48 +0300 Subject: [PATCH 20/44] Add page_has_prev(), page_has_next(), page_has_siblings() Until now, InnoDB inefficiently compared the aligned fields FIL_PAGE_PREV, FIL_PAGE_NEXT to the byte-order-agnostic value FIL_NULL. This is a backport of 32170f8c6d55c497ae7a791997e17ff7c992b86f from MariaDB Server 10.3. --- storage/innobase/btr/btr0btr.cc | 12 +++++------ storage/innobase/btr/btr0cur.cc | 28 ++++++++++---------------- storage/innobase/btr/btr0defragment.cc | 2 +- storage/innobase/dict/dict0stats.cc | 4 ++-- storage/innobase/gis/gis0rtree.cc | 2 +- storage/innobase/gis/gis0sea.cc | 2 +- storage/innobase/ibuf/ibuf0ibuf.cc | 3 +-- storage/innobase/include/btr0cur.ic | 15 ++++++-------- storage/innobase/include/btr0pcur.ic | 16 ++++----------- storage/innobase/include/page0page.h | 18 +++++++++++++++++ storage/innobase/page/page0cur.cc | 2 +- storage/innobase/page/page0page.cc | 3 +-- storage/innobase/page/page0zip.cc | 11 ++++------ 13 files changed, 56 insertions(+), 62 deletions(-) diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc index f2b7b0d3f73..1bd49fa048e 100644 --- a/storage/innobase/btr/btr0btr.cc +++ b/storage/innobase/btr/btr0btr.cc @@ -1987,7 +1987,7 @@ btr_root_raise_and_insert( they should already have been set. The previous node field must be FIL_NULL if root_page_zip != NULL, because the REC_INFO_MIN_REC_FLAG (of the first user record) will be - set if and only if btr_page_get_prev() == FIL_NULL. */ + set if and only if !page_has_prev(). */ btr_page_set_next(root, root_page_zip, FIL_NULL, mtr); btr_page_set_prev(root, root_page_zip, FIL_NULL, mtr); @@ -3361,8 +3361,7 @@ btr_lift_page_up( bool lift_father_up; buf_block_t* block_orig = block; - ut_ad(btr_page_get_prev(page, mtr) == FIL_NULL); - ut_ad(btr_page_get_next(page, mtr) == FIL_NULL); + ut_ad(!page_has_siblings(page)); ut_ad(mtr_is_block_fix(mtr, block, MTR_MEMO_PAGE_X_FIX, index->table)); page_level = btr_page_get_level(page, mtr); @@ -3429,8 +3428,7 @@ btr_lift_page_up( page = buf_block_get_frame(block); page_level = btr_page_get_level(page, mtr); - ut_ad(btr_page_get_prev(page, mtr) == FIL_NULL); - ut_ad(btr_page_get_next(page, mtr) == FIL_NULL); + ut_ad(!page_has_siblings(page)); ut_ad(mtr_is_block_fix( mtr, block, MTR_MEMO_PAGE_X_FIX, index->table)); @@ -5077,13 +5075,13 @@ loop: if (left_page_no == FIL_NULL) { ut_a(node_ptr == page_rec_get_next( page_get_infimum_rec(father_page))); - ut_a(btr_page_get_prev(father_page, &mtr) == FIL_NULL); + ut_a(!page_has_prev(father_page)); } if (right_page_no == FIL_NULL) { ut_a(node_ptr == page_rec_get_prev( page_get_supremum_rec(father_page))); - ut_a(btr_page_get_next(father_page, &mtr) == FIL_NULL); + ut_a(!page_has_next(father_page)); } else { const rec_t* right_node_ptr; diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc index b23cacac227..d0d453ed828 100644 --- a/storage/innobase/btr/btr0cur.cc +++ b/storage/innobase/btr/btr0cur.cc @@ -595,10 +595,10 @@ btr_cur_will_modify_tree( /* is first, 2nd or last record */ if (page_rec_is_first(rec, page) - || (mach_read_from_4(page + FIL_PAGE_NEXT) != FIL_NULL + || (page_has_next(page) && (page_rec_is_last(rec, page) || page_rec_is_second_last(rec, page))) - || (mach_read_from_4(page + FIL_PAGE_PREV) != FIL_NULL + || (page_has_prev(page) && page_rec_is_second(rec, page))) { return(true); } @@ -680,13 +680,10 @@ btr_cur_need_opposite_intention( { switch (lock_intention) { case BTR_INTENTION_DELETE: - return((mach_read_from_4(page + FIL_PAGE_PREV) != FIL_NULL - && page_rec_is_first(rec, page)) - || (mach_read_from_4(page + FIL_PAGE_NEXT) != FIL_NULL - && page_rec_is_last(rec, page))); + return (page_has_prev(page) && page_rec_is_first(rec, page)) || + (page_has_next(page) && page_rec_is_last(rec, page)); case BTR_INTENTION_INSERT: - return(mach_read_from_4(page + FIL_PAGE_NEXT) != FIL_NULL - && page_rec_is_last(rec, page)); + return page_has_next(page) && page_rec_is_last(rec, page); case BTR_INTENTION_BOTH: return(false); } @@ -1898,7 +1895,7 @@ need_opposite_intention: MTR_MEMO_PAGE_S_FIX | MTR_MEMO_PAGE_X_FIX)); - if (btr_page_get_prev(page, mtr) != FIL_NULL + if (page_has_prev(page) && page_rec_is_first(node_ptr, page)) { if (leftmost_from_level == 0) { @@ -2015,7 +2012,7 @@ need_opposite_intention: } else if (!dict_index_is_spatial(index) && latch_mode == BTR_MODIFY_TREE && lock_intention == BTR_INTENTION_INSERT - && mach_read_from_4(page + FIL_PAGE_NEXT) != FIL_NULL + && page_has_next(page) && page_rec_is_last(page_cur_get_rec(page_cursor), page)) { /* btr_insert_into_right_sibling() might cause @@ -5302,7 +5299,7 @@ btr_cur_pessimistic_delete( } else if (UNIV_UNLIKELY(page_rec_is_first(rec, page))) { rec_t* next_rec = page_rec_get_next(rec); - if (btr_page_get_prev(page, mtr) == FIL_NULL) { + if (!page_has_prev(page)) { /* If we delete the leftmost node pointer on a non-leaf level, we must mark the new leftmost node @@ -6325,7 +6322,8 @@ btr_estimate_number_of_different_key_vals( } } - if (n_cols == dict_index_get_n_unique_in_tree(index)) { + if (n_cols == dict_index_get_n_unique_in_tree(index) + && page_has_siblings(page)) { /* If there is more than one leaf page in the tree, we add one because we know that the first record @@ -6336,11 +6334,7 @@ btr_estimate_number_of_different_key_vals( algorithm grossly underestimated the number of rows in the table. */ - if (btr_page_get_prev(page, &mtr) != FIL_NULL - || btr_page_get_next(page, &mtr) != FIL_NULL) { - - n_diff[n_cols - 1]++; - } + n_diff[n_cols - 1]++; } mtr_commit(&mtr); diff --git a/storage/innobase/btr/btr0defragment.cc b/storage/innobase/btr/btr0defragment.cc index 6995c6f0998..bcabfd3a3bf 100644 --- a/storage/innobase/btr/btr0defragment.cc +++ b/storage/innobase/btr/btr0defragment.cc @@ -602,7 +602,7 @@ btr_defragment_n_pages( } if (n_pages == 1) { - if (btr_page_get_prev(first_page, mtr) == FIL_NULL) { + if (!page_has_prev(first_page)) { /* last page in the index */ if (dict_index_get_page(index) == page_get_page_no(first_page)) diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc index 4db4687e600..f49fb87e4ea 100644 --- a/storage/innobase/dict/dict0stats.cc +++ b/storage/innobase/dict/dict0stats.cc @@ -1076,7 +1076,7 @@ dict_stats_analyze_index_level( ut_a(btr_page_get_level(page, mtr) == level); /* there should not be any pages on the left */ - ut_a(btr_page_get_prev(page, mtr) == FIL_NULL); + ut_a(!page_has_prev(page)); /* check whether the first record on the leftmost page is marked as such, if we are on a non-leaf level */ @@ -1689,7 +1689,7 @@ dict_stats_analyze_index_for_n_prefix( ut_a(btr_page_get_level(page, mtr) == n_diff_data->level); /* there should not be any pages on the left */ - ut_a(btr_page_get_prev(page, mtr) == FIL_NULL); + ut_a(!page_has_prev(page)); /* check whether the first record on the leftmost page is marked as such; we are on a non-leaf level */ diff --git a/storage/innobase/gis/gis0rtree.cc b/storage/innobase/gis/gis0rtree.cc index 2965a19a5e0..dc9e34903c2 100644 --- a/storage/innobase/gis/gis0rtree.cc +++ b/storage/innobase/gis/gis0rtree.cc @@ -1063,7 +1063,7 @@ func_start: page_no = block->page.id.page_no(); - if (btr_page_get_prev(page, mtr) == FIL_NULL && !page_is_leaf(page)) { + if (!page_has_prev(page) && !page_is_leaf(page)) { first_rec = page_rec_get_next( page_get_infimum_rec(buf_block_get_frame(block))); } diff --git a/storage/innobase/gis/gis0sea.cc b/storage/innobase/gis/gis0sea.cc index f1e4b82fd36..0a0a542689a 100644 --- a/storage/innobase/gis/gis0sea.cc +++ b/storage/innobase/gis/gis0sea.cc @@ -1713,7 +1713,7 @@ rtr_cur_search_with_match( first page as much as possible, as there will be problem when update MIN_REC rec in compress table */ if (buf_block_get_page_zip(block) - && mach_read_from_4(page + FIL_PAGE_PREV) == FIL_NULL + && !page_has_prev(page) && page_get_n_recs(page) >= 2) { rec = page_rec_get_next_const(rec); diff --git a/storage/innobase/ibuf/ibuf0ibuf.cc b/storage/innobase/ibuf/ibuf0ibuf.cc index 5581d1d1093..34cba10c6b5 100644 --- a/storage/innobase/ibuf/ibuf0ibuf.cc +++ b/storage/innobase/ibuf/ibuf0ibuf.cc @@ -3254,8 +3254,7 @@ ibuf_get_entry_counter_func( return(ULINT_UNDEFINED); } else if (!page_rec_is_infimum(rec)) { return(ibuf_get_entry_counter_low(mtr, rec, space, page_no)); - } else if (only_leaf - || fil_page_get_prev(page_align(rec)) == FIL_NULL) { + } else if (only_leaf || !page_has_prev(page_align(rec))) { /* The parent node pointer did not contain the searched for (space, page_no), which means that the search ended on the correct page regardless of the diff --git a/storage/innobase/include/btr0cur.ic b/storage/innobase/include/btr0cur.ic index 1decfa09e5b..7cf6c5982fa 100644 --- a/storage/innobase/include/btr0cur.ic +++ b/storage/innobase/include/btr0cur.ic @@ -138,10 +138,9 @@ btr_cur_compress_recommendation( LIMIT_OPTIMISTIC_INSERT_DEBUG(page_get_n_recs(page) * 2U, return(FALSE)); - if ((page_get_data_size(page) - < BTR_CUR_PAGE_COMPRESS_LIMIT(cursor->index)) - || ((btr_page_get_next(page, mtr) == FIL_NULL) - && (btr_page_get_prev(page, mtr) == FIL_NULL))) { + if (page_get_data_size(page) + < BTR_CUR_PAGE_COMPRESS_LIMIT(cursor->index) + || !page_has_siblings(page)) { /* The page fillfactor has dropped below a predefined minimum value OR the level in the B-tree contains just @@ -174,11 +173,9 @@ btr_cur_can_delete_without_compress( page = btr_cur_get_page(cursor); - if ((page_get_data_size(page) - rec_size - < BTR_CUR_PAGE_COMPRESS_LIMIT(cursor->index)) - || ((btr_page_get_next(page, mtr) == FIL_NULL) - && (btr_page_get_prev(page, mtr) == FIL_NULL)) - || (page_get_n_recs(page) < 2)) { + if (page_get_data_size(page) - rec_size + < BTR_CUR_PAGE_COMPRESS_LIMIT(cursor->index) + || !page_has_siblings(page) || page_get_n_recs(page) < 2) { /* The page fillfactor will drop below a predefined minimum value, OR the level in the B-tree contains just diff --git a/storage/innobase/include/btr0pcur.ic b/storage/innobase/include/btr0pcur.ic index 51ebcfbb2ee..8b0da666250 100644 --- a/storage/innobase/include/btr0pcur.ic +++ b/storage/innobase/include/btr0pcur.ic @@ -219,12 +219,8 @@ btr_pcur_is_before_first_in_tree( ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED); ut_ad(cursor->latch_mode != BTR_NO_LATCHES); - if (btr_page_get_prev(btr_pcur_get_page(cursor), mtr) != FIL_NULL) { - - return(FALSE); - } - - return(page_cur_is_before_first(btr_pcur_get_page_cur(cursor))); + return !page_has_prev(btr_pcur_get_page(cursor)) + && page_cur_is_before_first(btr_pcur_get_page_cur(cursor)); } /*********************************************************//** @@ -240,12 +236,8 @@ btr_pcur_is_after_last_in_tree( ut_ad(cursor->pos_state == BTR_PCUR_IS_POSITIONED); ut_ad(cursor->latch_mode != BTR_NO_LATCHES); - if (btr_page_get_next(btr_pcur_get_page(cursor), mtr) != FIL_NULL) { - - return(FALSE); - } - - return(page_cur_is_after_last(btr_pcur_get_page_cur(cursor))); + return !page_has_next(btr_pcur_get_page(cursor)) + && page_cur_is_after_last(btr_pcur_get_page_cur(cursor)); } /*********************************************************//** diff --git a/storage/innobase/include/page0page.h b/storage/innobase/include/page0page.h index ee261b55d16..c50e72a6542 100644 --- a/storage/innobase/include/page0page.h +++ b/storage/innobase/include/page0page.h @@ -697,6 +697,24 @@ inline bool page_has_siblings(const page_t* page) != ~uint64_t(0); } +/** Determine whether a page has a predecessor. +@param[in] page page frame +@return true if the page has a predecessor */ +inline bool page_has_prev(const page_t* page) +{ + return *reinterpret_cast(page + FIL_PAGE_PREV) + != FIL_NULL; +} + +/** Determine whether a page has a successor. +@param[in] page page frame +@return true if the page has a successor */ +inline bool page_has_next(const page_t* page) +{ + return *reinterpret_cast(page + FIL_PAGE_NEXT) + != FIL_NULL; +} + /************************************************************//** Gets the pointer to the next record on the page. @return pointer to next record */ diff --git a/storage/innobase/page/page0cur.cc b/storage/innobase/page/page0cur.cc index 92ff3e104ba..4071db7b4d9 100644 --- a/storage/innobase/page/page0cur.cc +++ b/storage/innobase/page/page0cur.cc @@ -521,7 +521,7 @@ up_rec_match: ulint rec_info = rec_get_info_bits(mid_rec, rec_offs_comp(offsets)); ut_ad(rec_info & REC_INFO_MIN_REC_FLAG); - ut_ad(btr_page_get_prev(page, &mtr) == FIL_NULL); + ut_ad(!page_has_prev(page)); mtr_commit(&mtr); #endif diff --git a/storage/innobase/page/page0page.cc b/storage/innobase/page/page0page.cc index 12a0f44011d..f950af02e31 100644 --- a/storage/innobase/page/page0page.cc +++ b/storage/innobase/page/page0page.cc @@ -2764,8 +2764,7 @@ page_delete_rec( if (!rec_offs_any_extern(offsets) && ((page_get_data_size(page) - rec_offs_size(offsets) < BTR_CUR_PAGE_COMPRESS_LIMIT(index)) - || (mach_read_from_4(page + FIL_PAGE_NEXT) == FIL_NULL - && mach_read_from_4(page + FIL_PAGE_PREV) == FIL_NULL) + || !page_has_siblings(page) || (page_get_n_recs(page) < 2))) { ulint root_page_no = dict_index_get_page(index); diff --git a/storage/innobase/page/page0zip.cc b/storage/innobase/page/page0zip.cc index e90c5f67f8e..9e3e58efa3a 100644 --- a/storage/innobase/page/page0zip.cc +++ b/storage/innobase/page/page0zip.cc @@ -670,8 +670,7 @@ page_zip_dir_encode( status = REC_STATUS_ORDINARY; } else { status = REC_STATUS_NODE_PTR; - if (UNIV_UNLIKELY - (mach_read_from_4(page + FIL_PAGE_PREV) == FIL_NULL)) { + if (UNIV_UNLIKELY(!page_has_prev(page))) { min_mark = REC_INFO_MIN_REC_FLAG; } } @@ -3187,8 +3186,7 @@ zlib_error: goto err_exit; } - info_bits = mach_read_from_4(page + FIL_PAGE_PREV) == FIL_NULL - ? REC_INFO_MIN_REC_FLAG : 0; + info_bits = page_has_prev(page) ? 0 : REC_INFO_MIN_REC_FLAG; if (UNIV_UNLIKELY(!page_zip_set_extra_bytes(page_zip, page, info_bits))) { @@ -4826,9 +4824,8 @@ page_zip_copy_recs( + page_zip->m_end < page_zip_get_size(page_zip)); if (!page_is_leaf(src) - && UNIV_UNLIKELY(mach_read_from_4(src + FIL_PAGE_PREV) == FIL_NULL) - && UNIV_LIKELY(mach_read_from_4(page - + FIL_PAGE_PREV) != FIL_NULL)) { + && UNIV_UNLIKELY(!page_has_prev(src)) + && UNIV_LIKELY(page_has_prev(page))) { /* Clear the REC_INFO_MIN_REC_FLAG of the first user record. */ ulint offs = rec_get_next_offs(page + PAGE_NEW_INFIMUM, TRUE); From 99dc40d6ac2234fa4c990665cc1914c1925cd641 Mon Sep 17 00:00:00 2001 From: Eugene Kosov Date: Mon, 30 Sep 2019 20:58:50 +0300 Subject: [PATCH 21/44] MDEV-19783 Random crashes and corrupt data in INSTANT-added columns The bug affects MariaDB Server 10.3 or later, but it makes sense to improve CHECK TABLE in earlier versions already. page_validate(): Check REC_INFO_MIN_REC_FLAG in the records. This allows CHECK TABLE to catch more bugs. --- storage/innobase/page/page0page.cc | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/storage/innobase/page/page0page.cc b/storage/innobase/page/page0page.cc index f950af02e31..bda4693648b 100644 --- a/storage/innobase/page/page0page.cc +++ b/storage/innobase/page/page0page.cc @@ -2392,6 +2392,7 @@ page_validate( ulint data_size; const rec_t* rec; const rec_t* old_rec = NULL; + const rec_t* first_rec = NULL; ulint offs; ulint n_slots; ibool ret = FALSE; @@ -2488,6 +2489,21 @@ page_validate( goto func_exit; } + if (rec == first_rec) { + if ((rec_get_info_bits(rec, page_is_comp(page)) + & REC_INFO_MIN_REC_FLAG) + && page_is_leaf(page)) { + ib::error() << "REC_INFO_MIN_REC_FLAG " + "is set in a leaf-page record"; + ret = false; + } + } else if (rec_get_info_bits(rec, page_is_comp(page)) + & REC_INFO_MIN_REC_FLAG) { + ib::error() << "REC_INFO_MIN_REC_FLAG record is not " + "first in page"; + ret = false; + } + /* Check that the records are in the ascending order */ if (count >= PAGE_HEAP_NO_USER_LOW && !page_rec_is_supremum(rec)) { @@ -2599,6 +2615,11 @@ page_validate( old_rec = rec; rec = page_rec_get_next_const(rec); + if (page_rec_is_infimum(old_rec) + && page_rec_is_user_rec(rec)) { + first_rec = rec; + } + /* set old_offsets to offsets; recycle offsets */ { ulint* offs = old_offsets; From ed0793e096a17955c5a03844b248bcf8303dd335 Mon Sep 17 00:00:00 2001 From: Eugene Kosov Date: Wed, 2 Oct 2019 22:47:45 +0300 Subject: [PATCH 22/44] MDEV-19783: Add more REC_INFO_MIN_REC_FLAG checks btr_cur_pessimistic_delete(): code changed in a way that allows to put more REC_INFO_MIN_REC_FLAG assertions inside btr_set_min_rec_mark(). Without that change tests innodb.innodb-table-online, innodb.temp_table_savepoint and innodb_zip.prefix_index_liftedlimit fail. Removed basically duplicated page_zip_validate() calls which fails because of temporary(!) invariant violation. That fixed innodb_zip.wl5522_debug_zip and innodb_zip.prefix_index_liftedlimit --- storage/innobase/btr/btr0btr.cc | 21 +++++++++------------ storage/innobase/btr/btr0cur.cc | 26 ++++++++++++++++---------- storage/innobase/include/btr0btr.h | 12 ++++-------- storage/innobase/include/page0page.ic | 4 ++++ storage/innobase/page/page0cur.cc | 4 ---- storage/innobase/page/page0zip.cc | 4 ---- 6 files changed, 33 insertions(+), 38 deletions(-) diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc index 1bd49fa048e..473e4248656 100644 --- a/storage/innobase/btr/btr0btr.cc +++ b/storage/innobase/btr/btr0btr.cc @@ -3309,25 +3309,22 @@ btr_parse_set_min_rec_mark( return(ptr + 2); } -/****************************************************************//** -Sets a record as the predefined minimum record. */ -void -btr_set_min_rec_mark( -/*=================*/ - rec_t* rec, /*!< in: record */ - mtr_t* mtr) /*!< in: mtr */ +/** Sets a record as the predefined minimum record. */ +void btr_set_min_rec_mark(rec_t* rec, mtr_t* mtr) { - ulint info_bits; + const bool comp = page_rec_is_comp(rec); - if (page_rec_is_comp(rec)) { - info_bits = rec_get_info_bits(rec, TRUE); + ut_ad(rec == page_rec_get_next_const(page_get_infimum_rec( + page_align(rec)))); + ut_ad(!(rec_get_info_bits(page_rec_get_next(rec), comp) + & REC_INFO_MIN_REC_FLAG)); + size_t info_bits = rec_get_info_bits(rec, comp); + if (comp) { rec_set_info_bits_new(rec, info_bits | REC_INFO_MIN_REC_FLAG); btr_set_min_rec_mark_log(rec, MLOG_COMP_REC_MIN_MARK, mtr); } else { - info_bits = rec_get_info_bits(rec, FALSE); - rec_set_info_bits_old(rec, info_bits | REC_INFO_MIN_REC_FLAG); btr_set_min_rec_mark_log(rec, MLOG_REC_MIN_MARK, mtr); diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc index d0d453ed828..3060865bc8e 100644 --- a/storage/innobase/btr/btr0cur.cc +++ b/storage/innobase/btr/btr0cur.cc @@ -5277,8 +5277,15 @@ btr_cur_pessimistic_delete( #endif /* UNIV_ZIP_DEBUG */ } - if (flags == 0) { - lock_update_delete(block, rec); + rec_t* next_rec = NULL; + bool min_mark_next_rec = false; + + if (page_is_leaf(page)) { + ut_ad(!(rec_get_info_bits(rec, page_rec_is_comp(rec)) + & REC_INFO_MIN_REC_FLAG)); + if (flags == 0) { + lock_update_delete(block, rec); + } } if (UNIV_UNLIKELY(page_get_n_recs(page) < 2) @@ -5297,20 +5304,14 @@ btr_cur_pessimistic_delete( if (page_is_leaf(page)) { btr_search_update_hash_on_delete(cursor); } else if (UNIV_UNLIKELY(page_rec_is_first(rec, page))) { - rec_t* next_rec = page_rec_get_next(rec); + next_rec = page_rec_get_next(rec); if (!page_has_prev(page)) { - /* If we delete the leftmost node pointer on a non-leaf level, we must mark the new leftmost node pointer as the predefined minimum record */ - /* This will make page_zip_validate() fail until - page_cur_delete_rec() completes. This is harmless, - because everything will take place within a single - mini-transaction and because writing to the redo log - is an atomic operation (performed by mtr_commit()). */ - btr_set_min_rec_mark(next_rec, mtr); + min_mark_next_rec = true; } else if (dict_index_is_spatial(index)) { /* For rtree, if delete the leftmost node pointer, we need to update parent page. */ @@ -5379,6 +5380,11 @@ btr_cur_pessimistic_delete( block->page.size, mtr); page_cur_delete_rec(btr_cur_get_page_cur(cursor), index, offsets, mtr); + + if (min_mark_next_rec) { + btr_set_min_rec_mark(next_rec, mtr); + } + #ifdef UNIV_ZIP_DEBUG ut_a(!page_zip || page_zip_validate(page_zip, page, index)); #endif /* UNIV_ZIP_DEBUG */ diff --git a/storage/innobase/include/btr0btr.h b/storage/innobase/include/btr0btr.h index e00b2545708..604890ed03c 100644 --- a/storage/innobase/include/btr0btr.h +++ b/storage/innobase/include/btr0btr.h @@ -508,14 +508,10 @@ btr_insert_on_non_leaf_level_func( mtr_t* mtr); /*!< in: mtr */ #define btr_insert_on_non_leaf_level(f,i,l,t,m) \ btr_insert_on_non_leaf_level_func(f,i,l,t,__FILE__,__LINE__,m) -/****************************************************************//** -Sets a record as the predefined minimum record. */ -void -btr_set_min_rec_mark( -/*=================*/ - rec_t* rec, /*!< in/out: record */ - mtr_t* mtr) /*!< in: mtr */ - MY_ATTRIBUTE((nonnull)); + +/** Sets a record as the predefined minimum record. */ +void btr_set_min_rec_mark(rec_t* rec, mtr_t* mtr) MY_ATTRIBUTE((nonnull)); + /** Seek to the parent page of a B-tree page. @param[in,out] index b-tree @param[in] block child page diff --git a/storage/innobase/include/page0page.ic b/storage/innobase/include/page0page.ic index 05774daac50..3956ecce0ee 100644 --- a/storage/innobase/include/page0page.ic +++ b/storage/innobase/include/page0page.ic @@ -659,6 +659,10 @@ page_rec_get_next_low( return(NULL); } + ut_ad(page_rec_is_infimum(rec) + || !(rec_get_info_bits(page + offs, comp) + & REC_INFO_MIN_REC_FLAG)); + return(page + offs); } diff --git a/storage/innobase/page/page0cur.cc b/storage/innobase/page/page0cur.cc index 4071db7b4d9..90c0dd377e1 100644 --- a/storage/innobase/page/page0cur.cc +++ b/storage/innobase/page/page0cur.cc @@ -2421,10 +2421,6 @@ page_cur_delete_rec( if (cur_n_owned <= PAGE_DIR_SLOT_MIN_N_OWNED) { page_dir_balance_slot(page, page_zip, cur_slot_no); } - -#ifdef UNIV_ZIP_DEBUG - ut_a(!page_zip || page_zip_validate(page_zip, page, index)); -#endif /* UNIV_ZIP_DEBUG */ } #ifdef UNIV_COMPILE_TEST_FUNCS diff --git a/storage/innobase/page/page0zip.cc b/storage/innobase/page/page0zip.cc index 9e3e58efa3a..d6abec57821 100644 --- a/storage/innobase/page/page0zip.cc +++ b/storage/innobase/page/page0zip.cc @@ -4291,10 +4291,6 @@ page_zip_clear_rec( } else { ut_ad(!rec_offs_any_extern(offsets)); } - -#ifdef UNIV_ZIP_DEBUG - ut_a(page_zip_validate(page_zip, page, index)); -#endif /* UNIV_ZIP_DEBUG */ } /**********************************************************************//** From b7408be0c3a4027b505f6122306c8d88ad0e92b2 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Fri, 4 Oct 2019 16:46:41 +0200 Subject: [PATCH 23/44] MDEV-20753: Sequence with limit 0 crashes server Do not try to push down conditions to engine if query was resolved without tables (and so the engine). --- sql/sql_select.cc | 2 +- storage/sequence/mysql-test/sequence/group_by.result | 6 ++++++ storage/sequence/mysql-test/sequence/group_by.test | 7 +++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 460c7346cdd..a68eaf00424 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2795,7 +2795,7 @@ bool JOIN::make_aggr_tables_info() distinct in the engine, so we do this for all queries, not only GROUP BY queries. */ - if (tables_list && !procedure) + if (tables_list && top_join_tab_count && !procedure) { /* At the moment we only support push down for queries where diff --git a/storage/sequence/mysql-test/sequence/group_by.result b/storage/sequence/mysql-test/sequence/group_by.result index 2941e85c1f4..7902fe6a348 100644 --- a/storage/sequence/mysql-test/sequence/group_by.result +++ b/storage/sequence/mysql-test/sequence/group_by.result @@ -97,3 +97,9 @@ count(NULL) select count(NULL) from seq_1_to_3; count(NULL) 0 +# +# MDEV-20753: Sequence with limit 0 crashes server +# +select count(NULL) from seq_1_to_3 limit 0; +count(NULL) +# End of 10.3 tests diff --git a/storage/sequence/mysql-test/sequence/group_by.test b/storage/sequence/mysql-test/sequence/group_by.test index b3f4ab58771..18e44cd2ab1 100644 --- a/storage/sequence/mysql-test/sequence/group_by.test +++ b/storage/sequence/mysql-test/sequence/group_by.test @@ -49,3 +49,10 @@ explain select count(*) from seq_1_to_15_step_2 group by mod(seq,2); create temporary table t1 select * from seq_1_to_3; select count(NULL) from t1; select count(NULL) from seq_1_to_3; + +--echo # +--echo # MDEV-20753: Sequence with limit 0 crashes server +--echo # +select count(NULL) from seq_1_to_3 limit 0; + +--echo # End of 10.3 tests From 896b869685484beac11785f7d1099be0fe265c49 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Sat, 5 Oct 2019 09:12:56 +0200 Subject: [PATCH 24/44] MDEV-19238 Mariadb spider - crashes on where null (fix and explanation came with MDEV-20753 (duplicate of this bug)) --- .../bugfix/include/select_by_null_deinit.inc | 11 +++ .../bugfix/include/select_by_null_init.inc | 24 +++++ .../spider/bugfix/r/select_by_null.result | 90 +++++++++++++++++++ .../spider/bugfix/t/select_by_null.cnf | 3 + .../spider/bugfix/t/select_by_null.test | 72 +++++++++++++++ 5 files changed, 200 insertions(+) create mode 100644 storage/spider/mysql-test/spider/bugfix/include/select_by_null_deinit.inc create mode 100644 storage/spider/mysql-test/spider/bugfix/include/select_by_null_init.inc create mode 100644 storage/spider/mysql-test/spider/bugfix/r/select_by_null.result create mode 100644 storage/spider/mysql-test/spider/bugfix/t/select_by_null.cnf create mode 100644 storage/spider/mysql-test/spider/bugfix/t/select_by_null.test diff --git a/storage/spider/mysql-test/spider/bugfix/include/select_by_null_deinit.inc b/storage/spider/mysql-test/spider/bugfix/include/select_by_null_deinit.inc new file mode 100644 index 00000000000..76b7582abfe --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/include/select_by_null_deinit.inc @@ -0,0 +1,11 @@ +--let $MASTER_1_COMMENT_2_1= $MASTER_1_COMMENT_2_1_BACKUP +--let $CHILD2_1_DROP_TABLES= $CHILD2_1_DROP_TABLES_BACKUP +--let $CHILD2_1_CREATE_TABLES= $CHILD2_1_CREATE_TABLES_BACKUP +--let $CHILD2_1_SELECT_TABLES= $CHILD2_1_SELECT_TABLES_BACKUP +--disable_warnings +--disable_query_log +--disable_result_log +--source ../t/test_deinit.inc +--enable_result_log +--enable_query_log +--enable_warnings diff --git a/storage/spider/mysql-test/spider/bugfix/include/select_by_null_init.inc b/storage/spider/mysql-test/spider/bugfix/include/select_by_null_init.inc new file mode 100644 index 00000000000..d07ba2a9fee --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/include/select_by_null_init.inc @@ -0,0 +1,24 @@ +--disable_warnings +--disable_query_log +--disable_result_log +--source ../t/test_init.inc +--enable_result_log +--enable_query_log +--enable_warnings +--let $MASTER_1_COMMENT_2_1_BACKUP= $MASTER_1_COMMENT_2_1 +let $MASTER_1_COMMENT_2_1= + COMMENT='table "tbl_a", srv "s_2_1"'; +--let $CHILD2_1_DROP_TABLES_BACKUP= $CHILD2_1_DROP_TABLES +let $CHILD2_1_DROP_TABLES= + DROP TABLE IF EXISTS tbl_a; +--let $CHILD2_1_CREATE_TABLES_BACKUP= $CHILD2_1_CREATE_TABLES +let $CHILD2_1_CREATE_TABLES= + CREATE TABLE tbl_a ( + pkey int NOT NULL, + PRIMARY KEY (pkey) + ) $CHILD2_1_ENGINE $CHILD2_1_CHARSET; +--let $CHILD2_1_SELECT_TABLES_BACKUP= $CHILD2_1_SELECT_TABLES +let $CHILD2_1_SELECT_TABLES= + SELECT pkey FROM tbl_a ORDER BY pkey; +let $CHILD2_1_SELECT_ARGUMENT1= + SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %'; diff --git a/storage/spider/mysql-test/spider/bugfix/r/select_by_null.result b/storage/spider/mysql-test/spider/bugfix/r/select_by_null.result new file mode 100644 index 00000000000..a7fa1b3b91f --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/r/select_by_null.result @@ -0,0 +1,90 @@ +for master_1 +for child2 +child2_1 +child2_2 +child2_3 +for child3 + +this test is for MDEV-16279 + +drop and create databases +connection master_1; +CREATE DATABASE auto_test_local; +USE auto_test_local; +connection child2_1; +SET @old_log_output = @@global.log_output; +SET GLOBAL log_output = 'TABLE,FILE'; +CREATE DATABASE auto_test_remote; +USE auto_test_remote; + +create table and insert +connection child2_1; +CHILD2_1_CREATE_TABLES +TRUNCATE TABLE mysql.general_log; +connection master_1; +CREATE TABLE tbl_a ( +pkey int NOT NULL, +PRIMARY KEY (pkey) +) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT_2_1 +INSERT INTO tbl_a (pkey) VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +INSERT INTO tbl_a (pkey) VALUES (10),(11),(12),(13),(14),(15),(16),(17),(18),(19); +INSERT INTO tbl_a (pkey) VALUES (20),(21),(22),(23),(24),(25),(26),(27),(28),(29); +FLUSH TABLES; + +select test 1 +connection child2_1; +TRUNCATE TABLE mysql.general_log; +connection master_1; +SELECT pkey FROM tbl_a WHERE NULL; +pkey +connection child2_1; +SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %'; +argument +SELECT argument FROM mysql.general_log WHERE argument LIKE '%select %' +SELECT pkey FROM tbl_a ORDER BY pkey; +pkey +0 +1 +2 +3 +4 +5 +6 +7 +8 +9 +10 +11 +12 +13 +14 +15 +16 +17 +18 +19 +20 +21 +22 +23 +24 +25 +26 +27 +28 +29 + +deinit +connection master_1; +DROP DATABASE IF EXISTS auto_test_local; +connection child2_1; +DROP DATABASE IF EXISTS auto_test_remote; +SET GLOBAL log_output = @old_log_output; +for master_1 +for child2 +child2_1 +child2_2 +child2_3 +for child3 + +end of test diff --git a/storage/spider/mysql-test/spider/bugfix/t/select_by_null.cnf b/storage/spider/mysql-test/spider/bugfix/t/select_by_null.cnf new file mode 100644 index 00000000000..05dfd8a0bce --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/select_by_null.cnf @@ -0,0 +1,3 @@ +!include include/default_mysqld.cnf +!include ../my_1_1.cnf +!include ../my_2_1.cnf diff --git a/storage/spider/mysql-test/spider/bugfix/t/select_by_null.test b/storage/spider/mysql-test/spider/bugfix/t/select_by_null.test new file mode 100644 index 00000000000..1f540b2a15f --- /dev/null +++ b/storage/spider/mysql-test/spider/bugfix/t/select_by_null.test @@ -0,0 +1,72 @@ +--source ../include/select_by_null_init.inc +--echo +--echo this test is for MDEV-16279 +--echo +--echo drop and create databases + +--connection master_1 +--disable_warnings +CREATE DATABASE auto_test_local; +USE auto_test_local; + +--connection child2_1 +SET @old_log_output = @@global.log_output; +SET GLOBAL log_output = 'TABLE,FILE'; +CREATE DATABASE auto_test_remote; +USE auto_test_remote; +--enable_warnings + +--echo +--echo create table and insert + +--connection child2_1 +--disable_query_log +echo CHILD2_1_CREATE_TABLES; +eval $CHILD2_1_CREATE_TABLES; +--enable_query_log +TRUNCATE TABLE mysql.general_log; + +--connection master_1 +--disable_query_log +echo CREATE TABLE tbl_a ( + pkey int NOT NULL, + PRIMARY KEY (pkey) +) MASTER_1_ENGINE MASTER_1_CHARSET MASTER_1_COMMENT_2_1; +eval CREATE TABLE tbl_a ( + pkey int NOT NULL, + PRIMARY KEY (pkey) +) $MASTER_1_ENGINE $MASTER_1_CHARSET $MASTER_1_COMMENT_2_1; +--enable_query_log +INSERT INTO tbl_a (pkey) VALUES (0),(1),(2),(3),(4),(5),(6),(7),(8),(9); +INSERT INTO tbl_a (pkey) VALUES (10),(11),(12),(13),(14),(15),(16),(17),(18),(19); +INSERT INTO tbl_a (pkey) VALUES (20),(21),(22),(23),(24),(25),(26),(27),(28),(29); +FLUSH TABLES; + +--echo +--echo select test 1 + +--connection child2_1 +TRUNCATE TABLE mysql.general_log; + +--connection master_1 +SELECT pkey FROM tbl_a WHERE NULL; + +--connection child2_1 +eval $CHILD2_1_SELECT_ARGUMENT1; +eval $CHILD2_1_SELECT_TABLES; + +--echo +--echo deinit +--disable_warnings + +--connection master_1 +DROP DATABASE IF EXISTS auto_test_local; + +--connection child2_1 +DROP DATABASE IF EXISTS auto_test_remote; +SET GLOBAL log_output = @old_log_output; + +--enable_warnings +--source ../include/select_by_null_deinit.inc +--echo +--echo end of test From 44a11a7c085f4f5a4042100df0828d54d596103d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Wed, 9 Oct 2019 11:41:14 +0300 Subject: [PATCH 25/44] MDEV-20780 : Galera test failure on galera_sr.galera_sr_ddl_master Fix wait_condition and use repeatable read with wsrep_sync at the end. --- .../galera_sr/r/galera_sr_ddl_master.result | 54 ++++++++++++------- .../galera_sr/t/galera_sr_ddl_master.test | 18 ++++--- 2 files changed, 47 insertions(+), 25 deletions(-) diff --git a/mysql-test/suite/galera_sr/r/galera_sr_ddl_master.result b/mysql-test/suite/galera_sr/r/galera_sr_ddl_master.result index cf9c7771bed..9b4419949f3 100644 --- a/mysql-test/suite/galera_sr/r/galera_sr_ddl_master.result +++ b/mysql-test/suite/galera_sr/r/galera_sr_ddl_master.result @@ -12,17 +12,18 @@ INSERT INTO t1 VALUES (4); INSERT INTO t1 VALUES (5); connection node_2; SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; -SELECT COUNT(*) > 0 FROM mysql.wsrep_streaming_log; -COUNT(*) > 0 -1 +SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; +SELECT COUNT(*) as expect_5 FROM mysql.wsrep_streaming_log; +expect_5 +5 connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1; ALTER TABLE t1 ADD COLUMN f2 INTEGER; connection node_1; INSERT INTO t1 VALUES (6); ERROR 40001: Deadlock found when trying to get lock; try restarting transaction -SELECT COUNT(*) = 0 FROM mysql.wsrep_streaming_log; -COUNT(*) = 0 -1 +SELECT COUNT(*) as expect_0 FROM mysql.wsrep_streaming_log; +expect_0 +0 ROLLBACK; START TRANSACTION; INSERT INTO t1 (f1) VALUES (1); @@ -32,17 +33,34 @@ INSERT INTO t1 (f1) VALUES (4); INSERT INTO t1 (f1) VALUES (5); INSERT INTO t1 (f1) VALUES (6); COMMIT; -SELECT COUNT(*) = 6 FROM t1; -COUNT(*) = 6 -1 -SELECT COUNT(*) = 0 FROM mysql.wsrep_streaming_log; -COUNT(*) = 0 -1 +SELECT COUNT(*) as expect_6 FROM t1; +expect_6 +6 +SELECT * FROM t1; +f1 f2 +1 NULL +2 NULL +3 NULL +4 NULL +5 NULL +6 NULL +SELECT COUNT(*) as expect_0 FROM mysql.wsrep_streaming_log; +expect_0 +0 connection node_2; -SELECT COUNT(*) = 6 FROM t1; -COUNT(*) = 6 -1 -SELECT COUNT(*) = 0 FROM mysql.wsrep_streaming_log; -COUNT(*) = 0 -1 +set global wsrep_sync_wait=15; +SELECT COUNT(*) as expect_6 FROM t1; +expect_6 +6 +SELECT * FROM t1; +f1 f2 +1 NULL +2 NULL +3 NULL +4 NULL +5 NULL +6 NULL +SELECT COUNT(*) as expect_0 FROM mysql.wsrep_streaming_log; +expect_0 +0 DROP TABLE t1; diff --git a/mysql-test/suite/galera_sr/t/galera_sr_ddl_master.test b/mysql-test/suite/galera_sr/t/galera_sr_ddl_master.test index 7da7f55ba15..bbab86d41a0 100644 --- a/mysql-test/suite/galera_sr/t/galera_sr_ddl_master.test +++ b/mysql-test/suite/galera_sr/t/galera_sr_ddl_master.test @@ -27,10 +27,11 @@ INSERT INTO t1 VALUES (5); --connection node_2 # SR replication is triggered and rows have been delivered to the slave SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; ---let $wait_condition = SELECT COUNT(*) > 0 FROM t1; +--let $wait_condition = SELECT COUNT(*) = 5 FROM t1; --source include/wait_condition.inc +SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; -SELECT COUNT(*) > 0 FROM mysql.wsrep_streaming_log; +SELECT COUNT(*) as expect_5 FROM mysql.wsrep_streaming_log; --connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1 ALTER TABLE t1 ADD COLUMN f2 INTEGER; @@ -39,7 +40,7 @@ ALTER TABLE t1 ADD COLUMN f2 INTEGER; --error ER_LOCK_DEADLOCK INSERT INTO t1 VALUES (6); -SELECT COUNT(*) = 0 FROM mysql.wsrep_streaming_log; +SELECT COUNT(*) as expect_0 FROM mysql.wsrep_streaming_log; # Check that the transaction thus aborted could be reissued @@ -53,11 +54,14 @@ INSERT INTO t1 (f1) VALUES (5); INSERT INTO t1 (f1) VALUES (6); COMMIT; -SELECT COUNT(*) = 6 FROM t1; -SELECT COUNT(*) = 0 FROM mysql.wsrep_streaming_log; +SELECT COUNT(*) as expect_6 FROM t1; +SELECT * FROM t1; +SELECT COUNT(*) as expect_0 FROM mysql.wsrep_streaming_log; --connection node_2 -SELECT COUNT(*) = 6 FROM t1; -SELECT COUNT(*) = 0 FROM mysql.wsrep_streaming_log; +set global wsrep_sync_wait=15; +SELECT COUNT(*) as expect_6 FROM t1; +SELECT * FROM t1; +SELECT COUNT(*) as expect_0 FROM mysql.wsrep_streaming_log; DROP TABLE t1; From 62dce14d156ff99836a23f5ccadcfaa19cf11f8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Wed, 9 Oct 2019 11:42:50 +0300 Subject: [PATCH 26/44] MDEV-20782 : Galera test failure on galera_sr.galera_sr_mysqldump_sst Add auto increment offset save and restore as node(s) are restarted. --- .../suite/galera_sr/r/galera_sr_mysqldump_sst.result | 2 ++ mysql-test/suite/galera_sr/t/galera_sr_mysqldump_sst.test | 8 ++++++++ 2 files changed, 10 insertions(+) diff --git a/mysql-test/suite/galera_sr/r/galera_sr_mysqldump_sst.result b/mysql-test/suite/galera_sr/r/galera_sr_mysqldump_sst.result index df454772346..6789990f18e 100644 --- a/mysql-test/suite/galera_sr/r/galera_sr_mysqldump_sst.result +++ b/mysql-test/suite/galera_sr/r/galera_sr_mysqldump_sst.result @@ -10,6 +10,8 @@ SET GLOBAL wsrep_sst_auth = 'sst:'; connection node_2; SET GLOBAL wsrep_sst_method = 'mysqldump'; connection node_1; +connection node_2; +connection node_1; CREATE TABLE ten (f1 INTEGER); INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); CREATE TABLE t1 (f1 INTEGER PRIMARY KEY AUTO_INCREMENT, f2 CHAR(255)) ENGINE=InnoDB; diff --git a/mysql-test/suite/galera_sr/t/galera_sr_mysqldump_sst.test b/mysql-test/suite/galera_sr/t/galera_sr_mysqldump_sst.test index 5a3f48e02a3..e660895cde6 100644 --- a/mysql-test/suite/galera_sr/t/galera_sr_mysqldump_sst.test +++ b/mysql-test/suite/galera_sr/t/galera_sr_mysqldump_sst.test @@ -7,6 +7,11 @@ --source suite/galera/include/galera_sst_set_mysqldump.inc +# Save original auto_increment_offset values. +--let $node_1=node_1 +--let $node_2=node_2 +--source suite/galera/include/auto_increment_offset_save.inc + --connection node_1 CREATE TABLE ten (f1 INTEGER); INSERT INTO ten VALUES (1),(2),(3),(4),(5),(6),(7),(8),(9),(10); @@ -77,3 +82,6 @@ DROP TABLE ten; # with SR, need to disable SR before that. SET SESSION wsrep_trx_fragment_size=0; --source suite/galera/include/galera_sst_restore.inc + +# Restore original auto_increment_offset values. +--source suite/galera/include/auto_increment_offset_restore.inc From f11d425a15e53d4b206146a9d52f5be324247826 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 9 Oct 2019 09:16:40 +0300 Subject: [PATCH 27/44] MDEV-20591: Follow-up fix calc_field_event_length(): For type=MYSQL_TYPE_BLOB and meta==0, return 0 instead of *ptr+1. This was noted by -Wimplicit-fallthrough. --- sql/log_event.cc | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/sql/log_event.cc b/sql/log_event.cc index 369e9229d03..15523ba0c36 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -3423,16 +3423,18 @@ static size_t calc_field_event_length(const uchar *ptr, uint type, uint meta) case MYSQL_TYPE_SET: return meta & 0xFF; case MYSQL_TYPE_BLOB: - if (meta > 4 ) + switch (meta) { + default: return 0; - if (meta == 1) + case 1: return *ptr + 1; - if (meta == 2) + case 2: return uint2korr(ptr) + 2; - if (meta == 3) + case 3: return uint3korr(ptr) + 3; - if (meta == 4) + case 4: return uint4korr(ptr) + 4; + } case MYSQL_TYPE_VARCHAR: case MYSQL_TYPE_VAR_STRING: length= meta; From c65cb244b35412ef54192b17120f7ace8a8af5fd Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Thu, 3 Oct 2019 18:12:08 +0530 Subject: [PATCH 28/44] MDEV-19335 Remove buf_page_t::encrypted The field buf_page_t::encrypted was added in MDEV-8588. It was made mostly redundant in MDEV-12699. Remove the field. --- extra/mariabackup/fil_cur.cc | 4 +- storage/innobase/buf/buf0buf.cc | 80 +++++++--------------------- storage/innobase/fil/fil0crypt.cc | 6 +-- storage/innobase/ibuf/ibuf0ibuf.cc | 4 +- storage/innobase/include/buf0buf.h | 2 - storage/innobase/include/fil0crypt.h | 4 +- 6 files changed, 24 insertions(+), 76 deletions(-) diff --git a/extra/mariabackup/fil_cur.cc b/extra/mariabackup/fil_cur.cc index dce0f9ba6f2..b229a37d934 100644 --- a/extra/mariabackup/fil_cur.cc +++ b/extra/mariabackup/fil_cur.cc @@ -339,11 +339,9 @@ static bool page_is_corrupted(const byte *page, ulint page_no, memcpy(tmp_page, page, page_size); - bool decrypted = false; if (!space->crypt_data || space->crypt_data->type == CRYPT_SCHEME_UNENCRYPTED - || !fil_space_decrypt(space, tmp_frame, tmp_page, - &decrypted)) { + || !fil_space_decrypt(space, tmp_frame, tmp_page)) { return true; } diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index e3c6605652f..b5ca51c81dc 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -589,12 +589,6 @@ decrypt_failed: << mach_read_from_4( FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION + dst_frame); - /* Mark page encrypted in case it should be. */ - if (space->crypt_data->type - != CRYPT_SCHEME_UNENCRYPTED) { - bpage->encrypted = true; - } - return false; } @@ -605,8 +599,7 @@ decrypt_failed: ut_d(fil_page_type_validate(dst_frame)); /* decrypt using crypt_buf to dst_frame */ - if (!fil_space_decrypt(space, slot->crypt_buf, - dst_frame, &bpage->encrypted)) { + if (!fil_space_decrypt(space, slot->crypt_buf, dst_frame)) { slot->release(); goto decrypt_failed; } @@ -1534,7 +1527,6 @@ buf_block_init( block->page.buf_fix_count = 0; block->page.io_fix = BUF_IO_NONE; block->page.flush_observer = NULL; - block->page.encrypted = false; block->page.real_size = 0; block->page.write_size = 0; block->modify_clock = 0; @@ -4044,7 +4036,6 @@ err_exit: if (encrypted) { ib::info() << "Row compressed page could be encrypted" " with key_version " << key_version; - block->page.encrypted = true; dict_set_encrypted_by_space(block->page.id.space()); } else { dict_set_corrupted_by_space(block->page.id.space()); @@ -5248,7 +5239,6 @@ buf_page_init_low( bpage->newest_modification = 0; bpage->oldest_modification = 0; bpage->write_size = 0; - bpage->encrypted = false; bpage->real_size = 0; bpage->slot = NULL; @@ -5841,15 +5831,16 @@ buf_page_monitor( } /** Mark a table corrupted. -@param[in] bpage Corrupted page. */ -static -void -buf_mark_space_corrupt(buf_page_t* bpage) +@param[in] bpage corrupted page +@param[in] space tablespace of the corrupted page */ +ATTRIBUTE_COLD +static void buf_mark_space_corrupt(buf_page_t* bpage, const fil_space_t& space) { /* 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) { + if (!space.crypt_data + || space.crypt_data->type == CRYPT_SCHEME_UNENCRYPTED) { dict_set_corrupted_by_space(bpage->id.space()); } else { dict_set_encrypted_by_space(bpage->id.space()); @@ -5891,7 +5882,7 @@ buf_corrupt_page_release(buf_page_t* bpage, const fil_space_t* space) mutex_exit(buf_page_get_mutex(bpage)); if (!srv_force_recovery) { - buf_mark_space_corrupt(bpage); + buf_mark_space_corrupt(bpage, *space); } /* After this point bpage can't be referenced. */ @@ -5921,7 +5912,6 @@ static dberr_t buf_page_check_corrupt(buf_page_t* bpage, fil_space_t* space) byte* dst_frame = (bpage->zip.data) ? bpage->zip.data : ((buf_block_t*) bpage)->frame; dberr_t err = DB_SUCCESS; - bool corrupted = false; /* In buf_decrypt_after_read we have either decrypted the page if page post encryption checksum matches and used key_id is found @@ -5929,33 +5919,20 @@ static dberr_t buf_page_check_corrupt(buf_page_t* bpage, fil_space_t* space) not decrypted and it could be either encrypted and corrupted or corrupted or good page. If we decrypted, there page could still be corrupted if used key does not match. */ - const bool still_encrypted = mach_read_from_4( + const bool seems_encrypted = mach_read_from_4( dst_frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION) && space->crypt_data - && space->crypt_data->type != CRYPT_SCHEME_UNENCRYPTED - && !bpage->encrypted - && fil_space_verify_crypt_checksum(dst_frame, bpage->size); + && space->crypt_data->type != CRYPT_SCHEME_UNENCRYPTED; - if (!still_encrypted) { - /* If traditional checksums match, we assume that page is - not anymore encrypted. */ - corrupted = buf_page_is_corrupted( - true, dst_frame, bpage->size, space); - - if (!corrupted) { - bpage->encrypted = false; - } else { - err = DB_PAGE_CORRUPTED; - } + /* If traditional checksums match, we assume that page is + not anymore encrypted. */ + if (buf_page_is_corrupted( + true, dst_frame, bpage->size, space)) { + err = DB_PAGE_CORRUPTED; } - /* Pages that we think are unencrypted but do not match the checksum - checks could be corrupted or encrypted or both. */ - if (corrupted && !bpage->encrypted) { - /* An error will be reported by - buf_page_io_complete(). */ - } else if (still_encrypted || (bpage->encrypted && corrupted)) { - bpage->encrypted = true; + if (seems_encrypted && err == DB_PAGE_CORRUPTED + && bpage->id.page_no() != 0) { err = DB_DECRYPTION_FAILED; ib::error() @@ -6017,7 +5994,6 @@ buf_page_io_complete(buf_page_t* bpage, bool dblwr, bool evict) if (io_type == BUF_IO_READ) { ulint read_page_no = 0; ulint read_space_id = 0; - uint key_version = 0; byte* frame = bpage->zip.data ? bpage->zip.data : reinterpret_cast(bpage)->frame; @@ -6057,8 +6033,6 @@ buf_page_io_complete(buf_page_t* bpage, bool dblwr, bool evict) read_page_no = mach_read_from_4(frame + FIL_PAGE_OFFSET); read_space_id = mach_read_from_4( frame + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID); - key_version = mach_read_from_4( - frame + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION); if (bpage->id.space() == TRX_SYS_SPACE && buf_dblwr_page_inside(bpage->id.page_no())) { @@ -6174,23 +6148,9 @@ database_corrupted: && fil_page_get_type(frame) == FIL_PAGE_INDEX && page_is_leaf(frame)) { - if (bpage->encrypted) { - ib::warn() - << "Table in tablespace " - << bpage->id.space() - << " encrypted. However key " - "management plugin or used " - << "key_version " << key_version - << " is not found or" - " used encryption algorithm or method does not match." - " Can't continue opening the table."; - } else { - - ibuf_merge_or_delete_for_page( - (buf_block_t*) bpage, bpage->id, - &bpage->size, TRUE); - } - + ibuf_merge_or_delete_for_page( + (buf_block_t*) bpage, bpage->id, + &bpage->size, TRUE); } fil_space_release_for_io(space); diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc index e1817985685..918ffd77542 100644 --- a/storage/innobase/fil/fil0crypt.cc +++ b/storage/innobase/fil/fil0crypt.cc @@ -793,7 +793,6 @@ Decrypt a page. @param[in] space Tablespace @param[in] tmp_frame Temporary buffer used for decrypting @param[in,out] src_frame Page to decrypt -@param[out] decrypted true if page was decrypted @return decrypted page, or original not encrypted page if decryption is not needed.*/ UNIV_INTERN @@ -801,13 +800,11 @@ byte* fil_space_decrypt( const fil_space_t* space, byte* tmp_frame, - byte* src_frame, - bool* decrypted) + byte* src_frame) { dberr_t err = DB_SUCCESS; byte* res = NULL; const page_size_t page_size(space->flags); - *decrypted = false; ut_ad(space->crypt_data != NULL && space->crypt_data->is_encrypted()); ut_ad(space->n_pending_ios > 0); @@ -817,7 +814,6 @@ fil_space_decrypt( if (err == DB_SUCCESS) { if (encrypted) { - *decrypted = true; /* Copy the decrypted page back to page buffer, not really any other options. */ memcpy(src_frame, tmp_frame, page_size.physical()); diff --git a/storage/innobase/ibuf/ibuf0ibuf.cc b/storage/innobase/ibuf/ibuf0ibuf.cc index 34cba10c6b5..ccc471da2aa 100644 --- a/storage/innobase/ibuf/ibuf0ibuf.cc +++ b/storage/innobase/ibuf/ibuf0ibuf.cc @@ -342,10 +342,8 @@ ibuf_header_page_get( page_id_t(IBUF_SPACE_ID, FSP_IBUF_HEADER_PAGE_NO), univ_page_size, RW_X_LATCH, mtr); - - if (!block->page.encrypted) { + if (block) { buf_block_dbg_add_level(block, SYNC_IBUF_HEADER); - page = buf_block_get_frame(block); } diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h index 6bfeeb83018..af2a7d90101 100644 --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h @@ -1468,8 +1468,6 @@ public: if written again we check is TRIM operation needed. */ - bool encrypted; /*!< page is still encrypted */ - ulint real_size; /*!< Real size of the page Normal pages == UNIV_PAGE_SIZE page compressed pages, payload diff --git a/storage/innobase/include/fil0crypt.h b/storage/innobase/include/fil0crypt.h index 24108f95167..3c56315ee9a 100644 --- a/storage/innobase/include/fil0crypt.h +++ b/storage/innobase/include/fil0crypt.h @@ -375,7 +375,6 @@ Decrypt a page @param[in] space Tablespace @param[in] tmp_frame Temporary buffer used for decrypting @param[in,out] src_frame Page to decrypt -@param[out] decrypted true if page was decrypted @return decrypted page, or original not encrypted page if decryption is not needed.*/ UNIV_INTERN @@ -383,8 +382,7 @@ byte* fil_space_decrypt( const fil_space_t* space, byte* tmp_frame, - byte* src_frame, - bool* decrypted) + byte* src_frame) MY_ATTRIBUTE((warn_unused_result)); /****************************************************************** From 6fde0073bfa8f572a02637816a389e56e430edf9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 9 Oct 2019 18:47:14 +0300 Subject: [PATCH 29/44] Rename log_make_checkpoint_at() to log_make_checkpoint() The function was always called with lsn=LSN_MAX. Remove that redundant parameter. Spotted by Thirunarayanan Balathandayuthapani. --- storage/innobase/buf/buf0dblwr.cc | 2 +- storage/innobase/handler/ha_innodb.cc | 2 +- storage/innobase/include/log0log.h | 8 +++----- storage/innobase/include/srv0srv.h | 4 ++-- storage/innobase/log/log0log.cc | 12 +++++------- storage/innobase/row/row0import.cc | 2 +- storage/innobase/row/row0trunc.cc | 2 +- storage/innobase/srv/srv0srv.cc | 4 ++-- storage/innobase/srv/srv0start.cc | 2 +- 9 files changed, 17 insertions(+), 21 deletions(-) diff --git a/storage/innobase/buf/buf0dblwr.cc b/storage/innobase/buf/buf0dblwr.cc index 8410a753699..78a7c06a3f0 100644 --- a/storage/innobase/buf/buf0dblwr.cc +++ b/storage/innobase/buf/buf0dblwr.cc @@ -328,7 +328,7 @@ too_small: mtr_commit(&mtr); /* Flush the modified pages to disk and make a checkpoint */ - log_make_checkpoint_at(LSN_MAX); + log_make_checkpoint(); /* Remove doublewrite pages from LRU */ buf_pool_invalidate(); diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 5ff36aa9c24..3267983c89f 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -19075,7 +19075,7 @@ checkpoint_now_set( + (log_sys->append_on_checkpoint != NULL ? log_sys->append_on_checkpoint->size() : 0) < log_sys->lsn) { - log_make_checkpoint_at(LSN_MAX); + log_make_checkpoint(); fil_flush_file_spaces(FIL_TYPE_LOG); } diff --git a/storage/innobase/include/log0log.h b/storage/innobase/include/log0log.h index 8a6705359db..0fd983a1a10 100644 --- a/storage/innobase/include/log0log.h +++ b/storage/innobase/include/log0log.h @@ -210,15 +210,13 @@ log_buffer_sync_in_background( /** Make a checkpoint. Note that this function does not flush dirty blocks from the buffer pool: it only checks what is lsn of the oldest modification in the pool, and writes information about the lsn in -log files. Use log_make_checkpoint_at() to flush also the pool. +log files. Use log_make_checkpoint() to flush also the pool. @param[in] sync whether to wait for the write to complete @return true if success, false if a checkpoint write was already running */ bool log_checkpoint(bool sync); -/** Make a checkpoint at or after a specified LSN. -@param[in] lsn the log sequence number, or LSN_MAX -for the latest LSN */ -void log_make_checkpoint_at(lsn_t lsn); +/** Make a checkpoint */ +void log_make_checkpoint(); /****************************************************************//** Makes a checkpoint at the latest lsn and writes it to first page of each diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h index 591eec4b42c..0f1936eac70 100644 --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h @@ -656,11 +656,11 @@ do { \ #ifdef HAVE_PSI_STAGE_INTERFACE /** Performance schema stage event for monitoring ALTER TABLE progress -everything after flush log_make_checkpoint_at(). */ +everything after flush log_make_checkpoint(). */ extern PSI_stage_info srv_stage_alter_table_end; /** Performance schema stage event for monitoring ALTER TABLE progress -log_make_checkpoint_at(). */ +log_make_checkpoint(). */ extern PSI_stage_info srv_stage_alter_table_flush; /** Performance schema stage event for monitoring ALTER TABLE progress diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc index 682a79409f9..c3eaa05b680 100644 --- a/storage/innobase/log/log0log.cc +++ b/storage/innobase/log/log0log.cc @@ -1553,7 +1553,7 @@ log_append_on_checkpoint( /** Make a checkpoint. Note that this function does not flush dirty blocks from the buffer pool: it only checks what is lsn of the oldest modification in the pool, and writes information about the lsn in -log files. Use log_make_checkpoint_at() to flush also the pool. +log files. Use log_make_checkpoint() to flush also the pool. @param[in] sync whether to wait for the write to complete @return true if success, false if a checkpoint write was already running */ bool log_checkpoint(bool sync) @@ -1667,14 +1667,12 @@ bool log_checkpoint(bool sync) return(true); } -/** Make a checkpoint at or after a specified LSN. -@param[in] lsn the log sequence number, or LSN_MAX -for the latest LSN */ -void log_make_checkpoint_at(lsn_t lsn) +/** Make a checkpoint */ +void log_make_checkpoint() { /* Preflush pages synchronously */ - while (!log_preflush_pool_modified_pages(lsn)) { + while (!log_preflush_pool_modified_pages(LSN_MAX)) { /* Flush as much as we can */ } @@ -2010,7 +2008,7 @@ wait_suspend_loop: if (!srv_read_only_mode) { service_manager_extend_timeout(INNODB_EXTEND_TIMEOUT_INTERVAL, "ensuring dirty buffer pool are written to log"); - log_make_checkpoint_at(LSN_MAX); + log_make_checkpoint(); log_mutex_enter(); diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index abadeafba9c..6d0d77c9f5b 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -2090,7 +2090,7 @@ row_import_cleanup( DBUG_EXECUTE_IF("ib_import_before_checkpoint_crash", DBUG_SUICIDE();); - log_make_checkpoint_at(LSN_MAX); + log_make_checkpoint(); return(err); } diff --git a/storage/innobase/row/row0trunc.cc b/storage/innobase/row/row0trunc.cc index 9906ba11614..09573610e7c 100644 --- a/storage/innobase/row/row0trunc.cc +++ b/storage/innobase/row/row0trunc.cc @@ -2224,7 +2224,7 @@ truncate_t::fixup_tables_in_non_system_tablespace() if (err == DB_SUCCESS && s_tables.size() > 0) { - log_make_checkpoint_at(LSN_MAX); + log_make_checkpoint(); } for (ulint i = 0; i < s_tables.size(); ++i) { diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc index a93a7cd71f8..bff26d05029 100644 --- a/storage/innobase/srv/srv0srv.cc +++ b/storage/innobase/srv/srv0srv.cc @@ -669,12 +669,12 @@ static const ulint SRV_MASTER_SLOT = 0; #ifdef HAVE_PSI_STAGE_INTERFACE /** Performance schema stage event for monitoring ALTER TABLE progress -everything after flush log_make_checkpoint_at(). */ +everything after flush log_make_checkpoint(). */ PSI_stage_info srv_stage_alter_table_end = {0, "alter table (end)", PSI_FLAG_STAGE_PROGRESS}; /** Performance schema stage event for monitoring ALTER TABLE progress -log_make_checkpoint_at(). */ +log_make_checkpoint(). */ PSI_stage_info srv_stage_alter_table_flush = {0, "alter table (flush)", PSI_FLAG_STAGE_PROGRESS}; diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index 46a2b7b7c09..75bdf17eab7 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -516,7 +516,7 @@ create_log_files( (log_sys->lsn - log_sys->last_checkpoint_lsn)); log_mutex_exit(); - log_make_checkpoint_at(LSN_MAX); + log_make_checkpoint(); return(DB_SUCCESS); } From cf71cc838e608b4a4b8ae2557d4957ecb9bef97a Mon Sep 17 00:00:00 2001 From: Sergey Vojtovich Date: Wed, 9 Oct 2019 22:05:33 +0400 Subject: [PATCH 30/44] After merge fix, this line was removed in adefaef --- sql/sql_show.cc | 1 - 1 file changed, 1 deletion(-) diff --git a/sql/sql_show.cc b/sql/sql_show.cc index deb1feb4f08..a93abe1ea77 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -4615,7 +4615,6 @@ fill_schema_table_by_open(THD *thd, MEM_ROOT *mem_root, DBUG_ASSERT(thd->lex == lex); result= open_tables_only_view_structure(thd, table_list, can_deadlock); - (void) read_statistics_for_tables_if_needed(thd, table_list); DEBUG_SYNC(thd, "after_open_table_ignore_flush"); From 6684989801cd0e93be5646716bb3cffedd271ce6 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Wed, 30 May 2018 12:43:54 +0300 Subject: [PATCH 31/44] versioning test suite fixes Preparation for MDEV-16210: replace.test: key_type combinations: PK and UNIQUE. foreign.test: Preparation for key_type combinations. Other fixes: * Merged versioning.update2 into versioning.update; * Removed test2 database and done individual drop instead. --- .../federated/federatedx_versioning.result | 8 +-- .../federated/federatedx_versioning.test | 7 ++- mysql-test/suite/versioning/common.inc | 2 - mysql-test/suite/versioning/common_finish.inc | 3 -- .../suite/versioning/key_type.combinations | 3 ++ mysql-test/suite/versioning/key_type.inc | 14 +++++ mysql-test/suite/versioning/r/alter.result | 17 +++--- mysql-test/suite/versioning/r/create.result | 13 +++-- mysql-test/suite/versioning/r/delete.result | 1 + mysql-test/suite/versioning/r/foreign.result | 46 +++++++++------- mysql-test/suite/versioning/r/online.result | 4 +- .../suite/versioning/r/partition.result | 21 ++++---- .../versioning/r/partition_innodb.result | 1 + mysql-test/suite/versioning/r/replace.result | 10 ++-- mysql-test/suite/versioning/r/select.result | 10 ++-- mysql-test/suite/versioning/r/truncate.result | 2 +- mysql-test/suite/versioning/r/trx_id.result | 4 +- .../suite/versioning/r/update-big.result | 2 +- mysql-test/suite/versioning/r/update.result | 24 +++++++++ mysql-test/suite/versioning/r/update2.result | 21 -------- mysql-test/suite/versioning/r/view.result | 9 ++-- mysql-test/suite/versioning/t/alter.test | 5 +- mysql-test/suite/versioning/t/create.test | 3 +- mysql-test/suite/versioning/t/delete.test | 1 + .../suite/versioning/t/engines.combinations | 8 --- mysql-test/suite/versioning/t/foreign.test | 53 ++++++++++++------- mysql-test/suite/versioning/t/online.test | 4 +- mysql-test/suite/versioning/t/partition.test | 14 ++--- .../suite/versioning/t/partition_innodb.test | 2 + mysql-test/suite/versioning/t/replace.test | 17 ++++-- mysql-test/suite/versioning/t/trx_id.test | 5 +- mysql-test/suite/versioning/t/update-big.test | 2 +- mysql-test/suite/versioning/t/update.test | 30 +++++++++++ mysql-test/suite/versioning/t/update2.test | 31 ----------- mysql-test/suite/versioning/t/view.test | 9 ++-- 35 files changed, 223 insertions(+), 183 deletions(-) create mode 100644 mysql-test/suite/versioning/key_type.combinations create mode 100644 mysql-test/suite/versioning/key_type.inc delete mode 100644 mysql-test/suite/versioning/r/update2.result delete mode 100644 mysql-test/suite/versioning/t/engines.combinations delete mode 100644 mysql-test/suite/versioning/t/update2.test diff --git a/mysql-test/suite/federated/federatedx_versioning.result b/mysql-test/suite/federated/federatedx_versioning.result index 9a7b180a5ab..c708b5f7932 100644 --- a/mysql-test/suite/federated/federatedx_versioning.result +++ b/mysql-test/suite/federated/federatedx_versioning.result @@ -4,14 +4,14 @@ row_start SYS_TYPE as row start invisible, row_end SYS_TYPE as row end invisible, period for system_time (row_start, row_end)) with system versioning; -create or replace table tf engine=FEDERATED connection='mysql://root@127.0.0.1:MASTER_MYPORT/test2/t1'; +create or replace table tf engine=FEDERATED connection='mysql://root@127.0.0.1:MASTER_MYPORT/test/t1'; show create table tf; Table Create Table tf CREATE TABLE `tf` ( `x` int(11) DEFAULT NULL, `row_start` SYS_TYPE NOT NULL INVISIBLE DEFAULT 0, `row_end` SYS_TYPE NOT NULL INVISIBLE DEFAULT 0 -) ENGINE=FEDERATED DEFAULT CHARSET=latin1 CONNECTION='mysql://root@127.0.0.1:MASTER_MYPORT/test2/t1' +) ENGINE=FEDERATED DEFAULT CHARSET=latin1 CONNECTION='mysql://root@127.0.0.1:MASTER_MYPORT/test/t1' # INSERT insert into t1 values (1); select * from tf; @@ -57,7 +57,7 @@ row_start SYS_TYPE as row start invisible, row_end SYS_TYPE as row end invisible, period for system_time (row_start, row_end)) with system versioning; -create or replace table t2f engine=FEDERATED connection='mysql://root@127.0.0.1:MASTER_MYPORT/test2/t2'; +create or replace table t2f engine=FEDERATED connection='mysql://root@127.0.0.1:MASTER_MYPORT/test/t2'; insert t2f (id, y) values (1, 2); replace t2f (id, y) values (1, 3); select *, check_row(row_start, row_end) from t2 for system_time all @@ -96,3 +96,5 @@ order by y; id y check_row(row_start, row_end) 2 2 HISTORICAL ROW 2 22 CURRENT ROW +drop view vt1; +drop tables t1, t2, t2f, tf; diff --git a/mysql-test/suite/federated/federatedx_versioning.test b/mysql-test/suite/federated/federatedx_versioning.test index b003403b629..40d0bc5018a 100644 --- a/mysql-test/suite/federated/federatedx_versioning.test +++ b/mysql-test/suite/federated/federatedx_versioning.test @@ -11,7 +11,7 @@ eval create or replace table t1 ( period for system_time (row_start, row_end)) with system versioning; --replace_result $MASTER_MYPORT MASTER_MYPORT -eval create or replace table tf engine=FEDERATED connection='mysql://root@127.0.0.1:$MASTER_MYPORT/test2/t1'; +eval create or replace table tf engine=FEDERATED connection='mysql://root@127.0.0.1:$MASTER_MYPORT/test/t1'; --replace_result $MASTER_MYPORT MASTER_MYPORT $sys_datatype_expl SYS_TYPE "'0000-00-00 00:00:00.000000'" 0 show create table tf; --echo # INSERT @@ -45,7 +45,7 @@ eval create or replace table t2 ( period for system_time (row_start, row_end)) with system versioning; --replace_result $MASTER_MYPORT MASTER_MYPORT -eval create or replace table t2f engine=FEDERATED connection='mysql://root@127.0.0.1:$MASTER_MYPORT/test2/t2'; +eval create or replace table t2f engine=FEDERATED connection='mysql://root@127.0.0.1:$MASTER_MYPORT/test/t2'; insert t2f (id, y) values (1, 2); replace t2f (id, y) values (1, 3); select *, check_row(row_start, row_end) from t2 for system_time all @@ -72,4 +72,7 @@ order by x; select *, check_row(row_start, row_end) from t2 for system_time all order by y; +drop view vt1; +drop tables t1, t2, t2f, tf; + --source suite/versioning/common_finish.inc diff --git a/mysql-test/suite/versioning/common.inc b/mysql-test/suite/versioning/common.inc index 39abccd7ecd..355b571e5a0 100644 --- a/mysql-test/suite/versioning/common.inc +++ b/mysql-test/suite/versioning/common.inc @@ -4,8 +4,6 @@ if (!$TEST_VERSIONING_SO) --skip needs test_versioning plugin } source include/have_innodb.inc; -create database test2 character set latin1; -use test2; set @@session.time_zone='+00:00'; select ifnull(max(transaction_id), 0) into @start_trx_id from mysql.transaction_registry; diff --git a/mysql-test/suite/versioning/common_finish.inc b/mysql-test/suite/versioning/common_finish.inc index 90a305078c8..61641c6c5ce 100644 --- a/mysql-test/suite/versioning/common_finish.inc +++ b/mysql-test/suite/versioning/common_finish.inc @@ -5,7 +5,4 @@ drop procedure if exists verify_trt_dummy; drop function if exists current_row; drop function if exists check_row; --enable_warnings - -use test; -drop database test2; --enable_query_log diff --git a/mysql-test/suite/versioning/key_type.combinations b/mysql-test/suite/versioning/key_type.combinations new file mode 100644 index 00000000000..93c0ea8bc06 --- /dev/null +++ b/mysql-test/suite/versioning/key_type.combinations @@ -0,0 +1,3 @@ +[unique] +[pk] +[sec] diff --git a/mysql-test/suite/versioning/key_type.inc b/mysql-test/suite/versioning/key_type.inc new file mode 100644 index 00000000000..888a1d97098 --- /dev/null +++ b/mysql-test/suite/versioning/key_type.inc @@ -0,0 +1,14 @@ +--disable_query_log +if ($MTR_COMBINATION_UNIQUE) +{ + let $KEY_TYPE= unique; +} +if ($MTR_COMBINATION_PK) +{ + let $KEY_TYPE= primary key; +} +if ($MTR_COMBINATION_SEC) +{ + let $KEY_TYPE= key; +} +--enable_query_log diff --git a/mysql-test/suite/versioning/r/alter.result b/mysql-test/suite/versioning/r/alter.result index b5d44332955..a453617d3b3 100644 --- a/mysql-test/suite/versioning/r/alter.result +++ b/mysql-test/suite/versioning/r/alter.result @@ -18,13 +18,13 @@ t CREATE TABLE `t` ( `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING alter table t add column y int; -ERROR HY000: Not allowed for system-versioned `test2`.`t`. Change @@system_versioning_alter_history to proceed with ALTER. +ERROR HY000: Not allowed for system-versioned `test`.`t`. Change @@system_versioning_alter_history to proceed with ALTER. alter table t add primary key (a); -ERROR HY000: Not allowed for system-versioned `test2`.`t`. Change @@system_versioning_alter_history to proceed with ALTER. +ERROR HY000: Not allowed for system-versioned `test`.`t`. Change @@system_versioning_alter_history to proceed with ALTER. alter table t add unique key (a); -ERROR HY000: Not allowed for system-versioned `test2`.`t`. Change @@system_versioning_alter_history to proceed with ALTER. +ERROR HY000: Not allowed for system-versioned `test`.`t`. Change @@system_versioning_alter_history to proceed with ALTER. alter table t engine innodb; -ERROR HY000: Not allowed for system-versioned `test2`.`t`. Change to/from native system versioning engine is not supported. +ERROR HY000: Not allowed for system-versioned `test`.`t`. Change to/from native system versioning engine is not supported. alter table t drop system versioning; show create table t; Table Create Table @@ -527,7 +527,7 @@ create or replace table t (x int) with system versioning; ERROR HY000: System versioning tables in the `mysql` database are not suported alter table user add system versioning; ERROR HY000: System versioning tables in the `mysql` database are not suported -use test2; +use test; # MDEV-15956 Strange ER_UNSUPPORTED_ACTION_ON_GENERATED_COLUMN upon ALTER on versioning column create or replace table t1 (i int, j int as (i), s timestamp(6) as row start, e timestamp(6) as row end, period for system_time(s,e)) with system versioning; alter table t1 modify s timestamp(6) as row start; @@ -537,10 +537,10 @@ create or replace table t (a int) with system versioning; insert into t values (0), (1); delete from t where a = 0; alter table t add check (a > 1); -ERROR 23000: CONSTRAINT `CONSTRAINT_1` failed for `test2`.`t` +ERROR 23000: CONSTRAINT `CONSTRAINT_1` failed for `test`.`t` alter table t add check (a > 0); insert into t values (0); -ERROR 23000: CONSTRAINT `CONSTRAINT_1` failed for `test2`.`t` +ERROR 23000: CONSTRAINT `CONSTRAINT_1` failed for `test`.`t` insert into t values (2); # # MDEV-18869 Assertion `!((field)->vcol_info && (field)->stored_in_db())' failed in innodb_col_no upon altering table with system versioning @@ -679,5 +679,4 @@ alter table t add column c int without system versioning, change column c c int, change column b b int without system versioning; -drop database test; -create database test; +drop table t; diff --git a/mysql-test/suite/versioning/r/create.result b/mysql-test/suite/versioning/r/create.result index f9d13123db5..5189e55bc30 100644 --- a/mysql-test/suite/versioning/r/create.result +++ b/mysql-test/suite/versioning/r/create.result @@ -15,7 +15,7 @@ t1 CREATE TABLE `t1` ( ) ENGINE=DEFAULT_ENGINE DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING select table_catalog,table_schema,table_name,table_type,version,table_rows,data_free,auto_increment,check_time,table_collation,checksum,create_options,table_comment from information_schema.tables where table_name='t1'; table_catalog def -table_schema test2 +table_schema test table_name t1 table_type SYSTEM VERSIONED version 10 @@ -29,7 +29,7 @@ create_options table_comment select table_catalog,table_schema,table_name,column_name,ordinal_position,column_default,character_maximum_length,character_octet_length,character_set_name,collation_name,column_key,extra,column_comment,is_generated,generation_expression from information_schema.columns where table_name='t1'; table_catalog def -table_schema test2 +table_schema test table_name t1 column_name x1 ordinal_position 1 @@ -44,7 +44,7 @@ column_comment is_generated NEVER generation_expression NULL table_catalog def -table_schema test2 +table_schema test table_name t1 column_name Sys_start ordinal_position 2 @@ -59,7 +59,7 @@ column_comment start is_generated ALWAYS generation_expression ROW START table_catalog def -table_schema test2 +table_schema test table_name t1 column_name Sys_end ordinal_position 3 @@ -235,7 +235,7 @@ tt1 CREATE TABLE `tt1` ( drop table tt1; create temporary table tt1 like t1; Warnings: -Warning 1105 System versioning is stripped from temporary `test2.tt1` +Warning 1105 System versioning is stripped from temporary `test.tt1` # Temporary is stripped from versioning show create table tt1; Table Create Table @@ -523,5 +523,4 @@ create or replace table t1 (x int without system versioning) with system versioning select 1 as x; ERROR HY000: Table `t1` must have at least one versioned column -drop database test; -create database test; +drop tables t0, t1, t2, t3; diff --git a/mysql-test/suite/versioning/r/delete.result b/mysql-test/suite/versioning/r/delete.result index cfce8aa3069..77b7fc80286 100644 --- a/mysql-test/suite/versioning/r/delete.result +++ b/mysql-test/suite/versioning/r/delete.result @@ -115,3 +115,4 @@ select x from t1 for system_time all; x 2 1 +drop table t1; diff --git a/mysql-test/suite/versioning/r/foreign.result b/mysql-test/suite/versioning/r/foreign.result index 001577750ba..e5ffb6c5f0c 100644 --- a/mysql-test/suite/versioning/r/foreign.result +++ b/mysql-test/suite/versioning/r/foreign.result @@ -2,7 +2,8 @@ # Test RESTRICT # ################# create table parent( -id int unique key +id int, +KEY_TYPE (id) ) engine innodb; create table child( parent_id int, @@ -16,13 +17,13 @@ on update restrict insert into parent values(1); insert into child values(1); delete from parent where id = 1; -ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test2`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)) +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)) delete from child where parent_id = 1; delete from parent where id = 1; insert into parent values(1); insert into child values(1); update parent set id=id+1; -ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test2`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)) +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)) delete from child; update parent set id=id+1; select * from child for system_time all; @@ -35,7 +36,8 @@ drop table parent; # Test when clustered index is a foreign key # ############################################## create table parent( -id int(10) unsigned unique key +id int(10) unsigned, +KEY_TYPE (id) ) engine innodb; create table child( parent_id int(10) unsigned primary key, @@ -47,14 +49,15 @@ foreign key(parent_id) references parent(id) insert into parent values(1); insert into child values(1); delete from parent where id = 1; -ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test2`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)) +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)) drop table child; drop table parent; ################ # Test CASCADE # ################ create table parent( -id int unique key +id int, +KEY_TYPE (id) ) engine innodb; create table child( parent_id int, @@ -87,7 +90,8 @@ parent_id drop table child; drop table parent; create or replace table parent ( -id int primary key, +id int, +KEY_TYPE(id), sys_start SYS_DATATYPE as row start invisible, sys_end SYS_DATATYPE as row end invisible, period for system_time(sys_start, sys_end) @@ -110,7 +114,8 @@ x parent_id drop table child; drop table parent; create or replace table parent ( -id int primary key +id int, +KEY_TYPE(id) ) engine innodb; create or replace table child ( @@ -138,8 +143,9 @@ drop table parent; ################# # Test SET NULL # ################# -create or replace table parent( -id int unique key +create table parent( +id int, +KEY_TYPE (id) ) engine innodb; create or replace table child( parent_id int, @@ -183,7 +189,8 @@ drop table parent; # Parent table is foreign # ########################### create or replace table parent( -id int unique key, +id int, +KEY_TYPE (id), sys_start SYS_DATATYPE as row start invisible, sys_end SYS_DATATYPE as row end invisible, period for system_time(sys_start, sys_end) @@ -195,26 +202,27 @@ foreign key(parent_id) references parent(id) insert into parent values(1); insert into child values(1); delete from parent; -ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test2`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)) +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)) update parent set id=2; -ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test2`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)) +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)) delete from child; delete from parent; insert into child values(1); -ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test2`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)) +ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)) insert into parent values(1); insert into child values(1); delete from parent; -ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test2`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)) +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)) update parent set id=2; -ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test2`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)) +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`child`, CONSTRAINT `child_ibfk_1` FOREIGN KEY (`parent_id`) REFERENCES `parent` (`id`)) drop table child; drop table parent; ################### # crash on DELETE # ################### create or replace table a ( -cola int(10) primary key, +cola int(10), +KEY_TYPE (cola), v_cola int(10) as (cola mod 10) virtual, sys_start SYS_DATATYPE as row start invisible, sys_end SYS_DATATYPE as row end invisible, @@ -233,7 +241,7 @@ foreign key (v_cola) references a (v_cola); insert into a(cola) values (12); insert into b(cola, v_cola) values (10,2); delete from a; -ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test2`.`b`, CONSTRAINT `v_cola_fk` FOREIGN KEY (`v_cola`) REFERENCES `a` (`v_cola`)) +ERROR 23000: Cannot delete or update a parent row: a foreign key constraint fails (`test`.`b`, CONSTRAINT `v_cola_fk` FOREIGN KEY (`v_cola`) REFERENCES `a` (`v_cola`)) drop table b, a; ############################################### # CASCADE UPDATE foreign not system versioned # @@ -296,7 +304,7 @@ SET FOREIGN_KEY_CHECKS= OFF; INSERT IGNORE INTO t2 VALUES (1); SET FOREIGN_KEY_CHECKS= ON; UPDATE t2 SET f2= 2; -ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test2`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`f2`) REFERENCES `t1` (`f1`)) +ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`f2`) REFERENCES `t1` (`f1`)) DELETE FROM t2; DROP TABLE t2, t1; # diff --git a/mysql-test/suite/versioning/r/online.result b/mysql-test/suite/versioning/r/online.result index 2e5a165dd81..aabf2b98cbf 100644 --- a/mysql-test/suite/versioning/r/online.result +++ b/mysql-test/suite/versioning/r/online.result @@ -89,13 +89,13 @@ period for system_time(row_start, row_end) insert into t values (1, 1); select c.prtype from information_schema.innodb_sys_columns as c join information_schema.innodb_sys_tables as t on c.table_id=t.table_id -where t.name='test2/t' and c.name='b'; +where t.name='test/t' and c.name='b'; prtype 50179 set @@system_versioning_alter_history=keep; select c.prtype from information_schema.innodb_sys_columns as c join information_schema.innodb_sys_tables as t on c.table_id=t.table_id -where t.name='test2/t' and c.name='b'; +where t.name='test/t' and c.name='b'; prtype 50179 show create table t; diff --git a/mysql-test/suite/versioning/r/partition.result b/mysql-test/suite/versioning/r/partition.result index b364dca5376..2163ebeb1a0 100644 --- a/mysql-test/suite/versioning/r/partition.result +++ b/mysql-test/suite/versioning/r/partition.result @@ -46,7 +46,7 @@ period for system_time(row_start, row_end)) engine=DEFAULT_ENGINE with system versioning partition by hash(i); alter table t1 engine=NON_DEFAULT_ENGINE; -ERROR HY000: Not allowed for system-versioned `test2`.`t1`. Change to/from native system versioning engine is not supported. +ERROR HY000: Not allowed for system-versioned `test`.`t1`. Change to/from native system versioning engine is not supported. ## CREATE TABLE create or replace table t1 (x int) partition by system_time ( @@ -254,11 +254,11 @@ x 6 insert into t1 values (7), (8); Warnings: -Warning 4114 Versioned table `test2`.`t1`: partition `p1` is full, add more HISTORY partitions +Warning 4114 Versioned table `test`.`t1`: partition `p1` is full, add more HISTORY partitions ### warn about full partition delete from t1; Warnings: -Warning 4114 Versioned table `test2`.`t1`: partition `p1` is full, add more HISTORY partitions +Warning 4114 Versioned table `test`.`t1`: partition `p1` is full, add more HISTORY partitions select * from t1 partition (p1) order by x; x 4 @@ -433,16 +433,16 @@ create or replace table t1 (i int) with system versioning partition by system_time interval 1 hour ( partition p0 history, partition pn current); set @ts=(select partition_description from information_schema.partitions -where table_schema='test2' and table_name='t1' and partition_name='p0'); +where table_schema='test' and table_name='t1' and partition_name='p0'); alter table t1 add column b int; -select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test2' and table_name='t1'; +select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test' and table_name='t1'; partition_name partition_ordinal_position partition_method timediff(partition_description, @ts) p0 1 SYSTEM_TIME 00:00:00.000000 pn 2 SYSTEM_TIME NULL Warnings: Warning 1292 Truncated incorrect time value: 'CURRENT' alter table t1 add partition (partition p1 history, partition p2 history); -select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test2' and table_name='t1'; +select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test' and table_name='t1'; partition_name partition_ordinal_position partition_method timediff(partition_description, @ts) p0 1 SYSTEM_TIME 00:00:00.000000 p1 2 SYSTEM_TIME 01:00:00.000000 @@ -451,7 +451,7 @@ pn 4 SYSTEM_TIME NULL Warnings: Warning 1292 Truncated incorrect time value: 'CURRENT' alter table t1 drop partition p0; -select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test2' and table_name='t1'; +select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test' and table_name='t1'; partition_name partition_ordinal_position partition_method timediff(partition_description, @ts) p1 1 SYSTEM_TIME 01:00:00.000000 p2 2 SYSTEM_TIME 02:00:00.000000 @@ -460,7 +460,7 @@ Warnings: Warning 1292 Truncated incorrect time value: 'CURRENT' alter table t1 drop partition p2; ERROR HY000: Can only drop oldest partitions when rotating by INTERVAL -select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test2' and table_name='t1'; +select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test' and table_name='t1'; partition_name partition_ordinal_position partition_method timediff(partition_description, @ts) p1 1 SYSTEM_TIME 01:00:00.000000 p2 2 SYSTEM_TIME 02:00:00.000000 @@ -556,7 +556,7 @@ insert into t1 values (0), (1), (2), (3); delete from t1 where x < 3; delete from t1; Warnings: -Warning 4114 Versioned table `test2`.`t1`: partition `p1` is full, add more HISTORY partitions +Warning 4114 Versioned table `test`.`t1`: partition `p1` is full, add more HISTORY partitions unlock tables; # # MDEV-20336 Assertion bitmap_is_set(read_partitions) upon SELECT FOR UPDATE from versioned table @@ -564,4 +564,5 @@ unlock tables; create or replace table t1 (pk int primary key) with system versioning partition by system_time limit 100 (partition p1 history, partition pn current); execute immediate 'select * from t1 for update'; pk -drop table t1; +drop view v1; +drop tables t, t1, t2, t3, t4; diff --git a/mysql-test/suite/versioning/r/partition_innodb.result b/mysql-test/suite/versioning/r/partition_innodb.result index 5fd2d7b4dce..3c4adce099a 100644 --- a/mysql-test/suite/versioning/r/partition_innodb.result +++ b/mysql-test/suite/versioning/r/partition_innodb.result @@ -21,6 +21,7 @@ partition p0 history, partition pn current ); ERROR HY000: `row_start` must be of type TIMESTAMP(6) for system-versioned table `#sql-temporary` +drop table t1; create or replace table t ( a int primary key, row_start bigint unsigned as row start invisible, diff --git a/mysql-test/suite/versioning/r/replace.result b/mysql-test/suite/versioning/r/replace.result index e5dcf61678e..bda61f118b0 100644 --- a/mysql-test/suite/versioning/r/replace.result +++ b/mysql-test/suite/versioning/r/replace.result @@ -1,9 +1,10 @@ -create table t ( -id int primary key, +create or replace table t( +id int, +KEY_TYPE(id), x int, row_start SYS_DATATYPE as row start invisible, row_end SYS_DATATYPE as row end invisible, -period for system_time (row_start, row_end) +period for system_time(row_start, row_end) ) with system versioning; insert t values (1, 2); replace t values (1, 3); @@ -32,7 +33,8 @@ insert into t1 values (1,1); create or replace table t2 (c int); create or replace view v as select t1.* from t1 join t2; replace into v (a, b) select a, b from t1; -drop table t1; +drop view v; +drop tables t1, t2; CREATE TABLE t1 ( pk INT AUTO_INCREMENT, f INT, diff --git a/mysql-test/suite/versioning/r/select.result b/mysql-test/suite/versioning/r/select.result index 40202edf4a6..c887e524e63 100644 --- a/mysql-test/suite/versioning/r/select.result +++ b/mysql-test/suite/versioning/r/select.result @@ -153,21 +153,21 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join) Warnings: -Note 1003 select `test2`.`t1`.`x` AS `IJ2_x1`,`test2`.`t1`.`y` AS `y1`,`test2`.`t2`.`x` AS `x2`,`test2`.`t2`.`y` AS `y2` from `test2`.`t1` FOR SYSTEM_TIME ALL join `test2`.`t2` FOR SYSTEM_TIME ALL where `test2`.`t1`.`x` = `test2`.`t2`.`x` and `test2`.`t2`.`row_end` > @`t0` and `test2`.`t2`.`row_start` <= @`t0` and `test2`.`t1`.`row_end` > @`t0` and `test2`.`t1`.`row_start` <= @`t0` +Note 1003 select `test`.`t1`.`x` AS `IJ2_x1`,`test`.`t1`.`y` AS `y1`,`test`.`t2`.`x` AS `x2`,`test`.`t2`.`y` AS `y2` from `test`.`t1` FOR SYSTEM_TIME ALL join `test`.`t2` FOR SYSTEM_TIME ALL where `test`.`t1`.`x` = `test`.`t2`.`x` and `test`.`t2`.`row_end` > @`t0` and `test`.`t2`.`row_start` <= @`t0` and `test`.`t1`.`row_end` > @`t0` and `test`.`t1`.`row_start` <= @`t0` explain extended select * from (select t1.x as LJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 left join t2 on t1.x = t2.x) for system_time as of timestamp @t0 as t; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where 1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) Warnings: -Note 1003 select `test2`.`t1`.`x` AS `LJ2_x1`,`test2`.`t1`.`y` AS `y1`,`test2`.`t2`.`x` AS `x2`,`test2`.`t2`.`y` AS `y2` from `test2`.`t1` FOR SYSTEM_TIME ALL left join `test2`.`t2` FOR SYSTEM_TIME ALL on(`test2`.`t2`.`x` = `test2`.`t1`.`x` and `test2`.`t2`.`row_end` > @`t0` and `test2`.`t2`.`row_start` <= @`t0`) where `test2`.`t1`.`row_end` > @`t0` and `test2`.`t1`.`row_start` <= @`t0` +Note 1003 select `test`.`t1`.`x` AS `LJ2_x1`,`test`.`t1`.`y` AS `y1`,`test`.`t2`.`x` AS `x2`,`test`.`t2`.`y` AS `y2` from `test`.`t1` FOR SYSTEM_TIME ALL left join `test`.`t2` FOR SYSTEM_TIME ALL on(`test`.`t2`.`x` = `test`.`t1`.`x` and `test`.`t2`.`row_end` > @`t0` and `test`.`t2`.`row_start` <= @`t0`) where `test`.`t1`.`row_end` > @`t0` and `test`.`t1`.`row_start` <= @`t0` explain extended select * from (select t1.x as RJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 right join t2 on t1.x = t2.x) for system_time as of timestamp @t0 as t; id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where 1 SIMPLE t1 ALL NULL NULL NULL NULL 5 100.00 Using where; Using join buffer (flat, BNL join) Warnings: -Note 1003 select `test2`.`t1`.`x` AS `RJ2_x1`,`test2`.`t1`.`y` AS `y1`,`test2`.`t2`.`x` AS `x2`,`test2`.`t2`.`y` AS `y2` from `test2`.`t2` FOR SYSTEM_TIME ALL left join `test2`.`t1` FOR SYSTEM_TIME ALL on(`test2`.`t1`.`x` = `test2`.`t2`.`x` and `test2`.`t1`.`row_end` > @`t0` and `test2`.`t1`.`row_start` <= @`t0`) where `test2`.`t2`.`row_end` > @`t0` and `test2`.`t2`.`row_start` <= @`t0` +Note 1003 select `test`.`t1`.`x` AS `RJ2_x1`,`test`.`t1`.`y` AS `y1`,`test`.`t2`.`x` AS `x2`,`test`.`t2`.`y` AS `y2` from `test`.`t2` FOR SYSTEM_TIME ALL left join `test`.`t1` FOR SYSTEM_TIME ALL on(`test`.`t1`.`x` = `test`.`t2`.`x` and `test`.`t1`.`row_end` > @`t0` and `test`.`t1`.`row_start` <= @`t0`) where `test`.`t2`.`row_end` > @`t0` and `test`.`t2`.`row_start` <= @`t0` select * from (select t1.x as IJ2_x1, t1.y as y1, t2.x as x2, t2.y as y2 from t1 inner join t2 on t1.x = t2.x) for system_time as of timestamp @t0 as t; IJ2_x1 y1 x2 y2 @@ -294,7 +294,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t2 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (flat, BNL join) 1 SIMPLE t3 ALL NULL NULL NULL NULL 3 100.00 Using where; Using join buffer (incremental, BNL join) Warnings: -Note 1003 select `test2`.`t1`.`a` AS `a`,`test2`.`t2`.`a` AS `a` from `test2`.`t1` FOR SYSTEM_TIME ALL left join (`test2`.`t1` FOR SYSTEM_TIME ALL `t2` left join `test2`.`t1` FOR SYSTEM_TIME ALL `t3` on(`test2`.`t3`.`a` = `test2`.`t2`.`a` and `test2`.`t3`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999')) on(`test2`.`t2`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999' and `test2`.`t1`.`a` > 1) where `test2`.`t1`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999' +Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t2`.`a` AS `a` from `test`.`t1` FOR SYSTEM_TIME ALL left join (`test`.`t1` FOR SYSTEM_TIME ALL `t2` left join `test`.`t1` FOR SYSTEM_TIME ALL `t3` on(`test`.`t3`.`a` = `test`.`t2`.`a` and `test`.`t3`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999')) on(`test`.`t2`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999' and `test`.`t1`.`a` > 1) where `test`.`t1`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999' select * from t1 left outer join (t1 as t2 left join t1 as t3 using (a)) on t1.a>1; a a 2 1 @@ -511,7 +511,7 @@ id select_type table type possible_keys key key_len ref rows filtered Extra 1 SIMPLE t3 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join) 1 SIMPLE t4 ALL NULL NULL NULL NULL 2 100.00 Using where; Using join buffer (incremental, BNL join) Warnings: -Note 1003 select `test2`.`t1`.`f1` AS `f1` from `test2`.`t1` FOR SYSTEM_TIME ALL join `test2`.`t2` left join (`test2`.`t3` left join `test2`.`t4` FOR SYSTEM_TIME ALL on(`test2`.`t4`.`f4` = `test2`.`t2`.`f2` and `test2`.`t4`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999')) on(`test2`.`t3`.`f3` = `test2`.`t2`.`f2`) where `test2`.`t1`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999' +Note 1003 select `test`.`t1`.`f1` AS `f1` from `test`.`t1` FOR SYSTEM_TIME ALL join `test`.`t2` left join (`test`.`t3` left join `test`.`t4` FOR SYSTEM_TIME ALL on(`test`.`t4`.`f4` = `test`.`t2`.`f2` and `test`.`t4`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999')) on(`test`.`t3`.`f3` = `test`.`t2`.`f2`) where `test`.`t1`.`row_end` = TIMESTAMP'2038-01-19 03:14:07.999999' drop view v1; drop table t1, t2, t3, t4; # diff --git a/mysql-test/suite/versioning/r/truncate.result b/mysql-test/suite/versioning/r/truncate.result index 9d016a2bcd7..93f240272c1 100644 --- a/mysql-test/suite/versioning/r/truncate.result +++ b/mysql-test/suite/versioning/r/truncate.result @@ -93,7 +93,7 @@ drop view v; create or replace table t (i int); create or replace view v as select * from t; drop table v; -ERROR 42S02: 'test2.v' is a view +ERROR 42S02: 'test.v' is a view lock table v write; delete history from v before system_time now(6); ERROR 42S02: 'v' is a view diff --git a/mysql-test/suite/versioning/r/trx_id.result b/mysql-test/suite/versioning/r/trx_id.result index 98543caadbc..413272f55f9 100644 --- a/mysql-test/suite/versioning/r/trx_id.result +++ b/mysql-test/suite/versioning/r/trx_id.result @@ -181,9 +181,7 @@ select row_start from t1 into @trx_id; select trt_begin_ts(@trx_id) <= @ts1 as BEGIN_TS_GOOD; BEGIN_TS_GOOD 1 -drop database test; -create database test; -use test; +drop table t1; # # MDEV-16100 FOR SYSTEM_TIME erroneously resolves string user variables as transaction IDs # diff --git a/mysql-test/suite/versioning/r/update-big.result b/mysql-test/suite/versioning/r/update-big.result index 5accf0a0b56..89297fe5d89 100644 --- a/mysql-test/suite/versioning/r/update-big.result +++ b/mysql-test/suite/versioning/r/update-big.result @@ -12,7 +12,7 @@ insert into t1 select * from t1; insert into t1 select * from t1; insert into t1 select * from t1; insert into t1 select * from t1; -connect con1,localhost,root,,test2; +connect con1,localhost,root,,test; alter table t1 add system versioning; connection default; update t1 set a= 7 where a = 3; diff --git a/mysql-test/suite/versioning/r/update.result b/mysql-test/suite/versioning/r/update.result index 334d8d8899b..af263a63fae 100644 --- a/mysql-test/suite/versioning/r/update.result +++ b/mysql-test/suite/versioning/r/update.result @@ -241,3 +241,27 @@ B2 salary 1 2500 drop table t1; drop table t2; +### Issue tempesta-tech/mariadb#365, bug 7 (duplicate of historical row) +create or replace table t1 (a int primary key, b int) +with system versioning engine myisam; +insert into t1 (a) values (1); +replace t1 values (1,2),(1,3),(2,4); +# +# MDEV-14829 Assertion `0' failed in Protocol::end_statement upon concurrent UPDATE +# +create or replace table t1 (pk int, a char(3), b char(3), primary key(pk)) +engine=innodb with system versioning; +insert into t1 (pk) values (1); +connect con1,localhost,root,,test; +start transaction; +select * from t1 for update; +pk a b +1 NULL NULL +connection default; +update t1 set b = 'foo'; +connection con1; +update t1 set a = 'bar'; +ERROR 40001: Deadlock found when trying to get lock; try restarting transaction +disconnect con1; +connection default; +drop table t1; diff --git a/mysql-test/suite/versioning/r/update2.result b/mysql-test/suite/versioning/r/update2.result deleted file mode 100644 index 73e6c5b393d..00000000000 --- a/mysql-test/suite/versioning/r/update2.result +++ /dev/null @@ -1,21 +0,0 @@ -### Issue #365, bug 7 (duplicate of historical row) -create or replace table t1 (a int primary key, b int) -with system versioning engine myisam; -insert into t1 (a) values (1); -replace t1 values (1,2),(1,3),(2,4); -create or replace table t1 (pk int, a char(3), b char(3), primary key(pk)) -engine=innodb with system versioning; -insert into t1 (pk) values (1); -connect con1,localhost,root,,test; -start transaction; -select * from t1 for update; -pk a b -1 NULL NULL -connection default; -update t1 set b = 'foo'; -connection con1; -update t1 set a = 'bar'; -ERROR 40001: Deadlock found when trying to get lock; try restarting transaction -disconnect con1; -connection default; -drop table t1; diff --git a/mysql-test/suite/versioning/r/view.result b/mysql-test/suite/versioning/r/view.result index e897f0e17d9..850eba32c0d 100644 --- a/mysql-test/suite/versioning/r/view.result +++ b/mysql-test/suite/versioning/r/view.result @@ -118,9 +118,8 @@ execute stmt; a execute stmt; a -drop database test2; -create database test2; -use test2; +drop view v1; +drop tables t1, t2; # # MDEV-15146 SQLError[4122]: View is not system versioned # @@ -148,5 +147,5 @@ create or replace view v1 as select * from t1 for system_time as of date_sub(now show create view v1; View Create View character_set_client collation_connection v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select `t1`.`i` AS `i` from `t1` FOR SYSTEM_TIME AS OF current_timestamp() - interval 6 second latin1 latin1_swedish_ci -drop view v1; -drop table t1; +drop view v1, vt1, vt12; +drop tables t1, t3; diff --git a/mysql-test/suite/versioning/t/alter.test b/mysql-test/suite/versioning/t/alter.test index 735bde0614d..c8275a5d3f4 100644 --- a/mysql-test/suite/versioning/t/alter.test +++ b/mysql-test/suite/versioning/t/alter.test @@ -453,7 +453,7 @@ use mysql; create or replace table t (x int) with system versioning; --error ER_VERS_DB_NOT_SUPPORTED alter table user add system versioning; -use test2; +use test; --echo # MDEV-15956 Strange ER_UNSUPPORTED_ACTION_ON_GENERATED_COLUMN upon ALTER on versioning column create or replace table t1 (i int, j int as (i), s timestamp(6) as row start, e timestamp(6) as row end, period for system_time(s,e)) with system versioning; @@ -574,5 +574,4 @@ alter table t change column c c int, change column b b int without system versioning; -drop database test; -create database test; +drop table t; diff --git a/mysql-test/suite/versioning/t/create.test b/mysql-test/suite/versioning/t/create.test index b8caf6b7097..fc4120ef2aa 100644 --- a/mysql-test/suite/versioning/t/create.test +++ b/mysql-test/suite/versioning/t/create.test @@ -405,5 +405,4 @@ create or replace table t1 (x int without system versioning) with system versioning select 1 as x; -drop database test; -create database test; +drop tables t0, t1, t2, t3; diff --git a/mysql-test/suite/versioning/t/delete.test b/mysql-test/suite/versioning/t/delete.test index 01c8ba438ab..b9045898bb0 100644 --- a/mysql-test/suite/versioning/t/delete.test +++ b/mysql-test/suite/versioning/t/delete.test @@ -81,5 +81,6 @@ insert into t1 values (1); update t1 set x= 2; delete from t1; select x from t1 for system_time all; +drop table t1; --source suite/versioning/common_finish.inc diff --git a/mysql-test/suite/versioning/t/engines.combinations b/mysql-test/suite/versioning/t/engines.combinations deleted file mode 100644 index 561c5656929..00000000000 --- a/mysql-test/suite/versioning/t/engines.combinations +++ /dev/null @@ -1,8 +0,0 @@ -[timestamp] -default-storage-engine=innodb - -[trx_id] -default-storage-engine=innodb - -[myisam] -default-storage-engine=myisam diff --git a/mysql-test/suite/versioning/t/foreign.test b/mysql-test/suite/versioning/t/foreign.test index 1f4b3404618..d60172f99bc 100644 --- a/mysql-test/suite/versioning/t/foreign.test +++ b/mysql-test/suite/versioning/t/foreign.test @@ -1,11 +1,15 @@ --source suite/versioning/common.inc +let $KEY_TYPE= primary key; + --echo ################# --echo # Test RESTRICT # --echo ################# -create table parent( - id int unique key +--replace_result "$KEY_TYPE" KEY_TYPE +eval create table parent( + id int, + $KEY_TYPE (id) ) engine innodb; --replace_result $sys_datatype_expl SYS_DATATYPE @@ -42,8 +46,10 @@ drop table parent; --echo # Test when clustered index is a foreign key # --echo ############################################## -create table parent( - id int(10) unsigned unique key +--replace_result "$KEY_TYPE" KEY_TYPE +eval create table parent( + id int(10) unsigned, + $KEY_TYPE (id) ) engine innodb; --replace_result $sys_datatype_expl SYS_DATATYPE @@ -68,8 +74,10 @@ drop table parent; --echo # Test CASCADE # --echo ################ -create table parent( - id int unique key +--replace_result "$KEY_TYPE" KEY_TYPE +eval create table parent( + id int, + $KEY_TYPE (id) ) engine innodb; --replace_result $sys_datatype_expl SYS_DATATYPE @@ -99,9 +107,10 @@ select * from child for system_time all; drop table child; drop table parent; ---replace_result $sys_datatype_expl SYS_DATATYPE +--replace_result $sys_datatype_expl SYS_DATATYPE "$KEY_TYPE" KEY_TYPE eval create or replace table parent ( - id int primary key, + id int, + $KEY_TYPE(id), sys_start $sys_datatype_expl as row start invisible, sys_end $sys_datatype_expl as row end invisible, period for system_time(sys_start, sys_end) @@ -126,8 +135,10 @@ select * from child; drop table child; drop table parent; -create or replace table parent ( - id int primary key +--replace_result "$KEY_TYPE" KEY_TYPE +eval create or replace table parent ( + id int, + $KEY_TYPE(id) ) engine innodb; @@ -158,8 +169,10 @@ drop table parent; --echo # Test SET NULL # --echo ################# -create or replace table parent( - id int unique key +--replace_result "$KEY_TYPE" KEY_TYPE +eval create table parent( + id int, + $KEY_TYPE (id) ) engine innodb; --replace_result $sys_datatype_expl SYS_DATATYPE @@ -196,9 +209,10 @@ drop table parent; --echo # Parent table is foreign # --echo ########################### ---replace_result $sys_datatype_expl SYS_DATATYPE +--replace_result $sys_datatype_expl SYS_DATATYPE "$KEY_TYPE" KEY_TYPE eval create or replace table parent( - id int unique key, + id int, + $KEY_TYPE (id), sys_start $sys_datatype_expl as row start invisible, sys_end $sys_datatype_expl as row end invisible, period for system_time(sys_start, sys_end) @@ -236,9 +250,10 @@ drop table parent; --echo # crash on DELETE # --echo ################### ---replace_result $sys_datatype_expl SYS_DATATYPE +--replace_result $sys_datatype_expl SYS_DATATYPE "$KEY_TYPE" KEY_TYPE eval create or replace table a ( - cola int(10) primary key, + cola int(10), + $KEY_TYPE (cola), v_cola int(10) as (cola mod 10) virtual, sys_start $sys_datatype_expl as row start invisible, sys_end $sys_datatype_expl as row end invisible, @@ -406,8 +421,8 @@ REPLACE INTO t2 SELECT * FROM t2; # Cleanup DROP TABLE t1, t2; --let $datadir= `select @@datadir` ---remove_file $datadir/test2/t1.data ---remove_file $datadir/test2/t1.data.2 ---remove_file $datadir/test2/t2.data +--remove_file $datadir/test/t1.data +--remove_file $datadir/test/t1.data.2 +--remove_file $datadir/test/t2.data --source suite/versioning/common_finish.inc diff --git a/mysql-test/suite/versioning/t/online.test b/mysql-test/suite/versioning/t/online.test index c02df3d3044..cff3193407b 100644 --- a/mysql-test/suite/versioning/t/online.test +++ b/mysql-test/suite/versioning/t/online.test @@ -107,7 +107,7 @@ insert into t values (1, 1); select c.prtype from information_schema.innodb_sys_columns as c join information_schema.innodb_sys_tables as t on c.table_id=t.table_id - where t.name='test2/t' and c.name='b'; + where t.name='test/t' and c.name='b'; set @@system_versioning_alter_history=keep; @@ -125,7 +125,7 @@ set debug_dbug= default; select c.prtype from information_schema.innodb_sys_columns as c join information_schema.innodb_sys_tables as t on c.table_id=t.table_id - where t.name='test2/t' and c.name='b'; + where t.name='test/t' and c.name='b'; --replace_result $sys_datatype_expl SYS_DATATYPE show create table t; diff --git a/mysql-test/suite/versioning/t/partition.test b/mysql-test/suite/versioning/t/partition.test index a9dff811d40..eca322d9ef4 100644 --- a/mysql-test/suite/versioning/t/partition.test +++ b/mysql-test/suite/versioning/t/partition.test @@ -402,17 +402,17 @@ partition by system_time interval 1 hour ( partition p0 history, partition pn current); set @ts=(select partition_description from information_schema.partitions - where table_schema='test2' and table_name='t1' and partition_name='p0'); + where table_schema='test' and table_name='t1' and partition_name='p0'); alter table t1 add column b int; -select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test2' and table_name='t1'; +select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test' and table_name='t1'; alter table t1 add partition (partition p1 history, partition p2 history); -select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test2' and table_name='t1'; +select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test' and table_name='t1'; alter table t1 drop partition p0; -select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test2' and table_name='t1'; +select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test' and table_name='t1'; --error ER_VERS_DROP_PARTITION_INTERVAL alter table t1 drop partition p2; -select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test2' and table_name='t1'; +select partition_name,partition_ordinal_position,partition_method,timediff(partition_description, @ts) from information_schema.partitions where table_schema='test' and table_name='t1'; --echo # --echo # MDEV-15103 Assertion in ha_partition::part_records() for updating VIEW @@ -513,6 +513,8 @@ unlock tables; --echo # create or replace table t1 (pk int primary key) with system versioning partition by system_time limit 100 (partition p1 history, partition pn current); execute immediate 'select * from t1 for update'; -drop table t1; + +drop view v1; +drop tables t, t1, t2, t3, t4; --source suite/versioning/common_finish.inc diff --git a/mysql-test/suite/versioning/t/partition_innodb.test b/mysql-test/suite/versioning/t/partition_innodb.test index 36adb6345b0..aaaf7001644 100644 --- a/mysql-test/suite/versioning/t/partition_innodb.test +++ b/mysql-test/suite/versioning/t/partition_innodb.test @@ -29,6 +29,8 @@ alter table t1 partition by system_time ( partition pn current ); +drop table t1; + --error ER_VERS_TRX_PART_HISTORIC_ROW_NOT_SUPPORTED create or replace table t ( a int primary key, diff --git a/mysql-test/suite/versioning/t/replace.test b/mysql-test/suite/versioning/t/replace.test index 22d32ff3795..392c0ffcf35 100644 --- a/mysql-test/suite/versioning/t/replace.test +++ b/mysql-test/suite/versioning/t/replace.test @@ -1,13 +1,19 @@ +--source suite/versioning/key_type.inc +if ($MTR_COMBINATION_SEC) +{ + --skip pk or unique only +} --source suite/versioning/common.inc --source suite/versioning/engines.inc ---replace_result $sys_datatype_expl SYS_DATATYPE -eval create table t ( - id int primary key, +--replace_result $sys_datatype_expl SYS_DATATYPE "$KEY_TYPE" KEY_TYPE +eval create or replace table t( + id int, + $KEY_TYPE(id), x int, row_start $sys_datatype_expl as row start invisible, row_end $sys_datatype_expl as row end invisible, - period for system_time (row_start, row_end) + period for system_time(row_start, row_end) ) with system versioning; insert t values (1, 2); @@ -35,7 +41,8 @@ insert into t1 values (1,1); create or replace table t2 (c int); create or replace view v as select t1.* from t1 join t2; replace into v (a, b) select a, b from t1; -drop table t1; +drop view v; +drop tables t1, t2; --replace_result $sys_datatype_expl SYS_DATATYPE eval CREATE TABLE t1 ( diff --git a/mysql-test/suite/versioning/t/trx_id.test b/mysql-test/suite/versioning/t/trx_id.test index 943d9182a8a..617c46a9332 100644 --- a/mysql-test/suite/versioning/t/trx_id.test +++ b/mysql-test/suite/versioning/t/trx_id.test @@ -173,10 +173,7 @@ commit; select row_start from t1 into @trx_id; select trt_begin_ts(@trx_id) <= @ts1 as BEGIN_TS_GOOD; -drop database test; -create database test; -use test; - +drop table t1; --echo # --echo # MDEV-16100 FOR SYSTEM_TIME erroneously resolves string user variables as transaction IDs diff --git a/mysql-test/suite/versioning/t/update-big.test b/mysql-test/suite/versioning/t/update-big.test index f5a72b22454..175bfc79a48 100644 --- a/mysql-test/suite/versioning/t/update-big.test +++ b/mysql-test/suite/versioning/t/update-big.test @@ -17,7 +17,7 @@ insert into t1 select * from t1; insert into t1 select * from t1; insert into t1 select * from t1; ---connect (con1,localhost,root,,test2) +--connect (con1,localhost,root,,test) alter table t1 add system versioning; --connection default diff --git a/mysql-test/suite/versioning/t/update.test b/mysql-test/suite/versioning/t/update.test index 95c844c88a2..a9550564a15 100644 --- a/mysql-test/suite/versioning/t/update.test +++ b/mysql-test/suite/versioning/t/update.test @@ -147,4 +147,34 @@ select @tmp2 = sys_trx_start as B2, salary from t2; drop table t1; drop table t2; +--echo ### Issue tempesta-tech/mariadb#365, bug 7 (duplicate of historical row) +create or replace table t1 (a int primary key, b int) +with system versioning engine myisam; +insert into t1 (a) values (1); + +replace t1 values (1,2),(1,3),(2,4); + +--echo # +--echo # MDEV-14829 Assertion `0' failed in Protocol::end_statement upon concurrent UPDATE +--echo # + +create or replace table t1 (pk int, a char(3), b char(3), primary key(pk)) + engine=innodb with system versioning; + +insert into t1 (pk) values (1); +connect (con1,localhost,root,,test); +start transaction; +select * from t1 for update; +connection default; +send update t1 set b = 'foo'; +connection con1; +let $wait_condition= select count(*) from information_schema.innodb_lock_waits; +source include/wait_condition.inc; +error ER_LOCK_DEADLOCK; +update t1 set a = 'bar'; +disconnect con1; +connection default; +reap; +drop table t1; + source suite/versioning/common_finish.inc; diff --git a/mysql-test/suite/versioning/t/update2.test b/mysql-test/suite/versioning/t/update2.test deleted file mode 100644 index 87ca3746b12..00000000000 --- a/mysql-test/suite/versioning/t/update2.test +++ /dev/null @@ -1,31 +0,0 @@ -source include/have_innodb.inc; - -echo ### Issue #365, bug 7 (duplicate of historical row); -create or replace table t1 (a int primary key, b int) -with system versioning engine myisam; -insert into t1 (a) values (1); - -replace t1 values (1,2),(1,3),(2,4); - -# -# MDEV-14829 Assertion `0' failed in Protocol::end_statement upon concurrent UPDATE -# - -create or replace table t1 (pk int, a char(3), b char(3), primary key(pk)) - engine=innodb with system versioning; - -insert into t1 (pk) values (1); -connect (con1,localhost,root,,test); -start transaction; -select * from t1 for update; -connection default; -send update t1 set b = 'foo'; -connection con1; -let $wait_condition= select count(*) from information_schema.innodb_lock_waits; -source include/wait_condition.inc; -error ER_LOCK_DEADLOCK; -update t1 set a = 'bar'; -disconnect con1; -connection default; -reap; -drop table t1; diff --git a/mysql-test/suite/versioning/t/view.test b/mysql-test/suite/versioning/t/view.test index d824f1c52c0..5a03a50f1d3 100644 --- a/mysql-test/suite/versioning/t/view.test +++ b/mysql-test/suite/versioning/t/view.test @@ -98,9 +98,8 @@ create or replace table t2 (b int) with system versioning; prepare stmt from 'select a from v1 inner join t2 group by a order by a'; execute stmt; execute stmt; -drop database test2; -create database test2; -use test2; +drop view v1; +drop tables t1, t2; --echo # --echo # MDEV-15146 SQLError[4122]: View is not system versioned @@ -122,7 +121,7 @@ select * from t1 for system_time as of now() - interval 6 second; create or replace view v1 as select * from t1 for system_time as of date_sub(now(), interval 6 second); show create view v1; -drop view v1; -drop table t1; +drop view v1, vt1, vt12; +drop tables t1, t3; --source suite/versioning/common_finish.inc From 75ba5c815d0272b35a28225d495a4a03fe63d29f Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Wed, 30 May 2018 13:19:03 +0300 Subject: [PATCH 32/44] MDEV-16210 FK constraints on versioned tables use historical rows, which may cause constraint violation Constraint check is done on secondary index update. F.ex. DELETE does row_upd_sec_index_entry() and checks constraints in row_upd_check_references_constraints(). UPDATE is optimized for the case when order is not changed (node->cmpl_info & UPD_NODE_NO_ORD_CHANGE) and doesn't do row_upd_sec_index_entry(), so it doesn't check constraints. Since for versioned DELETE we do UPDATE actually, but expect behaviour of DELETE in terms of constraints, we should deny this optimization to get constraints checked. Fix wrong referenced table check when versioned DELETE inserts history in parent table. Set check_ref to false in this case. Removed unused dup_chk_only argument for row_ins_sec_index_entry() and added check_ref argument. MDEV-18057 fix was superseded by this fix and reverted. foreign.test: All key_type combinations: pk, unique, sec(ondary). --- mysql-test/suite/versioning/r/foreign.result | 19 +++++++++------- mysql-test/suite/versioning/t/foreign.test | 23 ++++++++++---------- storage/innobase/include/row0ins.h | 5 ++++- storage/innobase/row/row0ins.cc | 17 ++++++++++----- storage/innobase/row/row0upd.cc | 11 ++++++---- 5 files changed, 46 insertions(+), 29 deletions(-) diff --git a/mysql-test/suite/versioning/r/foreign.result b/mysql-test/suite/versioning/r/foreign.result index e5ffb6c5f0c..6a9746b62e2 100644 --- a/mysql-test/suite/versioning/r/foreign.result +++ b/mysql-test/suite/versioning/r/foreign.result @@ -298,15 +298,18 @@ select count(*) from subchild; count(*) 0 drop table subchild, child, parent; -CREATE TABLE t1 (f1 INT, KEY(f1)) ENGINE=InnoDB; -CREATE TABLE t2 (f2 INT, FOREIGN KEY (f2) REFERENCES t1 (f1)) ENGINE=InnoDB WITH SYSTEM VERSIONING; -SET FOREIGN_KEY_CHECKS= OFF; -INSERT IGNORE INTO t2 VALUES (1); -SET FOREIGN_KEY_CHECKS= ON; -UPDATE t2 SET f2= 2; +# +# MDEV-18057 Assertion `(node->state == 5) || (node->state == 6)' failed in row_upd_sec_step upon DELETE after UPDATE failed due to FK violation +# +create or replace table t1 (f1 int, key(f1)) engine=innodb; +create or replace table t2 (f2 int, foreign key (f2) references t1 (f1)) engine=innodb with system versioning; +set foreign_key_checks= off; +insert ignore into t2 values (1); +set foreign_key_checks= on; +update t2 set f2= 2; ERROR 23000: Cannot add or update a child row: a foreign key constraint fails (`test`.`t2`, CONSTRAINT `t2_ibfk_1` FOREIGN KEY (`f2`) REFERENCES `t1` (`f1`)) -DELETE FROM t2; -DROP TABLE t2, t1; +delete from t2; +drop table t2, t1; # # MDEV-18879 Corrupted record inserted by FOREIGN KEY operation # diff --git a/mysql-test/suite/versioning/t/foreign.test b/mysql-test/suite/versioning/t/foreign.test index d60172f99bc..9f015630e0a 100644 --- a/mysql-test/suite/versioning/t/foreign.test +++ b/mysql-test/suite/versioning/t/foreign.test @@ -1,7 +1,6 @@ +--source suite/versioning/key_type.inc --source suite/versioning/common.inc -let $KEY_TYPE= primary key; - --echo ################# --echo # Test RESTRICT # --echo ################# @@ -331,19 +330,21 @@ select count(*) from subchild; drop table subchild, child, parent; +--echo # +--echo # MDEV-18057 Assertion `(node->state == 5) || (node->state == 6)' failed in row_upd_sec_step upon DELETE after UPDATE failed due to FK violation +--echo # +create or replace table t1 (f1 int, key(f1)) engine=innodb; +create or replace table t2 (f2 int, foreign key (f2) references t1 (f1)) engine=innodb with system versioning; -CREATE TABLE t1 (f1 INT, KEY(f1)) ENGINE=InnoDB; -CREATE TABLE t2 (f2 INT, FOREIGN KEY (f2) REFERENCES t1 (f1)) ENGINE=InnoDB WITH SYSTEM VERSIONING; +set foreign_key_checks= off; +insert ignore into t2 values (1); -SET FOREIGN_KEY_CHECKS= OFF; -INSERT IGNORE INTO t2 VALUES (1); - -SET FOREIGN_KEY_CHECKS= ON; +set foreign_key_checks= on; --error ER_NO_REFERENCED_ROW_2 -UPDATE t2 SET f2= 2; -DELETE FROM t2; +update t2 set f2= 2; +delete from t2; -DROP TABLE t2, t1; +drop table t2, t1; --echo # --echo # MDEV-18879 Corrupted record inserted by FOREIGN KEY operation diff --git a/storage/innobase/include/row0ins.h b/storage/innobase/include/row0ins.h index ddc3db8c694..87a72d88eb6 100644 --- a/storage/innobase/include/row0ins.h +++ b/storage/innobase/include/row0ins.h @@ -145,7 +145,10 @@ row_ins_sec_index_entry( /*====================*/ dict_index_t* index, /*!< in: secondary index */ dtuple_t* entry, /*!< in/out: index entry to insert */ - que_thr_t* thr) /*!< in: query thread */ + que_thr_t* thr, /*!< in: query thread */ + bool check_ref) /*!< in: TRUE if we want to check that + the referenced table is ok, FALSE if we + want to check the foreign key table */ MY_ATTRIBUTE((warn_unused_result)); /***********************************************************//** Inserts a row to a table. This is a high-level function used in diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index 62115beddc0..88deacbc823 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -1988,7 +1988,10 @@ row_ins_check_foreign_constraints( dict_index_t* index, /*!< in: index */ bool pk, /*!< in: index->is_primary() */ dtuple_t* entry, /*!< in: index entry for index */ - que_thr_t* thr) /*!< in: query thread */ + que_thr_t* thr, /*!< in: query thread */ + bool check_ref = true) /*!< in: TRUE if we want to check that + the referenced table is ok, FALSE if we + want to check the foreign key table */ { dict_foreign_t* foreign; dberr_t err; @@ -2037,7 +2040,7 @@ row_ins_check_foreign_constraints( table from being dropped while the check is running. */ err = row_ins_check_foreign_constraint( - TRUE, foreign, table, entry, thr); + check_ref, foreign, table, entry, thr); if (referenced_table) { foreign->foreign_table->dec_fk_checks(); @@ -3267,7 +3270,10 @@ row_ins_sec_index_entry( /*====================*/ dict_index_t* index, /*!< in: secondary index */ dtuple_t* entry, /*!< in/out: index entry to insert */ - que_thr_t* thr) /*!< in: query thread */ + que_thr_t* thr, /*!< in: query thread */ + bool check_ref) /*!< in: true if we want to check that + the referenced table is ok, false if we + want to check the foreign key table */ { dberr_t err; mem_heap_t* offsets_heap; @@ -3280,7 +3286,8 @@ row_ins_sec_index_entry( if (!index->table->foreign_set.empty()) { err = row_ins_check_foreign_constraints(index->table, index, - false, entry, thr); + false, entry, thr, + check_ref); if (err != DB_SUCCESS) { return(err); @@ -3355,7 +3362,7 @@ row_ins_index_entry( if (index->is_primary()) { return row_ins_clust_index_entry(index, entry, thr, 0); } else { - return row_ins_sec_index_entry(index, entry, thr); + return(row_ins_sec_index_entry(index, entry, thr, true)); } } diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc index d081c5c2122..64021b48ee2 100644 --- a/storage/innobase/row/row0upd.cc +++ b/storage/innobase/row/row0upd.cc @@ -2529,7 +2529,8 @@ row_upd_sec_index_entry( ut_a(entry); /* Insert new index entry */ - err = row_ins_sec_index_entry(index, entry, thr); + err = row_ins_sec_index_entry(index, entry, thr, + node->is_delete != VERSIONED_DELETE); func_exit: mem_heap_free(heap); @@ -3191,9 +3192,8 @@ row_upd_clust_step( row_upd_eval_new_vals(node->update); } - if (node->cmpl_info & UPD_NODE_NO_ORD_CHANGE) { + if (!node->is_delete && node->cmpl_info & UPD_NODE_NO_ORD_CHANGE) { - node->index = NULL; err = row_upd_clust_rec( flags, node, index, offsets, &heap, thr, &mtr); goto exit_func; @@ -3237,7 +3237,10 @@ row_upd_clust_step( goto exit_func; } - node->state = UPD_NODE_UPDATE_SOME_SEC; + ut_ad(node->is_delete != PLAIN_DELETE); + node->state = node->is_delete ? + UPD_NODE_UPDATE_ALL_SEC : + UPD_NODE_UPDATE_SOME_SEC; } node->index = dict_table_get_next_index(index); From 647a38818a44012c22128e0e1cad96739aa8a5c2 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Wed, 23 May 2018 22:15:04 +0300 Subject: [PATCH 33/44] MDEV-16130 wrong error message adding AS ROW START to versioned table --- mysql-test/suite/versioning/r/alter.result | 8 ++++++-- mysql-test/suite/versioning/t/alter.test | 9 +++++++-- sql/handler.cc | 6 ++++-- sql/sql_table.cc | 6 ------ 4 files changed, 17 insertions(+), 12 deletions(-) diff --git a/mysql-test/suite/versioning/r/alter.result b/mysql-test/suite/versioning/r/alter.result index a453617d3b3..532412e3574 100644 --- a/mysql-test/suite/versioning/r/alter.result +++ b/mysql-test/suite/versioning/r/alter.result @@ -80,13 +80,17 @@ t CREATE TABLE `t` ( `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 alter table t add column trx_start timestamp(6) as row start; -ERROR HY000: Table `t` is not system-versioned +ERROR HY000: Duplicate ROW START column `trx_start` alter table t add system versioning; show create table t; Table Create Table t CREATE TABLE `t` ( `a` int(11) DEFAULT NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 WITH SYSTEM VERSIONING +alter table t add column trx_start timestamp(6) as row start; +ERROR HY000: Duplicate ROW START column `trx_start` +alter table t modify a int as row start; +ERROR HY000: Duplicate ROW START column `a` alter table t add column b int; show create table t; Table Create Table @@ -531,7 +535,7 @@ use test; # MDEV-15956 Strange ER_UNSUPPORTED_ACTION_ON_GENERATED_COLUMN upon ALTER on versioning column create or replace table t1 (i int, j int as (i), s timestamp(6) as row start, e timestamp(6) as row end, period for system_time(s,e)) with system versioning; alter table t1 modify s timestamp(6) as row start; -ERROR HY000: Can not change system versioning field `s` +ERROR HY000: Duplicate ROW START column `s` # ignore CHECK for historical rows create or replace table t (a int) with system versioning; insert into t values (0), (1); diff --git a/mysql-test/suite/versioning/t/alter.test b/mysql-test/suite/versioning/t/alter.test index c8275a5d3f4..ff33f2cf95b 100644 --- a/mysql-test/suite/versioning/t/alter.test +++ b/mysql-test/suite/versioning/t/alter.test @@ -68,12 +68,17 @@ select row_start from t; alter table t drop system versioning; show create table t; ---error ER_VERS_NOT_VERSIONED +--error ER_VERS_DUPLICATE_ROW_START_END alter table t add column trx_start timestamp(6) as row start; alter table t add system versioning; show create table t; +--error ER_VERS_DUPLICATE_ROW_START_END +alter table t add column trx_start timestamp(6) as row start; +--error ER_VERS_DUPLICATE_ROW_START_END +alter table t modify a int as row start; + alter table t add column b int; show create table t; @@ -457,7 +462,7 @@ use test; --echo # MDEV-15956 Strange ER_UNSUPPORTED_ACTION_ON_GENERATED_COLUMN upon ALTER on versioning column create or replace table t1 (i int, j int as (i), s timestamp(6) as row start, e timestamp(6) as row end, period for system_time(s,e)) with system versioning; ---error ER_VERS_ALTER_SYSTEM_FIELD +--error ER_VERS_DUPLICATE_ROW_START_END alter table t1 modify s timestamp(6) as row start; --echo # ignore CHECK for historical rows diff --git a/sql/handler.cc b/sql/handler.cc index 587ec633245..1494060e24d 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -7301,13 +7301,15 @@ bool Vers_parse_info::fix_alter_info(THD *thd, Alter_info *alter_info, return false; } + if (!(alter_info->flags & ALTER_ADD_SYSTEM_VERSIONING)) { List_iterator_fast it(alter_info->create_list); while (Create_field *f= it++) { - if (f->change.length && f->flags & VERS_SYSTEM_FIELD) + if (f->flags & VERS_SYSTEM_FIELD) { - my_error(ER_VERS_ALTER_SYSTEM_FIELD, MYF(0), f->field_name.str); + my_error(ER_VERS_DUPLICATE_ROW_START_END, MYF(0), + f->flags & VERS_SYS_START_FLAG ? "START" : "END", f->field_name.str); return true; } } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index b4cf6f61f60..c2c26222a82 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -8159,12 +8159,6 @@ mysql_prepare_alter_table(THD *thd, TABLE *table, alter_ctx->datetime_field= def; alter_ctx->error_if_not_empty= TRUE; } - if (def->flags & VERS_SYSTEM_FIELD && - !(alter_info->flags & ALTER_ADD_SYSTEM_VERSIONING)) - { - my_error(ER_VERS_NOT_VERSIONED, MYF(0), table->s->table_name.str); - goto err; - } if (!def->after.str) new_create_list.push_back(def, thd->mem_root); else From a92f3146d22cb3b290228c0e66eb1ea6c7b7c373 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Sat, 11 May 2019 17:27:23 +0300 Subject: [PATCH 34/44] MDEV-19406 Assertion on updating view of join with versioned table TABLE::mark_columns_needed_for_update(): use_all_columns() assigns pointer of all_set into read_set and write_set, but this is not good since all_set is changed later by TABLE::mark_columns_used_by_index_no_reset(). Do column_bitmaps_signal() whenever we change read_set/write_set. --- mysql-test/suite/versioning/r/update.result | 11 +++++++ mysql-test/suite/versioning/t/update.test | 15 ++++++++++ sql/log_event.cc | 2 ++ sql/sql_insert.cc | 1 + sql/table.cc | 32 ++++++++++++++------- 5 files changed, 51 insertions(+), 10 deletions(-) diff --git a/mysql-test/suite/versioning/r/update.result b/mysql-test/suite/versioning/r/update.result index af263a63fae..eaa8549b38a 100644 --- a/mysql-test/suite/versioning/r/update.result +++ b/mysql-test/suite/versioning/r/update.result @@ -265,3 +265,14 @@ ERROR 40001: Deadlock found when trying to get lock; try restarting transaction disconnect con1; connection default; drop table t1; +# +# MDEV-19406 Assertion on updating view of join with versioned table +# +create or replace table t1 (pk int primary key, a date, b int, index(b)) engine=innodb with system versioning; +create or replace table t2 (c int); +create or replace view v as select * from t1 join t2; +insert into t1 (pk) values (1); +update t1 set a= '2012-12-12'; +update v set a= '2000-01-01' order by b limit 1; +drop view v; +drop table t1, t2; diff --git a/mysql-test/suite/versioning/t/update.test b/mysql-test/suite/versioning/t/update.test index a9550564a15..e41c7d15995 100644 --- a/mysql-test/suite/versioning/t/update.test +++ b/mysql-test/suite/versioning/t/update.test @@ -177,4 +177,19 @@ connection default; reap; drop table t1; +--echo # +--echo # MDEV-19406 Assertion on updating view of join with versioned table +--echo # +--disable_warnings +create or replace table t1 (pk int primary key, a date, b int, index(b)) engine=innodb with system versioning; +create or replace table t2 (c int); +create or replace view v as select * from t1 join t2; + +insert into t1 (pk) values (1); +update t1 set a= '2012-12-12'; +update v set a= '2000-01-01' order by b limit 1; # point of failure +drop view v; +drop table t1, t2; +--enable_warnings + source suite/versioning/common_finish.inc; diff --git a/sql/log_event.cc b/sql/log_event.cc index dc7203fc94f..78111e86f20 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -13450,6 +13450,7 @@ Rows_log_event::write_row(rpl_group_info *rgi, { ulong sec_part; bitmap_set_bit(table->read_set, table->vers_start_field()->field_index); + table->file->column_bitmaps_signal(); // Check whether a row came from unversioned table and fix vers fields. if (table->vers_start_field()->get_timestamp(&sec_part) == 0 && sec_part == 0) table->vers_update_fields(); @@ -14010,6 +14011,7 @@ int Rows_log_event::find_row(rpl_group_info *rgi) table->vers_end_field()->set_max(); m_vers_from_plain= true; } + table->file->column_bitmaps_signal(); } DBUG_PRINT("info",("looking for the following record")); diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 7913ea2b2ec..dc8ee19b1e1 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1945,6 +1945,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) if (table->versioned(VERS_TRX_ID)) { bitmap_set_bit(table->write_set, table->vers_start_field()->field_index); + table->file->column_bitmaps_signal(); table->vers_start_field()->store(0, false); } if (unlikely(error= table->file->ha_update_row(table->record[1], diff --git a/sql/table.cc b/sql/table.cc index e2b2a5ec273..34523767eb4 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -6510,15 +6510,16 @@ void TABLE::mark_columns_needed_for_delete() } } - if (need_signal) - file->column_bitmaps_signal(); - if (s->versioned) { bitmap_set_bit(read_set, s->vers_start_field()->field_index); bitmap_set_bit(read_set, s->vers_end_field()->field_index); bitmap_set_bit(write_set, s->vers_end_field()->field_index); + need_signal= true; } + + if (need_signal) + file->column_bitmaps_signal(); } @@ -6531,7 +6532,7 @@ void TABLE::mark_columns_needed_for_delete() updated columns to be read. If this is no the case, we do like in the delete case and mark - if neeed, either the primary key column or all columns to be read. + if needed, either the primary key column or all columns to be read. (see mark_columns_needed_for_delete() for details) If the engine has HA_REQUIRES_KEY_COLUMNS_FOR_DELETE, we will @@ -6595,14 +6596,18 @@ void TABLE::mark_columns_needed_for_update() need_signal= true; } } - /* - For System Versioning we have to read all columns since we will store - a copy of previous row with modified Sys_end column back to a table. - */ if (s->versioned) { - // We will copy old columns to a new row. - use_all_columns(); + /* + For System Versioning we have to read all columns since we store + a copy of previous row with modified row_end back to a table. + + Without write_set versioning.rpl,row is unstable until MDEV-16370 is + applied. + */ + bitmap_union(read_set, &s->all_set); + bitmap_union(write_set, &s->all_set); + need_signal= true; } if (check_constraints) { @@ -7991,7 +7996,10 @@ void TABLE::vers_update_fields() if (versioned(VERS_TIMESTAMP)) { if (!vers_write) + { + file->column_bitmaps_signal(); return; + } if (vers_start_field()->store_timestamp(in_use->query_start(), in_use->query_start_sec_part())) DBUG_ASSERT(0); @@ -7999,11 +8007,15 @@ void TABLE::vers_update_fields() else { if (!vers_write) + { + file->column_bitmaps_signal(); return; + } } vers_end_field()->set_max(); bitmap_set_bit(read_set, vers_end_field()->field_index); + file->column_bitmaps_signal(); } From c9cba59749e1b5a39a9e3a0a5b8bd762507245f9 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Mon, 8 Oct 2018 20:38:58 +0300 Subject: [PATCH 35/44] MDEV-17333 Assertion in update_auto_increment() upon exotic LOAD While `handler::next_insert_id` is restored on duplicate key errors `part_share->next_auto_inc_val` is not restored which causes discrepancy. --- mysql-test/main/auto_increment_ranges.inc | 20 +++++++++++++++++++ .../main/auto_increment_ranges_innodb.result | 11 ++++++++++ .../main/auto_increment_ranges_myisam.result | 11 ++++++++++ sql/ha_partition.h | 15 ++++++++++++++ sql/handler.h | 16 ++++++++++++++- sql/sql_insert.cc | 8 ++++---- 6 files changed, 76 insertions(+), 5 deletions(-) diff --git a/mysql-test/main/auto_increment_ranges.inc b/mysql-test/main/auto_increment_ranges.inc index dc60f07a700..d94e446a0f5 100644 --- a/mysql-test/main/auto_increment_ranges.inc +++ b/mysql-test/main/auto_increment_ranges.inc @@ -238,3 +238,23 @@ delete from t1 where a=32767; --error HA_ERR_AUTOINC_ERANGE insert into t1 values(NULL); drop table t1; + +--echo # +--echo # MDEV-17333 Assertion in update_auto_increment() upon exotic LOAD +--echo # +--source include/have_partition.inc +let $mysqld_datadir= `select @@datadir`; +--write_file $mysqld_datadir/test/load.data +1 1 +0 2 +3 3 +4 1 +0 1 +6 6 +EOF +create or replace table t1 (pk int auto_increment, x int, primary key(pk), unique key(x)) +with system versioning partition by system_time interval 2 day +(partition p1 history, partition pn current); +load data infile 'load.data' ignore into table t1; +--remove_file $mysqld_datadir/test/load.data +drop table t1; diff --git a/mysql-test/main/auto_increment_ranges_innodb.result b/mysql-test/main/auto_increment_ranges_innodb.result index 0471a5a33ba..61eccc6f944 100644 --- a/mysql-test/main/auto_increment_ranges_innodb.result +++ b/mysql-test/main/auto_increment_ranges_innodb.result @@ -264,6 +264,17 @@ delete from t1 where a=32767; insert into t1 values(NULL); ERROR 22003: Out of range value for column 'a' at row 1 drop table t1; +# +# MDEV-17333 Assertion in update_auto_increment() upon exotic LOAD +# +create or replace table t1 (pk int auto_increment, x int, primary key(pk), unique key(x)) +with system versioning partition by system_time interval 2 day +(partition p1 history, partition pn current); +load data infile 'load.data' ignore into table t1; +Warnings: +Warning 1062 Duplicate entry '1' for key 'x' +Warning 1062 Duplicate entry '1' for key 'x' +drop table t1; create table t1 (pk int auto_increment primary key, f varchar(20)); insert t1 (f) values ('a'), ('b'), ('c'), ('d'); select null, f into outfile 'load.data' from t1 limit 1; diff --git a/mysql-test/main/auto_increment_ranges_myisam.result b/mysql-test/main/auto_increment_ranges_myisam.result index e849e980083..a300518adeb 100644 --- a/mysql-test/main/auto_increment_ranges_myisam.result +++ b/mysql-test/main/auto_increment_ranges_myisam.result @@ -270,3 +270,14 @@ delete from t1 where a=32767; insert into t1 values(NULL); ERROR 22003: Out of range value for column 'a' at row 1 drop table t1; +# +# MDEV-17333 Assertion in update_auto_increment() upon exotic LOAD +# +create or replace table t1 (pk int auto_increment, x int, primary key(pk), unique key(x)) +with system versioning partition by system_time interval 2 day +(partition p1 history, partition pn current); +load data infile 'load.data' ignore into table t1; +Warnings: +Warning 1062 Duplicate entry '1' for key 'x' +Warning 1062 Duplicate entry '1' for key 'x' +drop table t1; diff --git a/sql/ha_partition.h b/sql/ha_partition.h index d795502600f..0c945e5b317 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -92,6 +92,7 @@ public: bool auto_inc_initialized; mysql_mutex_t auto_inc_mutex; /**< protecting auto_inc val */ ulonglong next_auto_inc_val; /**< first non reserved value */ + ulonglong prev_auto_inc_val; /**< stored next_auto_inc_val */ /** Hash of partition names. Initialized in the first ha_partition::open() for the table_share. After that it is read-only, i.e. no locking required. @@ -103,6 +104,7 @@ public: Partition_share() : auto_inc_initialized(false), next_auto_inc_val(0), + prev_auto_inc_val(0), partition_name_hash_initialized(false), partition_names(NULL) { @@ -371,6 +373,19 @@ private: MY_BITMAP m_locked_partitions; /** Stores shared auto_increment etc. */ Partition_share *part_share; + /** Store and restore next_auto_inc_val over duplicate key errors. */ + virtual void store_auto_increment() + { + DBUG_ASSERT(part_share); + part_share->prev_auto_inc_val= part_share->next_auto_inc_val; + handler::store_auto_increment(); + } + virtual void restore_auto_increment() + { + DBUG_ASSERT(part_share); + part_share->next_auto_inc_val= part_share->prev_auto_inc_val; + handler::restore_auto_increment(); + } /** Temporary storage for new partitions Handler_shares during ALTER */ List m_new_partitions_share_refs; /** Sorted array of partition ids in descending order of number of rows. */ diff --git a/sql/handler.h b/sql/handler.h index 8a5c16dc4a7..fcaec4d5030 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -3008,6 +3008,10 @@ private: */ Handler_share **ha_share; + /** Stores next_insert_id for handling duplicate key errors. */ + ulonglong m_prev_insert_id; + + public: handler(handlerton *ht_arg, TABLE_SHARE *share_arg) :table_share(share_arg), table(0), @@ -3030,7 +3034,7 @@ public: auto_inc_intervals_count(0), m_psi(NULL), set_top_table_fields(FALSE), top_table(0), top_table_field(0), top_table_fields(0), - m_lock_type(F_UNLCK), ha_share(NULL) + m_lock_type(F_UNLCK), ha_share(NULL), m_prev_insert_id(0) { DBUG_PRINT("info", ("handler created F_UNLCK %d F_RDLCK %d F_WRLCK %d", @@ -3700,6 +3704,16 @@ public: insert_id_for_cur_row; } + /** Store and restore next_insert_id over duplicate key errors. */ + virtual void store_auto_increment() + { + m_prev_insert_id= next_insert_id; + } + virtual void restore_auto_increment() + { + restore_auto_increment(m_prev_insert_id); + } + virtual void update_create_info(HA_CREATE_INFO *create_info) {} int check_old_types(); virtual int assign_to_keycache(THD* thd, HA_CHECK_OPT* check_opt) diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index dc8ee19b1e1..59cc88f9db3 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1691,7 +1691,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) int error, trg_error= 0; char *key=0; MY_BITMAP *save_read_set, *save_write_set; - ulonglong prev_insert_id= table->file->next_insert_id; + table->file->store_auto_increment(); ulonglong insert_id_for_cur_row= 0; ulonglong prev_insert_id_for_cur_row= 0; DBUG_ENTER("write_record"); @@ -1844,7 +1844,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) if (res == VIEW_CHECK_ERROR) goto before_trg_err; - table->file->restore_auto_increment(prev_insert_id); + table->file->restore_auto_increment(); info->touched++; if (different_records) { @@ -2038,7 +2038,7 @@ int write_record(THD *thd, TABLE *table,COPY_INFO *info) if (!(thd->variables.old_behavior & OLD_MODE_NO_DUP_KEY_WARNINGS_WITH_IGNORE)) table->file->print_error(error, MYF(ME_JUST_WARNING)); - table->file->restore_auto_increment(prev_insert_id); + table->file->restore_auto_increment(); goto ok_or_after_trg_err; } @@ -2061,7 +2061,7 @@ err: table->file->print_error(error,MYF(0)); before_trg_err: - table->file->restore_auto_increment(prev_insert_id); + table->file->restore_auto_increment(); if (key) my_safe_afree(key, table->s->max_unique_length); table->column_bitmaps_set(save_read_set, save_write_set); From 726b1998fc9a97a8b2e58fe56668d570c4a01891 Mon Sep 17 00:00:00 2001 From: Michael Widenius Date: Thu, 10 Oct 2019 10:25:32 +0300 Subject: [PATCH 36/44] Fixed feedback_plugin_load to work with staticly loaded plugin --- mysql-test/suite/plugins/t/feedback_plugin_load.test | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/plugins/t/feedback_plugin_load.test b/mysql-test/suite/plugins/t/feedback_plugin_load.test index 1f9f837308b..c0546cef0f9 100644 --- a/mysql-test/suite/plugins/t/feedback_plugin_load.test +++ b/mysql-test/suite/plugins/t/feedback_plugin_load.test @@ -1,4 +1,8 @@ -if (`select count(*) = 0 from information_schema.plugins where plugin_name = 'feedback' and plugin_status='active' and @@feedback_url <> ""`) +if (`select count(*) = 0 from information_schema.plugins where plugin_name = 'feedback' and plugin_status='active'`) +{ + --skip Feedback plugin is not active +} +if (`select @@feedback_url = ""`) { --skip Feedback plugin is not active } From cb3f856ecdcaa2f63f51762f36226869ff08738f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Thu, 10 Oct 2019 10:36:11 +0300 Subject: [PATCH 37/44] Fix compiler error when using -Wconversion. /mariadb/10.3/wsrep/wsrep_gtid.c:45:26: error: conversion from 'long int' to 'unsigned int' may change value [-Werror=conversion] 45 | offset = endptr - str; --- wsrep/wsrep_gtid.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wsrep/wsrep_gtid.c b/wsrep/wsrep_gtid.c index bf5cab06585..fc87275f4ff 100644 --- a/wsrep/wsrep_gtid.c +++ b/wsrep/wsrep_gtid.c @@ -42,7 +42,7 @@ wsrep_gtid_scan(const char* str, size_t str_len, wsrep_gtid_t* gtid) gtid->seqno = strtoll(str + offset, &endptr, 0); if (errno == 0) { - offset = endptr - str; + offset = (unsigned int)(endptr - str); return offset; } } From 3c78d1b640f545025235bf52a0bde987817c3685 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Thu, 10 Oct 2019 11:08:31 +0300 Subject: [PATCH 38/44] Fix Mroonga compilation Fixed warnings: -Woverloaded-virtual, -Winconsistent-missing-override Caused by c9cba59749e1b5a39a9e3a0a5b8bd762507245f9 --- sql/handler.h | 2 +- storage/mroonga/ha_mroonga.hpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/sql/handler.h b/sql/handler.h index fcaec4d5030..345e0bc1f00 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -3688,7 +3688,7 @@ public: DBUG_PRINT("info",("auto_increment: next value %lu", (ulong)id)); next_insert_id= id; } - void restore_auto_increment(ulonglong prev_insert_id) + virtual void restore_auto_increment(ulonglong prev_insert_id) { /* Insertion of a row failed, re-use the lastly generated auto_increment diff --git a/storage/mroonga/ha_mroonga.hpp b/storage/mroonga/ha_mroonga.hpp index 7347af25bdc..f2fb2bfe8e7 100644 --- a/storage/mroonga/ha_mroonga.hpp +++ b/storage/mroonga/ha_mroonga.hpp @@ -571,7 +571,7 @@ public: void set_next_insert_id(ulonglong id); void get_auto_increment(ulonglong offset, ulonglong increment, ulonglong nb_desired_values, ulonglong *first_value, ulonglong *nb_reserved_values) mrn_override; - void restore_auto_increment(ulonglong prev_insert_id); + void restore_auto_increment(ulonglong prev_insert_id) mrn_override; void release_auto_increment() mrn_override; int check_for_upgrade(HA_CHECK_OPT *check_opt) mrn_override; #ifdef MRN_HANDLER_HAVE_RESET_AUTO_INCREMENT From 545c5452063ec9fc8a2f770512002f6c67c96770 Mon Sep 17 00:00:00 2001 From: Aleksey Midenkov Date: Thu, 10 Oct 2019 13:35:32 +0300 Subject: [PATCH 39/44] Fix compilation 2 (GCC 9) Fixed warning: -Woverloaded-virtual for GCC 9 (Clang treats it differently) Caused by c9cba59749e1b5a39a9e3a0a5b8bd762507245f9 --- sql/ha_partition.h | 5 +++++ storage/mroonga/ha_mroonga.hpp | 5 +++++ 2 files changed, 10 insertions(+) diff --git a/sql/ha_partition.h b/sql/ha_partition.h index 0c945e5b317..d48947822b9 100644 --- a/sql/ha_partition.h +++ b/sql/ha_partition.h @@ -373,6 +373,11 @@ private: MY_BITMAP m_locked_partitions; /** Stores shared auto_increment etc. */ Partition_share *part_share; + /** Fix spurious -Werror=overloaded-virtual in GCC 9 */ + virtual void restore_auto_increment(ulonglong prev_insert_id) + { + handler::restore_auto_increment(prev_insert_id); + } /** Store and restore next_auto_inc_val over duplicate key errors. */ virtual void store_auto_increment() { diff --git a/storage/mroonga/ha_mroonga.hpp b/storage/mroonga/ha_mroonga.hpp index f2fb2bfe8e7..e1dbb63178e 100644 --- a/storage/mroonga/ha_mroonga.hpp +++ b/storage/mroonga/ha_mroonga.hpp @@ -571,6 +571,11 @@ public: void set_next_insert_id(ulonglong id); void get_auto_increment(ulonglong offset, ulonglong increment, ulonglong nb_desired_values, ulonglong *first_value, ulonglong *nb_reserved_values) mrn_override; + /** Fix spurious -Werror=overloaded-virtual in GCC 9 */ + void restore_auto_increment() mrn_override + { + handler::restore_auto_increment(); + } void restore_auto_increment(ulonglong prev_insert_id) mrn_override; void release_auto_increment() mrn_override; int check_for_upgrade(HA_CHECK_OPT *check_opt) mrn_override; From 0f7732d1d1d898f1a9051858932c18bcc9d6f2b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 10 Oct 2019 15:19:44 +0300 Subject: [PATCH 40/44] MDEV-19335 adjustment for innodb_checksum_algorithm=full_crc32 When MDEV-12026 introduced innodb_checksum_algorithm=full_crc32 in MariaDB 10.4, it accidentally added a dependency on buf_page_t::encrypted. Now that the flag has been removed, we must adjust the page-read routine. buf_page_io_complete(): When the full_crc32 page checksum matches but the tablespace ID in the page does not match after decrypting, we should declare it a decryption failure and suppress the page dump output and any attempts to re-read the page. --- .../encryption/r/innodb-bad-key-change.result | 1 + .../r/innodb-bad-key-change2.result | 1 + .../r/innodb-bad-key-change4.result | 1 + .../t/innodb-bad-key-change.combinations | 4 +++ .../encryption/t/innodb-bad-key-change.test | 2 ++ .../t/innodb-bad-key-change2.combinations | 4 +++ .../encryption/t/innodb-bad-key-change2.test | 2 ++ .../t/innodb-bad-key-change3.combinations | 4 +++ .../t/innodb-bad-key-change4.combinations | 4 +++ .../encryption/t/innodb-bad-key-change4.test | 2 ++ storage/innobase/buf/buf0buf.cc | 27 ++++++++++++++----- 11 files changed, 45 insertions(+), 7 deletions(-) create mode 100644 mysql-test/suite/encryption/t/innodb-bad-key-change.combinations create mode 100644 mysql-test/suite/encryption/t/innodb-bad-key-change2.combinations create mode 100644 mysql-test/suite/encryption/t/innodb-bad-key-change3.combinations create mode 100644 mysql-test/suite/encryption/t/innodb-bad-key-change4.combinations diff --git a/mysql-test/suite/encryption/r/innodb-bad-key-change.result b/mysql-test/suite/encryption/r/innodb-bad-key-change.result index 45c32317557..255dde207ed 100644 --- a/mysql-test/suite/encryption/r/innodb-bad-key-change.result +++ b/mysql-test/suite/encryption/r/innodb-bad-key-change.result @@ -6,6 +6,7 @@ call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9] call mtr.add_suppression("InnoDB: Encrypted page \\[page id: space=[1-9][0-9]*, page number=3\\] in file .*test.t1.ibd looks corrupted; key_version=1"); call mtr.add_suppression("InnoDB: Table `test`\\.`t[12]` is corrupted"); call mtr.add_suppression("File '.*mysql-test.std_data.keysbad3\\.txt' not found"); +call mtr.add_suppression("\\[ERROR\\] InnoDB: Cannot decrypt \\[page id: space="); # Start server with keys2.txt # restart: --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys2.txt SET GLOBAL innodb_file_per_table = ON; diff --git a/mysql-test/suite/encryption/r/innodb-bad-key-change2.result b/mysql-test/suite/encryption/r/innodb-bad-key-change2.result index 78b9b7854de..543c3bc29b2 100644 --- a/mysql-test/suite/encryption/r/innodb-bad-key-change2.result +++ b/mysql-test/suite/encryption/r/innodb-bad-key-change2.result @@ -6,6 +6,7 @@ call mtr.add_suppression("InnoDB: Tablespace for table \`test\`.\`t1\` is set as call mtr.add_suppression("InnoDB: Table `test`\\.`t1` is corrupted"); call mtr.add_suppression("InnoDB: Cannot delete tablespace .* because it is not found in the tablespace memory cache"); call mtr.add_suppression("InnoDB: ALTER TABLE `test`\\.`t1` DISCARD TABLESPACE failed to find tablespace"); +call mtr.add_suppression("\\[ERROR\\] InnoDB: Cannot decrypt \\[page id: space="); # restart: --plugin-load-add=file_key_management.so --file-key-management --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys2.txt SET GLOBAL innodb_file_per_table = ON; CREATE TABLE t1 (pk INT PRIMARY KEY, f VARCHAR(8)) ENGINE=InnoDB diff --git a/mysql-test/suite/encryption/r/innodb-bad-key-change4.result b/mysql-test/suite/encryption/r/innodb-bad-key-change4.result index 6c23f94eb47..e37ee8eb8cd 100644 --- a/mysql-test/suite/encryption/r/innodb-bad-key-change4.result +++ b/mysql-test/suite/encryption/r/innodb-bad-key-change4.result @@ -3,6 +3,7 @@ call mtr.add_suppression("InnoDB: The page \\[page id: space=[1-9][0-9]*, page n call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9]*, page number=[1-9][0-9]*\\]"); call mtr.add_suppression("Couldn't load plugins from 'file_key_management"); call mtr.add_suppression("InnoDB: Table `test`\\.`t1` is corrupted"); +call mtr.add_suppression("\\[ERROR\\] InnoDB: Cannot decrypt \\[page id: space="); # restart: --plugin-load-add=file_key_management.so --file-key-management --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys2.txt SET GLOBAL innodb_file_per_table = ON; CREATE TABLE t1 (pk INT PRIMARY KEY, f VARCHAR(8)) ENGINE=InnoDB diff --git a/mysql-test/suite/encryption/t/innodb-bad-key-change.combinations b/mysql-test/suite/encryption/t/innodb-bad-key-change.combinations new file mode 100644 index 00000000000..be3ecd67aa8 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-bad-key-change.combinations @@ -0,0 +1,4 @@ +[crc32] +loose-innodb-checksum-algorithm=crc32 +[full_crc32] +loose-innodb-checksum-algorithm=full_crc32 diff --git a/mysql-test/suite/encryption/t/innodb-bad-key-change.test b/mysql-test/suite/encryption/t/innodb-bad-key-change.test index 552b9867d69..a9a32a3d6fc 100644 --- a/mysql-test/suite/encryption/t/innodb-bad-key-change.test +++ b/mysql-test/suite/encryption/t/innodb-bad-key-change.test @@ -16,6 +16,8 @@ call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9] call mtr.add_suppression("InnoDB: Encrypted page \\[page id: space=[1-9][0-9]*, page number=3\\] in file .*test.t1.ibd looks corrupted; key_version=1"); call mtr.add_suppression("InnoDB: Table `test`\\.`t[12]` is corrupted"); call mtr.add_suppression("File '.*mysql-test.std_data.keysbad3\\.txt' not found"); +# for innodb_checksum_algorithm=full_crc32 only +call mtr.add_suppression("\\[ERROR\\] InnoDB: Cannot decrypt \\[page id: space="); --echo # Start server with keys2.txt -- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt diff --git a/mysql-test/suite/encryption/t/innodb-bad-key-change2.combinations b/mysql-test/suite/encryption/t/innodb-bad-key-change2.combinations new file mode 100644 index 00000000000..be3ecd67aa8 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-bad-key-change2.combinations @@ -0,0 +1,4 @@ +[crc32] +loose-innodb-checksum-algorithm=crc32 +[full_crc32] +loose-innodb-checksum-algorithm=full_crc32 diff --git a/mysql-test/suite/encryption/t/innodb-bad-key-change2.test b/mysql-test/suite/encryption/t/innodb-bad-key-change2.test index f100c330bad..bdbf2327e5d 100644 --- a/mysql-test/suite/encryption/t/innodb-bad-key-change2.test +++ b/mysql-test/suite/encryption/t/innodb-bad-key-change2.test @@ -17,6 +17,8 @@ call mtr.add_suppression("InnoDB: Tablespace for table \`test\`.\`t1\` is set as call mtr.add_suppression("InnoDB: Table `test`\\.`t1` is corrupted"); call mtr.add_suppression("InnoDB: Cannot delete tablespace .* because it is not found in the tablespace memory cache"); call mtr.add_suppression("InnoDB: ALTER TABLE `test`\\.`t1` DISCARD TABLESPACE failed to find tablespace"); +# for innodb_checksum_algorithm=full_crc32 only +call mtr.add_suppression("\\[ERROR\\] InnoDB: Cannot decrypt \\[page id: space="); --let $restart_parameters=--plugin-load-add=file_key_management.so --file-key-management --file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt --source include/restart_mysqld.inc diff --git a/mysql-test/suite/encryption/t/innodb-bad-key-change3.combinations b/mysql-test/suite/encryption/t/innodb-bad-key-change3.combinations new file mode 100644 index 00000000000..be3ecd67aa8 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-bad-key-change3.combinations @@ -0,0 +1,4 @@ +[crc32] +loose-innodb-checksum-algorithm=crc32 +[full_crc32] +loose-innodb-checksum-algorithm=full_crc32 diff --git a/mysql-test/suite/encryption/t/innodb-bad-key-change4.combinations b/mysql-test/suite/encryption/t/innodb-bad-key-change4.combinations new file mode 100644 index 00000000000..be3ecd67aa8 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-bad-key-change4.combinations @@ -0,0 +1,4 @@ +[crc32] +loose-innodb-checksum-algorithm=crc32 +[full_crc32] +loose-innodb-checksum-algorithm=full_crc32 diff --git a/mysql-test/suite/encryption/t/innodb-bad-key-change4.test b/mysql-test/suite/encryption/t/innodb-bad-key-change4.test index d2f75a3d6c1..b341fc81d39 100644 --- a/mysql-test/suite/encryption/t/innodb-bad-key-change4.test +++ b/mysql-test/suite/encryption/t/innodb-bad-key-change4.test @@ -13,6 +13,8 @@ call mtr.add_suppression("failed to read or decrypt \\[page id: space=[1-9][0-9] # Suppression for builds where file_key_management plugin is linked statically call mtr.add_suppression("Couldn't load plugins from 'file_key_management"); call mtr.add_suppression("InnoDB: Table `test`\\.`t1` is corrupted"); +# for innodb_checksum_algorithm=full_crc32 only +call mtr.add_suppression("\\[ERROR\\] InnoDB: Cannot decrypt \\[page id: space="); --let $restart_parameters=--plugin-load-add=file_key_management.so --file-key-management --file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt --source include/restart_mysqld.inc diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index fa6a33662ad..7f00b27df0e 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -5955,7 +5955,7 @@ static dberr_t buf_page_check_corrupt(buf_page_t* bpage, fil_space_t* space) not decrypted and it could be either encrypted and corrupted or corrupted or good page. If we decrypted, there page could still be corrupted if used key does not match. */ - const bool seems_encrypted = (!space->full_crc32() && key_version) + const bool seems_encrypted = !space->full_crc32() && key_version && space->crypt_data && space->crypt_data->type != CRYPT_SCHEME_UNENCRYPTED; ut_ad(space->purpose != FIL_TYPE_TEMPORARY || space->full_crc32()); @@ -5970,7 +5970,6 @@ static dberr_t buf_page_check_corrupt(buf_page_t* bpage, fil_space_t* space) space->id, dst_frame, space->is_compressed())) { err = DB_PAGE_CORRUPTED; } - } else if (buf_page_is_corrupted(true, dst_frame, space->flags)) { err = DB_PAGE_CORRUPTED; } @@ -6085,13 +6084,26 @@ buf_page_io_complete(buf_page_t* bpage, bool dblwr, bool evict) } else if (read_space_id == 0 && read_page_no == 0) { /* This is likely an uninitialized page. */ - } else if ((bpage->id.space() != TRX_SYS_SPACE + } else if (((!space->full_crc32() + || bpage->id.space() != TRX_SYS_SPACE) && bpage->id.space() != read_space_id) || bpage->id.page_no() != read_page_no) { - /* We did not compare space_id to read_space_id - in the system tablespace, because the field - was written as garbage before MySQL 4.1.1, - which did not support innodb_file_per_table. */ + /* We do not compare space_id to read_space_id + in the system tablespace unless space->full_crc32(), + because the field was written as garbage before + MySQL 4.1.1, which introduced support for + innodb_file_per_table. */ + + if (space->full_crc32() + && *reinterpret_cast + (&frame[FIL_PAGE_FCRC32_KEY_VERSION]) + && space->crypt_data + && space->crypt_data->type + != CRYPT_SCHEME_UNENCRYPTED) { + ib::error() << "Cannot decrypt " << bpage->id; + err = DB_DECRYPTION_FAILED; + goto release_page; + } ib::error() << "Space id and page no stored in " "the page, read in are " @@ -6165,6 +6177,7 @@ database_corrupted: if (err == DB_PAGE_CORRUPTED || err == DB_DECRYPTION_FAILED) { +release_page: const page_id_t corrupt_page_id = bpage->id; buf_corrupt_page_release(bpage, space); From 6d7a8269532f4989b1515f259120e91019a74dec Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 10 Oct 2019 20:29:30 +0300 Subject: [PATCH 41/44] MDEV-20788: Bogus assertion failure for PAGE_FREE list In MDEV-11369 (instant ADD COLUMN) in MariaDB Server 10.3, we introduced the hidden metadata record that must be the first record in the clustered index if and only if index->is_instant() holds. To catch MDEV-19783, in commit ed0793e096a17955c5a03844b248bcf8303dd335 and commit 99dc40d6ac2234fa4c990665cc1914c1925cd641 we added some assertions to find cases where the metadata record is missing while it should not be, or a record exists when it should not. Those assertions were invalid when traversing the PAGE_FREE list. That list can contain anything; we must only be able to determine the successor and the size of each garbage record in it. page_validate(), page_simple_validate_old(), page_simple_validate_new(): Do not invoke page_rec_get_next_const() for traversing the PAGE_FREE list, but instead use a lower-level accessor that does not attempt to validate the REC_INFO_MIN_REC_FLAG. page_copy_rec_list_end_no_locks(), page_copy_rec_list_start(), page_delete_rec_list_start(): Add assertions. btr_page_get_split_rec_to_left(): Remove a redundant return value, and make the output parameter the return value. btr_page_get_split_rec_to_right(), btr_page_split_and_insert(): Clean up. --- storage/innobase/btr/btr0btr.cc | 208 +++++++++++------------------ storage/innobase/btr/btr0cur.cc | 2 +- storage/innobase/include/btr0btr.h | 40 +++--- storage/innobase/page/page0page.cc | 73 +++++++--- 4 files changed, 148 insertions(+), 175 deletions(-) diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc index 473e4248656..212b6489f29 100644 --- a/storage/innobase/btr/btr0btr.cc +++ b/storage/innobase/btr/btr0btr.cc @@ -2030,104 +2030,78 @@ btr_root_raise_and_insert( } } -/*************************************************************//** -Decides if the page should be split at the convergence point of inserts +/** Decide if the page should be split at the convergence point of inserts converging to the left. -@return TRUE if split recommended */ -ibool -btr_page_get_split_rec_to_left( -/*===========================*/ - btr_cur_t* cursor, /*!< in: cursor at which to insert */ - rec_t** split_rec) /*!< out: if split recommended, - the first record on upper half page, - or NULL if tuple to be inserted should - be first */ +@param[in] cursor insert position +@return the first record to be moved to the right half page +@retval NULL if no split is recommended */ +rec_t* btr_page_get_split_rec_to_left(const btr_cur_t* cursor) { - page_t* page; - rec_t* insert_point; - rec_t* infimum; - - page = btr_cur_get_page(cursor); - insert_point = btr_cur_get_rec(cursor); + rec_t* split_rec = btr_cur_get_rec(cursor); + const page_t* page = page_align(split_rec); if (page_header_get_ptr(page, PAGE_LAST_INSERT) - == page_rec_get_next(insert_point)) { - - infimum = page_get_infimum_rec(page); - - /* If the convergence is in the middle of a page, include also - the record immediately before the new insert to the upper - page. Otherwise, we could repeatedly move from page to page - lots of records smaller than the convergence point. */ - - if (infimum != insert_point - && page_rec_get_next(infimum) != insert_point) { - - *split_rec = insert_point; - } else { - *split_rec = page_rec_get_next(insert_point); - } - - return(TRUE); + != page_rec_get_next(split_rec)) { + return NULL; } - return(FALSE); + const rec_t* infimum = page_get_infimum_rec(page); + + /* If the convergence is in the middle of a page, include also + the record immediately before the new insert to the upper + page. Otherwise, we could repeatedly move from page to page + lots of records smaller than the convergence point. */ + + if (split_rec == infimum + || split_rec == page_rec_get_next_const(infimum)) { + split_rec = page_rec_get_next(split_rec); + } + + return split_rec; } -/*************************************************************//** -Decides if the page should be split at the convergence point of inserts +/** Decide if the page should be split at the convergence point of inserts converging to the right. -@return TRUE if split recommended */ -ibool -btr_page_get_split_rec_to_right( -/*============================*/ - btr_cur_t* cursor, /*!< in: cursor at which to insert */ - rec_t** split_rec) /*!< out: if split recommended, - the first record on upper half page, - or NULL if tuple to be inserted should - be first */ +@param[in] cursor insert position +@param[out] split_rec if split recommended, the first record + on the right half page, or + NULL if the to-be-inserted record + should be first +@return whether split is recommended */ +bool +btr_page_get_split_rec_to_right(const btr_cur_t* cursor, rec_t** split_rec) { - page_t* page; - rec_t* insert_point; - - page = btr_cur_get_page(cursor); - insert_point = btr_cur_get_rec(cursor); + rec_t* insert_point = btr_cur_get_rec(cursor); + const page_t* page = page_align(insert_point); /* We use eager heuristics: if the new insert would be right after the previous insert on the same page, we assume that there is a pattern of sequential inserts here. */ - if (page_header_get_ptr(page, PAGE_LAST_INSERT) == insert_point) { - - rec_t* next_rec; - - next_rec = page_rec_get_next(insert_point); - - if (page_rec_is_supremum(next_rec)) { -split_at_new: - /* Split at the new record to insert */ - *split_rec = NULL; - } else { - rec_t* next_next_rec = page_rec_get_next(next_rec); - if (page_rec_is_supremum(next_next_rec)) { - - goto split_at_new; - } - - /* If there are >= 2 user records up from the insert - point, split all but 1 off. We want to keep one because - then sequential inserts can use the adaptive hash - index, as they can do the necessary checks of the right - search position just by looking at the records on this - page. */ - - *split_rec = next_next_rec; - } - - return(TRUE); + if (page_header_get_ptr(page, PAGE_LAST_INSERT) != insert_point) { + return false; } - return(FALSE); + insert_point = page_rec_get_next(insert_point); + + if (page_rec_is_supremum(insert_point)) { + insert_point = NULL; + } else { + insert_point = page_rec_get_next(insert_point); + if (page_rec_is_supremum(insert_point)) { + insert_point = NULL; + } + + /* If there are >= 2 user records up from the insert + point, split all but 1 off. We want to keep one because + then sequential inserts can use the adaptive hash + index, as they can do the necessary checks of the right + search position just by looking at the records on this + page. */ + } + + *split_rec = insert_point; + return true; } /*************************************************************//** @@ -2782,30 +2756,20 @@ btr_page_split_and_insert( buf_block_t* block; page_t* page; page_zip_des_t* page_zip; - ulint page_no; - byte direction; - ulint hint_page_no; buf_block_t* new_block; page_t* new_page; page_zip_des_t* new_page_zip; rec_t* split_rec; buf_block_t* left_block; buf_block_t* right_block; - buf_block_t* insert_block; page_cur_t* page_cursor; rec_t* first_rec; byte* buf = 0; /* remove warning */ rec_t* move_limit; - ibool insert_will_fit; - ibool insert_left; ulint n_iterations = 0; - rec_t* rec; ulint n_uniq; - dict_index_t* index; - index = btr_cur_get_index(cursor); - - if (dict_index_is_spatial(index)) { + if (dict_index_is_spatial(cursor->index)) { /* Split rtree page and update parent */ return(rtr_page_split_and_insert(flags, cursor, offsets, heap, tuple, n_ext, mtr)); @@ -2837,23 +2801,19 @@ func_start: ut_ad(!page_is_empty(page)); /* try to insert to the next page if possible before split */ - rec = btr_insert_into_right_sibling( - flags, cursor, offsets, *heap, tuple, n_ext, mtr); - - if (rec != NULL) { + if (rec_t* rec = btr_insert_into_right_sibling( + flags, cursor, offsets, *heap, tuple, n_ext, mtr)) { return(rec); } - page_no = block->page.id.page_no(); - /* 1. Decide the split record; split_rec == NULL means that the tuple to be inserted should be the first record on the upper half-page */ - insert_left = FALSE; + bool insert_left = false; + ulint hint_page_no = block->page.id.page_no() + 1; + byte direction = FSP_UP; - if (tuple != NULL && n_iterations > 0) { - direction = FSP_UP; - hint_page_no = page_no + 1; + if (tuple && n_iterations > 0) { split_rec = btr_page_get_split_rec(cursor, tuple, n_ext); if (split_rec == NULL) { @@ -2861,17 +2821,10 @@ func_start: cursor, tuple, offsets, n_uniq, heap); } } else if (btr_page_get_split_rec_to_right(cursor, &split_rec)) { - direction = FSP_UP; - hint_page_no = page_no + 1; - - } else if (btr_page_get_split_rec_to_left(cursor, &split_rec)) { + } else if ((split_rec = btr_page_get_split_rec_to_left(cursor))) { direction = FSP_DOWN; - hint_page_no = page_no - 1; - ut_ad(split_rec); + hint_page_no -= 2; } else { - direction = FSP_UP; - hint_page_no = page_no + 1; - /* If there is only one record in the index page, we can't split the node in the middle by default. We need to determine whether the new record will be inserted @@ -2896,7 +2849,7 @@ func_start: new_block = btr_page_alloc(cursor->index, hint_page_no, direction, btr_page_get_level(page, mtr), mtr, mtr); - if (new_block == NULL && os_has_said_disk_full) { + if (!new_block) { return(NULL); } @@ -2921,12 +2874,8 @@ func_start: *offsets = rec_get_offsets(split_rec, cursor->index, *offsets, page_is_leaf(page), n_uniq, heap); - if (tuple != NULL) { - insert_left = cmp_dtuple_rec( - tuple, split_rec, *offsets) < 0; - } else { - insert_left = 1; - } + insert_left = !tuple + || cmp_dtuple_rec(tuple, split_rec, *offsets) < 0; if (!insert_left && new_page_zip && n_iterations > 0) { /* If a compressed page has already been split, @@ -2961,10 +2910,10 @@ insert_empty: on the appropriate half-page, we may release the tree x-latch. We can then move the records after releasing the tree latch, thus reducing the tree latch contention. */ + bool insert_will_fit; if (tuple == NULL) { - insert_will_fit = 1; - } - else if (split_rec) { + insert_will_fit = true; + } else if (split_rec) { insert_will_fit = !new_page_zip && btr_page_insert_fits(cursor, split_rec, offsets, tuple, n_ext, heap); @@ -3069,8 +3018,6 @@ insert_empty: new_block, block, move_limit); } - ut_ad(!dict_index_is_spatial(index)); - btr_search_move_or_delete_hash_entries( new_block, block, cursor->index); @@ -3102,18 +3049,15 @@ insert_empty: /* 6. The split and the tree modification is now completed. Decide the page where the tuple should be inserted */ + rec_t* rec; + buf_block_t* const insert_block = insert_left + ? left_block : right_block; - if (tuple == NULL) { + if (UNIV_UNLIKELY(!tuple)) { rec = NULL; goto func_exit; } - if (insert_left) { - insert_block = left_block; - } else { - insert_block = right_block; - } - /* 7. Reposition the cursor for insert and try insertion */ page_cursor = btr_cur_get_page_cur(cursor); @@ -3190,9 +3134,7 @@ func_exit: ut_ad(page_validate(buf_block_get_frame(left_block), cursor->index)); ut_ad(page_validate(buf_block_get_frame(right_block), cursor->index)); - if (tuple == NULL) { - ut_ad(rec == NULL); - } + ut_ad(tuple || !rec); ut_ad(!rec || rec_offs_validate(rec, cursor->index, *offsets)); return(rec); } diff --git a/storage/innobase/btr/btr0cur.cc b/storage/innobase/btr/btr0cur.cc index 3060865bc8e..788b34bca62 100644 --- a/storage/innobase/btr/btr0cur.cc +++ b/storage/innobase/btr/btr0cur.cc @@ -3138,7 +3138,7 @@ fail_err: && page_get_n_recs(page) >= 2 && dict_index_get_space_reserve() + rec_size > max_size && (btr_page_get_split_rec_to_right(cursor, &dummy) - || btr_page_get_split_rec_to_left(cursor, &dummy))) { + || btr_page_get_split_rec_to_left(cursor))) { goto fail; } diff --git a/storage/innobase/include/btr0btr.h b/storage/innobase/include/btr0btr.h index 604890ed03c..ded01e53bad 100644 --- a/storage/innobase/include/btr0btr.h +++ b/storage/innobase/include/btr0btr.h @@ -445,30 +445,22 @@ btr_page_reorganize( dict_index_t* index, /*!< in: the index tree of the page */ mtr_t* mtr) /*!< in/out: mini-transaction */ MY_ATTRIBUTE((nonnull)); -/*************************************************************//** -Decides if the page should be split at the convergence point of -inserts converging to left. -@return TRUE if split recommended */ -ibool -btr_page_get_split_rec_to_left( -/*===========================*/ - btr_cur_t* cursor, /*!< in: cursor at which to insert */ - rec_t** split_rec)/*!< out: if split recommended, - the first record on upper half page, - or NULL if tuple should be first */ - MY_ATTRIBUTE((warn_unused_result)); -/*************************************************************//** -Decides if the page should be split at the convergence point of -inserts converging to right. -@return TRUE if split recommended */ -ibool -btr_page_get_split_rec_to_right( -/*============================*/ - btr_cur_t* cursor, /*!< in: cursor at which to insert */ - rec_t** split_rec)/*!< out: if split recommended, - the first record on upper half page, - or NULL if tuple should be first */ - MY_ATTRIBUTE((warn_unused_result)); +/** Decide if the page should be split at the convergence point of inserts +converging to the left. +@param[in] cursor insert position +@return the first record to be moved to the right half page +@retval NULL if no split is recommended */ +rec_t* btr_page_get_split_rec_to_left(const btr_cur_t* cursor); +/** Decide if the page should be split at the convergence point of inserts +converging to the right. +@param[in] cursor insert position +@param[out] split_rec if split recommended, the first record + on the right half page, or + NULL if the to-be-inserted record + should be first +@return whether split is recommended */ +bool +btr_page_get_split_rec_to_right(const btr_cur_t* cursor, rec_t** split_rec); /*************************************************************//** Splits an index page to halves and inserts the tuple. It is assumed diff --git a/storage/innobase/page/page0page.cc b/storage/innobase/page/page0page.cc index bda4693648b..e316c8b1568 100644 --- a/storage/innobase/page/page0page.cc +++ b/storage/innobase/page/page0page.cc @@ -604,20 +604,20 @@ page_copy_rec_list_end_no_locks( /* Copy records from the original page to the new page */ while (!page_cur_is_after_last(&cur1)) { - rec_t* cur1_rec = page_cur_get_rec(&cur1); rec_t* ins_rec; - offsets = rec_get_offsets(cur1_rec, index, offsets, is_leaf, + offsets = rec_get_offsets(cur1.rec, index, offsets, is_leaf, ULINT_UNDEFINED, &heap); ins_rec = page_cur_insert_rec_low(cur2, index, - cur1_rec, offsets, mtr); + cur1.rec, offsets, mtr); if (UNIV_UNLIKELY(!ins_rec)) { ib::fatal() << "Rec offset " << page_offset(rec) - << ", cur1 offset " - << page_offset(page_cur_get_rec(&cur1)) + << ", cur1 offset " << page_offset(cur1.rec) << ", cur2 offset " << page_offset(cur2); } page_cur_move_to_next(&cur1); + ut_ad(!(rec_get_info_bits(cur1.rec, page_is_comp(new_page)) + & REC_INFO_MIN_REC_FLAG)); cur2 = ins_rec; } @@ -803,6 +803,8 @@ page_copy_rec_list_start( dict_index_t* index, /*!< in: record descriptor */ mtr_t* mtr) /*!< in: mtr */ { + ut_ad(page_align(rec) == block->frame); + page_t* new_page = buf_block_get_frame(new_block); page_zip_des_t* new_page_zip = buf_block_get_page_zip(new_block); page_cur_t cur1; @@ -820,7 +822,6 @@ page_copy_rec_list_start( predefined infimum record. */ if (page_rec_is_infimum(rec)) { - return(ret); } @@ -854,17 +855,18 @@ page_copy_rec_list_start( rec_move, max_to_move, &num_moved, mtr); } else { - while (page_cur_get_rec(&cur1) != rec) { - rec_t* cur1_rec = page_cur_get_rec(&cur1); - offsets = rec_get_offsets(cur1_rec, index, offsets, + offsets = rec_get_offsets(cur1.rec, index, offsets, is_leaf, ULINT_UNDEFINED, &heap); cur2 = page_cur_insert_rec_low(cur2, index, - cur1_rec, offsets, mtr); + cur1.rec, offsets, mtr); ut_a(cur2); page_cur_move_to_next(&cur1); + ut_ad(!(rec_get_info_bits(cur1.rec, + page_is_comp(new_page)) + & REC_INFO_MIN_REC_FLAG)); } } @@ -1254,6 +1256,7 @@ page_delete_rec_list_start( rec_offs_init(offsets_); + ut_ad(page_align(rec) == block->frame); ut_ad((ibool) !!page_rec_is_comp(rec) == dict_table_is_comp(index->table)); #ifdef UNIV_ZIP_DEBUG @@ -2163,7 +2166,17 @@ page_simple_validate_old( goto func_exit; } - rec = page_rec_get_next_const(rec); + ulint offs = rec_get_next_offs(rec, FALSE); + if (!offs) { + break; + } + if (UNIV_UNLIKELY(offs < PAGE_OLD_INFIMUM + || offs >= srv_page_size)) { + ib::error() << "Page free list is corrupted " << count; + goto func_exit; + } + + rec = page + offs; } if (UNIV_UNLIKELY(page_dir_get_n_heap(page) != count + 1)) { @@ -2355,7 +2368,17 @@ page_simple_validate_new( goto func_exit; } - rec = page_rec_get_next_const(rec); + const ulint offs = rec_get_next_offs(rec, TRUE); + if (!offs) { + break; + } + if (UNIV_UNLIKELY(offs < PAGE_OLD_INFIMUM + || offs >= srv_page_size)) { + ib::error() << "Page free list is corrupted " << count; + goto func_exit; + } + + rec = page + offs; } if (UNIV_UNLIKELY(page_dir_get_n_heap(page) != count + 1)) { @@ -2668,16 +2691,32 @@ n_owned_zero: page_is_leaf(page), ULINT_UNDEFINED, &heap); if (UNIV_UNLIKELY(!page_rec_validate(rec, offsets))) { + ret = FALSE; +next_free: + const ulint offs = rec_get_next_offs( + rec, page_is_comp(page)); + if (!offs) { + break; + } + if (UNIV_UNLIKELY(offs < PAGE_OLD_INFIMUM + || offs >= srv_page_size)) { + ib::error() << "Page free list is corrupted"; + ret = FALSE; + break; + } - goto func_exit; + rec = page + offs; + continue; } count++; offs = page_offset(rec_get_start(rec, offsets)); i = rec_offs_size(offsets); - if (UNIV_UNLIKELY(offs + i >= UNIV_PAGE_SIZE)) { - ib::error() << "Record offset out of bounds"; - goto func_exit; + if (UNIV_UNLIKELY(offs + i >= srv_page_size)) { + ib::error() << "Free record offset out of bounds: " + << offs << '+' << i; + ret = FALSE; + goto next_free; } while (i--) { @@ -2691,7 +2730,7 @@ n_owned_zero: buf[offs + i] = 1; } - rec = page_rec_get_next_const(rec); + goto next_free; } if (UNIV_UNLIKELY(page_dir_get_n_heap(page) != count + 1)) { From 01f45becd1b71433e240959228e35266f271bba1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 10 Oct 2019 20:40:26 +0300 Subject: [PATCH 42/44] MDEV-19783: Add more assertions btr_page_get_split_rec_to_left(): Assert that in the leftmost leaf page, the metadata record exists if and only if index->is_instant(). page_validate(): Correct the wording of a message. rec_init_offsets(): Assert that whenever a record is in "instant ALTER" format, index->is_instant() must hold. --- storage/innobase/btr/btr0btr.cc | 10 +++++++++- storage/innobase/page/page0page.cc | 5 +++-- storage/innobase/rem/rem0rec.cc | 3 +++ 3 files changed, 15 insertions(+), 3 deletions(-) diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc index 6fb56acce14..18f34d382e6 100644 --- a/storage/innobase/btr/btr0btr.cc +++ b/storage/innobase/btr/btr0btr.cc @@ -2062,6 +2062,14 @@ rec_t* btr_page_get_split_rec_to_left(const btr_cur_t* cursor) return NULL; } + /* The metadata record must be present in the leftmost leaf page + of the clustered index, if and only if index->is_instant(). */ + ut_ad(!page_is_leaf(page) || page_has_prev(page) + || cursor->index->is_instant() + == rec_is_metadata(page_rec_get_next_const( + page_get_infimum_rec(page)), + cursor->index)); + const rec_t* infimum = page_get_infimum_rec(page); /* If the convergence is in the middle of a page, include also @@ -2783,7 +2791,7 @@ btr_page_split_and_insert( ulint n_iterations = 0; ulint n_uniq; - if (dict_index_is_spatial(cursor->index)) { + if (cursor->index->is_spatial()) { /* Split rtree page and update parent */ return(rtr_page_split_and_insert(flags, cursor, offsets, heap, tuple, n_ext, mtr)); diff --git a/storage/innobase/page/page0page.cc b/storage/innobase/page/page0page.cc index d72d13f6d09..77bdbf8bf2c 100644 --- a/storage/innobase/page/page0page.cc +++ b/storage/innobase/page/page0page.cc @@ -839,7 +839,8 @@ page_copy_rec_list_start( const bool is_leaf = page_rec_is_leaf(rec); /* Copy records from the original page to the new page */ - if (dict_index_is_spatial(index)) { + if (index->is_spatial()) { + ut_ad(!index->is_instant()); ulint max_to_move = page_get_n_recs( buf_block_get_frame(block)); heap = mem_heap_create(256); @@ -2535,7 +2536,7 @@ wrong_page_type: & REC_INFO_MIN_REC_FLAG)) { if (page_has_prev(page)) { ib::error() << "REC_INFO_MIN_REC_FLAG " - "is set in on non-left page"; + "is set on non-left page"; ret = false; } else if (!page_is_leaf(page)) { /* leftmost node pointer page */ diff --git a/storage/innobase/rem/rem0rec.cc b/storage/innobase/rem/rem0rec.cc index 11e4bff217f..8803e691498 100644 --- a/storage/innobase/rem/rem0rec.cc +++ b/storage/innobase/rem/rem0rec.cc @@ -600,6 +600,7 @@ rec_init_offsets( break; case REC_STATUS_COLUMNS_ADDED: ut_ad(leaf); + ut_ad(index->is_instant()); rec_init_offsets_comp_ordinary(rec, index, offsets, index->n_core_fields, NULL, @@ -741,6 +742,8 @@ resolved: } if (i < rec_offs_n_fields(offsets)) { + ut_ad(index->is_instant()); + offs = (rec_offs_base(offsets)[i] & REC_OFFS_MASK) | REC_OFFS_DEFAULT; From 4cdb72f2372b27e1fbbc573812240c1e29128c8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 10 Oct 2019 21:21:24 +0300 Subject: [PATCH 43/44] MDEV-19783: Relax an assertion btr_page_get_split_rec_to_left(): Assert that in the leftmost leaf page, if the metadata record exists, index->is_instant() must hold. The assertion of commit 01f45becd1b71433e240959228e35266f271bba1 could fail during innobase_instant_try(). --- storage/innobase/btr/btr0btr.cc | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/storage/innobase/btr/btr0btr.cc b/storage/innobase/btr/btr0btr.cc index 18f34d382e6..ce736af2c11 100644 --- a/storage/innobase/btr/btr0btr.cc +++ b/storage/innobase/btr/btr0btr.cc @@ -2063,12 +2063,18 @@ rec_t* btr_page_get_split_rec_to_left(const btr_cur_t* cursor) } /* The metadata record must be present in the leftmost leaf page - of the clustered index, if and only if index->is_instant(). */ + of the clustered index, if and only if index->is_instant(). + However, during innobase_instant_try(), index->is_instant() + would already hold when row_ins_clust_index_entry_low() + is being invoked to insert the the metadata record. + So, we can only assert that when the metadata record exists, + index->is_instant() must hold. */ ut_ad(!page_is_leaf(page) || page_has_prev(page) || cursor->index->is_instant() - == rec_is_metadata(page_rec_get_next_const( - page_get_infimum_rec(page)), - cursor->index)); + || !(rec_get_info_bits(page_rec_get_next_const( + page_get_infimum_rec(page)), + dict_table_is_comp(cursor->index->table)) + & REC_INFO_MIN_REC_FLAG)); const rec_t* infimum = page_get_infimum_rec(page); From b05be3ef8c8668ddbcbe8e1c08dcd4fcc88eb4cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 11 Oct 2019 08:24:30 +0300 Subject: [PATCH 44/44] Add encryption.innodb-redo-badkey,strict_full_crc32 In commit 0f7732d1d1d898f1a9051858932c18bcc9d6f2b4 we introduced a innodb_checksum_algorithm=full_crc32 combination to a number of encryption tests, and also fixed the code accordingly. The default in MariaDB 10.5 is innodb_checksum_algorithm=full_crc32. In a test merge to 10.5, the test encryption.innodb-redo-badkey failed once due to a message that had been added in that commit. Let us introduce a full_crc32 option to that test. And let us use strict_crc32 and strict_full_crc32 instead of the non-strict variants, for the previously augmented tests, to be in line with the earlier tests encryption.corrupted_during_recovery and encryption.innodb_encrypt_temporary_tables. --- mysql-test/suite/encryption/r/innodb-redo-badkey.result | 1 + .../encryption/t/innodb-bad-key-change.combinations | 9 +++++---- .../encryption/t/innodb-bad-key-change2.combinations | 9 +++++---- .../encryption/t/innodb-bad-key-change3.combinations | 9 +++++---- .../encryption/t/innodb-bad-key-change4.combinations | 9 +++++---- .../suite/encryption/t/innodb-redo-badkey.combinations | 5 +++++ mysql-test/suite/encryption/t/innodb-redo-badkey.test | 2 ++ 7 files changed, 28 insertions(+), 16 deletions(-) create mode 100644 mysql-test/suite/encryption/t/innodb-redo-badkey.combinations diff --git a/mysql-test/suite/encryption/r/innodb-redo-badkey.result b/mysql-test/suite/encryption/r/innodb-redo-badkey.result index 33746dd9a11..f90e7aeb780 100644 --- a/mysql-test/suite/encryption/r/innodb-redo-badkey.result +++ b/mysql-test/suite/encryption/r/innodb-redo-badkey.result @@ -7,6 +7,7 @@ call mtr.add_suppression("InnoDB: Database page corruption on disk or a failed f call mtr.add_suppression("InnoDB: Failed to read file '.*' at offset .*"); call mtr.add_suppression("InnoDB: Plugin initialization aborted"); call mtr.add_suppression("Plugin 'InnoDB' registration as a STORAGE ENGINE failed"); +call mtr.add_suppression("\\[ERROR\\] InnoDB: Cannot decrypt \\[page id: space="); # restart: --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys2.txt # Wait max 10 min for key encryption threads to encrypt all spaces SET GLOBAL innodb_file_per_table = ON; diff --git a/mysql-test/suite/encryption/t/innodb-bad-key-change.combinations b/mysql-test/suite/encryption/t/innodb-bad-key-change.combinations index be3ecd67aa8..729380593f3 100644 --- a/mysql-test/suite/encryption/t/innodb-bad-key-change.combinations +++ b/mysql-test/suite/encryption/t/innodb-bad-key-change.combinations @@ -1,4 +1,5 @@ -[crc32] -loose-innodb-checksum-algorithm=crc32 -[full_crc32] -loose-innodb-checksum-algorithm=full_crc32 +[strict_crc32] +--innodb-checksum-algorithm=strict_crc32 + +[strict_full_crc32] +--innodb-checksum-algorithm=strict_full_crc32 diff --git a/mysql-test/suite/encryption/t/innodb-bad-key-change2.combinations b/mysql-test/suite/encryption/t/innodb-bad-key-change2.combinations index be3ecd67aa8..729380593f3 100644 --- a/mysql-test/suite/encryption/t/innodb-bad-key-change2.combinations +++ b/mysql-test/suite/encryption/t/innodb-bad-key-change2.combinations @@ -1,4 +1,5 @@ -[crc32] -loose-innodb-checksum-algorithm=crc32 -[full_crc32] -loose-innodb-checksum-algorithm=full_crc32 +[strict_crc32] +--innodb-checksum-algorithm=strict_crc32 + +[strict_full_crc32] +--innodb-checksum-algorithm=strict_full_crc32 diff --git a/mysql-test/suite/encryption/t/innodb-bad-key-change3.combinations b/mysql-test/suite/encryption/t/innodb-bad-key-change3.combinations index be3ecd67aa8..729380593f3 100644 --- a/mysql-test/suite/encryption/t/innodb-bad-key-change3.combinations +++ b/mysql-test/suite/encryption/t/innodb-bad-key-change3.combinations @@ -1,4 +1,5 @@ -[crc32] -loose-innodb-checksum-algorithm=crc32 -[full_crc32] -loose-innodb-checksum-algorithm=full_crc32 +[strict_crc32] +--innodb-checksum-algorithm=strict_crc32 + +[strict_full_crc32] +--innodb-checksum-algorithm=strict_full_crc32 diff --git a/mysql-test/suite/encryption/t/innodb-bad-key-change4.combinations b/mysql-test/suite/encryption/t/innodb-bad-key-change4.combinations index be3ecd67aa8..729380593f3 100644 --- a/mysql-test/suite/encryption/t/innodb-bad-key-change4.combinations +++ b/mysql-test/suite/encryption/t/innodb-bad-key-change4.combinations @@ -1,4 +1,5 @@ -[crc32] -loose-innodb-checksum-algorithm=crc32 -[full_crc32] -loose-innodb-checksum-algorithm=full_crc32 +[strict_crc32] +--innodb-checksum-algorithm=strict_crc32 + +[strict_full_crc32] +--innodb-checksum-algorithm=strict_full_crc32 diff --git a/mysql-test/suite/encryption/t/innodb-redo-badkey.combinations b/mysql-test/suite/encryption/t/innodb-redo-badkey.combinations new file mode 100644 index 00000000000..729380593f3 --- /dev/null +++ b/mysql-test/suite/encryption/t/innodb-redo-badkey.combinations @@ -0,0 +1,5 @@ +[strict_crc32] +--innodb-checksum-algorithm=strict_crc32 + +[strict_full_crc32] +--innodb-checksum-algorithm=strict_full_crc32 diff --git a/mysql-test/suite/encryption/t/innodb-redo-badkey.test b/mysql-test/suite/encryption/t/innodb-redo-badkey.test index ecdd97af2a6..d18fe5ba7d9 100644 --- a/mysql-test/suite/encryption/t/innodb-redo-badkey.test +++ b/mysql-test/suite/encryption/t/innodb-redo-badkey.test @@ -12,6 +12,8 @@ call mtr.add_suppression("InnoDB: Database page corruption on disk or a failed f call mtr.add_suppression("InnoDB: Failed to read file '.*' at offset .*"); call mtr.add_suppression("InnoDB: Plugin initialization aborted"); call mtr.add_suppression("Plugin 'InnoDB' registration as a STORAGE ENGINE failed"); +# for innodb_checksum_algorithm=full_crc32 only +call mtr.add_suppression("\\[ERROR\\] InnoDB: Cannot decrypt \\[page id: space="); -- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt -- source include/restart_mysqld.inc