diff --git a/client/mysqladmin.cc b/client/mysqladmin.cc index 6a5ac0a2611..45b332a6cd6 100644 --- a/client/mysqladmin.cc +++ b/client/mysqladmin.cc @@ -47,6 +47,7 @@ static uint opt_count_iterations= 0, my_end_arg; static ulong opt_connect_timeout, opt_shutdown_timeout; static char * unix_port=0; static char *opt_plugin_dir= 0, *opt_default_auth= 0; +static bool sql_log_bin_off= false; #ifdef HAVE_SMEM static char *shared_memory_base_name=0; @@ -600,6 +601,31 @@ static my_bool sql_connect(MYSQL *mysql, uint wait) } +static int maybe_disable_binlog(MYSQL *mysql) +{ + if (opt_local && !sql_log_bin_off) + { + if (mysql_query(mysql, "set local sql_log_bin=0")) + { + my_printf_error(0, "SET LOCAL SQL_LOG_BIN=0 failed; error: '%-.200s'", + error_flags, mysql_error(mysql)); + return -1; + } + } + sql_log_bin_off= true; + return 0; +} + + +int flush(MYSQL *mysql, const char *what) +{ + char buf[FN_REFLEN]; + my_snprintf(buf, sizeof(buf), "flush %s%s", + (opt_local && !sql_log_bin_off ? "local " : ""), what); + return mysql_query(mysql, buf); +} + + /** @brief Execute all commands @@ -629,17 +655,6 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) struct my_rnd_struct rand_st; char buff[FN_REFLEN + 20]; - if (opt_local) - { - sprintf(buff, "set local sql_log_bin=0"); - if (mysql_query(mysql, buff)) - { - my_printf_error(0, "SET LOCAL SQL_LOG_BIN=0 failed; error: '%-.200s'", - error_flags, mysql_error(mysql)); - return -1; - } - } - for (; argc > 0 ; argv++,argc--) { int command; @@ -651,6 +666,8 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) my_printf_error(0, "Too few arguments to create", error_flags); return 1; } + if (maybe_disable_binlog(mysql)) + return -1; sprintf(buff,"create database `%.*s`",FN_REFLEN,argv[1]); if (mysql_query(mysql,buff)) { @@ -668,6 +685,8 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) my_printf_error(0, "Too few arguments to drop", error_flags); return 1; } + if (maybe_disable_binlog(mysql)) + return -1; if (drop_db(mysql,argv[1])) return -1; argc--; argv++; @@ -708,7 +727,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) } case ADMIN_FLUSH_PRIVILEGES: case ADMIN_RELOAD: - if (mysql_query(mysql,"flush privileges")) + if (flush(mysql, "privileges")) { my_printf_error(0, "reload failed; error: '%s'", error_flags, mysql_error(mysql)); @@ -912,7 +931,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) } case ADMIN_FLUSH_LOGS: { - if (mysql_query(mysql,"flush logs")) + if (flush(mysql, "logs")) { my_printf_error(0, "flush failed; error: '%s'", error_flags, mysql_error(mysql)); @@ -922,7 +941,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) } case ADMIN_FLUSH_BINARY_LOG: { - if (mysql_query(mysql, "flush binary logs")) + if (flush(mysql, "binary logs")) { my_printf_error(0, "flush failed; error: '%s'", error_flags, mysql_error(mysql)); @@ -932,7 +951,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) } case ADMIN_FLUSH_ENGINE_LOG: { - if (mysql_query(mysql,"flush engine logs")) + if (flush(mysql, "engine logs")) { my_printf_error(0, "flush failed; error: '%s'", error_flags, mysql_error(mysql)); @@ -942,7 +961,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) } case ADMIN_FLUSH_ERROR_LOG: { - if (mysql_query(mysql, "flush error logs")) + if (flush(mysql, "error logs")) { my_printf_error(0, "flush failed; error: '%s'", error_flags, mysql_error(mysql)); @@ -952,7 +971,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) } case ADMIN_FLUSH_GENERAL_LOG: { - if (mysql_query(mysql, "flush general logs")) + if (flush(mysql, "general logs")) { my_printf_error(0, "flush failed; error: '%s'", error_flags, mysql_error(mysql)); @@ -962,7 +981,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) } case ADMIN_FLUSH_RELAY_LOG: { - if (mysql_query(mysql, "flush relay logs")) + if (flush(mysql, "relay logs")) { my_printf_error(0, "flush failed; error: '%s'", error_flags, mysql_error(mysql)); @@ -972,7 +991,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) } case ADMIN_FLUSH_SLOW_LOG: { - if (mysql_query(mysql,"flush slow logs")) + if (flush(mysql, "slow logs")) { my_printf_error(0, "flush failed; error: '%s'", error_flags, mysql_error(mysql)); @@ -982,7 +1001,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) } case ADMIN_FLUSH_HOSTS: { - if (mysql_query(mysql,"flush hosts")) + if (flush(mysql, "hosts")) { my_printf_error(0, "flush failed; error: '%s'", error_flags, mysql_error(mysql)); @@ -992,7 +1011,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) } case ADMIN_FLUSH_TABLES: { - if (mysql_query(mysql,"flush tables")) + if (flush(mysql, "tables")) { my_printf_error(0, "flush failed; error: '%s'", error_flags, mysql_error(mysql)); @@ -1002,7 +1021,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) } case ADMIN_FLUSH_STATUS: { - if (mysql_query(mysql,"flush status")) + if (flush(mysql, "status")) { my_printf_error(0, "flush failed; error: '%s'", error_flags, mysql_error(mysql)); @@ -1012,7 +1031,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) } case ADMIN_FLUSH_TABLE_STATISTICS: { - if (mysql_query(mysql,"flush table_statistics")) + if (flush(mysql, "table_statistics")) { my_printf_error(0, "flush failed; error: '%s'", error_flags, mysql_error(mysql)); @@ -1022,7 +1041,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) } case ADMIN_FLUSH_INDEX_STATISTICS: { - if (mysql_query(mysql,"flush index_statistics")) + if (flush(mysql, "index_statistics")) { my_printf_error(0, "flush failed; error: '%s'", error_flags, mysql_error(mysql)); @@ -1032,7 +1051,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) } case ADMIN_FLUSH_USER_STATISTICS: { - if (mysql_query(mysql,"flush user_statistics")) + if (flush(mysql, "user_statistics")) { my_printf_error(0, "flush failed; error: '%s'", error_flags, mysql_error(mysql)); @@ -1042,7 +1061,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) } case ADMIN_FLUSH_USER_RESOURCES: { - if (mysql_query(mysql, "flush user_resources")) + if (flush(mysql, "user_resources")) { my_printf_error(0, "flush failed; error: '%s'", error_flags, mysql_error(mysql)); @@ -1052,7 +1071,7 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) } case ADMIN_FLUSH_CLIENT_STATISTICS: { - if (mysql_query(mysql,"flush client_statistics")) + if (flush(mysql, "client_statistics")) { my_printf_error(0, "flush failed; error: '%s'", error_flags, mysql_error(mysql)); @@ -1062,9 +1081,8 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) } case ADMIN_FLUSH_ALL_STATISTICS: { - if (mysql_query(mysql, - "flush table_statistics,index_statistics," - "user_statistics,client_statistics")) + if (flush(mysql, "table_statistics,index_statistics," + "user_statistics,client_statistics")) { my_printf_error(0, "flush failed; error: '%s'", error_flags, mysql_error(mysql)); @@ -1074,9 +1092,8 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) } case ADMIN_FLUSH_ALL_STATUS: { - if (mysql_query(mysql, - "flush status,table_statistics,index_statistics," - "user_statistics,client_statistics")) + if (flush(mysql, "status,table_statistics,index_statistics," + "user_statistics,client_statistics")) { my_printf_error(0, "flush failed; error: '%s'", error_flags, mysql_error(mysql)); @@ -1094,6 +1111,8 @@ static int execute_commands(MYSQL *mysql,int argc, char **argv) start_time=time((time_t*) 0); my_rnd_init(&rand_st,(ulong) start_time,(ulong) start_time/2); + if (maybe_disable_binlog(mysql)) + return -1; if (argc < 1) { my_printf_error(0, "Too few arguments to change password", error_flags); diff --git a/mysql-test/r/alter_table_online.result b/mysql-test/r/alter_table_online.result index b3ef9c354f7..54df4e0c96c 100644 --- a/mysql-test/r/alter_table_online.result +++ b/mysql-test/r/alter_table_online.result @@ -184,6 +184,35 @@ CREATE TABLE t1 (a LONGTEXT COLLATE latin1_general_ci); ALTER TABLE t1 MODIFY a LONGTEXT COLLATE latin1_swedish_ci, ALGORITHM=INPLACE; ERROR 0A000: ALGORITHM=INPLACE is not supported for this operation. Try ALGORITHM=COPY DROP TABLE t1; -# -# End of MDEV-8948 ALTER ... INPLACE does work for BINARY, BLOB -# +select @@global.delay_key_write; +@@global.delay_key_write +ON +create table t1 (a int, b int, key(b)); +flush tables; +flush status; +show status like 'Feature_delay_key_write'; +Variable_name Value +Feature_delay_key_write 0 +insert t1 values (1,2),(2,3),(3,4); +show status like 'Feature_delay_key_write'; +Variable_name Value +Feature_delay_key_write 0 +alter online table t1 delay_key_write=1; +show status like 'Feature_delay_key_write'; +Variable_name Value +Feature_delay_key_write 1 +flush tables; +insert t1 values (1,2),(2,3),(3,4); +show status like 'Feature_delay_key_write'; +Variable_name Value +Feature_delay_key_write 2 +alter online table t1 delay_key_write=0; +show status like 'Feature_delay_key_write'; +Variable_name Value +Feature_delay_key_write 2 +flush tables; +insert t1 values (1,2),(2,3),(3,4); +show status like 'Feature_delay_key_write'; +Variable_name Value +Feature_delay_key_write 2 +drop table t1; diff --git a/mysql-test/r/partition_alter.result b/mysql-test/r/partition_alter.result index cbd90b5ba7c..76b55cefb07 100644 --- a/mysql-test/r/partition_alter.result +++ b/mysql-test/r/partition_alter.result @@ -51,3 +51,50 @@ execute stmt; execute stmt; deallocate prepare stmt; drop table test_data; +create table t1(id int, d date not null, b bool not null default 0, primary key(id,d)) +engine=innodb +partition by range columns (d) ( +partition p1 values less than ('2016-10-18'), +partition p2 values less than ('2020-10-19')); +insert t1 values (0, '2000-01-02', 0); +insert t1 values (1, '2020-01-02', 10); +alter table t1 add check (b in (0, 1)); +ERROR 23000: CONSTRAINT `CONSTRAINT_1` failed for `test`.`#sql-temporary` +alter table t1 add check (b in (0, 10)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(11) NOT NULL, + `d` date NOT NULL, + `b` tinyint(1) NOT NULL DEFAULT 0, + PRIMARY KEY (`id`,`d`), + CONSTRAINT `CONSTRAINT_1` CHECK (`b` in (0,10)) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 + PARTITION BY RANGE COLUMNS(d) +(PARTITION p1 VALUES LESS THAN ('2016-10-18') ENGINE = InnoDB, + PARTITION p2 VALUES LESS THAN ('2020-10-19') ENGINE = InnoDB) +insert t1 values (2, '2020-01-03', 20); +ERROR 23000: CONSTRAINT `CONSTRAINT_1` failed for `test`.`t1` +drop table t1; +create table t1(id int, d date not null, b bool not null default 0, primary key(id,d)) +partition by range columns (d) ( +partition p1 values less than ('2016-10-18'), +partition p2 values less than ('2020-10-19')); +insert t1 values (0, '2000-01-02', 0); +insert t1 values (1, '2020-01-02', 10); +alter table t1 add check (b in (0, 1)); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `id` int(11) NOT NULL, + `d` date NOT NULL, + `b` tinyint(1) NOT NULL DEFAULT 0, + PRIMARY KEY (`id`,`d`), + CONSTRAINT `CONSTRAINT_1` CHECK (`b` in (0,1)) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 + PARTITION BY RANGE COLUMNS(d) +(PARTITION p1 VALUES LESS THAN ('2016-10-18') ENGINE = MyISAM, + PARTITION p2 VALUES LESS THAN ('2020-10-19') ENGINE = MyISAM) +insert t1 values (2, '2020-01-03', 20); +ERROR 23000: CONSTRAINT `CONSTRAINT_1` failed for `test`.`t1` +drop table t1; diff --git a/mysql-test/suite/binlog/r/mysqladmin.result b/mysql-test/suite/binlog/r/mysqladmin.result new file mode 100644 index 00000000000..4be6c96d55b --- /dev/null +++ b/mysql-test/suite/binlog/r/mysqladmin.result @@ -0,0 +1,12 @@ +create user adm@localhost identified by 'foobar'; +grant reload on *.* to adm@localhost; +reset master; +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 # # flush status +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 # # flush status +drop user adm@localhost; diff --git a/mysql-test/suite/binlog/t/mysqladmin.test b/mysql-test/suite/binlog/t/mysqladmin.test new file mode 100644 index 00000000000..3c2fbc0a708 --- /dev/null +++ b/mysql-test/suite/binlog/t/mysqladmin.test @@ -0,0 +1,12 @@ +source include/have_binlog_format_statement.inc; +# +# MDEV-12612 mysqladmin --local flush... to use FLUSH LOCAL +# +create user adm@localhost identified by 'foobar'; +grant reload on *.* to adm@localhost; +reset master; +exec $MYSQLADMIN -uadm -pfoobar flush-status; +source include/show_binlog_events.inc; +exec $MYSQLADMIN --local -uadm -pfoobar flush-status; +source include/show_binlog_events.inc; +drop user adm@localhost; diff --git a/mysql-test/suite/federated/assisted_discovery.result b/mysql-test/suite/federated/assisted_discovery.result index f79e47da8b4..4818ff7bb02 100644 --- a/mysql-test/suite/federated/assisted_discovery.result +++ b/mysql-test/suite/federated/assisted_discovery.result @@ -38,6 +38,40 @@ id group a\\b a\\ name 1 1 2 NULL foo 2 1 2 NULL fee DROP TABLE t1; +create table t1 ( +a bigint(20) not null auto_increment, +b bigint(20) not null, +c tinyint(4) not null, +d varchar(4096) not null, +primary key (a), +key (b,c,d(255)) +); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` bigint(20) NOT NULL AUTO_INCREMENT, + `b` bigint(20) NOT NULL, + `c` tinyint(4) NOT NULL, + `d` varchar(4096) NOT NULL, + PRIMARY KEY (`a`), + KEY `b` (`b`,`c`,`d`(255)) +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +connection master; +create table t1 engine=federated +connection='mysql://root@127.0.0.1:SLAVE_PORT/test/t1'; +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` bigint(20) NOT NULL AUTO_INCREMENT, + `b` bigint(20) NOT NULL, + `c` tinyint(4) NOT NULL, + `d` varchar(4096) NOT NULL, + PRIMARY KEY (`a`), + KEY `b` (`b`,`c`,`d`(255)) +) ENGINE=FEDERATED DEFAULT CHARSET=latin1 CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/test/t1' +drop table t1; +connection slave; +drop table t1; connection master; DROP TABLE IF EXISTS federated.t1; DROP DATABASE IF EXISTS federated; diff --git a/mysql-test/suite/federated/assisted_discovery.test b/mysql-test/suite/federated/assisted_discovery.test index 9f3abe74ecc..fa83a2a8e19 100644 --- a/mysql-test/suite/federated/assisted_discovery.test +++ b/mysql-test/suite/federated/assisted_discovery.test @@ -30,5 +30,29 @@ connection slave; SELECT * FROM t1; DROP TABLE t1; +# +# +# +create table t1 ( + a bigint(20) not null auto_increment, + b bigint(20) not null, + c tinyint(4) not null, + d varchar(4096) not null, + primary key (a), + key (b,c,d(255)) +); +show create table t1; + +connection master; +--replace_result $SLAVE_MYPORT SLAVE_PORT +eval create table t1 engine=federated + connection='mysql://root@127.0.0.1:$SLAVE_MYPORT/test/t1'; +--replace_result $SLAVE_MYPORT SLAVE_PORT +show create table t1; +drop table t1; + +connection slave; +drop table t1; + source include/federated_cleanup.inc; diff --git a/mysql-test/suite/innodb/r/drop_table_background.result b/mysql-test/suite/innodb/r/drop_table_background.result new file mode 100644 index 00000000000..a6f5672ba7f --- /dev/null +++ b/mysql-test/suite/innodb/r/drop_table_background.result @@ -0,0 +1,9 @@ +CREATE TABLE t(c0 SERIAL, c1 INT, c2 INT, c3 INT, c4 INT, +KEY(c1), KEY(c2), KEY(c2,c1), +KEY(c3), KEY(c3,c1), KEY(c3,c2), KEY(c3,c2,c1), +KEY(c4), KEY(c4,c1), KEY(c4,c2), KEY(c4,c2,c1), +KEY(c4,c3), KEY(c4,c3,c1), KEY(c4,c3,c2), KEY(c4,c3,c2,c1)) ENGINE=InnoDB; +SET DEBUG_DBUG='+d,row_drop_table_add_to_background'; +DROP TABLE t; +CREATE TABLE t (a INT) ENGINE=InnoDB; +DROP TABLE t; diff --git a/mysql-test/suite/innodb/t/drop_table_background.test b/mysql-test/suite/innodb/t/drop_table_background.test new file mode 100644 index 00000000000..0f596dec574 --- /dev/null +++ b/mysql-test/suite/innodb/t/drop_table_background.test @@ -0,0 +1,30 @@ +--source include/have_innodb.inc +--source include/have_debug.inc +# Embedded server does not support restarting +--source include/not_embedded.inc + +CREATE TABLE t(c0 SERIAL, c1 INT, c2 INT, c3 INT, c4 INT, +KEY(c1), KEY(c2), KEY(c2,c1), +KEY(c3), KEY(c3,c1), KEY(c3,c2), KEY(c3,c2,c1), +KEY(c4), KEY(c4,c1), KEY(c4,c2), KEY(c4,c2,c1), +KEY(c4,c3), KEY(c4,c3,c1), KEY(c4,c3,c2), KEY(c4,c3,c2,c1)) ENGINE=InnoDB; + +let $n= 10; + +SET DEBUG_DBUG='+d,row_drop_table_add_to_background'; +--disable_query_log +let $i= $n; +while ($i) { + eval CREATE TABLE t$i LIKE t; + dec $i; +} +let $i= $n; +while ($i) { + eval DROP TABLE t$i; + dec $i; +} +--enable_query_log +DROP TABLE t; +--source include/restart_mysqld.inc +CREATE TABLE t (a INT) ENGINE=InnoDB; +DROP TABLE t; diff --git a/mysql-test/suite/sys_vars/r/delay_key_write_func.result b/mysql-test/suite/sys_vars/r/delay_key_write_func.result index 0fd1d492ef4..5cc4b2eaaad 100644 --- a/mysql-test/suite/sys_vars/r/delay_key_write_func.result +++ b/mysql-test/suite/sys_vars/r/delay_key_write_func.result @@ -1,24 +1,20 @@ '#--------------------FN_DYNVARS_023_01-------------------------#' SET @start_value= @@global.delay_key_write; -SET @@global.delay_key_write = ON; -SELECT @@global.delay_key_write; -@@global.delay_key_write -ON -connect user1,localhost,root,,,,; -connection user1; -SELECT @@global.delay_key_write AS res_is_ON; -res_is_ON -ON -SET @@global.delay_key_write = ALL; -disconnect user1; -connect user1,localhost,root,,,,; -connection user1; -SELECT @@global.delay_key_write AS res_is_ALL; -res_is_ALL -ALL '#--------------------FN_DYNVARS_023_02-------------------------#' +CREATE PROCEDURE sp_addRecords (IN var1 INT,IN var2 INT) +BEGIN +WHILE (var1 < var2) DO +INSERT INTO t1 VALUES(var1,REPEAT('MYSQL',10),100000.0/var1); +SET var1=var1+1; +END WHILE; +END// '---check when delay_key_write is OFF---' SET @@global.delay_key_write = OFF; +CREATE TABLE t1( +a INT PRIMARY KEY, +b VARCHAR(512), +c DOUBLE +) DELAY_KEY_WRITE = 1; FLUSH STATUS; CALL sp_addRecords(1,10); SHOW STATUS LIKE 'Key_reads'; @@ -33,8 +29,14 @@ Key_write_requests 9 SELECT COUNT(*) FROM t1; COUNT(*) 9 +DROP TABLE t1; '----check when delay_key_write is ON---' SET @@global.delay_key_write = ON; +CREATE TABLE t1( +a INT PRIMARY KEY, +b VARCHAR(512), +c DOUBLE +) DELAY_KEY_WRITE = 1; FLUSH STATUS; CALL sp_addRecords(1,10); SHOW STATUS LIKE 'Key_reads'; @@ -49,8 +51,14 @@ Key_write_requests 9 SELECT COUNT(*) FROM t1; COUNT(*) 9 +DROP TABLE t1; '----check when delay_key_write is ALL---' SET @@global.delay_key_write = ALL; +CREATE TABLE t1( +a INT PRIMARY KEY, +b VARCHAR(512), +c DOUBLE +) DELAY_KEY_WRITE = 0; FLUSH STATUS; CALL sp_addRecords(1,10); SHOW STATUS LIKE 'Key_reads'; @@ -67,6 +75,4 @@ COUNT(*) 9 DROP PROCEDURE sp_addRecords; DROP TABLE t1; -disconnect user1; -connection default; SET @@global.delay_key_write= @start_value; diff --git a/mysql-test/suite/sys_vars/t/delay_key_write_func.test b/mysql-test/suite/sys_vars/t/delay_key_write_func.test index 89f40ba544b..e823e51954c 100644 --- a/mysql-test/suite/sys_vars/t/delay_key_write_func.test +++ b/mysql-test/suite/sys_vars/t/delay_key_write_func.test @@ -20,32 +20,14 @@ ############################################################################### --echo '#--------------------FN_DYNVARS_023_01-------------------------#' -####################################################################### -# Check if setting delay_key_write is changed in every new connection # -####################################################################### - SET @start_value= @@global.delay_key_write; -SET @@global.delay_key_write = ON; -SELECT @@global.delay_key_write; - -connect (user1,localhost,root,,,,); -connection user1; -SELECT @@global.delay_key_write AS res_is_ON; -SET @@global.delay_key_write = ALL; -disconnect user1; - -connect (user1,localhost,root,,,,); -connection user1; -SELECT @@global.delay_key_write AS res_is_ALL; - --echo '#--------------------FN_DYNVARS_023_02-------------------------#' ###################################################### # Begin the functionality Testing of delay_key_write # ###################################################### # create procedure to add rows ---disable_query_log DELIMITER //; CREATE PROCEDURE sp_addRecords (IN var1 INT,IN var2 INT) BEGIN @@ -55,28 +37,19 @@ BEGIN END WHILE; END// DELIMITER ;// ---enable_query_log #============================================================================== --echo '---check when delay_key_write is OFF---' #============================================================================== - SET @@global.delay_key_write = OFF; - ---disable_query_log ---disable_warnings -DROP TABLE IF EXISTS t1; ---enable_warnings # create a table with delay_key_write enabled CREATE TABLE t1( a INT PRIMARY KEY, b VARCHAR(512), c DOUBLE ) DELAY_KEY_WRITE = 1; ---enable_query_log - FLUSH STATUS; @@ -86,6 +59,7 @@ SHOW STATUS LIKE 'Key_reads'; SHOW STATUS LIKE 'Key_writes'; SHOW STATUS LIKE 'Key_write_requests'; SELECT COUNT(*) FROM t1; +DROP TABLE t1; #============================================================================== --echo '----check when delay_key_write is ON---' @@ -93,17 +67,12 @@ SELECT COUNT(*) FROM t1; SET @@global.delay_key_write = ON; ---disable_query_log ---disable_warnings -DROP TABLE IF EXISTS t1; ---enable_warnings # create a table with delay_key_write enabled CREATE TABLE t1( a INT PRIMARY KEY, b VARCHAR(512), c DOUBLE ) DELAY_KEY_WRITE = 1; ---enable_query_log FLUSH STATUS; CALL sp_addRecords(1,10); @@ -112,23 +81,19 @@ SHOW STATUS LIKE 'Key_reads'; SHOW STATUS LIKE 'Key_writes'; SHOW STATUS LIKE 'Key_write_requests'; SELECT COUNT(*) FROM t1; +DROP TABLE t1; #============================================================================== --echo '----check when delay_key_write is ALL---' #============================================================================== SET @@global.delay_key_write = ALL; ---disable_query_log ---disable_warnings -DROP TABLE IF EXISTS t1; ---enable_warnings # create a table with delay_key_write disabled CREATE TABLE t1( a INT PRIMARY KEY, b VARCHAR(512), c DOUBLE ) DELAY_KEY_WRITE = 0; ---enable_query_log FLUSH STATUS; CALL sp_addRecords(1,10); @@ -140,12 +105,9 @@ SELECT COUNT(*) FROM t1; DROP PROCEDURE sp_addRecords; DROP TABLE t1; -disconnect user1; -connection default; SET @@global.delay_key_write= @start_value; #################################################### # End of functionality testing for delay_key_write # #################################################### - diff --git a/mysql-test/t/alter_table_online.test b/mysql-test/t/alter_table_online.test index 22ebadd64f9..15df36e8009 100644 --- a/mysql-test/t/alter_table_online.test +++ b/mysql-test/t/alter_table_online.test @@ -285,6 +285,24 @@ CREATE TABLE t1 (a LONGTEXT COLLATE latin1_general_ci); ALTER TABLE t1 MODIFY a LONGTEXT COLLATE latin1_swedish_ci, ALGORITHM=INPLACE; DROP TABLE t1; ---echo # ---echo # End of MDEV-8948 ALTER ... INPLACE does work for BINARY, BLOB ---echo # +# +# MDEV-11335 Changing delay_key_write option for MyISAM table should not copy rows +# +select @@global.delay_key_write; +create table t1 (a int, b int, key(b)); +flush tables; +flush status; +show status like 'Feature_delay_key_write'; +insert t1 values (1,2),(2,3),(3,4); +show status like 'Feature_delay_key_write'; +alter online table t1 delay_key_write=1; +show status like 'Feature_delay_key_write'; +flush tables; +insert t1 values (1,2),(2,3),(3,4); +show status like 'Feature_delay_key_write'; +alter online table t1 delay_key_write=0; +show status like 'Feature_delay_key_write'; +flush tables; +insert t1 values (1,2),(2,3),(3,4); +show status like 'Feature_delay_key_write'; +drop table t1; diff --git a/mysql-test/t/partition_alter.test b/mysql-test/t/partition_alter.test index 592d8fdaeaa..9194e9a8222 100644 --- a/mysql-test/t/partition_alter.test +++ b/mysql-test/t/partition_alter.test @@ -1,3 +1,4 @@ +--source include/have_innodb.inc --source include/have_partition.inc CREATE TABLE `test_data` ( @@ -64,3 +65,41 @@ deallocate prepare stmt; drop table test_data; +# +# MDEV-12389 ADD CHECK leaves an orphaned .par file +# + +--let $datadir=`SELECT @@datadir` + +# InnoDB +create table t1(id int, d date not null, b bool not null default 0, primary key(id,d)) +engine=innodb +partition by range columns (d) ( +partition p1 values less than ('2016-10-18'), +partition p2 values less than ('2020-10-19')); +insert t1 values (0, '2000-01-02', 0); +insert t1 values (1, '2020-01-02', 10); +--replace_regex /#sql-[0-9a-f_]*/#sql-temporary/ +--error ER_CONSTRAINT_FAILED +alter table t1 add check (b in (0, 1)); +alter table t1 add check (b in (0, 10)); +show create table t1; +--error ER_CONSTRAINT_FAILED +insert t1 values (2, '2020-01-03', 20); +drop table t1; +--list_files $datadir/test + +# MyISAM, different execution path +create table t1(id int, d date not null, b bool not null default 0, primary key(id,d)) +partition by range columns (d) ( +partition p1 values less than ('2016-10-18'), +partition p2 values less than ('2020-10-19')); +insert t1 values (0, '2000-01-02', 0); +insert t1 values (1, '2020-01-02', 10); +# FIXME: MDEV-12923 MyISAM allows CHECK constraint violation in ALTER TABLE +alter table t1 add check (b in (0, 1)); +show create table t1; +--error ER_CONSTRAINT_FAILED +insert t1 values (2, '2020-01-03', 20); +drop table t1; +--list_files $datadir/test diff --git a/plugin/auth_pam/auth_pam.c b/plugin/auth_pam/auth_pam.c index 95d95b9719c..ffc3d6f5537 100644 --- a/plugin/auth_pam/auth_pam.c +++ b/plugin/auth_pam/auth_pam.c @@ -166,7 +166,7 @@ static int pam_auth(MYSQL_PLUGIN_VIO *vio, MYSQL_SERVER_AUTH_INFO *info) end: pam_end(pamh, status); - PAM_DEBUG((stderr, "PAM: status = %d user = %s\n", status, new_username)); + PAM_DEBUG((stderr, "PAM: status = %d user = %s\n", status, info->authenticated_as)); return status == PAM_SUCCESS ? CR_OK : CR_ERROR; } diff --git a/plugin/cracklib_password_check/cracklib_password_check.c b/plugin/cracklib_password_check/cracklib_password_check.c index 7861d5fd83e..94587a6d659 100644 --- a/plugin/cracklib_password_check/cracklib_password_check.c +++ b/plugin/cracklib_password_check/cracklib_password_check.c @@ -30,6 +30,7 @@ static int crackme(MYSQL_LEX_STRING *username, MYSQL_LEX_STRING *password) const char *res; memcpy(user, username->str, username->length); + user[username->length]= 0; if ((host= strchr(user, '@'))) *host++= 0; diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index acb83ea494a..7e7ed69ab46 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -60,15 +60,22 @@ SET_SOURCE_FILES_PROPERTIES(${GEN_SOURCES} # Gen_lex_token # Make sure sql_yacc.h is generated before compiling gen_lex_token + +IF(NOT CMAKE_GENERATOR MATCHES "Visual Studio") + SET(DEPENDS_gen_lex_token DEPENDS gen_lex_token) + SET(DEPENDS_gen_lex_hash DEPENDS gen_lex_hash) +ENDIF() + + IF(NOT CMAKE_CROSSCOMPILING) - ADD_EXECUTABLE(gen_lex_token gen_lex_token.cc) - ADD_DEPENDENCIES(gen_lex_token GenServerSource) + ADD_EXECUTABLE(gen_lex_token gen_lex_token.cc + ${CMAKE_CURRENT_BINARY_DIR}/sql_yacc.h) ENDIF() ADD_CUSTOM_COMMAND( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/lex_token.h COMMAND gen_lex_token > lex_token.h - DEPENDS gen_lex_token + ${DEPENDS_gen_lex_token} ) ADD_DEFINITIONS(-DMYSQL_SERVER -DHAVE_EVENT_SCHEDULER) @@ -328,7 +335,7 @@ ENDIF() ADD_CUSTOM_COMMAND( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/lex_hash.h COMMAND gen_lex_hash > lex_hash.h - DEPENDS gen_lex_hash + ${DEPENDS_gen_lex_hash} ) MYSQL_ADD_EXECUTABLE(mysql_tzinfo_to_sql tztime.cc COMPONENT Server) diff --git a/sql/item_func.cc b/sql/item_func.cc index 8031788cadf..8529a1d08ca 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -3917,6 +3917,7 @@ longlong Item_master_gtid_wait::val_int() { DBUG_ASSERT(fixed == 1); longlong result= 0; + String *gtid_pos = args[0]->val_str(&value); if (args[0]->null_value) { @@ -3928,7 +3929,6 @@ longlong Item_master_gtid_wait::val_int() #ifdef HAVE_REPLICATION THD* thd= current_thd; longlong timeout_us; - String *gtid_pos = args[0]->val_str(&value); if (arg_count==2 && !args[1]->null_value) timeout_us= (longlong)(1e6*args[1]->val_real()); diff --git a/sql/item_func.h b/sql/item_func.h index 133074122dd..7ee4b67b097 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1835,7 +1835,7 @@ public: Item_master_gtid_wait(THD *thd, Item *a, Item *b): Item_int_func(thd, a, b) {} longlong val_int(); const char *func_name() const { return "master_gtid_wait"; } - void fix_length_and_dec() { max_length=10+1+10+1+20+1; maybe_null=0;} + void fix_length_and_dec() { max_length=2; } bool check_vcol_func_processor(void *arg) { return mark_unsupported_function(func_name(), "()", arg, VCOL_IMPOSSIBLE); diff --git a/sql/sql_class.h b/sql/sql_class.h index 986cb1c4793..2d1bf8a9886 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -4553,7 +4553,7 @@ public: select_result(thd_arg), suppress_my_ok(false) { DBUG_ENTER("select_result_interceptor::select_result_interceptor"); - DBUG_PRINT("enter", ("this 0x%lx", (ulong) this)); + DBUG_PRINT("enter", ("this %p", this)); DBUG_VOID_RETURN; } /* Remove gcc warning */ uint field_count(List &fields) const { return 0; } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 601e4fa4e3d..dcae5435d57 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -9135,7 +9135,9 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, TODO don't create the frm in the first place */ - deletefrm(alter_ctx.get_tmp_path()); + const char *path= alter_ctx.get_tmp_path(); + table->file->ha_create_partitioning_metadata(path, NULL, CHF_DELETE_FLAG); + deletefrm(path); my_free(const_cast(frm.str)); goto end_inplace; } diff --git a/storage/federatedx/ha_federatedx.h b/storage/federatedx/ha_federatedx.h index 2c2c6eef26b..f8531014ee4 100644 --- a/storage/federatedx/ha_federatedx.h +++ b/storage/federatedx/ha_federatedx.h @@ -330,7 +330,7 @@ public: return (HA_PRIMARY_KEY_IN_READ_INDEX | HA_FILE_BASED | HA_REC_NOT_IN_SEQ | HA_AUTO_PART_KEY | HA_CAN_INDEX_BLOBS | HA_BINLOG_ROW_CAPABLE | HA_BINLOG_STMT_CAPABLE | HA_CAN_REPAIR | - HA_NO_PREFIX_CHAR_KEYS | HA_PRIMARY_KEY_REQUIRED_FOR_DELETE | + HA_PRIMARY_KEY_REQUIRED_FOR_DELETE | HA_PARTIAL_COLUMN_READ | HA_NULL_IN_KEY); } /* diff --git a/storage/innobase/btr/btr0defragment.cc b/storage/innobase/btr/btr0defragment.cc index 6913124cea1..d4b83930191 100644 --- a/storage/innobase/btr/btr0defragment.cc +++ b/storage/innobase/btr/btr0defragment.cc @@ -154,7 +154,6 @@ btr_defragment_init() srv_defragment_interval = ut_microseconds_to_timer( (ulonglong) (1000000.0 / srv_defragment_frequency)); mutex_create(LATCH_ID_BTR_DEFRAGMENT_MUTEX, &btr_defragment_mutex); - os_thread_create(btr_defragment_thread, NULL, NULL); } /******************************************************************//** @@ -736,14 +735,13 @@ btr_defragment_n_pages( return current_block; } -/******************************************************************//** -Thread that merges consecutive b-tree pages into fewer pages to defragment -the index. */ +/** Whether btr_defragment_thread is active */ +bool btr_defragment_thread_active; + +/** Merge consecutive b-tree pages into fewer pages to defragment indexes */ extern "C" UNIV_INTERN os_thread_ret_t -DECLARE_THREAD(btr_defragment_thread)( -/*==========================================*/ - void* arg) /*!< in: work queue */ +DECLARE_THREAD(btr_defragment_thread)(void*) { btr_pcur_t* pcur; btr_cur_t* cursor; @@ -753,6 +751,8 @@ DECLARE_THREAD(btr_defragment_thread)( buf_block_t* last_block; while (srv_shutdown_state == SRV_SHUTDOWN_NONE) { + ut_ad(btr_defragment_thread_active); + /* If defragmentation is disabled, sleep before checking whether it's enabled. */ if (!srv_defragment) { @@ -844,7 +844,8 @@ DECLARE_THREAD(btr_defragment_thread)( btr_defragment_remove_item(item); } } - btr_defragment_shutdown(); + + btr_defragment_thread_active = false; os_thread_exit(); OS_THREAD_DUMMY_RETURN; } diff --git a/storage/innobase/include/btr0defragment.h b/storage/innobase/include/btr0defragment.h index 21ba6d9f426..9c78ec412a2 100644 --- a/storage/innobase/include/btr0defragment.h +++ b/storage/innobase/include/btr0defragment.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (C) 2013, 2014 Facebook, Inc. All Rights Reserved. -Copyright (C) 2014, 2015, MariaDB Corporation. +Copyright (C) 2014, 2017, 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 @@ -85,13 +85,13 @@ UNIV_INTERN void btr_defragment_save_defrag_stats_if_needed( dict_index_t* index); /*!< in: index */ -/******************************************************************//** -Thread that merges consecutive b-tree pages into fewer pages to defragment -the index. */ + +/** Merge consecutive b-tree pages into fewer pages to defragment indexes */ extern "C" UNIV_INTERN os_thread_ret_t -DECLARE_THREAD(btr_defragment_thread)( -/*==========================================*/ - void* arg); /*!< in: a dummy parameter required by - os_thread_create */ +DECLARE_THREAD(btr_defragment_thread)(void*); + +/** Whether btr_defragment_thread is active */ +extern bool btr_defragment_thread_active; + #endif diff --git a/storage/innobase/log/log0log.cc b/storage/innobase/log/log0log.cc index 2638250f0a3..072338187a3 100644 --- a/storage/innobase/log/log0log.cc +++ b/storage/innobase/log/log0log.cc @@ -44,6 +44,7 @@ Created 12/9/1995 Heikki Tuuri #include "fil0fil.h" #include "dict0boot.h" #include "dict0stats_bg.h" +#include "btr0defragment.h" #include "srv0srv.h" #include "srv0start.h" #include "trx0sys.h" @@ -2010,6 +2011,8 @@ loop: thread_name = "lock_wait_timeout_thread"; } else if (srv_buf_dump_thread_active) { thread_name = "buf_dump_thread"; + } else if (btr_defragment_thread_active) { + thread_name = "btr_defragment_thread"; } else if (srv_fast_shutdown != 2 && trx_rollback_or_clean_is_active) { thread_name = "rollback of recovered transactions"; } else { diff --git a/storage/innobase/row/row0merge.cc b/storage/innobase/row/row0merge.cc index 1db8a92ba7e..eb0a58f4c28 100644 --- a/storage/innobase/row/row0merge.cc +++ b/storage/innobase/row/row0merge.cc @@ -1230,7 +1230,7 @@ row_merge_write( IORequest request(IORequest::WRITE); const bool success = os_file_write_int_fd( - request, "(merge)", fd, buf, ofs, buf_len); + request, "(merge)", fd, out_buf, ofs, buf_len); #ifdef POSIX_FADV_DONTNEED /* The block will be needed on the next merge pass, @@ -4738,6 +4738,7 @@ row_merge_build_indexes( for (i = 0; i < n_indexes; i++) { merge_files[i].fd = -1; + merge_files[i].offset = 0; } total_static_cost = COST_BUILD_INDEX_STATIC * n_indexes + COST_READ_CLUSTERED_INDEX; diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc index ea6403a987f..0a84afa5106 100644 --- a/storage/innobase/srv/srv0srv.cc +++ b/storage/innobase/srv/srv0srv.cc @@ -1480,8 +1480,10 @@ srv_export_innodb_status(void) buf_get_total_stat(&stat); buf_get_total_list_len(&LRU_len, &free_len, &flush_list_len); buf_get_total_list_size_in_bytes(&buf_pools_list_size); - fil_crypt_total_stat(&crypt_stat); - btr_scrub_total_stat(&scrub_stat); + if (!srv_read_only_mode) { + fil_crypt_total_stat(&crypt_stat); + btr_scrub_total_stat(&scrub_stat); + } mutex_enter(&srv_innodb_monitor_mutex); @@ -1679,6 +1681,7 @@ srv_export_innodb_status(void) export_vars.innodb_sec_rec_cluster_reads_avoided = srv_stats.n_sec_rec_cluster_reads_avoided; + if (!srv_read_only_mode) { export_vars.innodb_encryption_rotation_pages_read_from_cache = crypt_stat.pages_read_from_cache; export_vars.innodb_encryption_rotation_pages_read_from_disk = @@ -1707,6 +1710,7 @@ srv_export_innodb_status(void) export_vars.innodb_scrub_page_split_failures_unknown = scrub_stat.page_split_failures_unknown; export_vars.innodb_scrub_log = srv_stats.n_log_scrubs; + } mutex_exit(&srv_innodb_monitor_mutex); } @@ -1856,7 +1860,7 @@ loop: } } - if (srv_shutdown_state >= SRV_SHUTDOWN_CLEANUP) { + if (srv_shutdown_state != SRV_SHUTDOWN_NONE) { goto exit_func; } @@ -1977,7 +1981,7 @@ loop: os_event_wait_time_low(srv_error_event, 1000000, sig_count); - if (srv_shutdown_state < SRV_SHUTDOWN_CLEANUP) { + if (srv_shutdown_state == SRV_SHUTDOWN_NONE) { goto loop; } @@ -2183,7 +2187,7 @@ srv_shutdown_print_master_pending( time_elapsed = ut_difftime(current_time, *last_print_time); if (time_elapsed > 60) { - *last_print_time = ut_time(); + *last_print_time = current_time; if (n_tables_to_drop) { ib::info() << "Waiting for " << n_tables_to_drop @@ -2286,7 +2290,7 @@ srv_master_do_active_tasks(void) ut_d(srv_master_do_disabled_loop()); - if (srv_shutdown_state > 0) { + if (srv_shutdown_state != SRV_SHUTDOWN_NONE) { return; } @@ -2311,11 +2315,7 @@ srv_master_do_active_tasks(void) /* Now see if various tasks that are performed at defined intervals need to be performed. */ - if (srv_shutdown_state > 0) { - return; - } - - if (srv_shutdown_state > 0) { + if (srv_shutdown_state != SRV_SHUTDOWN_NONE) { return; } @@ -2330,7 +2330,7 @@ srv_master_do_active_tasks(void) MONITOR_SRV_DICT_LRU_MICROSECOND, counter_time); } - if (srv_shutdown_state > 0) { + if (srv_shutdown_state != SRV_SHUTDOWN_NONE) { return; } @@ -2375,7 +2375,7 @@ srv_master_do_idle_tasks(void) ut_d(srv_master_do_disabled_loop()); - if (srv_shutdown_state > 0) { + if (srv_shutdown_state != SRV_SHUTDOWN_NONE) { return; } @@ -2391,7 +2391,7 @@ srv_master_do_idle_tasks(void) MONITOR_INC_TIME_IN_MICRO_SECS( MONITOR_SRV_IBUF_MERGE_MICROSECOND, counter_time); - if (srv_shutdown_state > 0) { + if (srv_shutdown_state != SRV_SHUTDOWN_NONE) { return; } @@ -2409,7 +2409,7 @@ srv_master_do_idle_tasks(void) MONITOR_INC_TIME_IN_MICRO_SECS( MONITOR_SRV_LOG_FLUSH_MICROSECOND, counter_time); - if (srv_shutdown_state > 0) { + if (srv_shutdown_state != SRV_SHUTDOWN_NONE) { return; } @@ -2420,70 +2420,42 @@ srv_master_do_idle_tasks(void) counter_time); } -/*********************************************************************//** -Perform the tasks during shutdown. The tasks that we do at shutdown -depend on srv_fast_shutdown: -2 => very fast shutdown => do no book keeping -1 => normal shutdown => clear drop table queue and make checkpoint -0 => slow shutdown => in addition to above do complete purge and ibuf -merge -@return TRUE if some work was done. FALSE otherwise */ +/** Perform shutdown tasks. +@param[in] ibuf_merge whether to complete the change buffer merge */ static -ibool -srv_master_do_shutdown_tasks( -/*=========================*/ - ib_time_t* last_print_time)/*!< last time the function - print the message */ +void +srv_shutdown(bool ibuf_merge) { - ulint n_bytes_merged = 0; - ulint n_tables_to_drop = 0; + ulint n_bytes_merged = 0; + ulint n_tables_to_drop; + ib_time_t now = ut_time(); - ut_ad(!srv_read_only_mode); + do { + ut_ad(!srv_read_only_mode); + ut_ad(srv_shutdown_state == SRV_SHUTDOWN_CLEANUP); + ++srv_main_shutdown_loops; - ++srv_main_shutdown_loops; + /* FIXME: Remove the background DROP TABLE queue; it is not + crash-safe and breaks ACID. */ + srv_main_thread_op_info = "doing background drop tables"; + n_tables_to_drop = row_drop_tables_for_mysql_in_background(); - ut_a(srv_shutdown_state > 0); + if (ibuf_merge) { + srv_main_thread_op_info = "checking free log space"; + log_free_check(); + srv_main_thread_op_info = "doing insert buffer merge"; + n_bytes_merged = ibuf_merge_in_background(true); - /* In very fast shutdown none of the following is necessary */ - if (srv_fast_shutdown == 2) { - return(FALSE); - } + /* Flush logs if needed */ + srv_sync_log_buffer_in_background(); + } - /* ALTER TABLE in MySQL requires on Unix that the table handler - can drop tables lazily after there no longer are SELECT - queries to them. */ - srv_main_thread_op_info = "doing background drop tables"; - n_tables_to_drop = row_drop_tables_for_mysql_in_background(); - - /* make sure that there is enough reusable space in the redo - log files */ - srv_main_thread_op_info = "checking free log space"; - log_free_check(); - - /* In case of normal shutdown we don't do ibuf merge or purge */ - if (srv_fast_shutdown == 1) { - goto func_exit; - } - - /* Do an ibuf merge */ - srv_main_thread_op_info = "doing insert buffer merge"; - n_bytes_merged = ibuf_merge_in_background(true); - - /* Flush logs if needed */ - srv_sync_log_buffer_in_background(); - -func_exit: - /* Make a new checkpoint about once in 10 seconds */ - srv_main_thread_op_info = "making checkpoint"; - log_checkpoint(TRUE, FALSE); - - /* Print progress message every 60 seconds during shutdown */ - if (srv_shutdown_state > 0 && srv_print_verbose_log) { - srv_shutdown_print_master_pending( - last_print_time, n_tables_to_drop, n_bytes_merged); - } - - return(n_bytes_merged || n_tables_to_drop); + /* Print progress message every 60 seconds during shutdown */ + if (srv_print_verbose_log) { + srv_shutdown_print_master_pending( + &now, n_tables_to_drop, n_bytes_merged); + } + } while (n_bytes_merged || n_tables_to_drop); } /*********************************************************************//** @@ -2516,7 +2488,6 @@ DECLARE_THREAD(srv_master_thread)( srv_slot_t* slot; ulint old_activity_count = srv_get_activity_count(); - ib_time_t last_print_time; ut_ad(!srv_read_only_mode); @@ -2535,7 +2506,6 @@ DECLARE_THREAD(srv_master_thread)( slot = srv_reserve_slot(SRV_MASTER); ut_a(slot == srv_sys.sys_threads); - last_print_time = ut_time(); loop: if (srv_force_recovery >= SRV_FORCE_NO_BACKGROUND) { goto suspend_thread; @@ -2555,14 +2525,26 @@ loop: } } - while (srv_shutdown_state != SRV_SHUTDOWN_EXIT_THREADS - && srv_master_do_shutdown_tasks(&last_print_time)) { - - /* Shouldn't loop here in case of very fast shutdown */ - ut_ad(srv_fast_shutdown < 2); +suspend_thread: + switch (srv_shutdown_state) { + case SRV_SHUTDOWN_NONE: + break; + case SRV_SHUTDOWN_FLUSH_PHASE: + case SRV_SHUTDOWN_LAST_PHASE: + ut_ad(0); + /* fall through */ + case SRV_SHUTDOWN_EXIT_THREADS: + /* srv_init_abort() must have been invoked */ + case SRV_SHUTDOWN_CLEANUP: + if (srv_shutdown_state == SRV_SHUTDOWN_CLEANUP + && srv_fast_shutdown < 2) { + srv_shutdown(srv_fast_shutdown == 1); + } + srv_suspend_thread(slot); + my_thread_end(); + os_thread_exit(); } -suspend_thread: srv_main_thread_op_info = "suspending"; srv_suspend_thread(slot); @@ -2574,14 +2556,7 @@ suspend_thread: srv_main_thread_op_info = "waiting for server activity"; srv_resume_thread(slot); - - if (srv_shutdown_state != SRV_SHUTDOWN_EXIT_THREADS) { - goto loop; - } - - my_thread_end(); - os_thread_exit(); - DBUG_RETURN(0); + goto loop; } /** diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index e04eba2c466..95ce941d8a1 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -2724,6 +2724,8 @@ files_checked: /* Initialize online defragmentation. */ btr_defragment_init(); + btr_defragment_thread_active = true; + os_thread_create(btr_defragment_thread, NULL, NULL); srv_start_state_set(SRV_START_STATE_STAT); } @@ -2846,7 +2848,7 @@ innodb_shutdown() fil_crypt_threads_cleanup(); btr_scrub_cleanup(); - /* FIXME: call btr_defragment_shutdown(); */ + btr_defragment_shutdown(); } /* This must be disabled before closing the buffer pool diff --git a/storage/myisam/ha_myisam.cc b/storage/myisam/ha_myisam.cc index 0bc33a365e8..d46b4df8e05 100644 --- a/storage/myisam/ha_myisam.cc +++ b/storage/myisam/ha_myisam.cc @@ -852,6 +852,10 @@ int ha_myisam::open(const char *name, int mode, uint test_if_locked) /* Count statistics of usage for newly open normal files */ if (file->s->reopen == 1 && ! (test_if_locked & HA_OPEN_TMP_TABLE)) { + /* use delay_key_write from .frm, not .MYI */ + file->s->delay_key_write= delay_key_write_options == DELAY_KEY_WRITE_ALL || + (delay_key_write_options == DELAY_KEY_WRITE_ON && + table->s->db_create_options & HA_OPTION_DELAY_KEY_WRITE); if (file->s->delay_key_write) feature_files_opened_with_delayed_keys++; } @@ -2367,10 +2371,8 @@ bool ha_myisam::check_if_incompatible_data(HA_CREATE_INFO *create_info, table_changes & IS_EQUAL_PACK_LENGTH) // Not implemented yet return COMPATIBLE_DATA_NO; - if ((options & (HA_OPTION_PACK_RECORD | HA_OPTION_CHECKSUM | - HA_OPTION_DELAY_KEY_WRITE)) != - (create_info->table_options & (HA_OPTION_PACK_RECORD | HA_OPTION_CHECKSUM | - HA_OPTION_DELAY_KEY_WRITE))) + if ((options & (HA_OPTION_PACK_RECORD | HA_OPTION_CHECKSUM)) != + (create_info->table_options & (HA_OPTION_PACK_RECORD | HA_OPTION_CHECKSUM))) return COMPATIBLE_DATA_NO; return COMPATIBLE_DATA_YES; } diff --git a/storage/xtradb/btr/btr0defragment.cc b/storage/xtradb/btr/btr0defragment.cc index 64dc077d582..c2f58a8e1cf 100644 --- a/storage/xtradb/btr/btr0defragment.cc +++ b/storage/xtradb/btr/btr0defragment.cc @@ -154,7 +154,6 @@ btr_defragment_init() (ulonglong) (1000000.0 / srv_defragment_frequency)); mutex_create(btr_defragment_mutex_key, &btr_defragment_mutex, SYNC_ANY_LATCH); - os_thread_create(btr_defragment_thread, NULL, NULL); } /******************************************************************//** @@ -735,14 +734,13 @@ btr_defragment_n_pages( return current_block; } -/******************************************************************//** -Thread that merges consecutive b-tree pages into fewer pages to defragment -the index. */ +/** Whether btr_defragment_thread is active */ +bool btr_defragment_thread_active; + +/** Merge consecutive b-tree pages into fewer pages to defragment indexes */ extern "C" UNIV_INTERN os_thread_ret_t -DECLARE_THREAD(btr_defragment_thread)( -/*==========================================*/ - void* arg) /*!< in: work queue */ +DECLARE_THREAD(btr_defragment_thread)(void*) { btr_pcur_t* pcur; btr_cur_t* cursor; @@ -752,6 +750,8 @@ DECLARE_THREAD(btr_defragment_thread)( buf_block_t* last_block; while (srv_shutdown_state == SRV_SHUTDOWN_NONE) { + ut_ad(btr_defragment_thread_active); + /* If defragmentation is disabled, sleep before checking whether it's enabled. */ if (!srv_defragment) { @@ -825,9 +825,9 @@ DECLARE_THREAD(btr_defragment_thread)( btr_defragment_remove_item(item); } } - btr_defragment_shutdown(); + + btr_defragment_thread_active = false; os_thread_exit(NULL); OS_THREAD_DUMMY_RETURN; } - #endif /* !UNIV_HOTBACKUP */ diff --git a/storage/xtradb/include/btr0defragment.h b/storage/xtradb/include/btr0defragment.h index 5c54b898e37..477824c1a35 100644 --- a/storage/xtradb/include/btr0defragment.h +++ b/storage/xtradb/include/btr0defragment.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (C) 2013, 2014 Facebook, Inc. All Rights Reserved. -Copyright (C) 2014, 2015, MariaDB Corporation. +Copyright (C) 2014, 2017, 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 @@ -89,15 +89,14 @@ UNIV_INTERN void btr_defragment_save_defrag_stats_if_needed( dict_index_t* index); /*!< in: index */ -/******************************************************************//** -Thread that merges consecutive b-tree pages into fewer pages to defragment -the index. */ + +/** Merge consecutive b-tree pages into fewer pages to defragment indexes */ extern "C" UNIV_INTERN os_thread_ret_t -DECLARE_THREAD(btr_defragment_thread)( -/*==========================================*/ - void* arg); /*!< in: a dummy parameter required by - os_thread_create */ +DECLARE_THREAD(btr_defragment_thread)(void*); + +/** Whether btr_defragment_thread is active */ +extern bool btr_defragment_thread_active; #endif /* !UNIV_HOTBACKUP */ #endif diff --git a/storage/xtradb/log/log0log.cc b/storage/xtradb/log/log0log.cc index d39bcb87117..eae7f2bb09b 100644 --- a/storage/xtradb/log/log0log.cc +++ b/storage/xtradb/log/log0log.cc @@ -55,12 +55,13 @@ Created 12/9/1995 Heikki Tuuri #include "mem0mem.h" #include "buf0buf.h" #include "buf0flu.h" -#include "srv0srv.h" #include "lock0lock.h" #include "log0recv.h" #include "fil0fil.h" #include "dict0boot.h" -#include "dict0stats_bg.h" /* dict_stats_event */ +#include "dict0stats_bg.h" +#include "dict0stats_bg.h" +#include "btr0defragment.h" #include "srv0srv.h" #include "srv0start.h" #include "trx0sys.h" @@ -3618,6 +3619,8 @@ loop: thread_name = "lock_wait_timeout_thread"; } else if (srv_buf_dump_thread_active) { thread_name = "buf_dump_thread"; + } else if (btr_defragment_thread_active) { + thread_name = "btr_defragment_thread"; } else if (srv_fast_shutdown != 2 && trx_rollback_or_clean_is_active) { thread_name = "rollback of recovered transactions"; } else { diff --git a/storage/xtradb/os/os0file.cc b/storage/xtradb/os/os0file.cc index 34336a4bb7d..20b202506f5 100644 --- a/storage/xtradb/os/os0file.cc +++ b/storage/xtradb/os/os0file.cc @@ -6423,22 +6423,27 @@ os_file_trim( flt.Ranges[0].Offset = off; flt.Ranges[0].Length = trim_len; + OVERLAPPED overlapped = { 0 }; + overlapped.hEvent = win_get_syncio_event(); BOOL ret = DeviceIoControl(slot->file, FSCTL_FILE_LEVEL_TRIM, - &flt, sizeof(flt), NULL, NULL, NULL, NULL); - + &flt, sizeof(flt), NULL, NULL, NULL, &overlapped); + DWORD tmp; + if (ret) { + ret = GetOverlappedResult(slot->file, &overlapped, &tmp, FALSE); + } + else if (GetLastError() == ERROR_IO_PENDING) { + ret = GetOverlappedResult(slot->file, &overlapped, &tmp, TRUE); + } if (!ret) { + DWORD last_error = GetLastError(); /* After first failure do not try to trim again */ os_fallocate_failed = true; srv_use_trim = FALSE; ut_print_timestamp(stderr); - fprintf(stderr, - " InnoDB: Warning: fallocate call failed with error.\n" - " InnoDB: start: %lu len: %lu payload: %lu\n" - " InnoDB: Disabling fallocate for now.\n", off, trim_len, len); - os_file_handle_error_no_exit(slot->name, - " DeviceIOControl(FSCTL_FILE_LEVEL_TRIM) ", - FALSE, __FILE__, __LINE__); + fprintf(stderr, + " InnoDB: Warning: DeviceIoControl(FSCTL_FILE_LEVEL_TRIM) call failed with error %u%s. Disabling trimming.\n", + last_error, last_error == ERROR_NOT_SUPPORTED ? "(ERROR_NOT_SUPPORTED)" : ""); if (slot->write_size) { *slot->write_size = 0; diff --git a/storage/xtradb/row/row0merge.cc b/storage/xtradb/row/row0merge.cc index 32c63afcc6d..6a1298087eb 100644 --- a/storage/xtradb/row/row0merge.cc +++ b/storage/xtradb/row/row0merge.cc @@ -1023,7 +1023,7 @@ row_merge_write( mach_write_to_4((byte *)out_buf, 0); } - ret = os_file_write_int_fd("(merge)", fd, buf, ofs, buf_len); + ret = os_file_write_int_fd("(merge)", fd, out_buf, ofs, buf_len); #ifdef UNIV_DEBUG if (row_merge_print_block_write) { @@ -4037,6 +4037,7 @@ row_merge_build_indexes( for (i = 0; i < n_indexes; i++) { merge_files[i].fd = -1; + merge_files[i].offset = 0; } total_static_cost = COST_BUILD_INDEX_STATIC * n_indexes + COST_READ_CLUSTERED_INDEX; diff --git a/storage/xtradb/srv/srv0srv.cc b/storage/xtradb/srv/srv0srv.cc index 77e18e43ef1..fca6e859aa8 100644 --- a/storage/xtradb/srv/srv0srv.cc +++ b/storage/xtradb/srv/srv0srv.cc @@ -1779,8 +1779,10 @@ srv_export_innodb_status(void) buf_get_total_stat(&stat); buf_get_total_list_len(&LRU_len, &free_len, &flush_list_len); buf_get_total_list_size_in_bytes(&buf_pools_list_size); - fil_crypt_total_stat(&crypt_stat); - btr_scrub_total_stat(&scrub_stat); + if (!srv_read_only_mode) { + fil_crypt_total_stat(&crypt_stat); + btr_scrub_total_stat(&scrub_stat); + } mem_adaptive_hash = 0; @@ -2094,6 +2096,7 @@ srv_export_innodb_status(void) export_vars.innodb_sec_rec_cluster_reads_avoided = srv_stats.n_sec_rec_cluster_reads_avoided; + if (!srv_read_only_mode) { export_vars.innodb_encryption_rotation_pages_read_from_cache = crypt_stat.pages_read_from_cache; export_vars.innodb_encryption_rotation_pages_read_from_disk = @@ -2121,6 +2124,7 @@ srv_export_innodb_status(void) scrub_stat.page_split_failures_missing_index; export_vars.innodb_scrub_page_split_failures_unknown = scrub_stat.page_split_failures_unknown; + } mutex_exit(&srv_innodb_monitor_mutex); } @@ -2275,7 +2279,7 @@ loop: } } - if (srv_shutdown_state >= SRV_SHUTDOWN_CLEANUP) { + if (srv_shutdown_state != SRV_SHUTDOWN_NONE) { goto exit_func; } @@ -2413,7 +2417,7 @@ loop: os_event_wait_time_low(srv_error_event, 1000000, sig_count); - if (srv_shutdown_state < SRV_SHUTDOWN_CLEANUP) { + if (srv_shutdown_state == SRV_SHUTDOWN_NONE) { goto loop; } @@ -2858,7 +2862,7 @@ srv_shutdown_print_master_pending( time_elapsed = ut_difftime(current_time, *last_print_time); if (time_elapsed > 60) { - *last_print_time = ut_time(); + *last_print_time = current_time; if (n_tables_to_drop) { ut_print_timestamp(stderr); @@ -2911,7 +2915,7 @@ srv_master_do_active_tasks(void) MONITOR_INC_TIME_IN_MICRO_SECS( MONITOR_SRV_BACKGROUND_DROP_TABLE_MICROSECOND, counter_time); - if (srv_shutdown_state > 0) { + if (srv_shutdown_state != SRV_SHUTDOWN_NONE) { return; } @@ -2945,11 +2949,7 @@ srv_master_do_active_tasks(void) MONITOR_SRV_MEM_VALIDATE_MICROSECOND, counter_time); } #endif - if (srv_shutdown_state > 0) { - return; - } - - if (srv_shutdown_state > 0) { + if (srv_shutdown_state != SRV_SHUTDOWN_NONE) { return; } @@ -2962,7 +2962,7 @@ srv_master_do_active_tasks(void) MONITOR_SRV_DICT_LRU_MICROSECOND, counter_time); } - if (srv_shutdown_state > 0) { + if (srv_shutdown_state != SRV_SHUTDOWN_NONE) { return; } @@ -3006,7 +3006,7 @@ srv_master_do_idle_tasks(void) MONITOR_SRV_BACKGROUND_DROP_TABLE_MICROSECOND, counter_time); - if (srv_shutdown_state > 0) { + if (srv_shutdown_state != SRV_SHUTDOWN_NONE) { return; } @@ -3022,7 +3022,7 @@ srv_master_do_idle_tasks(void) MONITOR_INC_TIME_IN_MICRO_SECS( MONITOR_SRV_IBUF_MERGE_MICROSECOND, counter_time); - if (srv_shutdown_state > 0) { + if (srv_shutdown_state != SRV_SHUTDOWN_NONE) { return; } @@ -3038,7 +3038,7 @@ srv_master_do_idle_tasks(void) MONITOR_INC_TIME_IN_MICRO_SECS( MONITOR_SRV_LOG_FLUSH_MICROSECOND, counter_time); - if (srv_shutdown_state > 0) { + if (srv_shutdown_state != SRV_SHUTDOWN_NONE) { return; } @@ -3059,70 +3059,42 @@ srv_master_do_idle_tasks(void) } } -/*********************************************************************//** -Perform the tasks during shutdown. The tasks that we do at shutdown -depend on srv_fast_shutdown: -2 => very fast shutdown => do no book keeping -1 => normal shutdown => clear drop table queue and make checkpoint -0 => slow shutdown => in addition to above do complete purge and ibuf -merge -@return TRUE if some work was done. FALSE otherwise */ +/** Perform shutdown tasks. +@param[in] ibuf_merge whether to complete the change buffer merge */ static -ibool -srv_master_do_shutdown_tasks( -/*=========================*/ - ib_time_t* last_print_time)/*!< last time the function - print the message */ +void +srv_shutdown(bool ibuf_merge) { - ulint n_bytes_merged = 0; - ulint n_tables_to_drop = 0; + ulint n_bytes_merged = 0; + ulint n_tables_to_drop; + ib_time_t now = ut_time(); - ut_ad(!srv_read_only_mode); + do { + ut_ad(!srv_read_only_mode); + ut_ad(srv_shutdown_state == SRV_SHUTDOWN_CLEANUP); + ++srv_main_shutdown_loops; - ++srv_main_shutdown_loops; + /* FIXME: Remove the background DROP TABLE queue; it is not + crash-safe and breaks ACID. */ + srv_main_thread_op_info = "doing background drop tables"; + n_tables_to_drop = row_drop_tables_for_mysql_in_background(); - ut_a(srv_shutdown_state > 0); + if (ibuf_merge) { + srv_main_thread_op_info = "checking free log space"; + log_free_check(); + srv_main_thread_op_info = "doing insert buffer merge"; + n_bytes_merged = ibuf_merge_in_background(true); - /* In very fast shutdown none of the following is necessary */ - if (srv_fast_shutdown == 2) { - return(FALSE); - } + /* Flush logs if needed */ + srv_sync_log_buffer_in_background(); + } - /* ALTER TABLE in MySQL requires on Unix that the table handler - can drop tables lazily after there no longer are SELECT - queries to them. */ - srv_main_thread_op_info = "doing background drop tables"; - n_tables_to_drop = row_drop_tables_for_mysql_in_background(); - - /* make sure that there is enough reusable space in the redo - log files */ - srv_main_thread_op_info = "checking free log space"; - log_free_check(); - - /* In case of normal shutdown we don't do ibuf merge or purge */ - if (srv_fast_shutdown == 1) { - goto func_exit; - } - - /* Do an ibuf merge */ - srv_main_thread_op_info = "doing insert buffer merge"; - n_bytes_merged = ibuf_merge_in_background(true); - - /* Flush logs if needed */ - srv_sync_log_buffer_in_background(); - -func_exit: - /* Make a new checkpoint about once in 10 seconds */ - srv_main_thread_op_info = "making checkpoint"; - log_checkpoint(TRUE, FALSE, FALSE); - - /* Print progress message every 60 seconds during shutdown */ - if (srv_shutdown_state > 0 && srv_print_verbose_log) { - srv_shutdown_print_master_pending( - last_print_time, n_tables_to_drop, n_bytes_merged); - } - - return(n_bytes_merged || n_tables_to_drop); + /* Print progress message every 60 seconds during shutdown */ + if (srv_print_verbose_log) { + srv_shutdown_print_master_pending( + &now, n_tables_to_drop, n_bytes_merged); + } + } while (n_bytes_merged || n_tables_to_drop); } /*********************************************************************//** @@ -3156,7 +3128,6 @@ DECLARE_THREAD(srv_master_thread)( ulint old_activity_count = srv_get_activity_count(); ulint old_ibuf_merge_activity_count = srv_get_ibuf_merge_activity_count(); - ib_time_t last_print_time; ut_ad(!srv_read_only_mode); @@ -3179,7 +3150,6 @@ DECLARE_THREAD(srv_master_thread)( slot = srv_reserve_slot(SRV_MASTER); ut_a(slot == srv_sys.sys_threads); - last_print_time = ut_time(); loop: if (srv_force_recovery >= SRV_FORCE_NO_BACKGROUND) { goto suspend_thread; @@ -3205,13 +3175,26 @@ loop: } } - while (srv_master_do_shutdown_tasks(&last_print_time)) { - - /* Shouldn't loop here in case of very fast shutdown */ - ut_ad(srv_fast_shutdown < 2); +suspend_thread: + switch (srv_shutdown_state) { + case SRV_SHUTDOWN_NONE: + break; + case SRV_SHUTDOWN_FLUSH_PHASE: + case SRV_SHUTDOWN_LAST_PHASE: + ut_ad(0); + /* fall through */ + case SRV_SHUTDOWN_EXIT_THREADS: + /* srv_init_abort() must have been invoked */ + case SRV_SHUTDOWN_CLEANUP: + if (srv_shutdown_state == SRV_SHUTDOWN_CLEANUP + && srv_fast_shutdown < 2) { + srv_shutdown(srv_fast_shutdown == 1); + } + srv_suspend_thread(slot); + my_thread_end(); + os_thread_exit(NULL); } -suspend_thread: srv_main_thread_op_info = "suspending"; srv_suspend_thread(slot); @@ -3223,15 +3206,7 @@ suspend_thread: srv_main_thread_op_info = "waiting for server activity"; srv_resume_thread(slot); - - if (srv_shutdown_state == SRV_SHUTDOWN_EXIT_THREADS) { - my_thread_end(); - os_thread_exit(NULL); - } - goto loop; - - OS_THREAD_DUMMY_RETURN; /* Not reached, avoid compiler warning */ } /*********************************************************************//** diff --git a/storage/xtradb/srv/srv0start.cc b/storage/xtradb/srv/srv0start.cc index 14c7e05b57c..fd225e9cf65 100644 --- a/storage/xtradb/srv/srv0start.cc +++ b/storage/xtradb/srv/srv0start.cc @@ -3058,14 +3058,16 @@ files_checked: fil_system_enter(); fil_crypt_threads_init(); fil_system_exit(); + + /* Init data for datafile scrub threads */ + btr_scrub_init(); + + /* Initialize online defragmentation. */ + btr_defragment_init(); + btr_defragment_thread_active = true; + os_thread_create(btr_defragment_thread, NULL, NULL); } - /* Init data for datafile scrub threads */ - btr_scrub_init(); - - /* Initialize online defragmentation. */ - btr_defragment_init(); - srv_was_started = TRUE; return(DB_SUCCESS); @@ -3229,11 +3231,10 @@ innobase_shutdown_for_mysql(void) if (!srv_read_only_mode) { dict_stats_thread_deinit(); fil_crypt_threads_cleanup(); + btr_scrub_cleanup(); + btr_defragment_shutdown(); } - /* Cleanup data for datafile scrubbing */ - btr_scrub_cleanup(); - #ifdef __WIN__ /* MDEV-361: ha_innodb.dll leaks handles on Windows MDEV-7403: should not pass recv_writer_thread_handle to