From cce2b45c8f5b3245d2e63d2763aeec59153d2c6f Mon Sep 17 00:00:00 2001 From: Andrei Elkin Date: Thu, 10 Jan 2019 16:32:56 +0200 Subject: [PATCH 1/3] MDEV-17803 Row-based event is not applied when table map id is greater 32 bit int Row-based slave applier could not parse correctly the table id when the value exceeded the max of 32 bit unsigned int. The reason turns out in that the being parsed value placeholder was sized as 4 bytes. The type is fixed to ulonglong. Additionally the patch works around Rows_log_event::m_table_id 4 bytes size on 32 bits platforms. In case of last_table_id value overflows the 4 byte max, there won't be the zero value for m_table_id generated and the first wrapped-around value is one, this is thanks to excluding UINT_MAX32 + 1 from TABLE_SHARE::table_map_id. --- .../rpl/r/rpl_row_big_table_id_32bit.result | 38 +++++++++++++ .../rpl/r/rpl_row_big_table_id_64bit.result | 38 +++++++++++++ .../suite/rpl/t/rpl_row_big_table_id.inc | 56 +++++++++++++++++++ .../rpl/t/rpl_row_big_table_id_32bit.test | 11 ++++ .../rpl/t/rpl_row_big_table_id_64bit.test | 11 ++++ sql/table.h | 2 +- sql/table_cache.cc | 5 +- 7 files changed, 159 insertions(+), 2 deletions(-) create mode 100644 mysql-test/suite/rpl/r/rpl_row_big_table_id_32bit.result create mode 100644 mysql-test/suite/rpl/r/rpl_row_big_table_id_64bit.result create mode 100644 mysql-test/suite/rpl/t/rpl_row_big_table_id.inc create mode 100644 mysql-test/suite/rpl/t/rpl_row_big_table_id_32bit.test create mode 100644 mysql-test/suite/rpl/t/rpl_row_big_table_id_64bit.test diff --git a/mysql-test/suite/rpl/r/rpl_row_big_table_id_32bit.result b/mysql-test/suite/rpl/r/rpl_row_big_table_id_32bit.result new file mode 100644 index 00000000000..f84f02cc416 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_row_big_table_id_32bit.result @@ -0,0 +1,38 @@ +include/master-slave.inc +[connection master] +include/rpl_restart_server.inc [server_number=1] +SET @@debug_dbug="d,simulate_big_table_id"; +CREATE TABLE t (a int); +INSERT INTO t SET a= 0; +ALTER TABLE t comment ''; +INSERT INTO t SET a= 1; +ALTER TABLE t comment ''; +INSERT INTO t SET a= 2; +ALTER TABLE t comment ''; +INSERT INTO t SET a= 3; +show binlog events in from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000002 # Gtid 1 # BEGIN GTID #-#-# +master-bin.000002 # Table_map 1 # table_id: 4294967294 (test.t) +master-bin.000002 # Write_rows_v1 1 # table_id: 4294967294 flags: STMT_END_F +master-bin.000002 # Query 1 # COMMIT +master-bin.000002 # Gtid 1 # GTID #-#-# +master-bin.000002 # Query 1 # use `test`; ALTER TABLE t comment '' +master-bin.000002 # Gtid 1 # BEGIN GTID #-#-# +master-bin.000002 # Table_map 1 # table_id: 1 (test.t) +master-bin.000002 # Write_rows_v1 1 # table_id: 1 flags: STMT_END_F +master-bin.000002 # Query 1 # COMMIT +master-bin.000002 # Gtid 1 # GTID #-#-# +master-bin.000002 # Query 1 # use `test`; ALTER TABLE t comment '' +master-bin.000002 # Gtid 1 # BEGIN GTID #-#-# +master-bin.000002 # Table_map 1 # table_id: 2 (test.t) +master-bin.000002 # Write_rows_v1 1 # table_id: 2 flags: STMT_END_F +master-bin.000002 # Query 1 # COMMIT +master-bin.000002 # Gtid 1 # GTID #-#-# +master-bin.000002 # Query 1 # use `test`; ALTER TABLE t comment '' +master-bin.000002 # Gtid 1 # BEGIN GTID #-#-# +master-bin.000002 # Table_map 1 # table_id: 3 (test.t) +master-bin.000002 # Write_rows_v1 1 # table_id: 3 flags: STMT_END_F +master-bin.000002 # Query 1 # COMMIT +DROP TABLE t; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_row_big_table_id_64bit.result b/mysql-test/suite/rpl/r/rpl_row_big_table_id_64bit.result new file mode 100644 index 00000000000..d8ecadc61d1 --- /dev/null +++ b/mysql-test/suite/rpl/r/rpl_row_big_table_id_64bit.result @@ -0,0 +1,38 @@ +include/master-slave.inc +[connection master] +include/rpl_restart_server.inc [server_number=1] +SET @@debug_dbug="d,simulate_big_table_id"; +CREATE TABLE t (a int); +INSERT INTO t SET a= 0; +ALTER TABLE t comment ''; +INSERT INTO t SET a= 1; +ALTER TABLE t comment ''; +INSERT INTO t SET a= 2; +ALTER TABLE t comment ''; +INSERT INTO t SET a= 3; +show binlog events in from ; +Log_name Pos Event_type Server_id End_log_pos Info +master-bin.000002 # Gtid 1 # BEGIN GTID #-#-# +master-bin.000002 # Table_map 1 # table_id: 4294967294 (test.t) +master-bin.000002 # Write_rows_v1 1 # table_id: 4294967294 flags: STMT_END_F +master-bin.000002 # Query 1 # COMMIT +master-bin.000002 # Gtid 1 # GTID #-#-# +master-bin.000002 # Query 1 # use `test`; ALTER TABLE t comment '' +master-bin.000002 # Gtid 1 # BEGIN GTID #-#-# +master-bin.000002 # Table_map 1 # table_id: 4294967295 (test.t) +master-bin.000002 # Write_rows_v1 1 # table_id: 4294967295 flags: STMT_END_F +master-bin.000002 # Query 1 # COMMIT +master-bin.000002 # Gtid 1 # GTID #-#-# +master-bin.000002 # Query 1 # use `test`; ALTER TABLE t comment '' +master-bin.000002 # Gtid 1 # BEGIN GTID #-#-# +master-bin.000002 # Table_map 1 # table_id: 4294967296 (test.t) +master-bin.000002 # Write_rows_v1 1 # table_id: 4294967296 flags: STMT_END_F +master-bin.000002 # Query 1 # COMMIT +master-bin.000002 # Gtid 1 # GTID #-#-# +master-bin.000002 # Query 1 # use `test`; ALTER TABLE t comment '' +master-bin.000002 # Gtid 1 # BEGIN GTID #-#-# +master-bin.000002 # Table_map 1 # table_id: 4294967297 (test.t) +master-bin.000002 # Write_rows_v1 1 # table_id: 4294967297 flags: STMT_END_F +master-bin.000002 # Query 1 # COMMIT +DROP TABLE t; +include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_row_big_table_id.inc b/mysql-test/suite/rpl/t/rpl_row_big_table_id.inc new file mode 100644 index 00000000000..926b6e8b0ac --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_row_big_table_id.inc @@ -0,0 +1,56 @@ +################################################################## +# rpl_row_big_table_id +# +# MDEV-17803 Row-based event is not applied when +# table map id is greater 32 bit int +# +# Verify row-based events applying when table map id value is about and greater +# than 1 << 32. +################################################################## +--source include/have_debug.inc +--source include/have_binlog_format_row.inc +--source include/master-slave.inc + +--connection master +# To reset last table id +--let $rpl_server_number= 1 +--source include/rpl_restart_server.inc + +SET @@debug_dbug="d,simulate_big_table_id"; +CREATE TABLE t (a int); + +--let $binlog_file= query_get_value(SHOW MASTER STATUS, File, 1) +--let $binlog_pos= query_get_value(SHOW MASTER STATUS, Position, 1) +INSERT INTO t SET a= 0; +ALTER TABLE t comment ''; +INSERT INTO t SET a= 1; +ALTER TABLE t comment ''; +INSERT INTO t SET a= 2; +ALTER TABLE t comment ''; +INSERT INTO t SET a= 3; + +# display simulated big table_id +--let $_in_from=in '$binlog_file' from $binlog_pos +--replace_result "$_in_from" "in from " +--replace_column 2 # 5 # +--replace_regex /\/\* xid=.* \*\//\/* XID *\// /file_id=[0-9]+/file_id=#/ /GTID [0-9]+-[0-9]+-[0-9]+/GTID #-#-#/ +--eval show binlog events in '$binlog_file' from $binlog_pos + + +--sync_slave_with_master + +if (`SELECT sum(a) != 6 FROM t`) +{ + --echo *** unexpected result; check slave applier *** + --die +} + + +# Cleanup + +--connection master +DROP TABLE t; + +--sync_slave_with_master + +--source include/rpl_end.inc diff --git a/mysql-test/suite/rpl/t/rpl_row_big_table_id_32bit.test b/mysql-test/suite/rpl/t/rpl_row_big_table_id_32bit.test new file mode 100644 index 00000000000..08e1827c4c6 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_row_big_table_id_32bit.test @@ -0,0 +1,11 @@ +################################################################## +# rpl_row_big_table_id +# +# MDEV-17803 Row-based event is not applied when +# table map id is greater 32 bit int +# +# Verify row-based events applying when table map id value is about and greater +# than 1 << 32. +################################################################## +--source include/have_32bit.inc +--source rpl_row_big_table_id.inc diff --git a/mysql-test/suite/rpl/t/rpl_row_big_table_id_64bit.test b/mysql-test/suite/rpl/t/rpl_row_big_table_id_64bit.test new file mode 100644 index 00000000000..f9e021cdd2c --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_row_big_table_id_64bit.test @@ -0,0 +1,11 @@ +################################################################## +# rpl_row_big_table_id +# +# MDEV-17803 Row-based event is not applied when +# table map id is greater 32 bit int +# +# Verify row-based events applying when table map id value is about and greater +# than 1 << 32. +################################################################## +--source include/have_64bit.inc +--source rpl_row_big_table_id.inc diff --git a/sql/table.h b/sql/table.h index 4a1552f8c0d..10c1d1bc68e 100644 --- a/sql/table.h +++ b/sql/table.h @@ -1816,7 +1816,7 @@ struct TABLE_LIST /* Index names in a "... JOIN ... USE/IGNORE INDEX ..." clause. */ List *index_hints; TABLE *table; /* opened table */ - uint table_id; /* table id (from binlog) for opened table */ + ulonglong table_id; /* table id (from binlog) for opened table */ /* select_result for derived table to pass it from table creation to table filling procedure diff --git a/sql/table_cache.cc b/sql/table_cache.cc index f13d7183a99..1154017d8d5 100644 --- a/sql/table_cache.cc +++ b/sql/table_cache.cc @@ -1206,6 +1206,9 @@ void tdc_assign_new_table_id(TABLE_SHARE *share) DBUG_ASSERT(share); DBUG_ASSERT(tdc_inited); + DBUG_EXECUTE_IF("simulate_big_table_id", + if (last_table_id < UINT_MAX32) + last_table_id= UINT_MAX32 - 1;); /* There is one reserved number that cannot be used. Remember to change this when 6-byte global table id's are introduced. @@ -1215,7 +1218,7 @@ void tdc_assign_new_table_id(TABLE_SHARE *share) my_atomic_rwlock_wrlock(&LOCK_tdc_atomics); tid= my_atomic_add64(&last_table_id, 1); my_atomic_rwlock_wrunlock(&LOCK_tdc_atomics); - } while (unlikely(tid == ~0UL)); + } while (unlikely(tid == ~0UL || tid == 0)); share->table_map_id= tid; DBUG_PRINT("info", ("table_id= %lu", share->table_map_id)); From a0f3b9f94f3094ccb9ce75c53b25d36c4c78e922 Mon Sep 17 00:00:00 2001 From: Thirunarayanan Balathandayuthapani Date: Thu, 24 Jan 2019 13:52:51 +0530 Subject: [PATCH 2/3] MDEV-17376 Server fails to set ADD_PK_INDEX, DROP_PK_INDEX if unique index nominated as PK Problem: ======== Server fails to notify the engine by not setting the ADD_PK_INDEX and DROP_PK_INDEX When there is a i) Change in candidate for primary key. ii) New candidate for primary key. Fix: ==== Server sets the ADD_PK_INDEX and DROP_PK_INDEX while doing alter for the above problematic case. --- .../suite/innodb/r/alter_candidate_key.result | 107 ++++++++++++++++++ .../suite/innodb/r/innodb-table-online.result | 11 -- .../suite/innodb/t/alter_candidate_key.test | 72 ++++++++++++ .../suite/innodb/t/innodb-table-online.test | 4 - sql/sql_table.cc | 17 +++ 5 files changed, 196 insertions(+), 15 deletions(-) create mode 100644 mysql-test/suite/innodb/r/alter_candidate_key.result create mode 100644 mysql-test/suite/innodb/t/alter_candidate_key.test diff --git a/mysql-test/suite/innodb/r/alter_candidate_key.result b/mysql-test/suite/innodb/r/alter_candidate_key.result new file mode 100644 index 00000000000..b0b8e390c7e --- /dev/null +++ b/mysql-test/suite/innodb/r/alter_candidate_key.result @@ -0,0 +1,107 @@ +CREATE TABLE t1 (f1 INT NOT NULL, f2 INT NOT NULL, +UNIQUE KEY uidx2(f1,f2), +UNIQUE KEY uidx1(f2)) ENGINE=InnoDB; +INSERT INTO t1 VALUES(1, 1); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f1` int(11) NOT NULL, + `f2` int(11) NOT NULL, + UNIQUE KEY `uidx2` (`f1`,`f2`), + UNIQUE KEY `uidx1` (`f2`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SET DEBUG_SYNC = 'innodb_inplace_alter_table_enter + SIGNAL conc_dml WAIT_FOR go_ahead'; +ALTER TABLE t1 CHANGE COLUMN f1 f11 INT, ALGORITHM=INPLACE; +SET DEBUG_SYNC = 'now WAIT_FOR conc_dml'; +DELETE FROM t1; +SET DEBUG_SYNC = 'now SIGNAL go_ahead'; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f11` int(11) DEFAULT NULL, + `f2` int(11) NOT NULL, + UNIQUE KEY `uidx1` (`f2`), + UNIQUE KEY `uidx2` (`f11`,`f2`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +DROP TABLE t1; +CREATE TABLE t1(f1 INT, f2 INT, +PRIMARY KEY(f1, f2), +UNIQUE INDEX uidx2 (f1, f2), +UNIQUE INDEX uidx1 (f2))ENGINE=InnoDB; +ALTER TABLE t1 DROP PRIMARY KEY; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f1` int(11) NOT NULL DEFAULT '0', + `f2` int(11) NOT NULL DEFAULT '0', + UNIQUE KEY `uidx2` (`f1`,`f2`), + UNIQUE KEY `uidx1` (`f2`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +SET DEBUG_SYNC = 'innodb_inplace_alter_table_enter + SIGNAL conc_dml WAIT_FOR go_ahead'; +ALTER TABLE t1 CHANGE COLUMN f1 f11 INT, ALGORITHM=INPLACE; +SET DEBUG_SYNC = 'now WAIT_FOR conc_dml'; +INSERT INTO t1 VALUES(1, 1), (1, 1); +ERROR 23000: Duplicate entry '1-1' for key 'uidx2' +SET DEBUG_SYNC = 'now SIGNAL go_ahead'; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f11` int(11) DEFAULT NULL, + `f2` int(11) NOT NULL DEFAULT '0', + UNIQUE KEY `uidx1` (`f2`), + UNIQUE KEY `uidx2` (`f11`,`f2`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +CHECK TABLE t1; +Table Op Msg_type Msg_text +test.t1 check status OK +DROP TABLE t1; +SET SQL_MODE= strict_trans_tables; +CREATE TABLE t1(a INT UNIQUE) ENGINE=InnoDB; +SET DEBUG_SYNC='row_log_table_apply1_before SIGNAL dml WAIT_FOR dml_done'; +ALTER TABLE t1 MODIFY COLUMN a INT NOT NULL; +SET DEBUG_SYNC='now WAIT_FOR dml'; +BEGIN; +INSERT INTO t1 SET a=NULL; +ROLLBACK; +set DEBUG_SYNC='now SIGNAL dml_done'; +ERROR 22004: Invalid use of NULL value +DROP TABLE t1; +SET DEBUG_SYNC="RESET"; +SET SQL_MODE=DEFAULT; +CREATE TABLE t1(f1 INT NOT NULL, f2 INT NOT NULL, PRIMARY KEY(f1, f2), +UNIQUE KEY(f2))ENGINE=InnoDB; +ALTER TABLE t1 DROP PRIMARY KEY; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f1` int(11) NOT NULL, + `f2` int(11) NOT NULL, + UNIQUE KEY `f2` (`f2`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +DROP TABLE t1; +CREATE TABLE t1(f1 INT NOT NULL, f2 INT NOT NULL, +UNIQUE KEY(f2), UNIQUE KEY(f2))ENGINE=InnoDB; +Warnings: +Note 1831 Duplicate index `f2_2`. This is deprecated and will be disallowed in a future release. +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f1` int(11) NOT NULL, + `f2` int(11) NOT NULL, + UNIQUE KEY `f2` (`f2`), + UNIQUE KEY `f2_2` (`f2`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +ALTER TABLE t1 DROP INDEX f2, ALGORITHM=INPLACE; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f1` int(11) NOT NULL, + `f2` int(11) NOT NULL, + UNIQUE KEY `f2_2` (`f2`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/r/innodb-table-online.result b/mysql-test/suite/innodb/r/innodb-table-online.result index eb55ba57e36..0a8d1c2fefb 100644 --- a/mysql-test/suite/innodb/r/innodb-table-online.result +++ b/mysql-test/suite/innodb/r/innodb-table-online.result @@ -85,17 +85,6 @@ t1 CREATE TABLE `t1` ( UNIQUE KEY `c2` (`c2`), UNIQUE KEY `c2_2` (`c2`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT -ALTER TABLE t1 DROP INDEX c2, ALGORITHM = INPLACE; -ERROR 0A000: ALGORITHM=INPLACE is not supported. Reason: Dropping a primary key is not allowed without also adding a new primary key. Try ALGORITHM=COPY. -SHOW CREATE TABLE t1; -Table Create Table -t1 CREATE TABLE `t1` ( - `c1` int(11) NOT NULL, - `c2` int(11) NOT NULL, - `c3` text NOT NULL, - UNIQUE KEY `c2` (`c2`), - UNIQUE KEY `c2_2` (`c2`) -) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPACT ALTER TABLE t1 DROP INDEX c2, ADD PRIMARY KEY(c1); # session default SET DEBUG_SYNC = 'now WAIT_FOR scanned'; diff --git a/mysql-test/suite/innodb/t/alter_candidate_key.test b/mysql-test/suite/innodb/t/alter_candidate_key.test new file mode 100644 index 00000000000..7429cd89a1a --- /dev/null +++ b/mysql-test/suite/innodb/t/alter_candidate_key.test @@ -0,0 +1,72 @@ +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc + +CREATE TABLE t1 (f1 INT NOT NULL, f2 INT NOT NULL, + UNIQUE KEY uidx2(f1,f2), + UNIQUE KEY uidx1(f2)) ENGINE=InnoDB; +INSERT INTO t1 VALUES(1, 1); +SHOW CREATE TABLE t1; +SET DEBUG_SYNC = 'innodb_inplace_alter_table_enter + SIGNAL conc_dml WAIT_FOR go_ahead'; +--send ALTER TABLE t1 CHANGE COLUMN f1 f11 INT, ALGORITHM=INPLACE +connect (con1,localhost,root,,); +SET DEBUG_SYNC = 'now WAIT_FOR conc_dml'; +DELETE FROM t1; +SET DEBUG_SYNC = 'now SIGNAL go_ahead'; +connection default; +reap; +SHOW CREATE TABLE t1; +CHECK TABLE t1; +DROP TABLE t1; + +CREATE TABLE t1(f1 INT, f2 INT, + PRIMARY KEY(f1, f2), + UNIQUE INDEX uidx2 (f1, f2), + UNIQUE INDEX uidx1 (f2))ENGINE=InnoDB; +ALTER TABLE t1 DROP PRIMARY KEY; +SHOW CREATE TABLE t1; +SET DEBUG_SYNC = 'innodb_inplace_alter_table_enter + SIGNAL conc_dml WAIT_FOR go_ahead'; +--send ALTER TABLE t1 CHANGE COLUMN f1 f11 INT, ALGORITHM=INPLACE +connection con1; +SET DEBUG_SYNC = 'now WAIT_FOR conc_dml'; +--error ER_DUP_ENTRY +INSERT INTO t1 VALUES(1, 1), (1, 1); +SET DEBUG_SYNC = 'now SIGNAL go_ahead'; +connection default; +reap; +SHOW CREATE TABLE t1; +CHECK TABLE t1; +DROP TABLE t1; + +SET SQL_MODE= strict_trans_tables; +CREATE TABLE t1(a INT UNIQUE) ENGINE=InnoDB; +SET DEBUG_SYNC='row_log_table_apply1_before SIGNAL dml WAIT_FOR dml_done'; +--send ALTER TABLE t1 MODIFY COLUMN a INT NOT NULL +connection con1; +SET DEBUG_SYNC='now WAIT_FOR dml'; +BEGIN; +INSERT INTO t1 SET a=NULL; +ROLLBACK; +set DEBUG_SYNC='now SIGNAL dml_done'; +connection default; +--error ER_INVALID_USE_OF_NULL +reap; +DROP TABLE t1; +disconnect con1; +SET DEBUG_SYNC="RESET"; +SET SQL_MODE=DEFAULT; + +CREATE TABLE t1(f1 INT NOT NULL, f2 INT NOT NULL, PRIMARY KEY(f1, f2), + UNIQUE KEY(f2))ENGINE=InnoDB; +ALTER TABLE t1 DROP PRIMARY KEY; +SHOW CREATE TABLE t1; +DROP TABLE t1; + +CREATE TABLE t1(f1 INT NOT NULL, f2 INT NOT NULL, + UNIQUE KEY(f2), UNIQUE KEY(f2))ENGINE=InnoDB; +SHOW CREATE TABLE t1; +ALTER TABLE t1 DROP INDEX f2, ALGORITHM=INPLACE; +SHOW CREATE TABLE t1; +DROP TABLE t1; diff --git a/mysql-test/suite/innodb/t/innodb-table-online.test b/mysql-test/suite/innodb/t/innodb-table-online.test index 4e9f2f13344..b0711412a52 100644 --- a/mysql-test/suite/innodb/t/innodb-table-online.test +++ b/mysql-test/suite/innodb/t/innodb-table-online.test @@ -100,10 +100,6 @@ LOCK = SHARED, ALGORITHM = INPLACE; ALTER TABLE t1 ADD UNIQUE INDEX(c2), LOCK = EXCLUSIVE, ALGORITHM = INPLACE; -SHOW CREATE TABLE t1; -# We do not support plain DROP_PK_INDEX without ADD_PK_INDEX. ---error ER_ALTER_OPERATION_NOT_SUPPORTED_REASON -ALTER TABLE t1 DROP INDEX c2, ALGORITHM = INPLACE; SHOW CREATE TABLE t1; # Now the previous DEBUG_SYNC should kick in. --send diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 2302026b18b..df1ff8eaf5d 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -6439,6 +6439,12 @@ static bool fill_alter_inplace_info(THD *thd, KEY *new_key; KEY *new_key_end= ha_alter_info->key_info_buffer + ha_alter_info->key_count; + /* + Primary key index for the new table + */ + const KEY* const new_pk= (ha_alter_info->key_count > 0 && + is_candidate_key(ha_alter_info->key_info_buffer)) ? + ha_alter_info->key_info_buffer : NULL; DBUG_PRINT("info", ("index count old: %d new: %d", table->s->keys, ha_alter_info->key_count)); @@ -6513,6 +6519,17 @@ static bool fill_alter_inplace_info(THD *thd, new_field->field->field_index != key_part->fieldnr - 1) goto index_changed; } + + /* + Rebuild the index if following condition get satisfied: + + (i) Old table doesn't have primary key, new table has it and vice-versa + (ii) Primary key changed to another existing index + */ + if ((new_key == new_pk) != + ((uint) (table_key - table->key_info) == table->s->primary_key)) + goto index_changed; + continue; index_changed: From edeba0c8733409865c3abcab881af0d48b7be94f Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Wed, 23 Jan 2019 18:50:47 +0100 Subject: [PATCH 3/3] MDEV-17868 mysqltest fails to link with system PCRE libraries pcre needs symbols from pcreposix (but this is only an issue when linking with system static libraries) --- client/CMakeLists.txt | 2 +- libmysqld/examples/CMakeLists.txt | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/client/CMakeLists.txt b/client/CMakeLists.txt index c75abd4956d..c760a9dbf14 100644 --- a/client/CMakeLists.txt +++ b/client/CMakeLists.txt @@ -41,7 +41,7 @@ ENDIF(UNIX) MYSQL_ADD_EXECUTABLE(mysqltest mysqltest.cc COMPONENT Test) SET_SOURCE_FILES_PROPERTIES(mysqltest.cc PROPERTIES COMPILE_FLAGS "-DTHREADS") -TARGET_LINK_LIBRARIES(mysqltest mysqlclient pcre pcreposix) +TARGET_LINK_LIBRARIES(mysqltest mysqlclient pcreposix pcre) SET_TARGET_PROPERTIES(mysqltest PROPERTIES ENABLE_EXPORTS TRUE) diff --git a/libmysqld/examples/CMakeLists.txt b/libmysqld/examples/CMakeLists.txt index d47638ad2f9..1eb07a2adf8 100644 --- a/libmysqld/examples/CMakeLists.txt +++ b/libmysqld/examples/CMakeLists.txt @@ -34,7 +34,7 @@ ENDIF(UNIX) MYSQL_ADD_EXECUTABLE(mysqltest_embedded ../../client/mysqltest.cc COMPONENT Test) -TARGET_LINK_LIBRARIES(mysqltest_embedded mysqlserver pcre pcreposix) +TARGET_LINK_LIBRARIES(mysqltest_embedded mysqlserver pcreposix pcre) IF(CMAKE_GENERATOR MATCHES "Xcode") # It does not seem possible to tell Xcode the resulting target might need