From 403e6615fdd3f5f4de6d159457b2bd2fe566e0ad Mon Sep 17 00:00:00 2001 From: Elena Stepanova Date: Fri, 26 Jul 2019 18:17:55 +0300 Subject: [PATCH 01/11] List of unstable tests for 10.1.41 release (updated) --- mysql-test/unstable-tests | 38 +++++++++++++++++++++++++++----------- 1 file changed, 27 insertions(+), 11 deletions(-) diff --git a/mysql-test/unstable-tests b/mysql-test/unstable-tests index 0c7756d70ae..f09647523af 100644 --- a/mysql-test/unstable-tests +++ b/mysql-test/unstable-tests @@ -23,13 +23,14 @@ # ############################################################################## # -# Based on 10.1 1f498f901b394e869c430b777fdc233ab98d428f +# Based on 10.1 2382cd14a8c96cf8b4375d7338abfa6e1b333a86 main.alter_table_trans : MDEV-12084 - timeout main.analyze_stmt : Modified in 10.1.39 main.analyze_stmt_slow_query_log : MDEV-12237 - Wrong result main.auth_named_pipe : MDEV-14724 - System error 2 main.bootstrap : Modified in 10.1.41 +main.connect_debug : Modified in 10.1.41 main.count_distinct2 : MDEV-11768 - timeout main.create_delayed : MDEV-10605 - failed with timeout main.create_drop_event : MDEV-16271 - Wrong result @@ -81,11 +82,14 @@ main.host_cache_size_functionality : MDEV-10606 - sporadic failure on shutdown main.index_intersect_innodb : MDEV-10643 - failed with timeout main.index_merge_innodb : MDEV-7142 - Wrong execution plan, timeout with valgrind; modified in 10.1.39 main.index_merge_myisam : Include files modified in 10.1.39 +main.information_schema_parameters : Modified in 10.1.41 main.information_schema_prepare : Added in 10.1.39 main.innodb_mysql_lock : MDEV-7861 - sporadic lock detection failure +main.join : Modified in 10.1.41 main.join_cache : Modified in 10.1.41 main.join_nested : Modified in 10.1.41 main.join_outer : Modified in 10.1.41 +main.join_outer_innodb : Modified in 10.1.41 main.kill_processlist-6619 : MDEV-10793 - wrong result in processlist; modified in 10.1.39 main.loaddata : MDEV-19368 - mysqltest failed but provided no output; modified in 10.1.39 main.log_slow : MDEV-13263 - Wrong result; modified in 10.1.39 @@ -117,7 +121,10 @@ main.partition : Modified in 10.1.39 main.partition_debug_sync : MDEV-15669 - Deadlock found when trying to get lock main.partition_innodb : Modified in 10.1.39 main.partition_innodb_plugin : MDEV-12901 - Valgrind warnings -main.ps : MDEV-11017 - sporadic wrong Prepared_stmt_count; modified in 10.1.39 +main.plugin : Modified in 10.1.41 +main.plugin_not_embedded : Modified in 10.1.41 +main.ps : MDEV-11017 - sporadic wrong Prepared_stmt_count; modified in 10.1.41 +main.ps_innodb : Added in 10.1.41 main.query_cache : MDEV-12895 - Wrong result main.query_cache_debug : MDEV-15281 - Resize or similar command in progress main.range_vs_index_merge_innodb : MDEV-15283 - Server has gone away @@ -135,6 +142,7 @@ main.stat_tables_par_innodb : MDEV-14155 - wrong rounding main.statistics : Modified in 10.1.39 main.status : MDEV-8510 - sporadic wrong result main.status2 : Modified in 10.1.39 +main.subselect : Modified in 10.1.41 main.subselect_innodb : MDEV-10614 - sporadic wrong results main.subselect_sj : Modified in 10.1.41 main.subselect_sj_mat : Modified in 10.1.41 @@ -150,7 +158,7 @@ main.type_decimal : Modified in 10.1.39 main.type_year : Modified in 10.1.39 main.update_innodb : Modified in 10.1.39 main.userstat : Modified in 10.1.39 -main.view : Modified in 10.1.39 +main.view : Modified in 10.1.41 main.view_grant : Modified in 10.1.39 main.wait_timeout : Lost connection to MySQL server during query main.xa : MDEV-11769 - lock wait timeout @@ -169,13 +177,17 @@ archive-test_sql_discovery.discover : MDEV-16817 - Table marked as crashed #----------------------------------------------------------------------- -binlog.binlog_commit_wait : MDEV-10150 - Error: too much time elapsed -binlog.binlog_innodb_stm : Added in 10.1.39 -binlog.binlog_killed : MDEV-12925 - Wrong result -binlog.binlog_mysqlbinlog2 : Modified in 10.1.39 -binlog.binlog_mysqlbinlog_stop_never : Added in 10.1.41 -binlog.binlog_xa_recover : MDEV-8517 - Extra checkpoint -binlog.load_data_stm_view : MDEV-16948 - Wrong result +binlog.binlog_commit_wait : MDEV-10150 - Error: too much time elapsed +binlog.binlog_innodb_stm : Added in 10.1.39 +binlog.binlog_killed : MDEV-12925 - Wrong result +binlog.binlog_mysqlbinlog2 : Modified in 10.1.39 +binlog.binlog_mysqlbinlog_stop_never : Added in 10.1.41 +binlog.binlog_parallel_replication_marks_row : Include file modified in 10.1.41 +binlog.binlog_parallel_replication_marks_stm_mix : Include file modified in 10.1.41 +binlog.binlog_row_drop_tmp_tbl : Include file modified in 10.1.41 +binlog.binlog_stm_drop_tmp_tbl : MDEV-20188 - Unknown table on exec; include file modified in 10.1.41 +binlog.binlog_xa_recover : MDEV-8517 - Extra checkpoint +binlog.load_data_stm_view : MDEV-16948 - Wrong result #----------------------------------------------------------------------- @@ -279,6 +291,7 @@ innodb.innodb-64k-crash : MDEV-13872 - Failure and crash on innodb.innodb-alter-debug : MDEV-13182 - InnoDB: adjusting FSP_SPACE_FLAGS innodb.innodb-alter-nullable : Modified in 10.1.39 innodb.innodb-alter-table : MDEV-10619 - Testcase timeout +innodb.innodb-autoinc : Modified in 10.1.41 innodb.innodb-blob : MDEV-12053 - Client crash innodb.innodb-corrupted-table : Modified in 10.1.39 innodb.innodb-fk : MDEV-13832 - Assertion failure on shutdown @@ -309,7 +322,6 @@ innodb.xa_recovery : MDEV-15279 - mysqld got exception #----------------------------------------------------------------------- -innodb_fts.innodb-fts-fic : MDEV-14154 - Assertion failure innodb_fts.innodb_ft_aux_table : Added in 10.1.41 innodb_fts.innodb_fts_misc_debug : MDEV-14156 - Unexpected warning @@ -397,6 +409,9 @@ roles.flush_roles-17898 : Modified in 10.1.39 #----------------------------------------------------------------------- rpl.circular_serverid0 : MDEV-19372 - ASAN heap-use-after-free +rpl.create_or_replace_mix : Include file modified in 10.1.41 +rpl.create_or_replace_row : Include file modified in 10.1.41 +rpl.create_or_replace_statement : Include file modified in 10.1.41 rpl.create_select : MDEV-14121 - Assertion failure rpl.kill_race_condition : Modified in 10.1.41 rpl.last_insert_id : MDEV-10625 - warnings in error log @@ -447,6 +462,7 @@ rpl.rpl_rewrt_db : Modified in 10.1.39 rpl.rpl_row_basic_11bugs : MDEV-12171 - Server failed to start rpl.rpl_row_basic_2myisam : MDEV-13875 - command "diff_files" failed rpl.rpl_row_drop_create_temp_table : MDEV-14487 - Wrong result +rpl.rpl_row_drop_temp_table : Added in 10.1.41 rpl.rpl_row_img_blobs : MDEV-13875 - command "diff_files" failed rpl.rpl_row_img_eng_min : MDEV-13875 - command "diff_files" failed rpl.rpl_row_img_eng_noblob : MDEV-13875 - command "diff_files" failed From f79212f96d2b9ad23037201f6896ba303a222b5d Mon Sep 17 00:00:00 2001 From: Anel Husakovic Date: Wed, 31 Jul 2019 02:49:15 -0700 Subject: [PATCH 02/11] Fix extra space in mysql-test README --- mysql-test/README | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mysql-test/README b/mysql-test/README index c4ded4e8e79..08a8200e27f 100644 --- a/mysql-test/README +++ b/mysql-test/README @@ -60,7 +60,7 @@ In the file, put a set of SQL statements that create some tables, load test data, and run some queries to manipulate it. Your test should begin by dropping the tables you are going to create and -end by dropping them again. This ensures that you can run the test over +end by dropping them again. This ensures that you can run the test over and over again. If you are using mysqltest commands in your test case, you should create @@ -81,7 +81,7 @@ comments, you can create the result file in one of the following ways: # mysqltest --record --database test --result-file=r/test_case_name.result < t/test_case_name.test -When this is done, take a look at r/test_case_name.result . +When this is done, take a look at r/test_case_name.result. If the result is incorrect, you have found a bug. In this case, you should edit the test result to the correct results so that we can verify that the bug is corrected in future releases. From cabf10b640980fae6051a2a0f20b9b2b0c4143ce Mon Sep 17 00:00:00 2001 From: Daniel Bartholomew Date: Wed, 31 Jul 2019 09:53:58 -0400 Subject: [PATCH 03/11] bump the VERSION --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index b9002ef5c4d..df06ca3b38a 100644 --- a/VERSION +++ b/VERSION @@ -1,4 +1,4 @@ MYSQL_VERSION_MAJOR=5 MYSQL_VERSION_MINOR=5 -MYSQL_VERSION_PATCH=65 +MYSQL_VERSION_PATCH=66 MYSQL_VERSION_EXTRA= From 0bb8f33b55cc016d0ede86b97990a3ee30dcb069 Mon Sep 17 00:00:00 2001 From: Daniel Bartholomew Date: Wed, 31 Jul 2019 09:55:57 -0400 Subject: [PATCH 04/11] bump the VERSION --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 3e7ee013177..93f88d1e9c0 100644 --- a/VERSION +++ b/VERSION @@ -1,3 +1,3 @@ MYSQL_VERSION_MAJOR=10 MYSQL_VERSION_MINOR=1 -MYSQL_VERSION_PATCH=41 +MYSQL_VERSION_PATCH=42 From 319cec959c6295da3c2a1d003d12421a7d8ba343 Mon Sep 17 00:00:00 2001 From: Eugene Kosov Date: Thu, 1 Aug 2019 15:24:48 +0300 Subject: [PATCH 05/11] MDEV-17638 Improve error message about corruption of encrypted page Help user distinguish between space ID and page number. --- extra/innochecksum.cc | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/extra/innochecksum.cc b/extra/innochecksum.cc index d7c5cd7495b..00ca3e20339 100644 --- a/extra/innochecksum.cc +++ b/extra/innochecksum.cc @@ -525,7 +525,8 @@ is_page_corrupted( page_size.is_compressed() ? page_size.physical() : 0); if (is_corrupted && log_file) { fprintf(log_file, - "Page " ULINTPF ":%llu may be corrupted;" + "[page id: space=" ULINTPF + ", page_number=%llu] may be corrupted;" " key_version=" ULINTPF "\n", space_id, cur_page_num, mach_read_from_4( From eef7540405849287abf94c0332adfc50cf4f13c5 Mon Sep 17 00:00:00 2001 From: Sujatha Date: Mon, 5 Aug 2019 14:34:13 +0530 Subject: [PATCH 06/11] MDEV-18930: Failed CREATE OR REPLACE TEMPORARY not written into binary log makes data on master and slave diverge Problem: ======= Failed CREATE OR REPLACE TEMPORARY TABLE statement which dropped the table but failed at a later stage of creation of temporary table is not written to binarylog in row based replication. This causes the slave to diverge. Analysis: ======== CREATE OR REPLACE statements work as shown below. CREATE OR REPLACE TABLE table_name (a int); is basically the same as: DROP TABLE IF EXISTS table_name; CREATE TABLE table_name (a int); Hence every CREATE OR REPLACE TABLE command which dropped the table should be written to binary log, even when following CREATE TABLE part fails. In order to achieve this, during the execution of CREATE OR REPLACE command, when a table is dropped 'thd->log_current_statement' flag is set. When table creation results in an error within 'mysql_create_table' code, the error handling part looks for this flag. If it is set the failed CREATE OR REPLACE statement is written into the binary log inspite of error. This ensure that slave doesn't diverge from the master. In case of row based replication the error handling code returns very early, if the table is of type temporary. This is done based on the assumption that temporary tables are not replicated in row based replication. It fails to handle the cases where a temporary table was created as part of statement based replication at an earlier stage and the binary log format was changed to row because of an unsafe statement. In this case when a CREATE OR REPLACE statement is executed on this temporary table it will dropped but the query will not be written to binary log. Hence slave diverges. Fix: === In error handling code check the return status of create table operation. If it is successful and replication mode is row based and table is of type temporary then return. Other wise proceed further to the code which checks for thd->log_current_statement flag and does appropriate logging. --- .../rpl/r/rpl_create_or_replace_fail.result | 18 ++++++ .../rpl/t/rpl_create_or_replace_fail.test | 56 +++++++++++++++++++ sql/sql_table.cc | 2 +- 3 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 mysql-test/suite/rpl/r/rpl_create_or_replace_fail.result create mode 100644 mysql-test/suite/rpl/t/rpl_create_or_replace_fail.test diff --git a/mysql-test/suite/rpl/r/rpl_create_or_replace_fail.result b/mysql-test/suite/rpl/r/rpl_create_or_replace_fail.result new file mode 100644 index 00000000000..57178f0efbe --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_create_or_replace_fail.result @@ -0,0 +1,18 @@ +include/master-slave.inc +[connection master] +CREATE TEMPORARY TABLE t1 (a INT NOT NULL); +LOAD DATA INFILE 'x' INTO TABLE x; +ERROR 42S02: Table 'test.x' doesn't exist +CREATE OR REPLACE TEMPORARY TABLE t1 (x INT) PARTITION BY HASH(x); +ERROR HY000: Cannot create temporary table with partitions +"************** DROP TEMPORARY TABLE Should be present in Binary log **************" +include/show_binlog_events.inc +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE TEMPORARY TABLE t1 (a INT NOT NULL) +master-bin.000001 # Gtid # # GTID #-#-# +master-bin.000001 # Query # # use `test`; CREATE OR REPLACE TEMPORARY TABLE t1 (x INT) PARTITION BY HASH(x) +CREATE TABLE t1 (b INT); +INSERT INTO t1 VALUES (NULL); +DROP TABLE t1; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_create_or_replace_fail.test b/mysql-test/suite/rpl/t/rpl_create_or_replace_fail.test new file mode 100644 index 00000000000..e75f34b0b56 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_create_or_replace_fail.test @@ -0,0 +1,56 @@ +# ==== Purpose ==== +# +# Test verifies that failed CREATE OR REPLACE TEMPORARY TABLE statement which +# dropped the table but failed at a later stage of creation of temporary table +# is written to binarylog in row based replication. +# +# ==== Implementation ==== +# +# Steps: +# 0 - Have mixed based replication mode. +# 1 - Create a temporary table. It will be replicated as mixed replication +# mode is in use. +# 2 - Execute an unsafe statement which will switch current statement +# binlog format to 'ROW'. i.e If binlog_format=MIXED, there are open +# temporary tables, and an unsafe statement is executed, then subsequent +# statements are logged in row format. +# 3 - Execute a CREATE OR REPLACE TEMPORARY TABLE statement which tries to +# create partitions on temporary table. Since it is not supported it will +# fail. +# 4 - Check the binary log output to ensure that the failed statement is +# written to the binary log. +# 5 - Slave should be up and running and in sync with master. +# +# ==== References ==== +# +# MDEV-18930: Failed CREATE OR REPLACE TEMPORARY not written into binary log +# makes data on master and slave diverge +# + +--source include/have_partition.inc +--source include/have_binlog_format_mixed.inc +--source include/master-slave.inc + +CREATE TEMPORARY TABLE t1 (a INT NOT NULL); + +# Execute an unsafe statement which switches replication mode internally from +# "STATEMENT" to "ROW". +--error ER_NO_SUCH_TABLE +LOAD DATA INFILE 'x' INTO TABLE x; + +--error ER_PARTITION_NO_TEMPORARY +CREATE OR REPLACE TEMPORARY TABLE t1 (x INT) PARTITION BY HASH(x); + +--echo "************** DROP TEMPORARY TABLE Should be present in Binary log **************" +--source include/show_binlog_events.inc + +CREATE TABLE t1 (b INT); +INSERT INTO t1 VALUES (NULL); +--sync_slave_with_master + +# Cleanup +--connection master +DROP TABLE t1; + +--source include/rpl_end.inc + diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 656834c7852..fe923d73200 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -5092,7 +5092,7 @@ bool mysql_create_table(THD *thd, TABLE_LIST *create_table, err: /* In RBR we don't need to log CREATE TEMPORARY TABLE */ - if (thd->is_current_stmt_binlog_format_row() && create_info->tmp_table()) + if (!result && thd->is_current_stmt_binlog_format_row() && create_info->tmp_table()) DBUG_RETURN(result); if (create_info->tmp_table()) From 47f8a18fec604983e47fdf7c822d94b26d85cade Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Wed, 7 Aug 2019 12:35:04 +0530 Subject: [PATCH 07/11] MDEV-20247 Replication hangs with "preparing" and never starts - The commit ab6dd774082c57f48d998e03655c06b672799b2d wrongly sets the condition inside innobase_srv_conc_enter_innodb(). Problem is that InnoDB makes the thread to sleep indefinitely if it is a replication slave thread. Thanks to Sujatha Sivakumar for contributing the replication test case. --- .../r/rpl_sync_with_innodb_thd_conc.result | 13 ++++++ .../rpl/t/rpl_sync_with_innodb_thd_conc.test | 41 +++++++++++++++++++ storage/innobase/handler/ha_innodb.cc | 6 +-- storage/xtradb/handler/ha_innodb.cc | 6 +-- 4 files changed, 60 insertions(+), 6 deletions(-) create mode 100644 mysql-test/suite/rpl/r/rpl_sync_with_innodb_thd_conc.result create mode 100644 mysql-test/suite/rpl/t/rpl_sync_with_innodb_thd_conc.test diff --git a/mysql-test/suite/rpl/r/rpl_sync_with_innodb_thd_conc.result b/mysql-test/suite/rpl/r/rpl_sync_with_innodb_thd_conc.result new file mode 100644 index 00000000000..0ed894336a1 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_sync_with_innodb_thd_conc.result @@ -0,0 +1,13 @@ +include/master-slave.inc +[connection master] +SET @old_innodb_thread_concurrency := @@innodb_thread_concurrency; +SET @old_innodb_thread_sleep_delay := @@innodb_thread_sleep_delay; +SET GLOBAL innodb_thread_concurrency = 100; +CREATE TABLE t(f INT) ENGINE=INNODB; +INSERT INTO t VALUES (10); +include/diff_tables.inc [master:t, slave:t] +"===== Clean up=======" +DROP TABLE t; +SET GLOBAL innodb_thread_concurrency = @old_innodb_thread_concurrency; +SET GLOBAL innodb_thread_sleep_delay = @old_innodb_thread_sleep_delay; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_sync_with_innodb_thd_conc.test b/mysql-test/suite/rpl/t/rpl_sync_with_innodb_thd_conc.test new file mode 100644 index 00000000000..b4c2971d2fb --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_sync_with_innodb_thd_conc.test @@ -0,0 +1,41 @@ +# ==== Purpose ==== +# +# Test verifies that replication shouldn't hang when number of active threads +# on the slave server are less than the allowed innodb_thread_concurrency value. +# +# ==== Implementation ==== +# +# Steps: +# 0 - Have master slave replication setup with engine being Innodb. +# 1 - Configure innodb_thread_concurrency = 100. +# 2 - Do some DML on master and sync the slave with master. +# 3 - Ensure replication doesn't hang. +# +# ==== References ==== +# +# MDEV-20247: Replication hangs with "preparing" and never starts +# + +--source include/master-slave.inc +--source include/have_innodb.inc + +--connection slave +SET @old_innodb_thread_concurrency := @@innodb_thread_concurrency; +SET @old_innodb_thread_sleep_delay := @@innodb_thread_sleep_delay; +SET GLOBAL innodb_thread_concurrency = 100; + +--connection master +CREATE TABLE t(f INT) ENGINE=INNODB; +INSERT INTO t VALUES (10); +--sync_slave_with_master + +--let $diff_tables=master:t, slave:t +--source include/diff_tables.inc + +--echo "===== Clean up=======" +--connection master +DROP TABLE t; +--sync_slave_with_master +SET GLOBAL innodb_thread_concurrency = @old_innodb_thread_concurrency; +SET GLOBAL innodb_thread_sleep_delay = @old_innodb_thread_sleep_delay; +--source include/rpl_end.inc diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 081fcbd9c51..5dfe240631b 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -1686,9 +1686,9 @@ innobase_srv_conc_enter_innodb( && thd_is_replication_slave_thread(trx->mysql_thd)) { const ulonglong end = my_interval_timer() + ulonglong(srv_replication_delay) * 1000000; - while (srv_conc_get_active_threads() - >= srv_thread_concurrency - || my_interval_timer() >= end) { + while ((srv_conc_get_active_threads() + >= srv_thread_concurrency) + && my_interval_timer() < end) { os_thread_sleep(2000 /* 2 ms */); } } else { diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 5e7482ff6bf..b5002187e3b 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -1949,9 +1949,9 @@ innobase_srv_conc_enter_innodb( && thd_is_replication_slave_thread(trx->mysql_thd)) { const ulonglong end = my_interval_timer() + ulonglong(srv_replication_delay) * 1000000; - while (srv_conc_get_active_threads() - >= srv_thread_concurrency - || my_interval_timer() >= end) { + while ((srv_conc_get_active_threads() + >= srv_thread_concurrency) + && my_interval_timer() < end) { os_thread_sleep(2000 /* 2 ms */); } } else { From 284c72eacf2074bf50c1930d5e8eb333367eba2f Mon Sep 17 00:00:00 2001 From: Sachin Date: Wed, 17 Jul 2019 15:56:29 +0530 Subject: [PATCH 08/11] MDEV-17614 INSERT on dup key update is replication unsafe Problem:- When mysql executes INSERT ON DUPLICATE KEY INSERT, the storage engine checks if the inserted row would generate a duplicate key error. If yes, it returns the existing row to mysql, mysql updates it and sends it back to the storage engine.When the table has more than one unique or primary key, this statement is sensitive to the order in which the storage engines checks the keys. Depending on this order, the storage engine may determine different rows to mysql, and hence mysql can update different rows.The order that the storage engine checks keys is not deterministic. For example, InnoDB checks keys in an order that depends on the order in which indexes were added to the table. The first added index is checked first. So if master and slave have added indexes in different orders, then slave may go out of sync. Solution:- Make INSERT...ON DUPLICATE KEY UPDATE unsafe while using stmt or mixed format When there is more then one unique key. Although there is two exception. 1. Auto Increment key is not counted because Innodb will get gap lock for failed Insert and concurrent insert will get a next increment value. But if user supplies auto inc value it can be unsafe. 2. Count only unique keys for which insertion is performed. So this patch also addresses the bug id #72921 --- .../rpl/r/rpl_known_bugs_detection.result | 20 --- mysql-test/suite/rpl/r/rpl_mdev_17614.result | 98 ++++++++++++++ .../suite/rpl/r/rpl_unsafe_statements.result | 5 + .../suite/rpl/t/rpl_known_bugs_detection.test | 39 ------ mysql-test/suite/rpl/t/rpl_mdev_17614.test | 121 ++++++++++++++++++ .../suite/rpl/t/rpl_unsafe_statements.test | 2 +- sql/sql_class.cc | 42 ++++++ sql/sql_class.h | 40 ++++-- sql/sql_insert.cc | 1 + 9 files changed, 294 insertions(+), 74 deletions(-) create mode 100644 mysql-test/suite/rpl/r/rpl_mdev_17614.result create mode 100644 mysql-test/suite/rpl/t/rpl_mdev_17614.test diff --git a/mysql-test/suite/rpl/r/rpl_known_bugs_detection.result b/mysql-test/suite/rpl/r/rpl_known_bugs_detection.result index ea738b710fd..adef091ea3e 100644 --- a/mysql-test/suite/rpl/r/rpl_known_bugs_detection.result +++ b/mysql-test/suite/rpl/r/rpl_known_bugs_detection.result @@ -1,26 +1,6 @@ call mtr.add_suppression("Unsafe statement written to the binary log using statement format"); include/master-slave.inc [connection master] -call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT."); -CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY AUTO_INCREMENT, b INT, -UNIQUE(b)); -INSERT INTO t1(b) VALUES(1),(1),(2) ON DUPLICATE KEY UPDATE t1.b=10; -SELECT * FROM t1; -a b -1 10 -2 2 -call mtr.add_suppression("Slave SQL.*suffer.*http:..bugs.mysql.com.bug.php.id=24432"); -include/wait_for_slave_sql_error.inc [errno=1105] -Last_SQL_Error = 'Error 'master may suffer from http://bugs.mysql.com/bug.php?id=24432 so slave stops; check error log on slave for more info' on query. Default database: 'test'. Query: 'INSERT INTO t1(b) VALUES(1),(1),(2) ON DUPLICATE KEY UPDATE t1.b=10'' -SELECT * FROM t1; -a b -stop slave; -include/wait_for_slave_to_stop.inc -reset slave; -reset master; -drop table t1; -start slave; -include/wait_for_slave_to_start.inc CREATE TABLE t1 ( id bigint(20) unsigned NOT NULL auto_increment, field_1 int(10) unsigned NOT NULL, diff --git a/mysql-test/suite/rpl/r/rpl_mdev_17614.result b/mysql-test/suite/rpl/r/rpl_mdev_17614.result new file mode 100644 index 00000000000..28de23e28c9 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_mdev_17614.result @@ -0,0 +1,98 @@ +include/master-slave.inc +[connection master] +call mtr.add_suppression("Unsafe statement written to the binary log using statement format"); +CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY , b INT, +UNIQUE(b), c int) engine=innodb; +INSERT INTO t1 VALUES (1, 1, 1); +BEGIN; +INSERT INTO t1 VALUES (2, 1, 2) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c); +Warnings: +Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. INSERT... ON DUPLICATE KEY UPDATE on a table with more than one UNIQUE KEY is unsafe +INSERT INTO t1 VALUES(2, 2, 3) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c); +Warnings: +Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. INSERT... ON DUPLICATE KEY UPDATE on a table with more than one UNIQUE KEY is unsafe +COMMIT; +SELECT * FROM t1; +a b c +1 1 2 +2 2 3 +include/wait_for_slave_sql_error.inc [errno=1062] +Last_SQL_Error = 'Error 'Duplicate entry '1' for key 'b'' on query. Default database: 'test'. Query: 'INSERT INTO t1 VALUES (2, 1, 2) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c)'' +#Different value from server +SELECT * FROM t1; +a b c +1 1 1 +2 2 3 +stop slave; +include/wait_for_slave_to_stop.inc +reset slave; +reset master; +drop table t1; +start slave; +include/wait_for_slave_to_start.inc +CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY auto_increment, b INT, +UNIQUE(b), c int) engine=innodb; +INSERT INTO t1 VALUES (default, 1, 1); +BEGIN; +INSERT INTO t1 VALUES (default, 1, 2) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c); +INSERT INTO t1 VALUES(default, 2, 3) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c); +COMMIT; +SELECT * FROM t1; +a b c +1 1 2 +3 2 3 +#same data as master +SELECT * FROM t1; +a b c +1 1 2 +3 2 3 +drop table t1; +CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY, b INT, +UNIQUE(b), c int, d int ) engine=innodb; +INSERT INTO t1 VALUES (1, 1, 1, 1); +BEGIN; +INSERT INTO t1 VALUES (2, NULL, 2, 2) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c); +Warnings: +Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. INSERT... ON DUPLICATE KEY UPDATE on a table with more than one UNIQUE KEY is unsafe +INSERT INTO t1 VALUES(3, NULL, 2, 3) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c); +Warnings: +Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. INSERT... ON DUPLICATE KEY UPDATE on a table with more than one UNIQUE KEY is unsafe +COMMIT; +SELECT * FROM t1; +a b c d +1 1 1 1 +2 NULL 2 2 +3 NULL 2 3 +#same data as master +SELECT * FROM t1; +a b c d +1 1 1 1 +2 NULL 2 2 +3 NULL 2 3 +drop table t1; +CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY auto_increment, b INT, +UNIQUE(b), c int) engine=innodb; +INSERT INTO t1 VALUES (1, 1, 1); +BEGIN; +INSERT INTO t1 VALUES (2, 1, 2) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c); +INSERT INTO t1 VALUES(2, 2, 3) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c); +COMMIT; +SELECT * FROM t1; +a b c +1 1 2 +2 2 3 +include/wait_for_slave_sql_error.inc [errno=1062] +Last_SQL_Error = 'Error 'Duplicate entry '1' for key 'b'' on query. Default database: 'test'. Query: 'INSERT INTO t1 VALUES (2, 1, 2) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c)'' +#Different value from server +SELECT * FROM t1; +a b c +1 1 1 +2 2 3 +stop slave; +include/wait_for_slave_to_stop.inc +reset slave; +reset master; +drop table t1; +start slave; +include/wait_for_slave_to_start.inc +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_unsafe_statements.result b/mysql-test/suite/rpl/r/rpl_unsafe_statements.result index 2efb3eba2b1..55ff09f6fad 100644 --- a/mysql-test/suite/rpl/r/rpl_unsafe_statements.result +++ b/mysql-test/suite/rpl/r/rpl_unsafe_statements.result @@ -1,5 +1,6 @@ include/master-slave.inc [connection master] +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); CREATE TABLE t1(id INT AUTO_INCREMENT, i INT, PRIMARY KEY (id)) ENGINE=INNODB; CREATE TABLE t2(id INT AUTO_INCREMENT, i INT, PRIMARY KEY (id)) ENGINE=INNODB; CREATE TRIGGER trig1 AFTER INSERT ON t1 @@ -43,9 +44,13 @@ include/diff_tables.inc [master:t1, slave:t1] DROP TABLE t1; CREATE TABLE t1(i INT, j INT, UNIQUE KEY(i), UNIQUE KEY(j)) ENGINE=INNODB; INSERT INTO t1 (i,j) VALUES (1,2) ON DUPLICATE KEY UPDATE j=j+1; +Warnings: +Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. INSERT... ON DUPLICATE KEY UPDATE on a table with more than one UNIQUE KEY is unsafe START TRANSACTION; LOCK TABLES t1 WRITE; INSERT INTO t1 (i,j) VALUES (1,2) ON DUPLICATE KEY UPDATE j=j+1; +Warnings: +Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. INSERT... ON DUPLICATE KEY UPDATE on a table with more than one UNIQUE KEY is unsafe UNLOCK TABLES; COMMIT; include/diff_tables.inc [master:t1, slave:t1] diff --git a/mysql-test/suite/rpl/t/rpl_known_bugs_detection.test b/mysql-test/suite/rpl/t/rpl_known_bugs_detection.test index ab263ece407..5ea056d5f14 100644 --- a/mysql-test/suite/rpl/t/rpl_known_bugs_detection.test +++ b/mysql-test/suite/rpl/t/rpl_known_bugs_detection.test @@ -14,45 +14,6 @@ source include/have_binlog_checksum_off.inc; source include/master-slave.inc; -call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT."); - -# -# This is to test that slave properly detects if -# master may suffer from: -# BUG#24432 "INSERT... ON DUPLICATE KEY UPDATE skips auto_increment values" -# (i.e. on master, INSERT ON DUPLICATE KEY UPDATE is used and manipulates -# an auto_increment column, and is binlogged statement-based). -# - -# testcase with INSERT VALUES -CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY AUTO_INCREMENT, b INT, -UNIQUE(b)); -sync_slave_with_master; -connection master; -INSERT INTO t1(b) VALUES(1),(1),(2) ON DUPLICATE KEY UPDATE t1.b=10; -SELECT * FROM t1; -connection slave; - -# show the error message -#1105 = ER_UNKNOWN_ERROR ---let $slave_sql_errno= 1105 ---let $show_slave_sql_error= 1 -call mtr.add_suppression("Slave SQL.*suffer.*http:..bugs.mysql.com.bug.php.id=24432"); ---source include/wait_for_slave_sql_error.inc -# show that it was not replicated -SELECT * FROM t1; - -# restart replication for the next testcase -stop slave; ---source include/wait_for_slave_to_stop.inc -reset slave; -connection master; -reset master; -drop table t1; -connection slave; -start slave; ---source include/wait_for_slave_to_start.inc - # testcase with INSERT SELECT connection master; CREATE TABLE t1 ( diff --git a/mysql-test/suite/rpl/t/rpl_mdev_17614.test b/mysql-test/suite/rpl/t/rpl_mdev_17614.test new file mode 100644 index 00000000000..9b86c8c15b5 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_mdev_17614.test @@ -0,0 +1,121 @@ +source include/have_debug.inc; +source include/have_innodb.inc; +-- source include/have_binlog_format_statement.inc +source include/master-slave.inc; +# MDEV-17614 +# INSERT on dup key update is replication unsafe +# There can be three case +# 1. 2 unique key, Replication is unsafe. +# 2. 2 unique key , with one auto increment key, Safe to replicate because Innodb will acquire gap lock +# 3. n no of unique keys (n>1) but insert is only in 1 unique key +# 4. 2 unique key , with one auto increment key(but user gives auto inc value), unsafe to replicate + +# Case 1 +call mtr.add_suppression("Unsafe statement written to the binary log using statement format"); +CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY , b INT, +UNIQUE(b), c int) engine=innodb; +sync_slave_with_master; +connection master; +INSERT INTO t1 VALUES (1, 1, 1); +BEGIN; +INSERT INTO t1 VALUES (2, 1, 2) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c); + --connection master1 + INSERT INTO t1 VALUES(2, 2, 3) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c); +--connection master +COMMIT; +SELECT * FROM t1; +--connection slave +# show the error message +--let $slave_sql_errno= 1062 +--let $show_slave_sql_error= 1 +--source include/wait_for_slave_sql_error.inc +--echo #Different value from server +SELECT * FROM t1; + +# restart replication for the next testcase +stop slave; +--source include/wait_for_slave_to_stop.inc +reset slave; +connection master; +reset master; +drop table t1; +connection slave; +start slave; +--source include/wait_for_slave_to_start.inc +# Case 2 +--connection master +CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY auto_increment, b INT, +UNIQUE(b), c int) engine=innodb; +sync_slave_with_master; +connection master; +INSERT INTO t1 VALUES (default, 1, 1); +BEGIN; +INSERT INTO t1 VALUES (default, 1, 2) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c); + --connection master1 + INSERT INTO t1 VALUES(default, 2, 3) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c); +--connection master +COMMIT; +SELECT * FROM t1; +--sync_slave_with_master +--echo #same data as master +SELECT * FROM t1; + +connection master; +drop table t1; +--sync_slave_with_master + +# Case 3 +--connection master +CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY, b INT, +UNIQUE(b), c int, d int ) engine=innodb; +sync_slave_with_master; +connection master; +INSERT INTO t1 VALUES (1, 1, 1, 1); +BEGIN; +INSERT INTO t1 VALUES (2, NULL, 2, 2) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c); + --connection master1 + INSERT INTO t1 VALUES(3, NULL, 2, 3) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c); +--connection master +COMMIT; +SELECT * FROM t1; +--sync_slave_with_master +--echo #same data as master +SELECT * FROM t1; +connection master; +drop table t1; +--sync_slave_with_master + +# Case 4 +--connection master +CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY auto_increment, b INT, +UNIQUE(b), c int) engine=innodb; +sync_slave_with_master; +connection master; +INSERT INTO t1 VALUES (1, 1, 1); +BEGIN; +INSERT INTO t1 VALUES (2, 1, 2) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c); + --connection master1 + INSERT INTO t1 VALUES(2, 2, 3) ON DUPLICATE KEY UPDATE b=VALUES(b), c=VALUES(c); +--connection master +COMMIT; +SELECT * FROM t1; +--connection slave +# show the error message +--let $slave_sql_errno= 1062 +--let $show_slave_sql_error= 1 +--source include/wait_for_slave_sql_error.inc +--echo #Different value from server +SELECT * FROM t1; + +# restart replication for the next testcase +stop slave; +--source include/wait_for_slave_to_stop.inc +reset slave; +connection master; +reset master; +drop table t1; +connection slave; +start slave; +--source include/wait_for_slave_to_start.inc + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_unsafe_statements.test b/mysql-test/suite/rpl/t/rpl_unsafe_statements.test index cbb4b54a220..aa0bd076398 100644 --- a/mysql-test/suite/rpl/t/rpl_unsafe_statements.test +++ b/mysql-test/suite/rpl/t/rpl_unsafe_statements.test @@ -24,7 +24,7 @@ --source include/have_innodb.inc --source include/have_binlog_format_mixed.inc --source include/master-slave.inc - +call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); # Case-1: BINLOG_STMT_UNSAFE_AUTOINC_COLUMNS # Statement is unsafe because it invokes a trigger or a # stored function that inserts into an AUTO_INCREMENT column. diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 6bcff6d1fca..1a3ca54abf8 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -6144,6 +6144,48 @@ int THD::decide_logging_format(TABLE_LIST *tables) DBUG_RETURN(0); } +int THD::decide_logging_format_low(TABLE *table) +{ + /* + INSERT...ON DUPLICATE KEY UPDATE on a table with more than one unique keys + can be unsafe. + */ + if(wsrep_binlog_format() <= BINLOG_FORMAT_STMT && + !is_current_stmt_binlog_format_row() && + !lex->is_stmt_unsafe() && + lex->sql_command == SQLCOM_INSERT && + lex->duplicates == DUP_UPDATE) + { + uint unique_keys= 0; + uint keys= table->s->keys, i= 0; + Field *field; + for (KEY* keyinfo= table->s->key_info; + i < keys && unique_keys <= 1; i++, keyinfo++) + if (keyinfo->flags & HA_NOSAME && + !(keyinfo->key_part->field->flags & AUTO_INCREMENT_FLAG && + //User given auto inc can be unsafe + !keyinfo->key_part->field->val_int())) + { + for (uint j= 0; j < keyinfo->user_defined_key_parts; j++) + { + field= keyinfo->key_part[j].field; + if(!bitmap_is_set(table->write_set,field->field_index)) + goto exit; + } + unique_keys++; +exit:; + } + + if (unique_keys > 1) + { + lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_INSERT_TWO_KEYS); + binlog_unsafe_warning_flags|= lex->get_stmt_unsafe_flags(); + set_current_stmt_binlog_format_row_if_mixed(); + return 1; + } + } + return 0; +} /* Implementation of interface to write rows to the binary log through the diff --git a/sql/sql_class.h b/sql/sql_class.h index e3bc572ed0c..8a4d8ff06a3 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -2208,6 +2208,20 @@ public: /* container for handler's private per-connection data */ Ha_data ha_data[MAX_HA]; + /** + Bit field for the state of binlog warnings. + + The first Lex::BINLOG_STMT_UNSAFE_COUNT bits list all types of + unsafeness that the current statement has. + + This must be a member of THD and not of LEX, because warnings are + detected and issued in different places (@c + decide_logging_format() and @c binlog_query(), respectively). + Between these calls, the THD->lex object may change; e.g., if a + stored routine is invoked. Only THD persists between the calls. + */ + uint32 binlog_unsafe_warning_flags; + #ifndef MYSQL_CLIENT binlog_cache_mngr * binlog_setup_trx_data(); @@ -2317,20 +2331,6 @@ private: */ enum_binlog_format current_stmt_binlog_format; - /** - Bit field for the state of binlog warnings. - - The first Lex::BINLOG_STMT_UNSAFE_COUNT bits list all types of - unsafeness that the current statement has. - - This must be a member of THD and not of LEX, because warnings are - detected and issued in different places (@c - decide_logging_format() and @c binlog_query(), respectively). - Between these calls, the THD->lex object may change; e.g., if a - stored routine is invoked. Only THD persists between the calls. - */ - uint32 binlog_unsafe_warning_flags; - /* Number of outstanding table maps, i.e., table maps in the transaction cache. @@ -3939,6 +3939,18 @@ public: } void leave_locked_tables_mode(); int decide_logging_format(TABLE_LIST *tables); + /* + In Some cases when decide_logging_format is called it does not have all + information to decide the logging format. So that cases we call decide_logging_format_2 + at later stages in execution. + One example would be binlog format for IODKU but column with unique key is not inserted. + We dont have inserted columns info when we call decide_logging_format so on later stage we call + decide_logging_format_low + + @returns 0 if no format is changed + 1 if there is change in binlog format + */ + int decide_logging_format_low(TABLE *table); enum need_invoker { INVOKER_NONE=0, INVOKER_USER, INVOKER_ROLE}; void binlog_invoker(bool role) { m_binlog_invoker= role ? INVOKER_ROLE : INVOKER_USER; } diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 1ad74bd0f5a..f67897bb9c5 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -1025,6 +1025,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, error= 1; break; } + thd->decide_logging_format_low(table); #ifndef EMBEDDED_LIBRARY if (lock_type == TL_WRITE_DELAYED) { From b2a387a3f1a0603482d184241979f0172cba45cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 12 Aug 2019 14:05:26 +0300 Subject: [PATCH 09/11] Document TRASH_FILL, TRASH_ALLOC, TRASH_FREE --- include/my_valgrind.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/include/my_valgrind.h b/include/my_valgrind.h index ad22f0cad40..7a56b28c0f0 100644 --- a/include/my_valgrind.h +++ b/include/my_valgrind.h @@ -1,4 +1,4 @@ -/* Copyright (C) 2010 Monty Program Ab +/* Copyright (C) 2010, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -55,11 +55,19 @@ https://github.com/google/sanitizers/wiki/AddressSanitizerManualPoisoning */ #endif /* HAVE_VALGRIND */ #ifndef DBUG_OFF +/* NOTE: Do not invoke TRASH_FILL directly! Use TRASH_ALLOC or TRASH_FREE. + +The MEM_UNDEFINED() call before memset() is for canceling the effect +of any previous MEM_NOACCESS(). We must invoke MEM_UNDEFINED() after +writing the dummy pattern, unless MEM_NOACCESS() is going to be invoked. +On AddressSanitizer, the MEM_UNDEFINED() in TRASH_ALLOC() has no effect. */ #define TRASH_FILL(A,B,C) do { const size_t trash_tmp= (B); MEM_UNDEFINED(A, trash_tmp); memset(A, C, trash_tmp); } while (0) #else #define TRASH_FILL(A,B,C) do { MEM_UNDEFINED((A), (B)); } while (0) #endif +/** Note that some memory became allocated or uninitialized. */ #define TRASH_ALLOC(A,B) do { TRASH_FILL(A,B,0xA5); MEM_UNDEFINED(A,B); } while(0) +/** Note that some memory became freed. (Prohibit further access to it.) */ #define TRASH_FREE(A,B) do { TRASH_FILL(A,B,0x8F); MEM_NOACCESS(A,B); } while(0) #endif /* MY_VALGRIND_INCLUDED */ From 1217e4a0c05eff7a394e46e64dffc849c9edda22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 12 Aug 2019 14:12:32 +0300 Subject: [PATCH 10/11] Fix -Wimplicit-fallthrough --- storage/innobase/include/data0type.ic | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/storage/innobase/include/data0type.ic b/storage/innobase/include/data0type.ic index 2bf21513c1c..d31debef24a 100644 --- a/storage/innobase/include/data0type.ic +++ b/storage/innobase/include/data0type.ic @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2018, MariaDB Corporation. +Copyright (c) 2018, 2019, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -427,6 +427,7 @@ dtype_get_fixed_size_low( return(0); } #endif /* UNIV_DEBUG */ + /* fall through */ case DATA_CHAR: case DATA_FIXBINARY: case DATA_INT: @@ -503,6 +504,7 @@ dtype_get_min_size_low( return(0); } #endif /* UNIV_DEBUG */ + /* fall through */ case DATA_CHAR: case DATA_FIXBINARY: case DATA_INT: From 7a9e1fcd455bfa8e3d71fabb6b76769433567508 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 12 Aug 2019 14:45:28 +0300 Subject: [PATCH 11/11] MDEV-17614: Re-record a result --- mysql-test/suite/binlog/r/binlog_unsafe.result | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mysql-test/suite/binlog/r/binlog_unsafe.result b/mysql-test/suite/binlog/r/binlog_unsafe.result index 48d9db44b05..e8de90d3422 100644 --- a/mysql-test/suite/binlog/r/binlog_unsafe.result +++ b/mysql-test/suite/binlog/r/binlog_unsafe.result @@ -2706,6 +2706,8 @@ Warnings: Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. CREATE... REPLACE SELECT is unsafe because the order in which rows are retrieved by the SELECT determines which (if any) rows are replaced. This order cannot be predicted and may differ on master and the slave. INSERT INTO insert_2_keys VALUES (1, 2) ON DUPLICATE KEY UPDATE a=VALUES(a)+10, b=VALUES(b)+10; +Warnings: +Note 1592 Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT. INSERT... ON DUPLICATE KEY UPDATE on a table with more than one UNIQUE KEY is unsafe DROP TABLE filler_table; DROP TABLE insert_table; DROP TABLE update_table;