From cbad0bcd4146cec8a36e790ae98c4b9e604cf2e8 Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Fri, 13 Oct 2023 17:27:27 +0530 Subject: [PATCH 1/6] MDEV-31098 InnoDB Recovery doesn't display encryption message when no encryption configuration passed - InnoDB fails to report the error when encryption configuration wasn't passed. This patch addresses the issue by adding the error while loading the tablespace and deferring the tablespace creation. --- .../suite/encryption/r/innodb-redo-nokeys.result | 2 ++ .../suite/encryption/t/innodb-redo-nokeys.test | 5 +++++ storage/innobase/fil/fil0fil.cc | 15 ++++++++++++--- storage/innobase/include/fil0fil.h | 6 ++++++ storage/innobase/log/log0recv.cc | 6 +----- 5 files changed, 26 insertions(+), 8 deletions(-) diff --git a/mysql-test/suite/encryption/r/innodb-redo-nokeys.result b/mysql-test/suite/encryption/r/innodb-redo-nokeys.result index ba8f5b2fe85..ce24c7c7033 100644 --- a/mysql-test/suite/encryption/r/innodb-redo-nokeys.result +++ b/mysql-test/suite/encryption/r/innodb-redo-nokeys.result @@ -9,6 +9,7 @@ call mtr.add_suppression("InnoDB: Cannot apply log to \\[page id: space=[1-9][0- call mtr.add_suppression("InnoDB: Failed to read page .* from file '.*'"); call mtr.add_suppression("InnoDB: OPT_PAGE_CHECKSUM mismatch"); call mtr.add_suppression("InnoDB: Set innodb_force_recovery=1 to ignore corruption"); +call mtr.add_suppression("InnoDB: Encryption key is not found for"); # restart: --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys2.txt SET GLOBAL innodb_file_per_table = ON; create table t1(a int not null primary key auto_increment, c char(200), b blob, index(b(10))) engine=innodb row_format=compressed encrypted=yes encryption_key_id=20; @@ -39,5 +40,6 @@ SELECT * FROM INFORMATION_SCHEMA.ENGINES WHERE engine = 'innodb' AND support IN ('YES', 'DEFAULT', 'ENABLED'); ENGINE SUPPORT COMMENT TRANSACTIONS XA SAVEPOINTS +FOUND 1 /\[ERROR\] InnoDB: Encryption key is not found for .*test.t1.ibd/ in mysqld.1.err # restart: --file-key-management-filename=MYSQL_TEST_DIR/std_data/keys2.txt drop table t1,t2,t3,t4,t5; diff --git a/mysql-test/suite/encryption/t/innodb-redo-nokeys.test b/mysql-test/suite/encryption/t/innodb-redo-nokeys.test index ab77b3747b8..7323a9148c3 100644 --- a/mysql-test/suite/encryption/t/innodb-redo-nokeys.test +++ b/mysql-test/suite/encryption/t/innodb-redo-nokeys.test @@ -14,6 +14,7 @@ call mtr.add_suppression("InnoDB: Cannot apply log to \\[page id: space=[1-9][0- call mtr.add_suppression("InnoDB: Failed to read page .* from file '.*'"); call mtr.add_suppression("InnoDB: OPT_PAGE_CHECKSUM mismatch"); call mtr.add_suppression("InnoDB: Set innodb_force_recovery=1 to ignore corruption"); +call mtr.add_suppression("InnoDB: Encryption key is not found for"); -- let $restart_parameters=--file-key-management-filename=$MYSQL_TEST_DIR/std_data/keys2.txt -- source include/restart_mysqld.inc @@ -73,6 +74,10 @@ SELECT * FROM INFORMATION_SCHEMA.ENGINES WHERE engine = 'innodb' AND support IN ('YES', 'DEFAULT', 'ENABLED'); +let SEARCH_FILE = $MYSQLTEST_VARDIR/log/mysqld.1.err; +let SEARCH_PATTERN = \[ERROR\] InnoDB: Encryption key is not found for .*test.t1.ibd; +--source include/search_pattern_in_file.inc + # # In above server does start but InnoDB refuses to start # thus we need to restart server with correct key file diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index 8a0dc883eea..a4a949c223b 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -2428,6 +2428,17 @@ fil_ibd_discover( /* A datafile was not discovered for the filename given. */ return(false); } + +bool fil_crypt_check(fil_space_crypt_t *crypt_data, const char *f_name) +{ + if (crypt_data->is_key_found()) + return true; + sql_print_error("InnoDB: Encryption key is not found for %s", f_name); + crypt_data->~fil_space_crypt_t(); + ut_free(crypt_data); + return false; +} + /** Open an ibd tablespace and add it to the InnoDB data structures. This is similar to fil_ibd_open() except that it is used while processing the REDO log, so the data dictionary is not available and very little @@ -2576,9 +2587,7 @@ tablespace_check: first_page) : NULL; - if (crypt_data && !crypt_data->is_key_found()) { - crypt_data->~fil_space_crypt_t(); - ut_free(crypt_data); + if (crypt_data && !fil_crypt_check(crypt_data, filename)) { return FIL_LOAD_INVALID; } diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h index c3aadd587e0..7deec35d986 100644 --- a/storage/innobase/include/fil0fil.h +++ b/storage/innobase/include/fil0fil.h @@ -1946,4 +1946,10 @@ void test_make_filepath(); @return block size */ ulint fil_space_get_block_size(const fil_space_t* space, unsigned offset); +/** Check whether encryption key found +@param crypt_data Encryption data +@param f_name File name +@return encryption key found */ +bool fil_crypt_check(fil_space_crypt_t *crypt_data, const char *f_name); + #endif /* UNIV_INNOCHECKSUM */ diff --git a/storage/innobase/log/log0recv.cc b/storage/innobase/log/log0recv.cc index aa7ec6f2d04..99853ebb7c1 100644 --- a/storage/innobase/log/log0recv.cc +++ b/storage/innobase/log/log0recv.cc @@ -827,12 +827,8 @@ processed: const std::string &name, uint32_t flags, fil_space_crypt_t *crypt_data, uint32_t size) { - if (crypt_data && !crypt_data->is_key_found()) - { - crypt_data->~fil_space_crypt_t(); - ut_free(crypt_data); + if (crypt_data && !fil_crypt_check(crypt_data, name.c_str())) return nullptr; - } mysql_mutex_lock(&fil_system.mutex); fil_space_t *space= fil_space_t::create(it->first, flags, FIL_TYPE_TABLESPACE, crypt_data); From 18fa00a54cab7cc2b9453d42b8ebc038fd3d07bd Mon Sep 17 00:00:00 2001 From: Vlad Lesin Date: Thu, 12 Oct 2023 12:33:03 +0300 Subject: [PATCH 2/6] MDEV-32272 lock_release_on_prepare_try() does not release lock if supremum bit is set along with other bits set in lock's bitmap MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The error is caused by MDEV-30165 fix with the following commit: d13a57ae8181f2a8fbee86838d5476740e050d50 There is logical error in lock_release_on_prepare_try(): if (supremum_bit) lock_rec_unlock_supremum(*cell, lock); else lock_rec_dequeue_from_page(lock, false); Because there can be other bits set in the lock's bitmap, and the lock type can be suitable for releasing criteria, but the above logic releases only supremum bit of the lock. The fix is to release lock if it suits for releasing criteria and unlock supremum if supremum is locked otherwise. Tere is also the test for the case, which was reported by QA team. I placed it in a separate files, because it requires debug build. Reviewed by: Marko Mäkelä --- .../r/xa_prepare_reset_supremum_lock.result | 13 ++++++++ ...p_release_locks_on_dict_stats_table.result | 17 ++++++++++ .../t/xa_prepare_reset_supremum_lock.test | 23 +++++++++++-- ...xap_release_locks_on_dict_stats_table.test | 33 +++++++++++++++++++ storage/innobase/dict/dict0stats.cc | 11 +++++++ storage/innobase/lock/lock0lock.cc | 10 +++--- 6 files changed, 100 insertions(+), 7 deletions(-) create mode 100644 mysql-test/suite/innodb/r/xap_release_locks_on_dict_stats_table.result create mode 100644 mysql-test/suite/innodb/t/xap_release_locks_on_dict_stats_table.test diff --git a/mysql-test/suite/innodb/r/xa_prepare_reset_supremum_lock.result b/mysql-test/suite/innodb/r/xa_prepare_reset_supremum_lock.result index 475363444e9..bd971adf966 100644 --- a/mysql-test/suite/innodb/r/xa_prepare_reset_supremum_lock.result +++ b/mysql-test/suite/innodb/r/xa_prepare_reset_supremum_lock.result @@ -14,6 +14,19 @@ XA PREPARE '1'; connect con1,localhost,root; SET innodb_lock_wait_timeout=1; INSERT INTO t VALUES(50); +connection default; +XA COMMIT '1'; +XA START '1'; +SELECT * FROM t WHERE a > 20 LOCK IN SHARE MODE; +a +40 +50 +INSERT INTO t VALUES (5); +XA END '1'; +XA PREPARE '1'; +connection con1; +INSERT INTO t VALUES (60); +INSERT INTO t VALUES (30); disconnect con1; connection default; XA COMMIT '1'; diff --git a/mysql-test/suite/innodb/r/xap_release_locks_on_dict_stats_table.result b/mysql-test/suite/innodb/r/xap_release_locks_on_dict_stats_table.result new file mode 100644 index 00000000000..1a849f1c477 --- /dev/null +++ b/mysql-test/suite/innodb/r/xap_release_locks_on_dict_stats_table.result @@ -0,0 +1,17 @@ +call mtr.add_suppression("bytes freed by"); +SET @old_innodb_stats_persistent = @@innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=1; +CREATE TABLE t ENGINE=InnoDB AS SELECT 1; +SET @old_debug_dbug = @@global.debug_dbug; +XA START 'a'; +INSERT INTO mysql.innodb_index_stats SELECT '','' AS table_name,index_name,LAST_UPDATE,stat_name,0 AS stat_value,sample_size,stat_description FROM mysql.innodb_index_stats WHERE table_name='dummy' FOR UPDATE; +SET GLOBAL debug_dbug = "+d,dict_stats_save_exit_notify"; +INSERT INTO t VALUES (1); +XA END 'a'; +XA PREPARE 'a'; +SET DEBUG_SYNC="now WAIT_FOR dict_stats_save_finished"; +SET @@global.debug_dbug = @old_debug_dbug; +SET DEBUG_SYNC="RESET"; +SET GLOBAL innodb_stats_persistent = @old_innodb_stats_persistent; +XA COMMIT 'a'; +DROP TABLE t; diff --git a/mysql-test/suite/innodb/t/xa_prepare_reset_supremum_lock.test b/mysql-test/suite/innodb/t/xa_prepare_reset_supremum_lock.test index d285f6f4f3a..180e44d05ae 100644 --- a/mysql-test/suite/innodb/t/xa_prepare_reset_supremum_lock.test +++ b/mysql-test/suite/innodb/t/xa_prepare_reset_supremum_lock.test @@ -13,19 +13,36 @@ INSERT INTO t VALUES(20); SET TRANSACTION ISOLATION LEVEL REPEATABLE READ; XA START '1'; SELECT * FROM t WHERE a > 20 FOR UPDATE; +# The following INSERT is necessary because trx_prepare() resets locks +# only if there were modifications in transaction. INSERT INTO t VALUES(40); XA END '1'; XA PREPARE '1'; connect (con1,localhost,root); SET innodb_lock_wait_timeout=1; -# This will be finished with lock wait timeout error if XA PREPARE did not -# reset lock on supremum +# The following INSERT must not be blocked if XA PREPARE released supremum lock INSERT INTO t VALUES(50); + +--connection default +XA COMMIT '1'; + +XA START '1'; +SELECT * FROM t WHERE a > 20 LOCK IN SHARE MODE; +# The following INSERT is necessary because trx_prepare() resets locks +# only if there were modifications in transaction. +INSERT INTO t VALUES (5); +XA END '1'; +XA PREPARE '1'; + +--connection con1 +# The following INSERT must not be blocked if XA PREPARE released supremum lock +INSERT INTO t VALUES (60); +# The following INSERT must not be blocked if XA PREPARE released shared lock +INSERT INTO t VALUES (30); --disconnect con1 --connection default XA COMMIT '1'; DROP TABLE t; - --source include/wait_until_count_sessions.inc diff --git a/mysql-test/suite/innodb/t/xap_release_locks_on_dict_stats_table.test b/mysql-test/suite/innodb/t/xap_release_locks_on_dict_stats_table.test new file mode 100644 index 00000000000..a02a032ef61 --- /dev/null +++ b/mysql-test/suite/innodb/t/xap_release_locks_on_dict_stats_table.test @@ -0,0 +1,33 @@ +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc + +# Some memory is allocated in dict_stats_save() function for additional sync +# point. The memory is allocated in current_thd->mem_root pool after +# dict_stats_func() arranged new thd and freed after destroy_background_thd() +# attached background thread thd to the current_thd. That's there are +# different thread id's for memory allocation and deallocation, what causes +# the following warnings. This is not an error because the memory is still +# allocated and deallocated by the same thread in pool. +call mtr.add_suppression("bytes freed by"); + +SET @old_innodb_stats_persistent = @@innodb_stats_persistent; +SET GLOBAL innodb_stats_persistent=1; +CREATE TABLE t ENGINE=InnoDB AS SELECT 1; + +SET @old_debug_dbug = @@global.debug_dbug; + +XA START 'a'; +INSERT INTO mysql.innodb_index_stats SELECT '','' AS table_name,index_name,LAST_UPDATE,stat_name,0 AS stat_value,sample_size,stat_description FROM mysql.innodb_index_stats WHERE table_name='dummy' FOR UPDATE; # Note the SELECT is empty +SET GLOBAL debug_dbug = "+d,dict_stats_save_exit_notify"; +INSERT INTO t VALUES (1); +XA END 'a'; +XA PREPARE 'a'; + +# Locking queue validation will crash the server if the bug is not fixed +SET DEBUG_SYNC="now WAIT_FOR dict_stats_save_finished"; +SET @@global.debug_dbug = @old_debug_dbug; +SET DEBUG_SYNC="RESET"; +SET GLOBAL innodb_stats_persistent = @old_innodb_stats_persistent; +XA COMMIT 'a'; +DROP TABLE t; diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc index e8dd976f8d2..c553b31ef01 100644 --- a/storage/innobase/dict/dict0stats.cc +++ b/storage/innobase/dict/dict0stats.cc @@ -34,6 +34,8 @@ Created Jan 06, 2010 Vasil Dimov #include "log.h" #include "btr0btr.h" #include "que0que.h" +#include "scope.h" +#include "debug_sync.h" #include #include @@ -3245,6 +3247,15 @@ dict_stats_save( char db_utf8[MAX_DB_UTF8_LEN]; char table_utf8[MAX_TABLE_UTF8_LEN]; +#ifdef ENABLED_DEBUG_SYNC + DBUG_EXECUTE_IF("dict_stats_save_exit_notify", + SCOPE_EXIT([] { + debug_sync_set_action(current_thd, + STRING_WITH_LEN("now SIGNAL dict_stats_save_finished")); + }); + ); +#endif /* ENABLED_DEBUG_SYNC */ + if (high_level_read_only) { return DB_READ_ONLY; } diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index e7638e8f3ba..31e02d2451a 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -4345,17 +4345,19 @@ static bool lock_release_on_prepare_try(trx_t *trx) { ut_ad(!lock->index->table->is_temporary()); bool supremum_bit = lock_rec_get_nth_bit(lock, PAGE_HEAP_NO_SUPREMUM); - if (!supremum_bit && lock->is_rec_granted_exclusive_not_gap()) + bool rec_granted_exclusive_not_gap = + lock->is_rec_granted_exclusive_not_gap(); + if (!supremum_bit && rec_granted_exclusive_not_gap) continue; auto &lock_hash= lock_sys.hash_get(lock->type_mode); auto cell= lock_hash.cell_get(lock->un_member.rec_lock.page_id.fold()); auto latch= lock_sys_t::hash_table::latch(cell); if (latch->try_acquire()) { - if (supremum_bit) - lock_rec_unlock_supremum(*cell, lock); - else + if (!rec_granted_exclusive_not_gap) lock_rec_dequeue_from_page(lock, false); + else if (supremum_bit) + lock_rec_unlock_supremum(*cell, lock); latch->release(); } else From ec277a70e8677190fd57f16e36441fe3505d681f Mon Sep 17 00:00:00 2001 From: Monty Date: Sat, 14 Oct 2023 13:43:26 +0300 Subject: [PATCH 3/6] Do not create histograms for single column unique key The intentention was always to not create histograms for single value unique keys (as histograms is not useful in this case), but because of a bug in the code this was still done. The changes in the test cases was mainly because hist_size is now NULL for these kind of columns. --- mysql-test/main/stat_tables.result | 6 +- mysql-test/main/stat_tables_innodb.result | 6 +- mysql-test/main/statistics.result | 68 +++++++++++------------ sql/sql_statistics.cc | 2 +- 4 files changed, 41 insertions(+), 41 deletions(-) diff --git a/mysql-test/main/stat_tables.result b/mysql-test/main/stat_tables.result index 1c43dd268a8..be0da0d44d3 100644 --- a/mysql-test/main/stat_tables.result +++ b/mysql-test/main/stat_tables.result @@ -542,14 +542,14 @@ test.t1 analyze Warning Engine-independent statistics are not collected for colu test.t1 analyze status OK SELECT * FROM mysql.column_stats; db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram -test t1 pk 1 2 0.0000 4.0000 1.0000 0 NULL NULL +test t1 pk 1 2 0.0000 4.0000 1.0000 NULL NULL NULL DELETE FROM mysql.column_stats WHERE db_name='test' AND table_name='t1' AND column_name='t'; INSERT INTO mysql.column_stats VALUES ('test','t1','t','bar','foo', 0.0, 3.0, 1.0, 0, NULL, NULL); SELECT * FROM mysql.column_stats; db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram -test t1 pk 1 2 0.0000 4.0000 1.0000 0 NULL NULL +test t1 pk 1 2 0.0000 4.0000 1.0000 NULL NULL NULL test t1 t bar foo 0.0000 3.0000 1.0000 0 NULL NULL SELECT pk FROM t1; pk @@ -573,7 +573,7 @@ pk c 2 bar SELECT * FROM mysql.column_stats; db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram -test t1 pk 1 2 0.0000 4.0000 1.0000 0 NULL NULL +test t1 pk 1 2 0.0000 4.0000 1.0000 NULL NULL NULL test t1 c bar foo 0.0000 3.0000 1.0000 0 NULL NULL CREATE OR REPLACE TABLE t1 (pk int PRIMARY KEY, a char(7)); SELECT * FROM t1; diff --git a/mysql-test/main/stat_tables_innodb.result b/mysql-test/main/stat_tables_innodb.result index 163a417f810..0f18376a5d6 100644 --- a/mysql-test/main/stat_tables_innodb.result +++ b/mysql-test/main/stat_tables_innodb.result @@ -574,14 +574,14 @@ test.t1 analyze Warning Engine-independent statistics are not collected for colu test.t1 analyze status OK SELECT * FROM mysql.column_stats; db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram -test t1 pk 1 2 0.0000 4.0000 1.0000 0 NULL NULL +test t1 pk 1 2 0.0000 4.0000 1.0000 NULL NULL NULL DELETE FROM mysql.column_stats WHERE db_name='test' AND table_name='t1' AND column_name='t'; INSERT INTO mysql.column_stats VALUES ('test','t1','t','bar','foo', 0.0, 3.0, 1.0, 0, NULL, NULL); SELECT * FROM mysql.column_stats; db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram -test t1 pk 1 2 0.0000 4.0000 1.0000 0 NULL NULL +test t1 pk 1 2 0.0000 4.0000 1.0000 NULL NULL NULL test t1 t bar foo 0.0000 3.0000 1.0000 0 NULL NULL SELECT pk FROM t1; pk @@ -605,7 +605,7 @@ pk c 2 bar SELECT * FROM mysql.column_stats; db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram -test t1 pk 1 2 0.0000 4.0000 1.0000 0 NULL NULL +test t1 pk 1 2 0.0000 4.0000 1.0000 NULL NULL NULL test t1 c bar foo 0.0000 3.0000 1.0000 0 NULL NULL CREATE OR REPLACE TABLE t1 (pk int PRIMARY KEY, a char(7)); SELECT * FROM t1; diff --git a/mysql-test/main/statistics.result b/mysql-test/main/statistics.result index a442a33d14b..4e635139a88 100644 --- a/mysql-test/main/statistics.result +++ b/mysql-test/main/statistics.result @@ -70,7 +70,7 @@ db_name table_name cardinality test t1 40 SELECT * FROM mysql.column_stats; db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram -test t1 a 0 49 0.0000 4.0000 1.0000 0 NULL NULL +test t1 a 0 49 0.0000 4.0000 1.0000 NULL NULL NULL test t1 b vvvvvvvvvvvvv zzzzzzzzzzzzzzzzzz 0.2000 17.1250 6.4000 0 NULL NULL test t1 c aaaa dddddddd 0.1250 6.6571 7.0000 0 NULL NULL test t1 d 1989-03-12 1999-07-23 0.1500 3.0000 8.5000 0 NULL NULL @@ -93,7 +93,7 @@ COUNT(*) SELECT * FROM mysql.column_stats WHERE db_name='test' AND table_name='t1' AND column_name='a'; db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram -test t1 a 0 49 0.0000 4.0000 1.0000 0 NULL NULL +test t1 a 0 49 0.0000 4.0000 1.0000 NULL NULL NULL SELECT MIN(t1.a), MAX(t1.a), (SELECT COUNT(*) FROM t1 WHERE t1.b IS NULL) / (SELECT COUNT(*) FROM t1) AS "NULLS_RATIO(t1.a)", @@ -223,7 +223,7 @@ nulls_ratio, avg_frequency, hist_size, hist_type, HEX(histogram) FROM mysql.column_stats; db_name table_name column_name min_value max_value nulls_ratio avg_frequency hist_size hist_type HEX(histogram) -test t1 a 0 49 0.0000 1.0000 4 SINGLE_PREC_HB 2E62A1D0 +test t1 a 0 49 0.0000 1.0000 NULL NULL NULL test t1 b vvvvvvvvvvvvv zzzzzzzzzzzzzzzzzz 0.2000 6.4000 4 SINGLE_PREC_HB 003FBFFF test t1 c aaaa dddddddd 0.1250 7.0000 4 SINGLE_PREC_HB 0055AAFF test t1 d 1989-03-12 1999-07-23 0.1500 8.5000 4 SINGLE_PREC_HB 001919FF @@ -242,7 +242,7 @@ nulls_ratio, avg_frequency, hist_size, hist_type, HEX(histogram) FROM mysql.column_stats; db_name table_name column_name min_value max_value nulls_ratio avg_frequency hist_size hist_type HEX(histogram) -test t1 a 0 49 0.0000 1.0000 8 DOUBLE_PREC_HB 052F4363F4A1F9D0 +test t1 a 0 49 0.0000 1.0000 NULL NULL NULL test t1 b vvvvvvvvvvvvv zzzzzzzzzzzzzzzzzz 0.2000 6.4000 8 DOUBLE_PREC_HB 0000FF3FFFBFFFFF test t1 c aaaa dddddddd 0.1250 7.0000 8 DOUBLE_PREC_HB 00005555AAAAFFFF test t1 d 1989-03-12 1999-07-23 0.1500 8.5000 8 DOUBLE_PREC_HB 0000031A031AFFFF @@ -289,13 +289,13 @@ test t1 40 test t3 17 SELECT * FROM mysql.column_stats; db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram -test t1 a 0 49 0.0000 4.0000 1.0000 0 NULL NULL +test t1 a 0 49 0.0000 4.0000 1.0000 NULL NULL NULL test t1 b vvvvvvvvvvvvv zzzzzzzzzzzzzzzzzz 0.2000 17.1250 6.4000 0 NULL NULL test t1 c aaaa dddddddd 0.1250 6.6571 7.0000 0 NULL NULL test t1 d 1989-03-12 1999-07-23 0.1500 3.0000 8.5000 0 NULL NULL test t1 e 0.01 0.112 0.2250 8.0000 6.2000 0 NULL NULL test t1 f 1 5 0.2000 1.0000 6.4000 0 NULL NULL -test t3 a 0 38 0.0000 4.0000 1.0000 0 NULL NULL +test t3 a 0 38 0.0000 4.0000 1.0000 NULL NULL NULL test t3 b vvvvvvvvvvvvv zzzzzzzzzzzzzzzzzz 0.1765 18.0714 2.8000 0 NULL NULL test t3 c aaaa dddddddd 0.1176 6.4000 3.7500 0 NULL NULL SELECT * FROM mysql.index_stats; @@ -318,13 +318,13 @@ test s1 40 test t3 17 SELECT * FROM mysql.column_stats; db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram -test s1 a 0 49 0.0000 4.0000 1.0000 0 NULL NULL +test s1 a 0 49 0.0000 4.0000 1.0000 NULL NULL NULL test s1 b vvvvvvvvvvvvv zzzzzzzzzzzzzzzzzz 0.2000 17.1250 6.4000 0 NULL NULL test s1 c aaaa dddddddd 0.1250 6.6571 7.0000 0 NULL NULL test s1 d 1989-03-12 1999-07-23 0.1500 3.0000 8.5000 0 NULL NULL test s1 e 0.01 0.112 0.2250 8.0000 6.2000 0 NULL NULL test s1 f 1 5 0.2000 1.0000 6.4000 0 NULL NULL -test t3 a 0 38 0.0000 4.0000 1.0000 0 NULL NULL +test t3 a 0 38 0.0000 4.0000 1.0000 NULL NULL NULL test t3 b vvvvvvvvvvvvv zzzzzzzzzzzzzzzzzz 0.1765 18.0714 2.8000 0 NULL NULL test t3 c aaaa dddddddd 0.1176 6.4000 3.7500 0 NULL NULL SELECT * FROM mysql.index_stats; @@ -347,13 +347,13 @@ test t1 40 test t3 17 SELECT * FROM mysql.column_stats; db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram -test t1 a 0 49 0.0000 4.0000 1.0000 0 NULL NULL +test t1 a 0 49 0.0000 4.0000 1.0000 NULL NULL NULL test t1 b vvvvvvvvvvvvv zzzzzzzzzzzzzzzzzz 0.2000 17.1250 6.4000 0 NULL NULL test t1 c aaaa dddddddd 0.1250 6.6571 7.0000 0 NULL NULL test t1 d 1989-03-12 1999-07-23 0.1500 3.0000 8.5000 0 NULL NULL test t1 e 0.01 0.112 0.2250 8.0000 6.2000 0 NULL NULL test t1 f 1 5 0.2000 1.0000 6.4000 0 NULL NULL -test t3 a 0 38 0.0000 4.0000 1.0000 0 NULL NULL +test t3 a 0 38 0.0000 4.0000 1.0000 NULL NULL NULL test t3 b vvvvvvvvvvvvv zzzzzzzzzzzzzzzzzz 0.1765 18.0714 2.8000 0 NULL NULL test t3 c aaaa dddddddd 0.1176 6.4000 3.7500 0 NULL NULL SELECT * FROM mysql.index_stats; @@ -375,7 +375,7 @@ db_name table_name cardinality test t1 40 SELECT * FROM mysql.column_stats; db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram -test t1 a 0 49 0.0000 4.0000 1.0000 0 NULL NULL +test t1 a 0 49 0.0000 4.0000 1.0000 NULL NULL NULL test t1 b vvvvvvvvvvvvv zzzzzzzzzzzzzzzzzz 0.2000 17.1250 6.4000 0 NULL NULL test t1 c aaaa dddddddd 0.1250 6.6571 7.0000 0 NULL NULL test t1 d 1989-03-12 1999-07-23 0.1500 3.0000 8.5000 0 NULL NULL @@ -416,7 +416,7 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci SELECT * FROM mysql.column_stats; db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram -test t1 a 0 49 0.0000 4.0000 1.0000 0 NULL NULL +test t1 a 0 49 0.0000 4.0000 1.0000 NULL NULL NULL test t1 c aaaa dddddddd 0.1250 6.6571 7.0000 0 NULL NULL test t1 d 1989-03-12 1999-07-23 0.1500 3.0000 8.5000 0 NULL NULL test t1 f 1 5 0.2000 1.0000 6.4000 0 NULL NULL @@ -441,7 +441,7 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci SELECT * FROM mysql.column_stats; db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram -test t1 a 0 49 0.0000 4.0000 1.0000 0 NULL NULL +test t1 a 0 49 0.0000 4.0000 1.0000 NULL NULL NULL test t1 b vvvvvvvvvvvvv zzzzzzzzzzzzzzzzzz 0.2000 17.1250 6.4000 0 NULL NULL test t1 c aaaa dddddddd 0.1250 6.6571 7.0000 0 NULL NULL test t1 d 1989-03-12 1999-07-23 0.1500 3.0000 8.5000 0 NULL NULL @@ -468,7 +468,7 @@ db_name table_name cardinality test s1 40 SELECT * FROM mysql.column_stats; db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram -test s1 a 0 49 0.0000 4.0000 1.0000 0 NULL NULL +test s1 a 0 49 0.0000 4.0000 1.0000 NULL NULL NULL test s1 c aaaa dddddddd 0.1250 6.6571 7.0000 0 NULL NULL test s1 d 1989-03-12 1999-07-23 0.1500 3.0000 8.5000 0 NULL NULL test s1 e 0.01 0.112 0.2250 8.0000 6.2000 0 NULL NULL @@ -506,7 +506,7 @@ db_name table_name cardinality test t1 40 SELECT * FROM mysql.column_stats; db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram -test t1 a 0 49 0.0000 4.0000 1.0000 0 NULL NULL +test t1 a 0 49 0.0000 4.0000 1.0000 NULL NULL NULL test t1 b vvvvvvvvvvvvv zzzzzzzzzzzzzzzzzz 0.2000 17.1250 6.4000 0 NULL NULL test t1 c aaaa dddddddd 0.1250 6.6571 7.0000 0 NULL NULL test t1 d 1989-03-12 1999-07-23 0.1500 3.0000 8.5000 0 NULL NULL @@ -541,7 +541,7 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci SELECT * FROM mysql.column_stats; db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram -test t1 a 0 49 0.0000 4.0000 1.0000 0 NULL NULL +test t1 a 0 49 0.0000 4.0000 1.0000 NULL NULL NULL test t1 c aaaa dddddddd 0.1250 6.6571 7.0000 0 NULL NULL test t1 d 1989-03-12 1999-07-23 0.1500 3.0000 8.5000 0 NULL NULL test t1 e 0.01 0.112 0.2250 8.0000 6.2000 0 NULL NULL @@ -577,7 +577,7 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci SELECT * FROM mysql.column_stats; db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram -test t1 a 0 49 0.0000 4.0000 1.0000 0 NULL NULL +test t1 a 0 49 0.0000 4.0000 1.0000 NULL NULL NULL test t1 c aaaa dddddddd 0.1250 6.6571 7.0000 0 NULL NULL test t1 d 1989-03-12 1999-07-23 0.1500 3.0000 8.5000 0 NULL NULL test t1 e 0.01 0.112 0.2250 8.0000 6.2000 0 NULL NULL @@ -594,7 +594,7 @@ test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK SELECT * FROM mysql.column_stats; db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram -test t1 a 0 49 0.0000 4.0000 1.0000 0 NULL NULL +test t1 a 0 49 0.0000 4.0000 1.0000 NULL NULL NULL test t1 b vvvvvvvvvvvvv zzzzzzzzzzzzzzzzzz 0.2000 17.1250 6.4000 0 NULL NULL test t1 c aaaa dddddddd 0.1250 6.6571 7.0000 0 NULL NULL test t1 d 1989-03-12 1999-07-23 0.1500 3.0000 8.5000 0 NULL NULL @@ -635,7 +635,7 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci SELECT * FROM mysql.column_stats; db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram -test t1 a 0 49 0.0000 4.0000 1.0000 0 NULL NULL +test t1 a 0 49 0.0000 4.0000 1.0000 NULL NULL NULL test t1 c aaaa dddddddd 0.1250 6.6571 7.0000 0 NULL NULL test t1 d 1989-03-12 1999-07-23 0.1500 3.0000 8.5000 0 NULL NULL test t1 e 0.01 0.112 0.2250 8.0000 6.2000 0 NULL NULL @@ -664,7 +664,7 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci SELECT * FROM mysql.column_stats; db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram -test t1 a 0 49 0.0000 4.0000 1.0000 0 NULL NULL +test t1 a 0 49 0.0000 4.0000 1.0000 NULL NULL NULL test t1 c aaaa dddddddd 0.1250 6.6571 7.0000 0 NULL NULL test t1 d 1989-03-12 1999-07-23 0.1500 3.0000 8.5000 0 NULL NULL test t1 e 0.01 0.112 0.2250 8.0000 6.2000 0 NULL NULL @@ -683,7 +683,7 @@ LOAD DATA INFILE 'MYSQLTEST_VARDIR/tmp/save_index_stats' FIELDS TERMINATED BY ',' OPTIONALLY ENCLOSED BY '"' LINES TERMINATED BY '\n'; SELECT * FROM mysql.column_stats; db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram -test t1 a 0 49 0.0000 4.0000 1.0000 0 NULL NULL +test t1 a 0 49 0.0000 4.0000 1.0000 NULL NULL NULL test t1 b vvvvvvvvvvvvv zzzzzzzzzzzzzzzzzz 0.2000 17.1250 6.4000 0 NULL NULL test t1 c aaaa dddddddd 0.1250 6.6571 7.0000 0 NULL NULL test t1 d 1989-03-12 1999-07-23 0.1500 3.0000 8.5000 0 NULL NULL @@ -717,7 +717,7 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci SELECT * FROM mysql.column_stats; db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram -test t1 a 0 49 0.0000 4.0000 1.0000 0 NULL NULL +test t1 a 0 49 0.0000 4.0000 1.0000 NULL NULL NULL test t1 c aaaa dddddddd 0.1250 6.6571 7.0000 0 NULL NULL test t1 d 1989-03-12 1999-07-23 0.1500 3.0000 8.5000 0 NULL NULL test t1 e 0.01 0.112 0.2250 8.0000 6.2000 0 NULL NULL @@ -780,7 +780,7 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci SELECT * FROM mysql.column_stats; db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram -test t1 a 0 49 0.0000 4.0000 1.0000 0 NULL NULL +test t1 a 0 49 0.0000 4.0000 1.0000 NULL NULL NULL test t1 c aaaa dddddddd 0.1250 6.6571 7.0000 0 NULL NULL test t1 d 1989-03-12 1999-07-23 0.1500 3.0000 8.5000 0 NULL NULL test t1 e 0.01 0.112 0.2250 8.0000 6.2000 0 NULL NULL @@ -795,7 +795,7 @@ test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK SELECT * FROM mysql.column_stats; db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram -test t1 a 0 49 0.0000 4.0000 1.0000 0 NULL NULL +test t1 a 0 49 0.0000 4.0000 1.0000 NULL NULL NULL test t1 b NULL NULL 1.0000 NULL NULL 0 NULL NULL test t1 c aaaa dddddddd 0.1250 6.6571 7.0000 0 NULL NULL test t1 d 1989-03-12 1999-07-23 0.1500 3.0000 8.5000 0 NULL NULL @@ -819,7 +819,7 @@ test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK SELECT * FROM mysql.column_stats; db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram -test t1 a 0 49 0.0000 4.0000 1.0000 0 NULL NULL +test t1 a 0 49 0.0000 4.0000 1.0000 NULL NULL NULL test t1 b vvvvvvvvvvvvv zzzzzzzzzzzzzzzzzz 0.2000 17.1250 6.4000 0 NULL NULL test t1 c aaaa dddddddd 0.1250 6.6571 7.0000 0 NULL NULL test t1 d 1989-03-12 1999-07-23 0.1500 3.0000 8.5000 0 NULL NULL @@ -851,7 +851,7 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci SELECT * FROM mysql.column_stats; db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram -test t1 a 0 49 0.0000 4.0000 1.0000 0 NULL NULL +test t1 a 0 49 0.0000 4.0000 1.0000 NULL NULL NULL test t1 c aaaa dddddddd 0.1250 6.6571 7.0000 0 NULL NULL test t1 d 1989-03-12 1999-07-23 0.1500 3.0000 8.5000 0 NULL NULL test t1 e 0.01 0.112 0.2250 8.0000 6.2000 0 NULL NULL @@ -881,7 +881,7 @@ t1 CREATE TABLE `t1` ( ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci SELECT * FROM mysql.column_stats; db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram -test t1 a 0 49 0.0000 4.0000 1.0000 0 NULL NULL +test t1 a 0 49 0.0000 4.0000 1.0000 NULL NULL NULL test t1 c aaaa dddddddd 0.1250 6.6571 7.0000 0 NULL NULL test t1 d 1989-03-12 1999-07-23 0.1500 3.0000 8.5000 0 NULL NULL test t1 e 0.01 0.112 0.2250 8.0000 6.2000 0 NULL NULL @@ -896,7 +896,7 @@ test.t1 analyze status Engine-independent statistics collected test.t1 analyze status OK SELECT * FROM mysql.column_stats; db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram -test t1 a 0 49 0.0000 4.0000 1.0000 0 NULL NULL +test t1 a 0 49 0.0000 4.0000 1.0000 NULL NULL NULL test t1 b vvvvvvvvvvvvv zzzzzzzzzzzzzzzzzz 0.2000 17.1250 6.4000 0 NULL NULL test t1 c aaaa dddddddd 0.1250 6.6571 7.0000 0 NULL NULL test t1 d 1989-03-12 1999-07-23 0.1500 3.0000 8.5000 0 NULL NULL @@ -978,7 +978,7 @@ db_name table_name cardinality test t1 40 SELECT * FROM mysql.column_stats; db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram -test t1 a 0 49 0.0000 4.0000 1.0000 0 NULL NULL +test t1 a 0 49 0.0000 4.0000 1.0000 NULL NULL NULL test t1 b vvvvvvvvvvvvv zzzzzzzzzzzzzzzzzz 0.2000 17.1250 6.4000 0 NULL NULL test t1 c aaaa dddddddd 0.1250 6.6571 7.0000 0 NULL NULL test t1 d 1989-03-12 1999-07-23 0.1500 3.0000 8.5000 0 NULL NULL @@ -1009,8 +1009,8 @@ test t1 40 test t2 40 SELECT * FROM mysql.column_stats ORDER BY column_name, table_name; db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram -test t1 a 0 49 0.0000 4.0000 1.0000 0 NULL NULL -test t2 a 0 49 0.0000 4.0000 1.0000 0 NULL NULL +test t1 a 0 49 0.0000 4.0000 1.0000 NULL NULL NULL +test t2 a 0 49 0.0000 4.0000 1.0000 NULL NULL NULL test t1 b vvvvvvvvvvvvv zzzzzzzzzzzzzzzzzz 0.2000 17.1250 6.4000 0 NULL NULL test t2 b vvvvvvvvvvvvv zzzzzzzzzzzzzzzzzz 0.2000 17.1250 6.4000 0 NULL NULL test t1 c aaaa dddddddd 0.1250 6.6571 7.0000 0 NULL NULL @@ -1054,7 +1054,7 @@ db_name table_name cardinality test t2 40 SELECT * FROM mysql.column_stats ORDER BY column_name; db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram -test t2 a 0 49 0.0000 4.0000 1.0000 0 NULL NULL +test t2 a 0 49 0.0000 4.0000 1.0000 NULL NULL NULL test t2 b vvvvvvvvvvvvv zzzzzzzzzzzzzzzzzz 0.2000 17.1250 6.4000 0 NULL NULL test t2 c aaaa dddddddd 0.1250 6.6571 7.0000 0 NULL NULL test t2 d 1989-03-12 1999-07-23 0.1500 3.0000 8.5000 0 NULL NULL @@ -1235,7 +1235,7 @@ test.t1 analyze Warning Engine-independent statistics are not collected for colu test.t1 analyze status OK SELECT * FROM mysql.column_stats; db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram -test t1 a 0 49 0.0000 4.0000 1.0000 0 NULL NULL +test t1 a 0 49 0.0000 4.0000 1.0000 NULL NULL NULL test t1 c aaaa dddddddd 0.1250 6.6571 7.0000 0 NULL NULL test t1 d 1989-03-12 1999-07-23 0.1500 3.0000 8.5000 0 NULL NULL test t1 e 0.01 0.112 0.2250 8.0000 6.2000 0 NULL NULL @@ -1291,7 +1291,7 @@ db_name table_name cardinality test t1 40 SELECT * FROM mysql.column_stats; db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram -test t1 a 0 49 0.0000 4.0000 1.0000 0 NULL NULL +test t1 a 0 49 0.0000 4.0000 1.0000 NULL NULL NULL test t1 c aaaa dddddddd 0.1250 6.6571 7.0000 0 NULL NULL test t1 d 1989-03-12 1999-07-23 0.1500 3.0000 8.5000 0 NULL NULL test t1 e 0.01 0.112 0.2250 8.0000 6.2000 0 NULL NULL diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index ba4f5ec2d02..abeeee8019b 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -2345,7 +2345,7 @@ void Column_statistics_collected::init(THD *thd, Field *table_field) column_total_length= 0; if (is_single_pk_col) count_distinct= NULL; - if (table_field->flags & BLOB_FLAG) + else if (table_field->flags & BLOB_FLAG) count_distinct= NULL; else { From 1c554459b382479cca3045b4cc6b5d1e3a858664 Mon Sep 17 00:00:00 2001 From: Monty Date: Sat, 14 Oct 2023 15:46:29 +0300 Subject: [PATCH 4/6] MDEV-32449 Server crashes in Alter_info::add_stat_drop_index upon CREATE TABLE Fixed missing initialization of Alter_info() This could cause crashes in some create table like scenarios where some generated indexes where automatically dropped. I also added a test that we do not try to drop from index_stats for temporary tables. --- mysql-test/main/alter_table.result | 28 ++++++++++++++++++++++++++++ mysql-test/main/alter_table.test | 18 ++++++++++++++++++ sql/sql_alter.h | 1 + sql/sql_table.cc | 2 +- 4 files changed, 48 insertions(+), 1 deletion(-) diff --git a/mysql-test/main/alter_table.result b/mysql-test/main/alter_table.result index 21998597cad..084b757530a 100644 --- a/mysql-test/main/alter_table.result +++ b/mysql-test/main/alter_table.result @@ -3093,3 +3093,31 @@ drop table t1; # # End of 10.5 tests # +# +# MDEV-32449 Server crashes in Alter_info::add_stat_drop_index upon CREATE TABLE +# +CREATE TABLE t1 ( +`altcol1` blob DEFAULT '', +KEY `altcol1` (`altcol1`(2300)) +) ROW_FORMAT=PAGE, ENGINE=Aria; +ALTER TABLE t1 ADD FOREIGN KEY h (`altcol1`) REFERENCES t1 (`altcol1`) ON UPDATE SET DEFAULT, ALGORITHM=COPY; +Warnings: +Note 1071 Specified key was too long; max key length is 2300 bytes +create or replace table t2 like t1; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `altcol1` blob DEFAULT '', + KEY `altcol1` (`altcol1`(2300)), + KEY `h` (`altcol1`(2300)) +) ENGINE=Aria DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1 ROW_FORMAT=PAGE +show create table t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `altcol1` blob DEFAULT '', + KEY `altcol1` (`altcol1`(2300)) +) ENGINE=Aria DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1 ROW_FORMAT=PAGE +drop table t1,t2; +# +# End of 10.6 tests +# diff --git a/mysql-test/main/alter_table.test b/mysql-test/main/alter_table.test index 2867fc74f03..c8ad4c23e5c 100644 --- a/mysql-test/main/alter_table.test +++ b/mysql-test/main/alter_table.test @@ -2382,3 +2382,21 @@ drop table t1; --echo # --echo # End of 10.5 tests --echo # + +--echo # +--echo # MDEV-32449 Server crashes in Alter_info::add_stat_drop_index upon CREATE TABLE +--echo # + +CREATE TABLE t1 ( + `altcol1` blob DEFAULT '', + KEY `altcol1` (`altcol1`(2300)) +) ROW_FORMAT=PAGE, ENGINE=Aria; +ALTER TABLE t1 ADD FOREIGN KEY h (`altcol1`) REFERENCES t1 (`altcol1`) ON UPDATE SET DEFAULT, ALGORITHM=COPY; +create or replace table t2 like t1; +show create table t1; +show create table t2; +drop table t1,t2; + +--echo # +--echo # End of 10.6 tests +--echo # diff --git a/sql/sql_alter.h b/sql/sql_alter.h index 24203716cb2..4bec6801147 100644 --- a/sql/sql_alter.h +++ b/sql/sql_alter.h @@ -199,6 +199,7 @@ public: Alter_info() : flags(0), partition_flags(0), keys_onoff(LEAVE_AS_IS), + original_table(0), num_parts(0), requested_algorithm(ALTER_TABLE_ALGORITHM_NONE), requested_lock(ALTER_TABLE_LOCK_DEFAULT) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index bac8b6c4243..1ae4d2c88f0 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2898,7 +2898,7 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, key_iterator.rewind(); while ((key=key_iterator++)) { - if (key->type == Key::IGNORE_KEY) + if (key->type == Key::IGNORE_KEY && !create_info->tmp_table()) { /* The key was replaced by another key */ if (alter_info->add_stat_drop_index(thd, &key->name)) From cca9547892d620e969c2933465bf736ed1a592c9 Mon Sep 17 00:00:00 2001 From: Monty Date: Mon, 16 Oct 2023 12:55:17 +0300 Subject: [PATCH 5/6] Post fix for MDEV-32449 --- mysql-test/main/alter_table.result | 6 ++++++ mysql-test/main/alter_table.test | 8 ++++++++ sql/sql_table.cc | 5 +++-- 3 files changed, 17 insertions(+), 2 deletions(-) diff --git a/mysql-test/main/alter_table.result b/mysql-test/main/alter_table.result index 084b757530a..b8f85e33944 100644 --- a/mysql-test/main/alter_table.result +++ b/mysql-test/main/alter_table.result @@ -3118,6 +3118,12 @@ t2 CREATE TABLE `t2` ( KEY `altcol1` (`altcol1`(2300)) ) ENGINE=Aria DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci PAGE_CHECKSUM=1 ROW_FORMAT=PAGE drop table t1,t2; +# Another test for MDEV-32449 +CREATE TABLE t1 (a POINT, b POINT, KEY(a)) ENGINE=Aria; +ALTER TABLE t1 ADD FOREIGN KEY (a) REFERENCES t (b); +CREATE TEMPORARY TABLE t2 LIKE t1; +DROP TEMPORARY TABLE t2; +DROP TABLE t1; # # End of 10.6 tests # diff --git a/mysql-test/main/alter_table.test b/mysql-test/main/alter_table.test index c8ad4c23e5c..40f48ac87bd 100644 --- a/mysql-test/main/alter_table.test +++ b/mysql-test/main/alter_table.test @@ -2397,6 +2397,14 @@ show create table t1; show create table t2; drop table t1,t2; +--echo # Another test for MDEV-32449 + +CREATE TABLE t1 (a POINT, b POINT, KEY(a)) ENGINE=Aria; +ALTER TABLE t1 ADD FOREIGN KEY (a) REFERENCES t (b); +CREATE TEMPORARY TABLE t2 LIKE t1; +DROP TEMPORARY TABLE t2; +DROP TABLE t1; + --echo # --echo # End of 10.6 tests --echo # diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 1ae4d2c88f0..6f9e7bdab86 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2898,10 +2898,11 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info, key_iterator.rewind(); while ((key=key_iterator++)) { - if (key->type == Key::IGNORE_KEY && !create_info->tmp_table()) + if (key->type == Key::IGNORE_KEY) { /* The key was replaced by another key */ - if (alter_info->add_stat_drop_index(thd, &key->name)) + if (!create_info->tmp_table() && + alter_info->add_stat_drop_index(thd, &key->name)) DBUG_RETURN(true); continue; } From ee5cadd5c8b98dac58e55c673eeb48225e36f16e Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Mon, 16 Oct 2023 20:17:09 +0530 Subject: [PATCH 6/6] MDEV-28122 Optimize table crash while applying online log - InnoDB fails to check the overflow buffer while applying the operation to the table that was rebuilt. This is caused by commit 3cef4f8f0fc88ae5bfae4603d8d600ec84cc70a9 (MDEV-515). --- .../suite/innodb/r/innodb-table-online.result | 23 ++++++++++++++++ .../suite/innodb/t/innodb-table-online.test | 27 +++++++++++++++++++ storage/innobase/row/row0log.cc | 10 +++---- 3 files changed, 55 insertions(+), 5 deletions(-) diff --git a/mysql-test/suite/innodb/r/innodb-table-online.result b/mysql-test/suite/innodb/r/innodb-table-online.result index 5a8b3d24d75..caefcce47f1 100644 --- a/mysql-test/suite/innodb/r/innodb-table-online.result +++ b/mysql-test/suite/innodb/r/innodb-table-online.result @@ -470,6 +470,29 @@ SET DEBUG_SYNC="now SIGNAL con1_signal"; connection con1; DROP TABLE t1; connection default; +# +# MDEV-28122 Optimize table crash while applying online log +# +CREATE TABLE t1(f1 INT NOT NULL, f2 INT NOT NULL, +f3 CHAR(200), f4 CHAR(200), +f5 VARCHAR(87), PRIMARY KEY(f1))ENGINE=InnoDB; +INSERT INTO t1 VALUES(6000, 6000, "InnoDB", +"MariaDB", repeat('a', 87)); +SET DEBUG_SYNC="inplace_after_index_build SIGNAL dml_start WAIT_FOR dml_commit"; +ALTER TABLE t1 FORCE; +connection con1; +SET DEBUG_SYNC="now WAIT_FOR dml_start"; +BEGIN; +INSERT INTO t1 SELECT seq, seq, "IDB", "MDB", repeat('a', 87) FROM seq_1_to_127; +INSERT INTO t1 VALUES(128, 128, "IDB", "MDB", repeat('a', 86)); +INSERT INTO t1 VALUES(129, 129, "idb", "mdb", repeat('a', 2)); +COMMIT; +SET DEBUG_SYNC="now SIGNAL dml_commit"; +connection default; +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +DROP TABLE t1; SET DEBUG_SYNC=RESET; disconnect con1; SET GLOBAL innodb_file_per_table = @global_innodb_file_per_table_orig; diff --git a/mysql-test/suite/innodb/t/innodb-table-online.test b/mysql-test/suite/innodb/t/innodb-table-online.test index bfaabf24bd2..90c8dc2095d 100644 --- a/mysql-test/suite/innodb/t/innodb-table-online.test +++ b/mysql-test/suite/innodb/t/innodb-table-online.test @@ -2,6 +2,7 @@ --source include/innodb_encrypt_log.inc --source include/have_debug.inc --source include/have_debug_sync.inc +--source include/have_sequence.inc let $innodb_metrics_select= SELECT name, count FROM INFORMATION_SCHEMA.INNODB_METRICS WHERE subsystem = 'ddl'; @@ -440,6 +441,32 @@ connection con1; reap; DROP TABLE t1; connection default; + +--echo # +--echo # MDEV-28122 Optimize table crash while applying online log +--echo # +CREATE TABLE t1(f1 INT NOT NULL, f2 INT NOT NULL, + f3 CHAR(200), f4 CHAR(200), + f5 VARCHAR(87), PRIMARY KEY(f1))ENGINE=InnoDB; +INSERT INTO t1 VALUES(6000, 6000, "InnoDB", + "MariaDB", repeat('a', 87)); + +SET DEBUG_SYNC="inplace_after_index_build SIGNAL dml_start WAIT_FOR dml_commit"; +SEND ALTER TABLE t1 FORCE; + +connection con1; +SET DEBUG_SYNC="now WAIT_FOR dml_start"; +BEGIN; +INSERT INTO t1 SELECT seq, seq, "IDB", "MDB", repeat('a', 87) FROM seq_1_to_127; +INSERT INTO t1 VALUES(128, 128, "IDB", "MDB", repeat('a', 86)); +INSERT INTO t1 VALUES(129, 129, "idb", "mdb", repeat('a', 2)); +COMMIT; +SET DEBUG_SYNC="now SIGNAL dml_commit"; + +connection default; +reap; +CHECK TABLE t1; +DROP TABLE t1; SET DEBUG_SYNC=RESET; disconnect con1; diff --git a/storage/innobase/row/row0log.cc b/storage/innobase/row/row0log.cc index b21ff2b9f86..a0931ddf7cf 100644 --- a/storage/innobase/row/row0log.cc +++ b/storage/innobase/row/row0log.cc @@ -2167,6 +2167,11 @@ row_log_table_apply_op( *error = DB_SUCCESS; + /* 3 = 1 (op type) + 1 (extra_size) + at least 1 byte payload */ + if (mrec + 3 >= mrec_end) { + return(NULL); + } + const bool is_instant = log->is_instant(dup->index); const mrec_t* const mrec_start = mrec; @@ -2214,11 +2219,6 @@ row_log_table_apply_op( break; case ROW_T_DELETE: - /* 1 (extra_size) + at least 1 (payload) */ - if (mrec + 2 >= mrec_end) { - return(NULL); - } - extra_size = *mrec++; ut_ad(mrec < mrec_end);