From 6d5fe9ed0d64eac8d20712123046974642e7f99a Mon Sep 17 00:00:00 2001 From: Denis Protivensky Date: Wed, 20 Mar 2024 14:12:22 +0300 Subject: [PATCH 1/7] MDEV-28378: Don't hang trying to peek log event past the end of log While applying CTAS log event, we peek the relay log to see if CTAS contains inserted rows or if it's empty. The peek function didn't check for end-of-file condition when tried to get the next event from the log, and thus it hanged. The fix includes checking for end-of-file while peeking for log events and considering returned XID_EVENT value as a sign of an empty CTAS. Signed-off-by: Julius Goryavsky --- mysql-test/suite/galera/disabled.def | 1 - sql/slave.cc | 7 ++++++- sql/wsrep_mysqld.cc | 3 ++- 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/mysql-test/suite/galera/disabled.def b/mysql-test/suite/galera/disabled.def index e00bdbf85c0..759fc38be74 100644 --- a/mysql-test/suite/galera/disabled.def +++ b/mysql-test/suite/galera/disabled.def @@ -10,7 +10,6 @@ # ############################################################################## -galera_as_slave_ctas : MDEV-28378 timeout galera_pc_recovery : MDEV-25199 cluster fails to start up galera_sequences : MDEV-32561 WSREP FSM failure: no such a transition REPLICATING -> COMMITTED galera_concurrent_ctas : MDEV-32779 galera_concurrent_ctas: assertion in the galera::ReplicatorSMM::finish_cert() diff --git a/sql/slave.cc b/sql/slave.cc index 27dfcbf162d..90425b27772 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -8125,7 +8125,7 @@ end: #ifdef WITH_WSREP enum Log_event_type wsrep_peak_event(rpl_group_info *rgi, ulonglong* event_size) { - enum Log_event_type ev_type; + enum Log_event_type ev_type= UNKNOWN_EVENT; mysql_mutex_lock(&rgi->rli->data_lock); @@ -8136,6 +8136,11 @@ enum Log_event_type wsrep_peak_event(rpl_group_info *rgi, ulonglong* event_size) /* scan the log to read next event and we skip annotate events. */ do { + /* We've reached the end of log, return the last found event, if any. */ + if (future_pos >= rgi->rli->cur_log->end_of_file) + { + break; + } my_b_seek(rgi->rli->cur_log, future_pos); rgi->rli->event_relay_log_pos= future_pos; rgi->event_relay_log_pos= future_pos; diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index 1be48c7c120..fac87cdfa1c 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -2109,7 +2109,7 @@ bool wsrep_can_run_in_toi(THD *thd, const char *db, const char *table, If mariadb master has replicated a CTAS, we should not replicate the create table part separately as TOI, but to replicate both create table and following inserts as one write set. - Howver, if CTAS creates empty table, we should replicate the create table alone + However, if CTAS creates empty table, we should replicate the create table alone as TOI. We have to do relay log event lookup to see if row events follow the create table event. */ @@ -2122,6 +2122,7 @@ bool wsrep_can_run_in_toi(THD *thd, const char *db, const char *table, switch (ev_type) { case QUERY_EVENT: + case XID_EVENT: /* CTAS with empty table, we replicate create table as TOI */ break; From eb891b6a95384db3a1c49decbaa69a2b0c0aa97a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Tue, 5 Nov 2024 12:42:50 +0200 Subject: [PATCH 2/7] MDEV-35345 : Galera test failure on MW-402 Add missing have_debug[_sync].inc include. Signed-off-by: Julius Goryavsky --- mysql-test/suite/galera/t/MW-402.test | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mysql-test/suite/galera/t/MW-402.test b/mysql-test/suite/galera/t/MW-402.test index 4b83e25dc50..f84752e1b25 100644 --- a/mysql-test/suite/galera/t/MW-402.test +++ b/mysql-test/suite/galera/t/MW-402.test @@ -1,5 +1,7 @@ --source include/galera_cluster.inc --source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc --source include/galera_have_debug_sync.inc # From e4a3a11dcce7e800cb89ac681ef21e7ad6ba1d84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Tue, 5 Nov 2024 12:09:30 +0200 Subject: [PATCH 3/7] MDEV-35344 : Galera test failure on galera_sync_wait_upto Ignoring configured server_id should not be a warning because correct configuration is documented. Changed message to info level with more detailed message what was configured and what will be actually used. Signed-off-by: Julius Goryavsky --- mysql-test/suite/galera/t/galera_sync_wait_upto.test | 1 + .../suite/galera/t/galera_var_ignore_apply_errors.test | 1 + sql/wsrep_mysqld.cc | 5 ++--- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/mysql-test/suite/galera/t/galera_sync_wait_upto.test b/mysql-test/suite/galera/t/galera_sync_wait_upto.test index 8465ddebfeb..dce856c10f2 100644 --- a/mysql-test/suite/galera/t/galera_sync_wait_upto.test +++ b/mysql-test/suite/galera/t/galera_sync_wait_upto.test @@ -3,6 +3,7 @@ # --source include/galera_cluster.inc +--source include/have_debug.inc --source include/have_debug_sync.inc CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; 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 e5c13dddd29..02dd9fa8416 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 @@ -2,6 +2,7 @@ # Test option wsrep_ignore_apply_errors # +--source include/have_perfschema.inc --source include/galera_cluster.inc --source include/force_restart.inc diff --git a/sql/wsrep_mysqld.cc b/sql/wsrep_mysqld.cc index fac87cdfa1c..6fd6250ca24 100644 --- a/sql/wsrep_mysqld.cc +++ b/sql/wsrep_mysqld.cc @@ -827,9 +827,8 @@ void wsrep_init_globals() else { if (wsrep_gtid_mode && wsrep_gtid_server.server_id != global_system_variables.server_id) - { - WSREP_WARN("Ignoring server id for non bootstrap node."); - } + WSREP_INFO("Ignoring server id %ld for non bootstrap node, using %ld.", + global_system_variables.server_id, wsrep_gtid_server.server_id); } wsrep_init_schema(); if (WSREP_ON) From db68eb69f9e0e30dd1b2ce0cf875ea826419bab8 Mon Sep 17 00:00:00 2001 From: Julius Goryavsky Date: Wed, 6 Nov 2024 01:39:31 +0100 Subject: [PATCH 4/7] MDEV-35344: post-fix correction for other galera tests --- mysql-test/suite/galera/r/MDEV-10715.result | 2 +- mysql-test/suite/galera/r/MDEV-27806.result | 2 +- mysql-test/suite/galera/r/galera_gtid_server_id.result | 2 +- mysql-test/suite/galera/r/galera_gtid_slave.result | 2 +- .../suite/galera/r/galera_gtid_slave_sst_rsync.result | 2 +- mysql-test/suite/galera/r/galera_gtid_trx_conflict.result | 2 +- mysql-test/suite/galera/r/galera_last_committed_id.result | 2 +- .../suite/galera/r/galera_query_cache_invalidate.result | 4 ++-- mysql-test/suite/galera/r/galera_sync_wait_upto.result | 2 +- .../suite/galera/r/galera_var_gtid_domain_id.result | 2 +- mysql-test/suite/galera/r/mdev_10518.result | 2 +- mysql-test/suite/galera/t/MDEV-10715.test | 2 +- mysql-test/suite/galera/t/MDEV-27806.test | 2 +- mysql-test/suite/galera/t/galera_gtid_server_id.test | 2 +- mysql-test/suite/galera/t/galera_gtid_slave.test | 2 +- .../suite/galera/t/galera_gtid_slave_sst_rsync.test | 2 +- mysql-test/suite/galera/t/galera_gtid_trx_conflict.test | 2 +- mysql-test/suite/galera/t/galera_last_committed_id.test | 2 +- .../suite/galera/t/galera_query_cache_invalidate.test | 4 ++-- mysql-test/suite/galera/t/galera_sync_wait_upto.test | 2 +- mysql-test/suite/galera/t/galera_var_gtid_domain_id.test | 2 +- mysql-test/suite/galera/t/mdev_10518.test | 2 +- mysql-test/suite/galera_3nodes/r/MDEV-29171.result | 4 ++-- mysql-test/suite/galera_3nodes/r/galera_2_cluster.result | 8 ++++---- .../suite/galera_3nodes/r/galera_gtid_consistency.result | 4 ++-- mysql-test/suite/galera_3nodes/t/MDEV-29171.test | 4 ++-- mysql-test/suite/galera_3nodes/t/galera_2_cluster.test | 8 ++++---- .../suite/galera_3nodes/t/galera_gtid_consistency.test | 4 ++-- mysql-test/suite/galera_sr/r/mdev_18631.result | 2 +- mysql-test/suite/galera_sr/t/mdev_18631.test | 2 +- 30 files changed, 42 insertions(+), 42 deletions(-) diff --git a/mysql-test/suite/galera/r/MDEV-10715.result b/mysql-test/suite/galera/r/MDEV-10715.result index 12b9c2367c4..471c8b34c4d 100644 --- a/mysql-test/suite/galera/r/MDEV-10715.result +++ b/mysql-test/suite/galera/r/MDEV-10715.result @@ -27,4 +27,4 @@ wsrep_last_written_gtid() connection node_1; drop table t1; connection node_2; -CALL mtr.add_suppression("Ignoring server id for non bootstrap node"); +CALL mtr.add_suppression("Ignoring server id .* for non bootstrap node"); diff --git a/mysql-test/suite/galera/r/MDEV-27806.result b/mysql-test/suite/galera/r/MDEV-27806.result index 6fe288f4e8e..5b30d05fdf9 100644 --- a/mysql-test/suite/galera/r/MDEV-27806.result +++ b/mysql-test/suite/galera/r/MDEV-27806.result @@ -49,4 +49,4 @@ mysqld-bin.000003 # Query # # COMMIT BINLOG_POSITIONS_MATCH 1 DROP TABLE t1,ts1; -CALL mtr.add_suppression("Ignoring server id for non bootstrap node"); +CALL mtr.add_suppression("Ignoring server id .* for non bootstrap node"); diff --git a/mysql-test/suite/galera/r/galera_gtid_server_id.result b/mysql-test/suite/galera/r/galera_gtid_server_id.result index 5acf4519d0c..2b9eaffeded 100644 --- a/mysql-test/suite/galera/r/galera_gtid_server_id.result +++ b/mysql-test/suite/galera/r/galera_gtid_server_id.result @@ -5,7 +5,7 @@ select @@gtid_domain_id, @@server_id, @@wsrep_gtid_domain_id,@@wsrep_gtid_mode; @@gtid_domain_id @@server_id @@wsrep_gtid_domain_id @@wsrep_gtid_mode 0 11 1 1 connection node_2; -call mtr.add_suppression("WSREP: Ignoring server id for non bootstrap node\\."); +call mtr.add_suppression("WSREP: Ignoring server id .* for non bootstrap node"); select @@gtid_domain_id, @@server_id, @@wsrep_gtid_domain_id,@@wsrep_gtid_mode; @@gtid_domain_id @@server_id @@wsrep_gtid_domain_id @@wsrep_gtid_mode 0 12 1 1 diff --git a/mysql-test/suite/galera/r/galera_gtid_slave.result b/mysql-test/suite/galera/r/galera_gtid_slave.result index d460d169811..180be320102 100644 --- a/mysql-test/suite/galera/r/galera_gtid_slave.result +++ b/mysql-test/suite/galera/r/galera_gtid_slave.result @@ -42,4 +42,4 @@ SET GLOBAL wsrep_on=ON; connection node_3; reset master; connection node_2; -CALL mtr.add_suppression("Ignoring server id for non bootstrap node"); +CALL mtr.add_suppression("Ignoring server id .* for non bootstrap node"); diff --git a/mysql-test/suite/galera/r/galera_gtid_slave_sst_rsync.result b/mysql-test/suite/galera/r/galera_gtid_slave_sst_rsync.result index f41e3abc497..e9f11d6f44b 100644 --- a/mysql-test/suite/galera/r/galera_gtid_slave_sst_rsync.result +++ b/mysql-test/suite/galera/r/galera_gtid_slave_sst_rsync.result @@ -167,4 +167,4 @@ set global wsrep_on=ON; connection node_3; reset master; connection node_2; -CALL mtr.add_suppression("Ignoring server id for non bootstrap node"); +CALL mtr.add_suppression("Ignoring server id .* for non bootstrap node"); diff --git a/mysql-test/suite/galera/r/galera_gtid_trx_conflict.result b/mysql-test/suite/galera/r/galera_gtid_trx_conflict.result index 602816f18a9..a30351b2c39 100644 --- a/mysql-test/suite/galera/r/galera_gtid_trx_conflict.result +++ b/mysql-test/suite/galera/r/galera_gtid_trx_conflict.result @@ -42,4 +42,4 @@ SELECT @@gtid_binlog_state; @@gtid_binlog_state 1-1-101 DROP TABLE t1; -CALL mtr.add_suppression("Ignoring server id for non bootstrap node"); +CALL mtr.add_suppression("Ignoring server id .* for non bootstrap node"); diff --git a/mysql-test/suite/galera/r/galera_last_committed_id.result b/mysql-test/suite/galera/r/galera_last_committed_id.result index 1a1339ede32..58206baf7fe 100644 --- a/mysql-test/suite/galera/r/galera_last_committed_id.result +++ b/mysql-test/suite/galera/r/galera_last_committed_id.result @@ -34,4 +34,4 @@ wsrep_last_written_id_advanced SET AUTOCOMMIT=ON; DROP TABLE t1; connection node_2; -CALL mtr.add_suppression("Ignoring server id for non bootstrap node"); +CALL mtr.add_suppression("Ignoring server id .* for non bootstrap node"); diff --git a/mysql-test/suite/galera/r/galera_query_cache_invalidate.result b/mysql-test/suite/galera/r/galera_query_cache_invalidate.result index 425b512bc03..078920da3f2 100644 --- a/mysql-test/suite/galera/r/galera_query_cache_invalidate.result +++ b/mysql-test/suite/galera/r/galera_query_cache_invalidate.result @@ -3,9 +3,9 @@ connection node_1; connect node_3, 127.0.0.1, root, , test, $NODE_MYPORT_3; connect node_4, 127.0.0.1, root, , test, $NODE_MYPORT_4; connection node_2; -call mtr.add_suppression("WSREP: Ignoring server id for non bootstrap node\\."); +call mtr.add_suppression("WSREP: Ignoring server id .* for non bootstrap node"); connection node_4; -call mtr.add_suppression("WSREP: Ignoring server id for non bootstrap node\\."); +call mtr.add_suppression("WSREP: Ignoring server id .* for non bootstrap node"); connection node_3; CHANGE MASTER TO master_host='127.0.0.1', master_user='root', master_port=NODE_MYPORT_1, master_use_gtid=current_pos;; START SLAVE; diff --git a/mysql-test/suite/galera/r/galera_sync_wait_upto.result b/mysql-test/suite/galera/r/galera_sync_wait_upto.result index c9f468774fb..c6e5be5c232 100644 --- a/mysql-test/suite/galera/r/galera_sync_wait_upto.result +++ b/mysql-test/suite/galera/r/galera_sync_wait_upto.result @@ -24,4 +24,4 @@ WSREP_SYNC_WAIT_UPTO connection node_1; DROP TABLE t1; connection node_2; -CALL mtr.add_suppression("Ignoring server id for non bootstrap node"); +CALL mtr.add_suppression("Ignoring server id .* for non bootstrap node"); diff --git a/mysql-test/suite/galera/r/galera_var_gtid_domain_id.result b/mysql-test/suite/galera/r/galera_var_gtid_domain_id.result index 0edfdf47d34..7de74462ebc 100644 --- a/mysql-test/suite/galera/r/galera_var_gtid_domain_id.result +++ b/mysql-test/suite/galera/r/galera_var_gtid_domain_id.result @@ -90,7 +90,7 @@ set global wsrep_on=OFF; reset master; set global wsrep_on=ON; connection node_2; -CALL mtr.add_suppression("Ignoring server id for non bootstrap node"); +CALL mtr.add_suppression("Ignoring server id .* for non bootstrap node"); disconnect node_2; disconnect node_1; # End of test diff --git a/mysql-test/suite/galera/r/mdev_10518.result b/mysql-test/suite/galera/r/mdev_10518.result index 8426cd31349..09d4a6cb729 100644 --- a/mysql-test/suite/galera/r/mdev_10518.result +++ b/mysql-test/suite/galera/r/mdev_10518.result @@ -90,7 +90,7 @@ set global wsrep_on=OFF; reset master; set global wsrep_on=ON; connection node_2; -CALL mtr.add_suppression("Ignoring server id for non bootstrap node"); +CALL mtr.add_suppression("Ignoring server id .* for non bootstrap node"); disconnect node_2; disconnect node_1; # End of test diff --git a/mysql-test/suite/galera/t/MDEV-10715.test b/mysql-test/suite/galera/t/MDEV-10715.test index 20c5293f01b..29831994fdd 100644 --- a/mysql-test/suite/galera/t/MDEV-10715.test +++ b/mysql-test/suite/galera/t/MDEV-10715.test @@ -19,4 +19,4 @@ select wsrep_last_written_gtid(); drop table t1; --connection node_2 -CALL mtr.add_suppression("Ignoring server id for non bootstrap node"); \ No newline at end of file +CALL mtr.add_suppression("Ignoring server id .* for non bootstrap node"); diff --git a/mysql-test/suite/galera/t/MDEV-27806.test b/mysql-test/suite/galera/t/MDEV-27806.test index 62a0ca483e0..f8d896adb2d 100644 --- a/mysql-test/suite/galera/t/MDEV-27806.test +++ b/mysql-test/suite/galera/t/MDEV-27806.test @@ -48,4 +48,4 @@ CREATE TABLE ts1 AS SELECT * FROM t1; DROP TABLE t1,ts1; -CALL mtr.add_suppression("Ignoring server id for non bootstrap node"); +CALL mtr.add_suppression("Ignoring server id .* for non bootstrap node"); diff --git a/mysql-test/suite/galera/t/galera_gtid_server_id.test b/mysql-test/suite/galera/t/galera_gtid_server_id.test index f61bef4909b..df72e9a0c6e 100644 --- a/mysql-test/suite/galera/t/galera_gtid_server_id.test +++ b/mysql-test/suite/galera/t/galera_gtid_server_id.test @@ -3,7 +3,7 @@ --connection node_1 select @@gtid_domain_id, @@server_id, @@wsrep_gtid_domain_id,@@wsrep_gtid_mode; --connection node_2 -call mtr.add_suppression("WSREP: Ignoring server id for non bootstrap node\\."); +call mtr.add_suppression("WSREP: Ignoring server id .* for non bootstrap node"); select @@gtid_domain_id, @@server_id, @@wsrep_gtid_domain_id,@@wsrep_gtid_mode; --connection node_1 diff --git a/mysql-test/suite/galera/t/galera_gtid_slave.test b/mysql-test/suite/galera/t/galera_gtid_slave.test index b3fbbb02d5f..e798cc7fdb5 100644 --- a/mysql-test/suite/galera/t/galera_gtid_slave.test +++ b/mysql-test/suite/galera/t/galera_gtid_slave.test @@ -92,4 +92,4 @@ SET GLOBAL wsrep_on=ON; reset master; --connection node_2 -CALL mtr.add_suppression("Ignoring server id for non bootstrap node"); +CALL mtr.add_suppression("Ignoring server id .* for non bootstrap node"); diff --git a/mysql-test/suite/galera/t/galera_gtid_slave_sst_rsync.test b/mysql-test/suite/galera/t/galera_gtid_slave_sst_rsync.test index b2ddc7e153d..148bbc2b460 100644 --- a/mysql-test/suite/galera/t/galera_gtid_slave_sst_rsync.test +++ b/mysql-test/suite/galera/t/galera_gtid_slave_sst_rsync.test @@ -199,4 +199,4 @@ set global wsrep_on=ON; reset master; --connection node_2 -CALL mtr.add_suppression("Ignoring server id for non bootstrap node"); +CALL mtr.add_suppression("Ignoring server id .* for non bootstrap node"); diff --git a/mysql-test/suite/galera/t/galera_gtid_trx_conflict.test b/mysql-test/suite/galera/t/galera_gtid_trx_conflict.test index 6f05196b8da..940b66e54ab 100644 --- a/mysql-test/suite/galera/t/galera_gtid_trx_conflict.test +++ b/mysql-test/suite/galera/t/galera_gtid_trx_conflict.test @@ -53,4 +53,4 @@ SELECT @@gtid_binlog_state; SELECT @@gtid_binlog_state; DROP TABLE t1; -CALL mtr.add_suppression("Ignoring server id for non bootstrap node"); +CALL mtr.add_suppression("Ignoring server id .* for non bootstrap node"); diff --git a/mysql-test/suite/galera/t/galera_last_committed_id.test b/mysql-test/suite/galera/t/galera_last_committed_id.test index 6e1f0de7d0b..e3746b5a96d 100644 --- a/mysql-test/suite/galera/t/galera_last_committed_id.test +++ b/mysql-test/suite/galera/t/galera_last_committed_id.test @@ -66,4 +66,4 @@ SET AUTOCOMMIT=ON; DROP TABLE t1; --connection node_2 -CALL mtr.add_suppression("Ignoring server id for non bootstrap node"); +CALL mtr.add_suppression("Ignoring server id .* for non bootstrap node"); diff --git a/mysql-test/suite/galera/t/galera_query_cache_invalidate.test b/mysql-test/suite/galera/t/galera_query_cache_invalidate.test index fde02d6b9a8..c5c5f69dc27 100644 --- a/mysql-test/suite/galera/t/galera_query_cache_invalidate.test +++ b/mysql-test/suite/galera/t/galera_query_cache_invalidate.test @@ -22,9 +22,9 @@ --connect node_4, 127.0.0.1, root, , test, $NODE_MYPORT_4 --connection node_2 -call mtr.add_suppression("WSREP: Ignoring server id for non bootstrap node\\."); +call mtr.add_suppression("WSREP: Ignoring server id .* for non bootstrap node"); --connection node_4 -call mtr.add_suppression("WSREP: Ignoring server id for non bootstrap node\\."); +call mtr.add_suppression("WSREP: Ignoring server id .* for non bootstrap node"); --connection node_3 diff --git a/mysql-test/suite/galera/t/galera_sync_wait_upto.test b/mysql-test/suite/galera/t/galera_sync_wait_upto.test index dce856c10f2..aaecd8760f5 100644 --- a/mysql-test/suite/galera/t/galera_sync_wait_upto.test +++ b/mysql-test/suite/galera/t/galera_sync_wait_upto.test @@ -73,4 +73,4 @@ INSERT INTO t1 VALUES (2); DROP TABLE t1; --connection node_2 -CALL mtr.add_suppression("Ignoring server id for non bootstrap node"); +CALL mtr.add_suppression("Ignoring server id .* for non bootstrap node"); diff --git a/mysql-test/suite/galera/t/galera_var_gtid_domain_id.test b/mysql-test/suite/galera/t/galera_var_gtid_domain_id.test index 4de1121ae77..c9b8a890209 100644 --- a/mysql-test/suite/galera/t/galera_var_gtid_domain_id.test +++ b/mysql-test/suite/galera/t/galera_var_gtid_domain_id.test @@ -60,7 +60,7 @@ reset master; set global wsrep_on=ON; --connection node_2 -CALL mtr.add_suppression("Ignoring server id for non bootstrap node"); +CALL mtr.add_suppression("Ignoring server id .* for non bootstrap node"); --source include/galera_end.inc --echo # End of test diff --git a/mysql-test/suite/galera/t/mdev_10518.test b/mysql-test/suite/galera/t/mdev_10518.test index 4de1121ae77..c9b8a890209 100644 --- a/mysql-test/suite/galera/t/mdev_10518.test +++ b/mysql-test/suite/galera/t/mdev_10518.test @@ -60,7 +60,7 @@ reset master; set global wsrep_on=ON; --connection node_2 -CALL mtr.add_suppression("Ignoring server id for non bootstrap node"); +CALL mtr.add_suppression("Ignoring server id .* for non bootstrap node"); --source include/galera_end.inc --echo # End of test diff --git a/mysql-test/suite/galera_3nodes/r/MDEV-29171.result b/mysql-test/suite/galera_3nodes/r/MDEV-29171.result index 3a91bfea211..88883eb17a0 100644 --- a/mysql-test/suite/galera_3nodes/r/MDEV-29171.result +++ b/mysql-test/suite/galera_3nodes/r/MDEV-29171.result @@ -56,7 +56,7 @@ connection node_1; set global wsrep_gtid_domain_id=100; connection node_2; set global wsrep_gtid_domain_id=100; -CALL mtr.add_suppression("WSREP: Ignoring server id for non bootstrap node\\."); +CALL mtr.add_suppression("WSREP: Ignoring server id .* for non bootstrap node"); connection node_3; set global wsrep_gtid_domain_id=100; -CALL mtr.add_suppression("WSREP: Ignoring server id for non bootstrap node\\."); +CALL mtr.add_suppression("WSREP: Ignoring server id .* for non bootstrap node"); diff --git a/mysql-test/suite/galera_3nodes/r/galera_2_cluster.result b/mysql-test/suite/galera_3nodes/r/galera_2_cluster.result index 5214eafa1c8..bdd18ee2534 100644 --- a/mysql-test/suite/galera_3nodes/r/galera_2_cluster.result +++ b/mysql-test/suite/galera_3nodes/r/galera_2_cluster.result @@ -75,19 +75,19 @@ connection node_2; SET GLOBAL wsrep_on = OFF; RESET MASTER; SET GLOBAL wsrep_on = ON; -CALL mtr.add_suppression("Ignoring server id for non bootstrap node"); +CALL mtr.add_suppression("Ignoring server id .* for non bootstrap node"); connection node_3; SET GLOBAL wsrep_on = OFF; RESET MASTER; SET GLOBAL wsrep_on = ON; -CALL mtr.add_suppression("Ignoring server id for non bootstrap node"); +CALL mtr.add_suppression("Ignoring server id .* for non bootstrap node"); connection node_5; SET GLOBAL wsrep_on = OFF; RESET MASTER; SET GLOBAL wsrep_on = ON; -CALL mtr.add_suppression("Ignoring server id for non bootstrap node"); +CALL mtr.add_suppression("Ignoring server id .* for non bootstrap node"); connection node_6; SET GLOBAL wsrep_on = OFF; RESET MASTER; SET GLOBAL wsrep_on = ON; -CALL mtr.add_suppression("Ignoring server id for non bootstrap node"); +CALL mtr.add_suppression("Ignoring server id .* for non bootstrap node"); diff --git a/mysql-test/suite/galera_3nodes/r/galera_gtid_consistency.result b/mysql-test/suite/galera_3nodes/r/galera_gtid_consistency.result index 91ff0342b8d..22eef0eec80 100644 --- a/mysql-test/suite/galera_3nodes/r/galera_gtid_consistency.result +++ b/mysql-test/suite/galera_3nodes/r/galera_gtid_consistency.result @@ -199,12 +199,12 @@ SELECT COUNT(*) FROM t1; COUNT(*) 1950 connection node_2; -call mtr.add_suppression("WSREP: Ignoring server id for non bootstrap node"); +call mtr.add_suppression("WSREP: Ignoring server id .* for non bootstrap node"); call mtr.add_suppression("Sending JOIN failed: "); call mtr.add_suppression("WSREP: Failed to JOIN the cluster after SST"); call mtr.add_suppression("WSREP: FLOW message from member .* in non-primary configuration"); connection node_3; -call mtr.add_suppression("WSREP: Ignoring server id for non bootstrap node"); +call mtr.add_suppression("WSREP: Ignoring server id .* for non bootstrap node"); call mtr.add_suppression("Sending JOIN failed: "); call mtr.add_suppression("WSREP: Failed to JOIN the cluster after SST"); call mtr.add_suppression("WSREP: FLOW message from member .* in non-primary configuration"); diff --git a/mysql-test/suite/galera_3nodes/t/MDEV-29171.test b/mysql-test/suite/galera_3nodes/t/MDEV-29171.test index df1282609f0..4d67bf6ad0b 100644 --- a/mysql-test/suite/galera_3nodes/t/MDEV-29171.test +++ b/mysql-test/suite/galera_3nodes/t/MDEV-29171.test @@ -119,8 +119,8 @@ set global wsrep_gtid_domain_id=100; --connection node_2 set global wsrep_gtid_domain_id=100; -CALL mtr.add_suppression("WSREP: Ignoring server id for non bootstrap node\\."); +CALL mtr.add_suppression("WSREP: Ignoring server id .* for non bootstrap node"); --connection node_3 set global wsrep_gtid_domain_id=100; -CALL mtr.add_suppression("WSREP: Ignoring server id for non bootstrap node\\."); +CALL mtr.add_suppression("WSREP: Ignoring server id .* for non bootstrap node"); diff --git a/mysql-test/suite/galera_3nodes/t/galera_2_cluster.test b/mysql-test/suite/galera_3nodes/t/galera_2_cluster.test index d7b0f36551f..8fc9e492342 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_2_cluster.test +++ b/mysql-test/suite/galera_3nodes/t/galera_2_cluster.test @@ -129,7 +129,7 @@ SET GLOBAL wsrep_on = OFF; RESET MASTER; SET GLOBAL wsrep_on = ON; -CALL mtr.add_suppression("Ignoring server id for non bootstrap node"); +CALL mtr.add_suppression("Ignoring server id .* for non bootstrap node"); --connection node_3 @@ -137,7 +137,7 @@ SET GLOBAL wsrep_on = OFF; RESET MASTER; SET GLOBAL wsrep_on = ON; -CALL mtr.add_suppression("Ignoring server id for non bootstrap node"); +CALL mtr.add_suppression("Ignoring server id .* for non bootstrap node"); --connection node_5 @@ -145,7 +145,7 @@ SET GLOBAL wsrep_on = OFF; RESET MASTER; SET GLOBAL wsrep_on = ON; -CALL mtr.add_suppression("Ignoring server id for non bootstrap node"); +CALL mtr.add_suppression("Ignoring server id .* for non bootstrap node"); --connection node_6 @@ -153,4 +153,4 @@ SET GLOBAL wsrep_on = OFF; RESET MASTER; SET GLOBAL wsrep_on = ON; -CALL mtr.add_suppression("Ignoring server id for non bootstrap node"); +CALL mtr.add_suppression("Ignoring server id .* for non bootstrap node"); diff --git a/mysql-test/suite/galera_3nodes/t/galera_gtid_consistency.test b/mysql-test/suite/galera_3nodes/t/galera_gtid_consistency.test index 871014b39d0..4d99f865cb2 100644 --- a/mysql-test/suite/galera_3nodes/t/galera_gtid_consistency.test +++ b/mysql-test/suite/galera_3nodes/t/galera_gtid_consistency.test @@ -343,12 +343,12 @@ SELECT COUNT(*) FROM t1; # cleanups # --connection node_2 -call mtr.add_suppression("WSREP: Ignoring server id for non bootstrap node"); +call mtr.add_suppression("WSREP: Ignoring server id .* for non bootstrap node"); call mtr.add_suppression("Sending JOIN failed: "); call mtr.add_suppression("WSREP: Failed to JOIN the cluster after SST"); call mtr.add_suppression("WSREP: FLOW message from member .* in non-primary configuration"); --connection node_3 -call mtr.add_suppression("WSREP: Ignoring server id for non bootstrap node"); +call mtr.add_suppression("WSREP: Ignoring server id .* for non bootstrap node"); call mtr.add_suppression("Sending JOIN failed: "); call mtr.add_suppression("WSREP: Failed to JOIN the cluster after SST"); call mtr.add_suppression("WSREP: FLOW message from member .* in non-primary configuration"); diff --git a/mysql-test/suite/galera_sr/r/mdev_18631.result b/mysql-test/suite/galera_sr/r/mdev_18631.result index aa3b2c252e8..8e02d09ffd8 100644 --- a/mysql-test/suite/galera_sr/r/mdev_18631.result +++ b/mysql-test/suite/galera_sr/r/mdev_18631.result @@ -5,7 +5,7 @@ connection node_1; CREATE TABLE t1(f1 INT PRIMARY KEY) ENGINE=INNODB; INSERT INTO t1 VALUES (1), (2), (3); connection node_2; -call mtr.add_suppression("WSREP: Ignoring server id for non bootstrap node\\."); +call mtr.add_suppression("WSREP: Ignoring server id .* for non bootstrap node"); SELECT * FROM t1; f1 1 diff --git a/mysql-test/suite/galera_sr/t/mdev_18631.test b/mysql-test/suite/galera_sr/t/mdev_18631.test index 3e99e9fa9dc..2721e5028eb 100644 --- a/mysql-test/suite/galera_sr/t/mdev_18631.test +++ b/mysql-test/suite/galera_sr/t/mdev_18631.test @@ -13,7 +13,7 @@ CREATE TABLE t1(f1 INT PRIMARY KEY) ENGINE=INNODB; INSERT INTO t1 VALUES (1), (2), (3); --connection node_2 -call mtr.add_suppression("WSREP: Ignoring server id for non bootstrap node\\."); +call mtr.add_suppression("WSREP: Ignoring server id .* for non bootstrap node"); SELECT * FROM t1; --connection node_1 From 4b38af06a4b762f7cd55fa0292fb5e1e9a4f6b98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Wed, 30 Oct 2024 09:37:10 +0200 Subject: [PATCH 5/7] MDEV-35157 : wrong binlog timestamps on secondary nodes of a galera cluster Problem was missing thd->set_time() before binlog event execution in wsrep_apply_events. Removed part of earlier commit 1363580 because it had nothing to do with VERSIONED tables. Note that this commit does not contain mtr-testcase because actual timestamps on binlog file depends the actual time when events are executed and how long their execution takes. Signed-off-by: Julius Goryavsky --- sql/log_event_server.cc | 15 +++------------ sql/wsrep_applier.cc | 12 +++++++++++- sql/wsrep_high_priority_service.cc | 1 - 3 files changed, 14 insertions(+), 14 deletions(-) diff --git a/sql/log_event_server.cc b/sql/log_event_server.cc index 69a27ed6350..2a5019281ef 100644 --- a/sql/log_event_server.cc +++ b/sql/log_event_server.cc @@ -1721,10 +1721,7 @@ int Query_log_event::do_apply_event(rpl_group_info *rgi, Gtid_log_event::FL_COMPLETED_XA))) || rpl_filter->db_ok(thd->db.str)) { -#ifdef WITH_WSREP - if (!wsrep_thd_is_applying(thd)) -#endif - thd->set_time(when, when_sec_part); + thd->set_time(when, when_sec_part); thd->set_query_and_id((char*)query_arg, q_len_arg, thd->charset(), next_query_id()); thd->variables.pseudo_thread_id= thread_id; // for temp tables @@ -2863,10 +2860,7 @@ int Load_log_event::do_apply_event(NET* net, rpl_group_info *rgi, */ if (rpl_filter->db_ok(thd->db.str)) { -#ifdef WITH_WSREP - if (!wsrep_thd_is_applying(thd)) -#endif - thd->set_time(when, when_sec_part); + thd->set_time(when, when_sec_part); thd->set_query_id(next_query_id()); thd->get_stmt_da()->opt_clear_warning_info(thd->query_id); @@ -5701,10 +5695,7 @@ int Rows_log_event::do_apply_event(rpl_group_info *rgi) TIMESTAMP column to a table with one. So we call set_time(), like in SBR. Presently it changes nothing. */ -#ifdef WITH_WSREP - if (!wsrep_thd_is_applying(thd)) -#endif - thd->set_time(when, when_sec_part); + thd->set_time(when, when_sec_part); if (m_width == table->s->fields && bitmap_is_set_all(&m_cols)) set_flags(COMPLETE_ROWS_F); diff --git a/sql/wsrep_applier.cc b/sql/wsrep_applier.cc index 0ec8e6e7f47..feb78507bf9 100644 --- a/sql/wsrep_applier.cc +++ b/sql/wsrep_applier.cc @@ -1,4 +1,4 @@ -/* Copyright (C) 2013-2019 Codership Oy +/* Copyright (C) 2013-2024 Codership Oy This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -211,7 +211,17 @@ int wsrep_apply_events(THD* thd, } ev->thd= thd; + thd->set_time(); + + if (!ev->when) + { + my_hrtime_t hrtime= my_hrtime(); + ev->when= hrtime_to_my_time(hrtime); + ev->when_sec_part= hrtime_sec_part(hrtime); + } + exec_res= ev->apply_event(thd->wsrep_rgi); + DBUG_PRINT("info", ("exec_event result: %d", exec_res)); if (exec_res) diff --git a/sql/wsrep_high_priority_service.cc b/sql/wsrep_high_priority_service.cc index 1838095687f..798398b1bd9 100644 --- a/sql/wsrep_high_priority_service.cc +++ b/sql/wsrep_high_priority_service.cc @@ -215,7 +215,6 @@ int Wsrep_high_priority_service::start_transaction( const wsrep::ws_handle& ws_handle, const wsrep::ws_meta& ws_meta) { DBUG_ENTER(" Wsrep_high_priority_service::start_transaction"); - m_thd->set_time(); DBUG_RETURN(m_thd->wsrep_cs().start_transaction(ws_handle, ws_meta) || trans_begin(m_thd)); } From 98d57719e2836af289279528094d9577b7e22d8e Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Fri, 8 Nov 2024 11:35:19 +0530 Subject: [PATCH 6/7] MDEV-32667 dict_stats_save_index_stat() reads uninitialized index->stats_error_printed Problem: ======== - dict_stats_table_clone_create() does not initialize the flag stats_error_printed in either dict_table_t or dict_index_t. Because dict_stats_save_index_stat() is operating on a copy of a dict_index_t object, it appears that dict_index_t::stats_error_printed will always be false for actual metadata objects, and uninitialized in dict_stats_save_index_stat(). Solution: ========= dict_stats_table_clone_create(): Assign stats_error_printed for table and index while copying the statistics --- mysql-test/suite/innodb/r/stat_tables.result | 16 ++++++++++++++++ mysql-test/suite/innodb/t/stat_tables.test | 13 +++++++++++++ storage/innobase/dict/dict0stats.cc | 3 +++ 3 files changed, 32 insertions(+) diff --git a/mysql-test/suite/innodb/r/stat_tables.result b/mysql-test/suite/innodb/r/stat_tables.result index bb449570479..fe539b4d142 100644 --- a/mysql-test/suite/innodb/r/stat_tables.result +++ b/mysql-test/suite/innodb/r/stat_tables.result @@ -13,3 +13,19 @@ a drop table t1; rename table mysql.table_stats_save to mysql.table_stats; flush tables; +# +# MDEV-32667 dict_stats_save_index_stat() reads uninitialized +# index->stats_error_printed +# +call mtr.add_suppression("InnoDB: Cannot save index statistics for table"); +CREATE TABLE t1(a INT) ENGINE=InnoDB STATS_PERSISTENT=1 STATS_AUTO_RECALC=1; +BEGIN; +SELECT COUNT(*)>=0 FROM mysql.innodb_index_stats LOCK IN SHARE MODE; +COUNT(*)>=0 +1 +INSERT INTO t1 VALUES(0),(0); +SELECT sleep(1); +sleep(1) +0 +COMMIT; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/stat_tables.test b/mysql-test/suite/innodb/t/stat_tables.test index 68344b3f425..932e0e762d7 100644 --- a/mysql-test/suite/innodb/t/stat_tables.test +++ b/mysql-test/suite/innodb/t/stat_tables.test @@ -15,3 +15,16 @@ select * from t1; drop table t1; rename table mysql.table_stats_save to mysql.table_stats; flush tables; + +--echo # +--echo # MDEV-32667 dict_stats_save_index_stat() reads uninitialized +--echo # index->stats_error_printed +--echo # +call mtr.add_suppression("InnoDB: Cannot save index statistics for table"); +CREATE TABLE t1(a INT) ENGINE=InnoDB STATS_PERSISTENT=1 STATS_AUTO_RECALC=1; +BEGIN; +SELECT COUNT(*)>=0 FROM mysql.innodb_index_stats LOCK IN SHARE MODE; +INSERT INTO t1 VALUES(0),(0); +SELECT sleep(1); +COMMIT; +DROP TABLE t1; diff --git a/storage/innobase/dict/dict0stats.cc b/storage/innobase/dict/dict0stats.cc index 496a1a5e6f0..485b1916a66 100644 --- a/storage/innobase/dict/dict0stats.cc +++ b/storage/innobase/dict/dict0stats.cc @@ -423,6 +423,8 @@ dict_stats_table_clone_create( UT_LIST_INIT(t->freed_indexes, &dict_index_t::indexes); #endif /* BTR_CUR_HASH_ADAPT */ + t->stats_error_printed = table->stats_error_printed; + for (index = dict_table_get_first_index(table); index != NULL; index = dict_table_get_next_index(index)) { @@ -479,6 +481,7 @@ dict_stats_table_clone_create( idx->stat_defrag_n_page_split = 0; idx->stat_defrag_n_pages_freed = 0; + idx->stats_error_printed = index->stats_error_printed; } ut_d(t->magic_n = DICT_TABLE_MAGIC_N); From 7afee25b08bf801a97ce3246bb604d388572eace Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Fri, 8 Nov 2024 12:15:55 +0530 Subject: [PATCH 7/7] MDEV-35115 Inconsistent Replace behaviour when multiple unique index exist - Replace statement fails with duplicate key error when multiple unique key conflict happens. Reason is that Server expects the InnoDB engine to store the confliciting keys in ascending order. But the InnoDB doesn't store the conflicting keys in ascending order. Fix: === - Enable HA_DUPLICATE_KEY_NOT_IN_ORDER for InnoDB storage engine only when unique index order is different in .frm and innodb dictionary. --- .../innodb/r/innodb-replace,INPLACE.rdiff | 16 +++++ .../suite/innodb/r/innodb-replace.result | 50 +++++++++++++++ .../innodb/t/innodb-replace.combinations | 2 + mysql-test/suite/innodb/t/innodb-replace.test | 64 +++++++++++++++++++ storage/innobase/handler/ha_innodb.cc | 23 +++++-- storage/innobase/handler/ha_innodb.h | 6 ++ 6 files changed, 156 insertions(+), 5 deletions(-) create mode 100644 mysql-test/suite/innodb/r/innodb-replace,INPLACE.rdiff create mode 100644 mysql-test/suite/innodb/t/innodb-replace.combinations diff --git a/mysql-test/suite/innodb/r/innodb-replace,INPLACE.rdiff b/mysql-test/suite/innodb/r/innodb-replace,INPLACE.rdiff new file mode 100644 index 00000000000..a05e4bec7e9 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb-replace,INPLACE.rdiff @@ -0,0 +1,16 @@ +--- innodb-replace.result ++++ innodb-replace,INPLACE.result +@@ -31,10 +31,10 @@ + REPLACE INTO t1 (c1,c2,c3) VALUES (0,1,b'11'); + SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME IN ('HANDLER_DELETE','HANDLER_WRITE','HANDLER_READ_KEY','HANDLER_UPDATE'); + VARIABLE_NAME VARIABLE_VALUE +-HANDLER_DELETE 1 ++HANDLER_DELETE 2 + HANDLER_READ_KEY 2 +-HANDLER_UPDATE 1 +-HANDLER_WRITE 2 ++HANDLER_UPDATE 0 ++HANDLER_WRITE 3 + SELECT * FROM t1; + c1 c2 c3 + 0 1  diff --git a/mysql-test/suite/innodb/r/innodb-replace.result b/mysql-test/suite/innodb/r/innodb-replace.result index c926bb89a2e..16b1df73a85 100644 --- a/mysql-test/suite/innodb/r/innodb-replace.result +++ b/mysql-test/suite/innodb/r/innodb-replace.result @@ -11,3 +11,53 @@ ERROR HY000: DELAYED option not supported for table 't1' select * from t1; c1 c2 stamp drop table t1; +# +# MDEV-35115 Inconsistent Replace behaviour when multiple +# unique index exist +# +CREATE TABLE t1 (c1 NUMERIC UNSIGNED NOT NULL, +c2 INT3 UNIQUE, +c3 BIT(2) PRIMARY KEY)ENGINE=InnoDB; +ALTER TABLE t1 ADD UNIQUE INDEX(c1); +INSERT INTO t1 (c1,c2,c3) VALUES (0,0,b'01'); +INSERT INTO t1 (c1,c2,c3) VALUES (1,1,b'10'); +FLUSH STATUS; +SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME IN ('HANDLER_DELETE','HANDLER_WRITE','HANDLER_READ_KEY','HANDLER_UPDATE'); +VARIABLE_NAME VARIABLE_VALUE +HANDLER_DELETE 0 +HANDLER_READ_KEY 0 +HANDLER_UPDATE 0 +HANDLER_WRITE 0 +REPLACE INTO t1 (c1,c2,c3) VALUES (0,1,b'11'); +SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME IN ('HANDLER_DELETE','HANDLER_WRITE','HANDLER_READ_KEY','HANDLER_UPDATE'); +VARIABLE_NAME VARIABLE_VALUE +HANDLER_DELETE 1 +HANDLER_READ_KEY 2 +HANDLER_UPDATE 1 +HANDLER_WRITE 2 +SELECT * FROM t1; +c1 c2 c3 +0 1  +DROP TABLE t1; +CREATE TABLE t1 (f1 INT NOT NULL PRIMARY KEY, +f2 INT, f3 INT, f4 INT, +UNIQUE INDEX i1(f2))ENGINE=InnoDB; +ALTER TABLE t1 ADD INDEX i3(f4); +ALTER TABLE t1 ADD UNIQUE INDEX i2(f3); +INSERT INTO t1 VALUES (0,0,0,0); +INSERT INTO t1 VALUES (1,1,1,1); +FLUSH STATUS; +SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME IN ('HANDLER_DELETE','HANDLER_WRITE','HANDLER_READ_KEY','HANDLER_UPDATE'); +VARIABLE_NAME VARIABLE_VALUE +HANDLER_DELETE 0 +HANDLER_READ_KEY 0 +HANDLER_UPDATE 0 +HANDLER_WRITE 0 +REPLACE INTO t1 VALUES (0,0,1,1); +SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME IN ('HANDLER_DELETE','HANDLER_WRITE','HANDLER_READ_KEY','HANDLER_UPDATE'); +VARIABLE_NAME VARIABLE_VALUE +HANDLER_DELETE 1 +HANDLER_READ_KEY 2 +HANDLER_UPDATE 1 +HANDLER_WRITE 2 +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/innodb-replace.combinations b/mysql-test/suite/innodb/t/innodb-replace.combinations new file mode 100644 index 00000000000..e84e17b06ac --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-replace.combinations @@ -0,0 +1,2 @@ +[COPY] +[INPLACE] diff --git a/mysql-test/suite/innodb/t/innodb-replace.test b/mysql-test/suite/innodb/t/innodb-replace.test index 8c3aacde5e8..ee3a508786d 100644 --- a/mysql-test/suite/innodb/t/innodb-replace.test +++ b/mysql-test/suite/innodb/t/innodb-replace.test @@ -20,3 +20,67 @@ select * from t1; drop table t1; # End of 4.1 tests + +--echo # +--echo # MDEV-35115 Inconsistent Replace behaviour when multiple +--echo # unique index exist +--echo # +let $get_handler_status_counts= SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS WHERE VARIABLE_NAME IN ('HANDLER_DELETE','HANDLER_WRITE','HANDLER_READ_KEY','HANDLER_UPDATE'); + +let $MYSQLD_DATADIR= `select @@datadir`; +let $algorithm=`select regexp_replace('$MTR_COMBINATIONS', 'innodb,\|,innodb', '')`; + +CREATE TABLE t1 (c1 NUMERIC UNSIGNED NOT NULL, + c2 INT3 UNIQUE, + c3 BIT(2) PRIMARY KEY)ENGINE=InnoDB; + +replace_result ,ALGORITHM=COPY '' ,ALGORITHM=INPLACE ''; +eval ALTER TABLE t1 ADD UNIQUE INDEX(c1),ALGORITHM=$algorithm; +INSERT INTO t1 (c1,c2,c3) VALUES (0,0,b'01'); +INSERT INTO t1 (c1,c2,c3) VALUES (1,1,b'10'); + +FLUSH STATUS; + +--disable_ps2_protocol +eval $get_handler_status_counts; +--enable_ps2_protocol + +# INPLACE algorithm appends the index, so unique index +# reordering happened between innodb and .frm file. This +# lead to deletion of 2 existing rows for the replace statement + +# COPY algorithm does table rebuild everytime. No reordering +# happened in this case. This lead to 1 deletion of record +# and 1 update on the existing record +REPLACE INTO t1 (c1,c2,c3) VALUES (0,1,b'11'); + +--disable_ps2_protocol +eval $get_handler_status_counts; +--enable_ps2_protocol +SELECT * FROM t1; +DROP TABLE t1; + +CREATE TABLE t1 (f1 INT NOT NULL PRIMARY KEY, + f2 INT, f3 INT, f4 INT, + UNIQUE INDEX i1(f2))ENGINE=InnoDB; +replace_result ,ALGORITHM=COPY '' ,ALGORITHM=INPLACE ''; +eval ALTER TABLE t1 ADD INDEX i3(f4),ALGORITHM=$algorithm; + +replace_result ,ALGORITHM=COPY '' ,ALGORITHM=INPLACE ''; +eval ALTER TABLE t1 ADD UNIQUE INDEX i2(f3),ALGORITHM=$algorithm; + +INSERT INTO t1 VALUES (0,0,0,0); +INSERT INTO t1 VALUES (1,1,1,1); + +FLUSH STATUS; +--disable_ps2_protocol +eval $get_handler_status_counts; +--enable_ps2_protocol + +REPLACE INTO t1 VALUES (0,0,1,1); + +--disable_ps2_protocol +eval $get_handler_status_counts; +--enable_ps2_protocol + +DROP TABLE t1; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index f12212c1aeb..6fd3d6d8cdf 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -5590,15 +5590,15 @@ innobase_build_v_templ( } /** Check consistency between .frm indexes and InnoDB indexes. -@param[in] table table object formed from .frm @param[in] ib_table InnoDB table definition @retval true if not errors were found */ -static bool -check_index_consistency(const TABLE* table, const dict_table_t* ib_table) +bool +ha_innobase::check_index_consistency(const dict_table_t* ib_table) noexcept { ulint mysql_num_index = table->s->keys; ulint ib_num_index = UT_LIST_GET_LEN(ib_table->indexes); bool ret = true; + ulint last_unique = 0; /* If there exists inconsistency between MySQL and InnoDB dictionary (metadata) information, the number of index defined in MySQL @@ -5633,8 +5633,21 @@ check_index_consistency(const TABLE* table, const dict_table_t* ib_table) ret = false; goto func_exit; } - } + if (index->is_unique()) { + ulint i = 0; + while ((index = UT_LIST_GET_PREV(indexes, index))) i++; + /* Check if any unique index in InnoDB + dictionary are re-ordered compared to + the index in .frm */ + if (last_unique > i) { + m_int_table_flags + |= HA_DUPLICATE_KEY_NOT_IN_ORDER; + } + + last_unique = i; + } + } func_exit: return ret; } @@ -5874,7 +5887,7 @@ ha_innobase::open(const char* name, int, uint) mutex_exit(&dict_sys.mutex); } - if (!check_index_consistency(table, ib_table)) { + if (!check_index_consistency(ib_table)) { sql_print_error("InnoDB indexes are inconsistent with what " "defined in .frm for table %s", name); diff --git a/storage/innobase/handler/ha_innodb.h b/storage/innobase/handler/ha_innodb.h index bd99b230a67..ea0018cad25 100644 --- a/storage/innobase/handler/ha_innodb.h +++ b/storage/innobase/handler/ha_innodb.h @@ -437,6 +437,12 @@ public: const KEY_PART_INFO& old_part, const KEY_PART_INFO& new_part) const override; + /** Check consistency between .frm indexes and InnoDB indexes + Set HA_DUPLICATE_KEY_NOT_IN_ORDER if multiple unique index + are not in the correct order. + @param ib_table InnoDB table definition + @retval true if not errors were found */ + bool check_index_consistency(const dict_table_t* ib_table) noexcept; protected: bool can_convert_string(const Field_string* field,