summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexander Barkov <bar@mariadb.com>2019-10-01 06:10:19 +0400
committerAlexander Barkov <bar@mariadb.com>2019-10-01 07:11:54 +0400
commitf203245e9edcfb202c1b23fba186be043ce6002d (patch)
treeb2162bfdd8030fcb32cb44e8fe952f5d0cb4e520
parent576a5f091ebc052c0379e5032b9898787e519776 (diff)
parent4bcf524482b3a4260347b0fe912fa2660af97c43 (diff)
downloadmariadb-git-f203245e9edcfb202c1b23fba186be043ce6002d.tar.gz
Merge remote-tracking branch 'origin/10.1' into 10.2
-rw-r--r--mysql-test/r/myisam.result23
-rw-r--r--mysql-test/suite/binlog_encryption/rpl_parallel_ignored_errors.result50
-rw-r--r--mysql-test/suite/binlog_encryption/rpl_parallel_ignored_errors.test1
-rw-r--r--mysql-test/suite/rpl/include/rpl_parallel_ignored_errors.inc112
-rw-r--r--mysql-test/suite/rpl/r/rpl_parallel_ignored_errors.result50
-rw-r--r--mysql-test/suite/rpl/t/rpl_parallel_ignored_errors.test1
-rw-r--r--mysql-test/t/myisam.test19
-rw-r--r--sql/rpl_parallel.cc16
-rw-r--r--sql/sql_table.cc16
-rw-r--r--support-files/rpm/server-preun.sh2
10 files changed, 281 insertions, 9 deletions
diff --git a/mysql-test/r/myisam.result b/mysql-test/r/myisam.result
index f2f06f9413a..dc99dc06b6d 100644
--- a/mysql-test/r/myisam.result
+++ b/mysql-test/r/myisam.result
@@ -2592,3 +2592,26 @@ myisam_block_size 1024
select @@global.myisam_block_size;
@@global.myisam_block_size
1024
+#
+# MDEV-20704 An index on a double column erroneously uses prefix compression
+#
+CREATE TABLE t1 (
+id INT NOT NULL PRIMARY KEY,
+d DOUBLE,
+KEY (d)
+) ENGINE=MyISAM;
+
+MyISAM file: MYSQLD_DATADIR/test/t1
+Record format: Fixed length
+Character set: latin1_swedish_ci (8)
+Data records: 0 Deleted blocks: 0
+Recordlength: 13
+
+table description:
+Key Start Len Index Type
+1 2 4 unique long
+2 6 8 multip. double NULL
+DROP TABLE t1;
+#
+# End of 5.5 tests
+#
diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_ignored_errors.result b/mysql-test/suite/binlog_encryption/rpl_parallel_ignored_errors.result
new file mode 100644
index 00000000000..570d2534ed7
--- /dev/null
+++ b/mysql-test/suite/binlog_encryption/rpl_parallel_ignored_errors.result
@@ -0,0 +1,50 @@
+include/master-slave.inc
+[connection master]
+connection server_2;
+include/stop_slave.inc
+SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads;
+SET @old_parallel_mode=@@GLOBAL.slave_parallel_mode;
+SET @old_dbug= @@GLOBAL.debug_dbug;
+SET GLOBAL slave_parallel_mode='optimistic';
+SET GLOBAL slave_parallel_threads= 3;
+CHANGE MASTER TO master_use_gtid=slave_pos;
+CALL mtr.add_suppression("Commit failed due to failure of an earlier commit on which this one depends");
+include/start_slave.inc
+connection server_1;
+ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB;
+CREATE TABLE t1 (a int PRIMARY KEY) ENGINE=InnoDB;
+include/save_master_gtid.inc
+connection server_2;
+include/sync_with_master_gtid.inc
+connect con_temp2,127.0.0.1,root,,test,$SERVER_MYPORT_2,;
+BEGIN;
+INSERT INTO t1 VALUES (32);
+connection server_1;
+INSERT INTO t1 VALUES (32);
+connection server_2;
+SET GLOBAL debug_dbug="+d,hold_worker_on_schedule";
+SET debug_sync="debug_sync_action SIGNAL reached_pause WAIT_FOR continue_worker";
+connection server_1;
+SET gtid_seq_no=100;
+INSERT INTO t1 VALUES (33);
+connection server_2;
+SET debug_sync='now WAIT_FOR reached_pause';
+connection server_1;
+INSERT INTO t1 VALUES (34);
+connection server_2;
+connection con_temp2;
+COMMIT;
+connection server_2;
+include/stop_slave.inc
+include/assert.inc [table t1 should have zero rows where a>32]
+SELECT * FROM t1 WHERE a>32;
+a
+DELETE FROM t1 WHERE a=32;
+SET GLOBAL slave_parallel_threads=@old_parallel_threads;
+SET GLOBAL slave_parallel_mode=@old_parallel_mode;
+SET GLOBAL debug_dbug=@old_debug;
+SET DEBUG_SYNC= 'RESET';
+include/start_slave.inc
+connection server_1;
+DROP TABLE t1;
+include/rpl_end.inc
diff --git a/mysql-test/suite/binlog_encryption/rpl_parallel_ignored_errors.test b/mysql-test/suite/binlog_encryption/rpl_parallel_ignored_errors.test
new file mode 100644
index 00000000000..8a26778c8f2
--- /dev/null
+++ b/mysql-test/suite/binlog_encryption/rpl_parallel_ignored_errors.test
@@ -0,0 +1 @@
+--source suite/rpl/include/rpl_parallel_ignored_errors.inc
diff --git a/mysql-test/suite/rpl/include/rpl_parallel_ignored_errors.inc b/mysql-test/suite/rpl/include/rpl_parallel_ignored_errors.inc
new file mode 100644
index 00000000000..25da12f30a3
--- /dev/null
+++ b/mysql-test/suite/rpl/include/rpl_parallel_ignored_errors.inc
@@ -0,0 +1,112 @@
+# ==== Purpose ====
+#
+# Test verifies that, in parallel replication, transaction failure notification
+# is propagated to all the workers. Workers should abort the execution of
+# transaction event groups, whose event positions are higher than the failing
+# transaction group.
+#
+# ==== Implementation ====
+#
+# Steps:
+# 0 - Create a table t1 on master which has a primary key. Enable parallel
+# replication on slave with slave_parallel_mode='optimistic' and
+# slave_parallel_threads=3.
+# 1 - On slave start a transaction and execute a local INSERT statement
+# which will insert value 32. This is done to block the INSERT coming
+# from master.
+# 2 - On master execute an INSERT statement with value 32, so that it is
+# blocked on slave.
+# 3 - On slave enable a debug sync point such that it holds the worker thread
+# execution as soon as work is scheduled to it.
+# 4 - INSERT value 33 on master. It will be held on slave by other worker
+# thread due to debug simulation.
+# 5 - INSERT value 34 on master.
+# 6 - On slave, enusre that INSERT 34 has reached a state where it waits for
+# its prior transactions to commit.
+# 7 - Commit the local INSERT 32 on slave server so that first worker will
+# error out.
+# 8 - Now send a continue signal to second worker processing 33. It should
+# wakeup and propagate the error to INSERT 34.
+# 9 - Upon slave stop due to error, check that no rows are found after the
+# failed INSERT 32.
+#
+# ==== References ====
+#
+# MDEV-20645: Replication consistency is broken as workers miss the error
+# notification from an earlier failed group.
+#
+
+--source include/have_innodb.inc
+--source include/have_debug.inc
+--source include/have_debug_sync.inc
+--source include/have_binlog_format_statement.inc
+--source include/master-slave.inc
+
+--enable_connect_log
+--connection server_2
+--source include/stop_slave.inc
+SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads;
+SET @old_parallel_mode=@@GLOBAL.slave_parallel_mode;
+SET @old_dbug= @@GLOBAL.debug_dbug;
+SET GLOBAL slave_parallel_mode='optimistic';
+SET GLOBAL slave_parallel_threads= 3;
+CHANGE MASTER TO master_use_gtid=slave_pos;
+CALL mtr.add_suppression("Commit failed due to failure of an earlier commit on which this one depends");
+--source include/start_slave.inc
+
+--connection server_1
+ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB;
+CREATE TABLE t1 (a int PRIMARY KEY) ENGINE=InnoDB;
+--source include/save_master_gtid.inc
+
+--connection server_2
+--source include/sync_with_master_gtid.inc
+
+--connect (con_temp2,127.0.0.1,root,,test,$SERVER_MYPORT_2,)
+BEGIN;
+INSERT INTO t1 VALUES (32);
+
+--connection server_1
+INSERT INTO t1 VALUES (32);
+
+--connection server_2
+--let $wait_condition= SELECT COUNT(*) = 1 FROM information_schema.processlist WHERE info like "INSERT INTO t1 VALUES (32)"
+--source include/wait_condition.inc
+SET GLOBAL debug_dbug="+d,hold_worker_on_schedule";
+SET debug_sync="debug_sync_action SIGNAL reached_pause WAIT_FOR continue_worker";
+
+--connection server_1
+SET gtid_seq_no=100;
+INSERT INTO t1 VALUES (33);
+
+--connection server_2
+SET debug_sync='now WAIT_FOR reached_pause';
+
+--connection server_1
+INSERT INTO t1 VALUES (34);
+
+--connection server_2
+--let $wait_condition= SELECT COUNT(*) = 1 FROM information_schema.processlist WHERE state like "Waiting for prior transaction to commit"
+--source include/wait_condition.inc
+--connection con_temp2
+COMMIT;
+
+# Clean up.
+--connection server_2
+--source include/stop_slave.inc
+--let $assert_cond= COUNT(*) = 0 FROM t1 WHERE a>32
+--let $assert_text= table t1 should have zero rows where a>32
+--source include/assert.inc
+SELECT * FROM t1 WHERE a>32;
+DELETE FROM t1 WHERE a=32;
+
+SET GLOBAL slave_parallel_threads=@old_parallel_threads;
+SET GLOBAL slave_parallel_mode=@old_parallel_mode;
+SET GLOBAL debug_dbug=@old_debug;
+SET DEBUG_SYNC= 'RESET';
+--source include/start_slave.inc
+
+--connection server_1
+DROP TABLE t1;
+--disable_connect_log
+--source include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/r/rpl_parallel_ignored_errors.result b/mysql-test/suite/rpl/r/rpl_parallel_ignored_errors.result
new file mode 100644
index 00000000000..570d2534ed7
--- /dev/null
+++ b/mysql-test/suite/rpl/r/rpl_parallel_ignored_errors.result
@@ -0,0 +1,50 @@
+include/master-slave.inc
+[connection master]
+connection server_2;
+include/stop_slave.inc
+SET @old_parallel_threads=@@GLOBAL.slave_parallel_threads;
+SET @old_parallel_mode=@@GLOBAL.slave_parallel_mode;
+SET @old_dbug= @@GLOBAL.debug_dbug;
+SET GLOBAL slave_parallel_mode='optimistic';
+SET GLOBAL slave_parallel_threads= 3;
+CHANGE MASTER TO master_use_gtid=slave_pos;
+CALL mtr.add_suppression("Commit failed due to failure of an earlier commit on which this one depends");
+include/start_slave.inc
+connection server_1;
+ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB;
+CREATE TABLE t1 (a int PRIMARY KEY) ENGINE=InnoDB;
+include/save_master_gtid.inc
+connection server_2;
+include/sync_with_master_gtid.inc
+connect con_temp2,127.0.0.1,root,,test,$SERVER_MYPORT_2,;
+BEGIN;
+INSERT INTO t1 VALUES (32);
+connection server_1;
+INSERT INTO t1 VALUES (32);
+connection server_2;
+SET GLOBAL debug_dbug="+d,hold_worker_on_schedule";
+SET debug_sync="debug_sync_action SIGNAL reached_pause WAIT_FOR continue_worker";
+connection server_1;
+SET gtid_seq_no=100;
+INSERT INTO t1 VALUES (33);
+connection server_2;
+SET debug_sync='now WAIT_FOR reached_pause';
+connection server_1;
+INSERT INTO t1 VALUES (34);
+connection server_2;
+connection con_temp2;
+COMMIT;
+connection server_2;
+include/stop_slave.inc
+include/assert.inc [table t1 should have zero rows where a>32]
+SELECT * FROM t1 WHERE a>32;
+a
+DELETE FROM t1 WHERE a=32;
+SET GLOBAL slave_parallel_threads=@old_parallel_threads;
+SET GLOBAL slave_parallel_mode=@old_parallel_mode;
+SET GLOBAL debug_dbug=@old_debug;
+SET DEBUG_SYNC= 'RESET';
+include/start_slave.inc
+connection server_1;
+DROP TABLE t1;
+include/rpl_end.inc
diff --git a/mysql-test/suite/rpl/t/rpl_parallel_ignored_errors.test b/mysql-test/suite/rpl/t/rpl_parallel_ignored_errors.test
new file mode 100644
index 00000000000..90f09a76546
--- /dev/null
+++ b/mysql-test/suite/rpl/t/rpl_parallel_ignored_errors.test
@@ -0,0 +1 @@
+--source include/rpl_parallel_ignored_errors.inc
diff --git a/mysql-test/t/myisam.test b/mysql-test/t/myisam.test
index 0eb6a746ee0..217789fccb2 100644
--- a/mysql-test/t/myisam.test
+++ b/mysql-test/t/myisam.test
@@ -1792,3 +1792,22 @@ drop table t1;
#
show variables like 'myisam_block_size';
select @@global.myisam_block_size;
+
+
+--echo #
+--echo # MDEV-20704 An index on a double column erroneously uses prefix compression
+--echo #
+
+CREATE TABLE t1 (
+ id INT NOT NULL PRIMARY KEY,
+ d DOUBLE,
+ KEY (d)
+) ENGINE=MyISAM;
+let $MYSQLD_DATADIR= `select @@datadir`;
+--replace_result $MYSQLD_DATADIR MYSQLD_DATADIR
+--exec $MYISAMCHK -d $MYSQLD_DATADIR/test/t1
+DROP TABLE t1;
+
+--echo #
+--echo # End of 5.5 tests
+--echo #
diff --git a/sql/rpl_parallel.cc b/sql/rpl_parallel.cc
index 6340e4d7cc6..027aa5f628c 100644
--- a/sql/rpl_parallel.cc
+++ b/sql/rpl_parallel.cc
@@ -228,6 +228,12 @@ finish_event_group(rpl_parallel_thread *rpt, uint64 sub_id,
entry->stop_on_error_sub_id == (uint64)ULONGLONG_MAX)
entry->stop_on_error_sub_id= sub_id;
mysql_mutex_unlock(&entry->LOCK_parallel_entry);
+ DBUG_EXECUTE_IF("hold_worker_on_schedule", {
+ if (entry->stop_on_error_sub_id < (uint64)ULONGLONG_MAX)
+ {
+ debug_sync_set_action(thd, STRING_WITH_LEN("now SIGNAL continue_worker"));
+ }
+ });
DBUG_EXECUTE_IF("rpl_parallel_simulate_wait_at_retry", {
if (rgi->current_gtid.seq_no == 1000) {
@@ -1138,6 +1144,13 @@ handle_rpl_parallel_thread(void *arg)
bool did_enter_cond= false;
PSI_stage_info old_stage;
+ DBUG_EXECUTE_IF("hold_worker_on_schedule", {
+ if (rgi->current_gtid.domain_id == 0 &&
+ rgi->current_gtid.seq_no == 100) {
+ debug_sync_set_action(thd,
+ STRING_WITH_LEN("now SIGNAL reached_pause WAIT_FOR continue_worker"));
+ }
+ });
DBUG_EXECUTE_IF("rpl_parallel_scheduled_gtid_0_x_100", {
if (rgi->current_gtid.domain_id == 0 &&
rgi->current_gtid.seq_no == 100) {
@@ -1179,7 +1192,10 @@ handle_rpl_parallel_thread(void *arg)
skip_event_group= do_gco_wait(rgi, gco, &did_enter_cond, &old_stage);
if (unlikely(entry->stop_on_error_sub_id <= rgi->wait_commit_sub_id))
+ {
skip_event_group= true;
+ rgi->worker_error= 1;
+ }
if (likely(!skip_event_group))
do_ftwrl_wait(rgi, &did_enter_cond, &old_stage);
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 7b71973887e..1d135ca83f8 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -4038,16 +4038,16 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
/* Use packed keys for long strings on the first column */
if (!((*db_options) & HA_OPTION_NO_PACK_KEYS) &&
!((create_info->table_options & HA_OPTION_NO_PACK_KEYS)) &&
- (key_part_length >= KEY_DEFAULT_PACK_LENGTH &&
- (sql_field->sql_type == MYSQL_TYPE_STRING ||
- sql_field->sql_type == MYSQL_TYPE_VARCHAR ||
- sql_field->pack_flag & FIELDFLAG_BLOB)))
+ (key_part_length >= KEY_DEFAULT_PACK_LENGTH &&
+ (sql_field->sql_type == MYSQL_TYPE_STRING ||
+ sql_field->sql_type == MYSQL_TYPE_VARCHAR ||
+ f_is_blob(sql_field->pack_flag))))
{
- if ((column_nr == 0 && (sql_field->pack_flag & FIELDFLAG_BLOB)) ||
+ if ((column_nr == 0 && f_is_blob(sql_field->pack_flag)) ||
sql_field->sql_type == MYSQL_TYPE_VARCHAR)
- key_info->flags|= HA_BINARY_PACK_KEY | HA_VAR_LENGTH_KEY;
- else
- key_info->flags|= HA_PACK_KEY;
+ key_info->flags|= HA_BINARY_PACK_KEY | HA_VAR_LENGTH_KEY;
+ else
+ key_info->flags|= HA_PACK_KEY;
}
/* Check if the key segment is partial, set the key flag accordingly */
if (key_part_length != sql_field->key_length)
diff --git a/support-files/rpm/server-preun.sh b/support-files/rpm/server-preun.sh
index 1d733a7d899..038f601f43c 100644
--- a/support-files/rpm/server-preun.sh
+++ b/support-files/rpm/server-preun.sh
@@ -9,7 +9,7 @@ if [ $1 = 0 ] ; then
%{_sysconfdir}/init.d/mysql stop > /dev/null
fi
if [ -x /sbin/chkconfig ] ; then
- /sbin/chkconfig --del mysql > /dev/null 2>&1
+ /sbin/chkconfig --del mysql > /dev/null 2>&1 || :
fi
fi