summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--client/mysql_upgrade.c4
-rw-r--r--include/ma_dyncol.h6
-rw-r--r--man/mysql_upgrade.13
-rw-r--r--mysql-test/include/kill_and_restart_mysqld.inc15
-rw-r--r--mysql-test/r/ctype_utf8.result15
-rw-r--r--mysql-test/r/ctype_utf8mb4.result26
-rw-r--r--mysql-test/r/func_str.result33
-rw-r--r--mysql-test/r/loadxml.result20
-rw-r--r--mysql-test/std_data/loaddata/mdev14628a.xml4
-rw-r--r--mysql-test/std_data/loaddata/mdev14628b.xml3
-rw-r--r--mysql-test/suite/innodb/r/recovery_shutdown.result64
-rw-r--r--mysql-test/suite/innodb/r/update_time.result1
-rw-r--r--mysql-test/suite/innodb/t/recovery_shutdown.test59
-rw-r--r--mysql-test/suite/innodb/t/table_definition_cache_debug.opt2
-rw-r--r--mysql-test/suite/innodb/t/update_time.test3
-rw-r--r--mysql-test/suite/innodb_gis/r/kill_server.result1
-rw-r--r--mysql-test/suite/innodb_gis/r/rtree_compress2.result1
-rw-r--r--mysql-test/suite/innodb_gis/r/rtree_crash.result41
-rw-r--r--mysql-test/suite/innodb_gis/r/rtree_recovery.result2
-rw-r--r--mysql-test/suite/innodb_gis/r/types.result1
-rw-r--r--mysql-test/suite/innodb_gis/t/kill_server.test3
-rw-r--r--mysql-test/suite/innodb_gis/t/rtree_compress2.test3
-rw-r--r--mysql-test/suite/innodb_gis/t/rtree_recovery.test5
-rw-r--r--mysql-test/suite/innodb_gis/t/types.test3
-rw-r--r--mysql-test/suite/storage_engine/type_bit_indexes.result4
-rw-r--r--mysql-test/t/ctype_utf8.test12
-rw-r--r--mysql-test/t/ctype_utf8mb4.test18
-rw-r--r--mysql-test/t/func_str.test30
-rw-r--r--mysql-test/t/loadxml.test19
-rw-r--r--mysys/ma_dyncol.c3
-rw-r--r--mysys/thr_alarm.c4
-rw-r--r--sql/field.cc51
-rw-r--r--sql/field.h4
-rw-r--r--sql/item_cmpfunc.cc6
-rw-r--r--sql/item_strfunc.cc34
-rw-r--r--sql/item_strfunc.h8
-rw-r--r--sql/sql_load.cc82
-rw-r--r--sql/sql_show.cc1
-rw-r--r--storage/innobase/ha/ha0ha.cc58
-rw-r--r--storage/innobase/handler/ha_innodb.cc3
-rw-r--r--storage/innobase/include/ha0ha.h7
-rw-r--r--storage/innobase/include/que0que.h3
-rw-r--r--storage/innobase/include/trx0roll.h7
-rw-r--r--storage/innobase/row/row0quiesce.cc4
-rw-r--r--storage/innobase/row/row0umod.cc18
-rw-r--r--storage/innobase/row/row0undo.cc7
-rw-r--r--storage/innobase/srv/srv0srv.cc28
-rw-r--r--storage/innobase/srv/srv0start.cc4
-rw-r--r--storage/innobase/trx/trx0purge.cc70
-rw-r--r--storage/innobase/trx/trx0roll.cc165
-rw-r--r--storage/innobase/trx/trx0undo.cc16
-rw-r--r--storage/maria/ma_loghandler.c1
-rw-r--r--storage/rocksdb/mysql-test/storage_engine/disabled.def1
-rw-r--r--storage/rocksdb/mysql-test/storage_engine/type_bit_indexes.rdiff20
-rw-r--r--storage/rocksdb/mysql-test/storage_engine/type_enum_indexes.rdiff11
-rw-r--r--storage/rocksdb/mysql-test/storage_engine/type_set_indexes.rdiff20
-rw-r--r--storage/tokudb/mysql-test/rpl/r/rpl_tokudb_row_log.result2
-rw-r--r--storage/tokudb/mysql-test/rpl/r/rpl_tokudb_stm_log.result2
58 files changed, 663 insertions, 378 deletions
diff --git a/client/mysql_upgrade.c b/client/mysql_upgrade.c
index 771fb947e73..c7ef8bfc47a 100644
--- a/client/mysql_upgrade.c
+++ b/client/mysql_upgrade.c
@@ -166,8 +166,8 @@ static struct my_option my_long_options[]=
"server with which it was built/distributed.",
&opt_version_check, &opt_version_check, 0,
GET_BOOL, NO_ARG, 1, 0, 0, 0, 0, 0},
- {"write-binlog", OPT_WRITE_BINLOG, "All commands including those, "
- "issued by mysqlcheck, are written to the binary log.",
+ {"write-binlog", OPT_WRITE_BINLOG, "All commands including those "
+ "issued by mysqlcheck are written to the binary log.",
&opt_write_binlog, &opt_write_binlog, 0, GET_BOOL, NO_ARG,
0, 0, 0, 0, 0, 0},
{0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
diff --git a/include/ma_dyncol.h b/include/ma_dyncol.h
index cb03ccb5382..300474e061e 100644
--- a/include/ma_dyncol.h
+++ b/include/ma_dyncol.h
@@ -63,6 +63,12 @@ typedef struct st_mysql_lex_string LEX_STRING;
/* NO and OK is the same used just to show semantics */
#define ER_DYNCOL_NO ER_DYNCOL_OK
+#ifdef HAVE_CHARSET_utf8mb4
+#define DYNCOL_UTF (&my_charset_utf8mb4_general_ci)
+#else
+#define DYNCOL_UTF (&my_charset_utf8_general_ci)
+#endif
+
enum enum_dyncol_func_result
{
ER_DYNCOL_OK= 0,
diff --git a/man/mysql_upgrade.1 b/man/mysql_upgrade.1
index c1197efe6b9..4ea0f4e054d 100644
--- a/man/mysql_upgrade.1
+++ b/man/mysql_upgrade.1
@@ -691,8 +691,7 @@ it was built/distributed. Defaults to on; use \fB\-\-skip\-version\-check\fR to
.sp
Cause binary logging to be enabled while
\fBmysql_upgrade\fR
-runs\&. This is the default behavior; to disable binary logging during the upgrade, use the inverse of this option (that is, start the program with
-\fB\-\-skip\-write\-binlog\fR)\&.
+runs\&.
.RE
.SH "COPYRIGHT"
.br
diff --git a/mysql-test/include/kill_and_restart_mysqld.inc b/mysql-test/include/kill_and_restart_mysqld.inc
deleted file mode 100644
index b67fb7350b4..00000000000
--- a/mysql-test/include/kill_and_restart_mysqld.inc
+++ /dev/null
@@ -1,15 +0,0 @@
-if (!$restart_parameters)
-{
- let $restart_parameters = restart;
-}
-
---let $_server_id= `SELECT @@server_id`
---let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/mysqld.$_server_id.expect
-
---echo # Kill and $restart_parameters
---exec echo "$restart_parameters" > $_expect_file_name
---shutdown_server 0
---source include/wait_until_disconnected.inc
---enable_reconnect
---source include/wait_until_connected_again.inc
---disable_reconnect
diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result
index 7381c1c4004..dfe96d1a904 100644
--- a/mysql-test/r/ctype_utf8.result
+++ b/mysql-test/r/ctype_utf8.result
@@ -10272,6 +10272,21 @@ DROP TABLE allbytes;
SET sql_mode = DEFAULT;
# End of ctype_backslash.inc
#
+# MDEV-12681 Wrong VIEW results for CHAR(0xDF USING latin1)
+#
+SET NAMES utf8;
+SELECT CHAR(0xDF USING latin1);
+CHAR(0xDF USING latin1)
+CREATE OR REPLACE VIEW v1 AS SELECT CHAR(0xDF USING latin1) AS c;
+SHOW CREATE VIEW v1;
+View Create View character_set_client collation_connection
+v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select char(0xdf using latin1) AS `c` utf8 utf8_general_ci
+SELECT * FROM v1;
+c
+DROP VIEW v1;
+#
# End of 10.0 tests
#
#
diff --git a/mysql-test/r/ctype_utf8mb4.result b/mysql-test/r/ctype_utf8mb4.result
index cf3000baf6a..fbe95d9f44b 100644
--- a/mysql-test/r/ctype_utf8mb4.result
+++ b/mysql-test/r/ctype_utf8mb4.result
@@ -3430,6 +3430,32 @@ a b
a 😁 b a ? b
DROP TABLE t1;
#
+# MDEV-8949: COLUMN_CREATE unicode name breakage
+#
+SET NAMES utf8mb4;
+SELECT COLUMN_JSON(COLUMN_CREATE(_utf8mb4 0xF09F988E, 1));
+COLUMN_JSON(COLUMN_CREATE(_utf8mb4 0xF09F988E, 1))
+{"😎":1}
+SELECT COLUMN_LIST(COLUMN_CREATE(_utf8mb4 0xF09F988E, 1));
+COLUMN_LIST(COLUMN_CREATE(_utf8mb4 0xF09F988E, 1))
+`😎`
+SELECT COLUMN_GET(COLUMN_CREATE(_utf8mb4 0xF09F988E, 1), _utf8mb4 0xF09F988E
+as int);
+COLUMN_GET(COLUMN_CREATE(_utf8mb4 0xF09F988E, 1), _utf8mb4 0xF09F988E
+as int)
+1
+CREATE TABLE t1 AS SELECT
+COLUMN_LIST(COLUMN_CREATE('a',1)),
+COLUMN_JSON(COLUMN_CREATE('b',1));
+SHOW CREATE TABLE t1;
+Table Create Table
+t1 CREATE TABLE `t1` (
+ `COLUMN_LIST(COLUMN_CREATE('a',1))` longtext CHARACTER SET utf8mb4 DEFAULT NULL,
+ `COLUMN_JSON(COLUMN_CREATE('b',1))` longtext CHARACTER SET utf8mb4 DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t1;
+SET NAMES default;
+#
# End of 10.0 tests
#
#
diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result
index 7389eeed5d7..2b376373f51 100644
--- a/mysql-test/r/func_str.result
+++ b/mysql-test/r/func_str.result
@@ -4734,6 +4734,27 @@ set global max_allowed_packet=default;
# End of 5.6 tests
#
#
+# Start of 10.0 tests
+#
+#
+# MDEV-12681 Wrong VIEW results for CHAR(0xDF USING latin1)
+#
+EXPLAIN EXTENDED SELECT CHAR(0xDF USING latin1);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1003 select char(0xdf using latin1) AS `CHAR(0xDF USING latin1)`
+EXPLAIN EXTENDED SELECT CHAR(0xDF USING `binary`);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1003 select char(0xdf) AS `CHAR(0xDF USING ``binary``)`
+EXPLAIN EXTENDED SELECT CHAR(0xDF);
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 SIMPLE NULL NULL NULL NULL NULL NULL NULL NULL No tables used
+Warnings:
+Note 1003 select char(0xdf) AS `CHAR(0xDF)`
+#
# Start of 10.1 tests
#
#
@@ -4843,6 +4864,12 @@ YQ== 61
Yq== 62
DROP TABLE t1;
#
+# End of 10.1 tests
+#
+#
+# Start of 10.3 tests
+#
+#
# MDEV-12685 Oracle-compatible function CHR()
#
select chr(65);
@@ -4859,12 +4886,6 @@ utf8 3 1
drop database mysqltest1;
use test;
#
-# End of 10.1 tests
-#
-#
-# Start of 10.3 tests
-#
-#
# MDEV-12592 Illegal mix of collations with the HEX function
#
SET NAMES utf8;
diff --git a/mysql-test/r/loadxml.result b/mysql-test/r/loadxml.result
index 1d7af4f8b38..b0fb867a676 100644
--- a/mysql-test/r/loadxml.result
+++ b/mysql-test/r/loadxml.result
@@ -134,3 +134,23 @@ LOAD XML INFILE '../../std_data/loaddata/mdev12696.xml' INTO TABLE v1 (c2);
ERROR HY000: Column 'c2' is not updatable
DROP VIEW v1;
DROP TABLE t1;
+#
+# MDEV-14628 Wrong autoinc value assigned by LOAD XML in the NO_AUTO_VALUE_ON_ZERO mode
+#
+SET sql_mode=NO_AUTO_VALUE_ON_ZERO;
+CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT);
+LOAD XML INFILE '../../std_data/loaddata/mdev14628a.xml' INTO TABLE t1 ROWS IDENTIFIED BY '<row>';
+SELECT * FROM t1 ORDER BY b;
+a b
+1 bbb1
+2 bbb2
+DROP TABLE t1;
+SET sql_mode=DEFAULT;
+SET sql_mode='';
+CREATE TABLE t1 (id INT, g GEOMETRY NOT NULL);
+LOAD XML INFILE '../../std_data/loaddata/mdev14628b.xml' INTO TABLE t1 ROWS IDENTIFIED BY '<row>';
+ERROR 22004: Column set to default value; NULL supplied to NOT NULL column 'g' at row 1
+SELECT * FROM t1;
+id g
+DROP TABLE t1;
+SET sql_mode=DEFAULT;
diff --git a/mysql-test/std_data/loaddata/mdev14628a.xml b/mysql-test/std_data/loaddata/mdev14628a.xml
new file mode 100644
index 00000000000..34ee7336a5a
--- /dev/null
+++ b/mysql-test/std_data/loaddata/mdev14628a.xml
@@ -0,0 +1,4 @@
+<list>
+ <row a="1" b="bbb1"/>
+ <row b="bbb2"/>
+</list>
diff --git a/mysql-test/std_data/loaddata/mdev14628b.xml b/mysql-test/std_data/loaddata/mdev14628b.xml
new file mode 100644
index 00000000000..2ea02d2a35f
--- /dev/null
+++ b/mysql-test/std_data/loaddata/mdev14628b.xml
@@ -0,0 +1,3 @@
+<list>
+ <row id="1"/>
+</list>
diff --git a/mysql-test/suite/innodb/r/recovery_shutdown.result b/mysql-test/suite/innodb/r/recovery_shutdown.result
new file mode 100644
index 00000000000..7b6c9863b59
--- /dev/null
+++ b/mysql-test/suite/innodb/r/recovery_shutdown.result
@@ -0,0 +1,64 @@
+#
+# MDEV-13797 InnoDB may hang if shutdown is initiated soon after startup
+# while rolling back recovered incomplete transactions
+#
+CREATE TABLE t (a INT) ENGINE=InnoDB;
+BEGIN;
+COMMIT;
+connect con$c,localhost,root,,;
+CREATE TABLE t8 (a SERIAL, b INT UNIQUE, c INT UNIQUE) ENGINE=InnoDB;
+BEGIN;
+INSERT INTO t8 (a) SELECT NULL FROM t;
+UPDATE t8 SET a=a+100, b=a;
+DELETE FROM t8;
+connect con$c,localhost,root,,;
+CREATE TABLE t7 (a SERIAL, b INT UNIQUE, c INT UNIQUE) ENGINE=InnoDB;
+BEGIN;
+INSERT INTO t7 (a) SELECT NULL FROM t;
+UPDATE t7 SET a=a+100, b=a;
+DELETE FROM t7;
+connect con$c,localhost,root,,;
+CREATE TABLE t6 (a SERIAL, b INT UNIQUE, c INT UNIQUE) ENGINE=InnoDB;
+BEGIN;
+INSERT INTO t6 (a) SELECT NULL FROM t;
+UPDATE t6 SET a=a+100, b=a;
+DELETE FROM t6;
+connect con$c,localhost,root,,;
+CREATE TABLE t5 (a SERIAL, b INT UNIQUE, c INT UNIQUE) ENGINE=InnoDB;
+BEGIN;
+INSERT INTO t5 (a) SELECT NULL FROM t;
+UPDATE t5 SET a=a+100, b=a;
+DELETE FROM t5;
+connect con$c,localhost,root,,;
+CREATE TABLE t4 (a SERIAL, b INT UNIQUE, c INT UNIQUE) ENGINE=InnoDB;
+BEGIN;
+INSERT INTO t4 (a) SELECT NULL FROM t;
+UPDATE t4 SET a=a+100, b=a;
+DELETE FROM t4;
+connect con$c,localhost,root,,;
+CREATE TABLE t3 (a SERIAL, b INT UNIQUE, c INT UNIQUE) ENGINE=InnoDB;
+BEGIN;
+INSERT INTO t3 (a) SELECT NULL FROM t;
+UPDATE t3 SET a=a+100, b=a;
+DELETE FROM t3;
+connect con$c,localhost,root,,;
+CREATE TABLE t2 (a SERIAL, b INT UNIQUE, c INT UNIQUE) ENGINE=InnoDB;
+BEGIN;
+INSERT INTO t2 (a) SELECT NULL FROM t;
+UPDATE t2 SET a=a+100, b=a;
+DELETE FROM t2;
+connect con$c,localhost,root,,;
+CREATE TABLE t1 (a SERIAL, b INT UNIQUE, c INT UNIQUE) ENGINE=InnoDB;
+BEGIN;
+INSERT INTO t1 (a) SELECT NULL FROM t;
+UPDATE t1 SET a=a+100, b=a;
+DELETE FROM t1;
+INSERT INTO t1(a) SELECT NULL FROM t;
+INSERT INTO t1(a) SELECT NULL FROM t1;
+INSERT INTO t1(a) SELECT NULL FROM t1;
+INSERT INTO t1(a) SELECT NULL FROM t1;
+INSERT INTO t1(a) SELECT NULL FROM t1;
+connection default;
+SET GLOBAL innodb_flush_log_at_trx_commit=1;
+CREATE TABLE u(a SERIAL) ENGINE=INNODB;
+DROP TABLE t,u;
diff --git a/mysql-test/suite/innodb/r/update_time.result b/mysql-test/suite/innodb/r/update_time.result
index ab3eeb08dc7..d8b9069b1ae 100644
--- a/mysql-test/suite/innodb/r/update_time.result
+++ b/mysql-test/suite/innodb/r/update_time.result
@@ -43,7 +43,6 @@ XA PREPARE 'xatrx';
CONNECT con1,localhost,root,,;
call mtr.add_suppression("Found 1 prepared XA transactions");
FLUSH TABLES;
-# Kill and restart
SELECT update_time FROM information_schema.tables WHERE table_name = 't';
update_time
NULL
diff --git a/mysql-test/suite/innodb/t/recovery_shutdown.test b/mysql-test/suite/innodb/t/recovery_shutdown.test
new file mode 100644
index 00000000000..fbe26368e1b
--- /dev/null
+++ b/mysql-test/suite/innodb/t/recovery_shutdown.test
@@ -0,0 +1,59 @@
+--source include/have_innodb.inc
+--source include/not_embedded.inc
+
+--echo #
+--echo # MDEV-13797 InnoDB may hang if shutdown is initiated soon after startup
+--echo # while rolling back recovered incomplete transactions
+--echo #
+
+CREATE TABLE t (a INT) ENGINE=InnoDB;
+let $size = 100;
+let $trx = 8;
+let $c = $size;
+BEGIN;
+--disable_query_log
+while ($c) {
+INSERT INTO t VALUES();
+dec $c;
+}
+--enable_query_log
+COMMIT;
+
+let $c = $trx;
+while ($c)
+{
+connect (con$c,localhost,root,,);
+eval CREATE TABLE t$c (a SERIAL, b INT UNIQUE, c INT UNIQUE) ENGINE=InnoDB;
+BEGIN;
+eval INSERT INTO t$c (a) SELECT NULL FROM t;
+eval UPDATE t$c SET a=a+$size, b=a;
+eval DELETE FROM t$c;
+dec $c;
+}
+
+INSERT INTO t1(a) SELECT NULL FROM t;
+INSERT INTO t1(a) SELECT NULL FROM t1;
+INSERT INTO t1(a) SELECT NULL FROM t1;
+INSERT INTO t1(a) SELECT NULL FROM t1;
+INSERT INTO t1(a) SELECT NULL FROM t1;
+
+--connection default
+SET GLOBAL innodb_flush_log_at_trx_commit=1;
+CREATE TABLE u(a SERIAL) ENGINE=INNODB;
+
+--let $shutdown_timeout=0
+--source include/restart_mysqld.inc
+--let $shutdown_timeout=60
+--source include/restart_mysqld.inc
+
+--disable_query_log
+let $c = $trx;
+while ($c)
+{
+disconnect con$c;
+eval DROP TABLE t$c;
+dec $c;
+}
+--enable_query_log
+
+DROP TABLE t,u;
diff --git a/mysql-test/suite/innodb/t/table_definition_cache_debug.opt b/mysql-test/suite/innodb/t/table_definition_cache_debug.opt
index 6195e055dc8..6d341857397 100644
--- a/mysql-test/suite/innodb/t/table_definition_cache_debug.opt
+++ b/mysql-test/suite/innodb/t/table_definition_cache_debug.opt
@@ -1 +1 @@
---innodb-open-files=13
+--innodb-open-files=20
diff --git a/mysql-test/suite/innodb/t/update_time.test b/mysql-test/suite/innodb/t/update_time.test
index e2213c5d9b7..1a00e3b9f73 100644
--- a/mysql-test/suite/innodb/t/update_time.test
+++ b/mysql-test/suite/innodb/t/update_time.test
@@ -67,7 +67,8 @@ CONNECT (con1,localhost,root,,);
call mtr.add_suppression("Found 1 prepared XA transactions");
FLUSH TABLES;
---source include/kill_and_restart_mysqld.inc
+--let $shutdown_timeout=0
+--source include/restart_mysqld.inc
SELECT update_time FROM information_schema.tables WHERE table_name = 't';
diff --git a/mysql-test/suite/innodb_gis/r/kill_server.result b/mysql-test/suite/innodb_gis/r/kill_server.result
index 579317872b4..eac4feb442f 100644
--- a/mysql-test/suite/innodb_gis/r/kill_server.result
+++ b/mysql-test/suite/innodb_gis/r/kill_server.result
@@ -36,6 +36,5 @@ call mtr.add_suppression("InnoDB: A copy of page \[page id: space=[0-9]+, page n
START TRANSACTION;
CALL insert_t1(5000);
COMMIT;
-# Kill and restart
drop procedure insert_t1;
drop table t1;
diff --git a/mysql-test/suite/innodb_gis/r/rtree_compress2.result b/mysql-test/suite/innodb_gis/r/rtree_compress2.result
index 3522a1097aa..04940f2b3b1 100644
--- a/mysql-test/suite/innodb_gis/r/rtree_compress2.result
+++ b/mysql-test/suite/innodb_gis/r/rtree_compress2.result
@@ -20,6 +20,5 @@ call mtr.add_suppression("InnoDB: A copy of page \[page id: space=[0-9]+, page n
START TRANSACTION;
CALL insert_t1(5000);
COMMIT;
-# Kill and restart
drop procedure insert_t1;
drop table t1;
diff --git a/mysql-test/suite/innodb_gis/r/rtree_crash.result b/mysql-test/suite/innodb_gis/r/rtree_crash.result
deleted file mode 100644
index 12ca15a420d..00000000000
--- a/mysql-test/suite/innodb_gis/r/rtree_crash.result
+++ /dev/null
@@ -1,41 +0,0 @@
-create table t1 (c1 int, c2 geometry not null, spatial index (c2))engine=innodb;
-create procedure insert_t1(IN total int)
-begin
-declare i int default 1;
-while (i <= total) DO
-insert into t1 values (i, Point(i, i));
-set i = i + 1;
-end while;
-end|
-CALL insert_t1(5000);
-select count(*) from t1;
-count(*)
-5000
-check table t1;
-Table Op Msg_type Msg_text
-test.t1 check status OK
-truncate table t1;
-CALL insert_t1(10000);
-select count(*) from t1;
-count(*)
-10000
-drop index c2 on t1;
-create spatial index idx on t1(c2);
-show create table t1;
-Table Create Table
-t1 CREATE TABLE `t1` (
- `c1` int(11) DEFAULT NULL,
- `c2` geometry NOT NULL,
- SPATIAL KEY `idx` (`c2`)
-) ENGINE=InnoDB DEFAULT CHARSET=latin1
-check table t1;
-Table Op Msg_type Msg_text
-test.t1 check status OK
-truncate table t1;
-call mtr.add_suppression("InnoDB: page [0-9]+ in the doublewrite buffer is not within space bounds.*");
-START TRANSACTION;
-CALL insert_t1(5000);
-COMMIT;
-# Kill and restart
-drop procedure insert_t1;
-drop table t1;
diff --git a/mysql-test/suite/innodb_gis/r/rtree_recovery.result b/mysql-test/suite/innodb_gis/r/rtree_recovery.result
index d2f4409f38c..3572e3e0bed 100644
--- a/mysql-test/suite/innodb_gis/r/rtree_recovery.result
+++ b/mysql-test/suite/innodb_gis/r/rtree_recovery.result
@@ -18,7 +18,6 @@ end while;
end|
CALL insert_t1(367);
COMMIT;
-# Kill and restart
check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
@@ -29,7 +28,6 @@ CALL update_t1(367);
SET @poly1 = ST_GeomFromText('POLYGON((10000 10000, 10000 10350, 10350 10350, 10350 10000, 10000 10000))');
delete from t1 where ST_Contains(@poly1, c2);
COMMIT;
-# Kill and restart
check table t1;
Table Op Msg_type Msg_text
test.t1 check status OK
diff --git a/mysql-test/suite/innodb_gis/r/types.result b/mysql-test/suite/innodb_gis/r/types.result
index ac1802085d6..7d823927df1 100644
--- a/mysql-test/suite/innodb_gis/r/types.result
+++ b/mysql-test/suite/innodb_gis/r/types.result
@@ -53,7 +53,6 @@ COMMIT;
INSERT INTO t_wl6455 VALUES(11, POINT(11,11));
BEGIN;
INSERT INTO t_wl6455 VALUES(1, POINT(1,1));
-# Kill and restart
CHECK TABLE t_wl6455;
Table Op Msg_type Msg_text
test.t_wl6455 check status OK
diff --git a/mysql-test/suite/innodb_gis/t/kill_server.test b/mysql-test/suite/innodb_gis/t/kill_server.test
index 9b6469606ca..028bbbdd40d 100644
--- a/mysql-test/suite/innodb_gis/t/kill_server.test
+++ b/mysql-test/suite/innodb_gis/t/kill_server.test
@@ -58,7 +58,8 @@ CALL insert_t1(5000);
COMMIT;
---source include/kill_and_restart_mysqld.inc
+--let $shutdown_timeout=0
+--source include/restart_mysqld.inc
# Clean up.
drop procedure insert_t1;
diff --git a/mysql-test/suite/innodb_gis/t/rtree_compress2.test b/mysql-test/suite/innodb_gis/t/rtree_compress2.test
index 5956fc9a774..86ef1171833 100644
--- a/mysql-test/suite/innodb_gis/t/rtree_compress2.test
+++ b/mysql-test/suite/innodb_gis/t/rtree_compress2.test
@@ -51,7 +51,8 @@ CALL insert_t1(5000);
COMMIT;
---source include/kill_and_restart_mysqld.inc
+--let $shutdown_timeout=0
+--source include/restart_mysqld.inc
# Clean up.
drop procedure insert_t1;
diff --git a/mysql-test/suite/innodb_gis/t/rtree_recovery.test b/mysql-test/suite/innodb_gis/t/rtree_recovery.test
index 9e332c089f2..d995048ceac 100644
--- a/mysql-test/suite/innodb_gis/t/rtree_recovery.test
+++ b/mysql-test/suite/innodb_gis/t/rtree_recovery.test
@@ -44,7 +44,8 @@ delimiter ;|
CALL insert_t1(367);
COMMIT;
---source include/kill_and_restart_mysqld.inc
+--let $shutdown_timeout=0
+--source include/restart_mysqld.inc
# Check table.
check table t1;
@@ -63,7 +64,7 @@ SET @poly1 = ST_GeomFromText('POLYGON((10000 10000, 10000 10350, 10350 10350, 10
delete from t1 where ST_Contains(@poly1, c2);
COMMIT;
---source include/kill_and_restart_mysqld.inc
+--source include/restart_mysqld.inc
# Check table.
check table t1;
diff --git a/mysql-test/suite/innodb_gis/t/types.test b/mysql-test/suite/innodb_gis/t/types.test
index bd03e7b1dbe..65f65e5ae1f 100644
--- a/mysql-test/suite/innodb_gis/t/types.test
+++ b/mysql-test/suite/innodb_gis/t/types.test
@@ -73,7 +73,8 @@ INSERT INTO t_wl6455 VALUES(11, POINT(11,11));
BEGIN;
INSERT INTO t_wl6455 VALUES(1, POINT(1,1));
---source include/kill_and_restart_mysqld.inc
+--let $shutdown_timeout=0
+--source include/restart_mysqld.inc
CHECK TABLE t_wl6455;
SELECT ST_AsText(g) FROM t_wl6455;
diff --git a/mysql-test/suite/storage_engine/type_bit_indexes.result b/mysql-test/suite/storage_engine/type_bit_indexes.result
index e7c0cf656c5..af8ddf7d6c9 100644
--- a/mysql-test/suite/storage_engine/type_bit_indexes.result
+++ b/mysql-test/suite/storage_engine/type_bit_indexes.result
@@ -69,7 +69,7 @@ INSERT INTO t1 (a,b,c,d) VALUES
(1,0xFFFF,0xFFFFFFFF,0xFFFFFFFFFFFFFFFF);
EXPLAIN SELECT HEX(b+c) FROM t1 WHERE c > 1 OR HEX(b) < 0xFFFFFF;
id select_type table type possible_keys key key_len ref rows Extra
-# # # # # NULL # # # #
+# # # # # b_c # # # #
SELECT HEX(b+c) FROM t1 WHERE c > 1 OR HEX(b) < 0xFFFFFF;
HEX(b+c)
10
@@ -98,7 +98,7 @@ INSERT INTO t1 (a,b,c,d) VALUES
(1,0xFFFF,0xFFFFFFFF,0xFFFFFFFFFFFFFFFF);
EXPLAIN SELECT DISTINCT a+0 FROM t1 ORDER BY a;
id select_type table type possible_keys key key_len ref rows Extra
-# # # # # NULL # # # #
+# # # # # a # # # #
SELECT DISTINCT a+0 FROM t1 ORDER BY a;
a+0
0
diff --git a/mysql-test/t/ctype_utf8.test b/mysql-test/t/ctype_utf8.test
index adb846a0df2..b839042b91e 100644
--- a/mysql-test/t/ctype_utf8.test
+++ b/mysql-test/t/ctype_utf8.test
@@ -1879,6 +1879,18 @@ let $ctype_unescape_combinations=selected;
--source include/ctype_unescape.inc
--echo #
+--echo # MDEV-12681 Wrong VIEW results for CHAR(0xDF USING latin1)
+--echo #
+
+SET NAMES utf8;
+SELECT CHAR(0xDF USING latin1);
+CREATE OR REPLACE VIEW v1 AS SELECT CHAR(0xDF USING latin1) AS c;
+SHOW CREATE VIEW v1;
+SELECT * FROM v1;
+DROP VIEW v1;
+
+
+--echo #
--echo # End of 10.0 tests
--echo #
diff --git a/mysql-test/t/ctype_utf8mb4.test b/mysql-test/t/ctype_utf8mb4.test
index 94b5d77ad90..7aa644fe8a9 100644
--- a/mysql-test/t/ctype_utf8mb4.test
+++ b/mysql-test/t/ctype_utf8mb4.test
@@ -1923,6 +1923,24 @@ SELECT * FROM t1;
DROP TABLE t1;
--echo #
+--echo # MDEV-8949: COLUMN_CREATE unicode name breakage
+--echo #
+
+SET NAMES utf8mb4;
+SELECT COLUMN_JSON(COLUMN_CREATE(_utf8mb4 0xF09F988E, 1));
+SELECT COLUMN_LIST(COLUMN_CREATE(_utf8mb4 0xF09F988E, 1));
+SELECT COLUMN_GET(COLUMN_CREATE(_utf8mb4 0xF09F988E, 1), _utf8mb4 0xF09F988E
+as int);
+
+CREATE TABLE t1 AS SELECT
+ COLUMN_LIST(COLUMN_CREATE('a',1)),
+ COLUMN_JSON(COLUMN_CREATE('b',1));
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+SET NAMES default;
+
+--echo #
--echo # End of 10.0 tests
--echo #
diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test
index a75330ab981..dbb7502a3ec 100644
--- a/mysql-test/t/func_str.test
+++ b/mysql-test/t/func_str.test
@@ -1810,6 +1810,18 @@ set global max_allowed_packet=default;
--echo #
--echo #
+--echo # Start of 10.0 tests
+--echo #
+
+--echo #
+--echo # MDEV-12681 Wrong VIEW results for CHAR(0xDF USING latin1)
+--echo #
+
+EXPLAIN EXTENDED SELECT CHAR(0xDF USING latin1);
+EXPLAIN EXTENDED SELECT CHAR(0xDF USING `binary`);
+EXPLAIN EXTENDED SELECT CHAR(0xDF);
+
+--echo #
--echo # Start of 10.1 tests
--echo #
@@ -1854,6 +1866,15 @@ SELECT f1,HEX(f2) FROM t1 WHERE f1='YQ==' AND (f2= from_base64(
DROP TABLE t1;
--echo #
+--echo # End of 10.1 tests
+--echo #
+
+
+--echo #
+--echo # Start of 10.3 tests
+--echo #
+
+--echo #
--echo # MDEV-12685 Oracle-compatible function CHR()
--echo #
select chr(65);
@@ -1865,15 +1886,6 @@ drop database mysqltest1;
use test;
--echo #
---echo # End of 10.1 tests
---echo #
-
-
---echo #
---echo # Start of 10.3 tests
---echo #
-
---echo #
--echo # MDEV-12592 Illegal mix of collations with the HEX function
--echo #
diff --git a/mysql-test/t/loadxml.test b/mysql-test/t/loadxml.test
index 0bd97a81649..623deea6ec6 100644
--- a/mysql-test/t/loadxml.test
+++ b/mysql-test/t/loadxml.test
@@ -143,3 +143,22 @@ LOAD XML INFILE '../../std_data/loaddata/mdev12696.xml' INTO TABLE v1 (c1);
LOAD XML INFILE '../../std_data/loaddata/mdev12696.xml' INTO TABLE v1 (c2);
DROP VIEW v1;
DROP TABLE t1;
+
+--echo #
+--echo # MDEV-14628 Wrong autoinc value assigned by LOAD XML in the NO_AUTO_VALUE_ON_ZERO mode
+--echo #
+
+SET sql_mode=NO_AUTO_VALUE_ON_ZERO;
+CREATE TABLE t1 (a INT AUTO_INCREMENT PRIMARY KEY, b TEXT);
+LOAD XML INFILE '../../std_data/loaddata/mdev14628a.xml' INTO TABLE t1 ROWS IDENTIFIED BY '<row>';
+SELECT * FROM t1 ORDER BY b;
+DROP TABLE t1;
+SET sql_mode=DEFAULT;
+
+SET sql_mode='';
+CREATE TABLE t1 (id INT, g GEOMETRY NOT NULL);
+--error ER_WARN_NULL_TO_NOTNULL
+LOAD XML INFILE '../../std_data/loaddata/mdev14628b.xml' INTO TABLE t1 ROWS IDENTIFIED BY '<row>';
+SELECT * FROM t1;
+DROP TABLE t1;
+SET sql_mode=DEFAULT;
diff --git a/mysys/ma_dyncol.c b/mysys/ma_dyncol.c
index 125b3a4632d..3c15e373182 100644
--- a/mysys/ma_dyncol.c
+++ b/mysys/ma_dyncol.c
@@ -4183,8 +4183,7 @@ mariadb_dyncol_json_internal(DYNAMIC_COLUMN *str, DYNAMIC_STRING *json,
}
else
{
- if ((rc= mariadb_dyncol_val_str(json, &val,
- &my_charset_utf8_general_ci, '"')) < 0)
+ if ((rc= mariadb_dyncol_val_str(json, &val, DYNCOL_UTF, '"')) < 0)
goto err;
}
}
diff --git a/mysys/thr_alarm.c b/mysys/thr_alarm.c
index a101c23be58..97656e6b77f 100644
--- a/mysys/thr_alarm.c
+++ b/mysys/thr_alarm.c
@@ -274,7 +274,7 @@ void thr_end_alarm(thr_alarm_t *alarmed)
/*
Come here when some alarm in queue is due.
Mark all alarms with are finnished in list.
- Shedule alarms to be sent again after 1-10 sec (many alarms at once)
+ Schedule alarms to be sent again after 1-10 sec (many alarms at once)
If alarm_aborted is set then all alarms are given and resent
every second.
*/
@@ -426,7 +426,7 @@ void end_thr_alarm(my_bool free_structures)
if (alarm_aborted != 1) /* If memory not freed */
{
mysql_mutex_lock(&LOCK_alarm);
- DBUG_PRINT("info",("Resheduling %d waiting alarms",alarm_queue.elements));
+ DBUG_PRINT("info",("Rescheduling %d waiting alarms",alarm_queue.elements));
alarm_aborted= -1; /* mark aborted */
if (alarm_queue.elements || (alarm_thread_running && free_structures))
{
diff --git a/sql/field.cc b/sql/field.cc
index 51562dd4198..7d8f8a9af20 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -1253,6 +1253,20 @@ warn:
}
+bool Field::load_data_set_null(THD *thd)
+{
+ reset();
+ set_null();
+ if (!maybe_null())
+ {
+ if (this != table->next_number_field)
+ set_warning(Sql_condition::WARN_LEVEL_WARN, ER_WARN_NULL_TO_NOTNULL, 1);
+ }
+ set_has_explicit_value(); // Do not auto-update this field
+ return false;
+}
+
+
/**
Numeric fields base class constructor.
*/
@@ -5152,6 +5166,27 @@ int Field_timestamp::set_time()
return 0;
}
+
+bool Field_timestamp::load_data_set_null(THD *thd)
+{
+ if (!maybe_null())
+ {
+ /*
+ Timestamp fields that are NOT NULL are autoupdated if there is no
+ corresponding value in the data file.
+ */
+ set_time();
+ }
+ else
+ {
+ reset();
+ set_null();
+ }
+ set_has_explicit_value(); // Do not auto-update this field
+ return false;
+}
+
+
#ifdef NOT_USED
static void store_native(ulonglong num, uchar *to, uint bytes)
{
@@ -8734,6 +8769,22 @@ bool Field_geom::can_optimize_range(const Item_bool_func *cond,
return item->cmp_type() == STRING_RESULT;
}
+
+bool Field_geom::load_data_set_null(THD *thd)
+{
+ Field_blob::reset();
+ if (!maybe_null())
+ {
+ my_error(ER_WARN_NULL_TO_NOTNULL, MYF(0), field_name.str,
+ thd->get_stmt_da()->current_row_for_warning());
+ return true;
+ }
+ set_null();
+ set_has_explicit_value(); // Do not auto-update this field
+ return false;
+}
+
+
#endif /*HAVE_SPATIAL*/
/****************************************************************************
diff --git a/sql/field.h b/sql/field.h
index eb6510bc9a4..624921b628e 100644
--- a/sql/field.h
+++ b/sql/field.h
@@ -1161,6 +1161,8 @@ public:
{ if (null_ptr) null_ptr[row_offset]&= (uchar) ~null_bit; }
inline bool maybe_null(void) const
{ return null_ptr != 0 || table->maybe_null; }
+ // Set to NULL on LOAD DATA or LOAD XML
+ virtual bool load_data_set_null(THD *thd);
/* @return true if this field is NULL-able (even if temporarily) */
inline bool real_maybe_null(void) const { return null_ptr != 0; }
@@ -2457,6 +2459,7 @@ public:
{
return get_equal_const_item_datetime(thd, ctx, const_item);
}
+ bool load_data_set_null(THD *thd);
uint size_of() const { return sizeof(*this); }
};
@@ -3649,6 +3652,7 @@ public:
but the underlying blob must still be reset.
*/
int reset(void) { return Field_blob::reset() || !maybe_null(); }
+ bool load_data_set_null(THD *thd);
geometry_type get_geometry_type() { return geom_type; };
static geometry_type geometry_type_merge(geometry_type, geometry_type);
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 191616365fd..dff5fb5df0f 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -6960,20 +6960,20 @@ longlong Item_func_dyncol_exists::val_int()
null_value= 1;
return 1;
}
- if (my_charset_same(nm->charset(), &my_charset_utf8_general_ci))
+ if (my_charset_same(nm->charset(), DYNCOL_UTF))
{
buf.str= (char *) nm->ptr();
buf.length= nm->length();
}
else
{
- uint strlen= nm->length() * my_charset_utf8_general_ci.mbmaxlen + 1;
+ uint strlen= nm->length() * DYNCOL_UTF->mbmaxlen + 1;
uint dummy_errors;
buf.str= (char *) current_thd->alloc(strlen);
if (buf.str)
{
buf.length=
- copy_and_convert(buf.str, strlen, &my_charset_utf8_general_ci,
+ copy_and_convert(buf.str, strlen, DYNCOL_UTF,
nm->ptr(), nm->length(), nm->charset(),
&dummy_errors);
}
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 90bfb11e822..483a6468c2e 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -2918,6 +2918,20 @@ String *Item_func_make_set::val_str(String *str)
}
+void Item_func_char::print(String *str, enum_query_type query_type)
+{
+ str->append(Item_func_char::func_name());
+ str->append('(');
+ print_args(str, 0, query_type);
+ if (collation.collation != &my_charset_bin)
+ {
+ str->append(C_STRING_WITH_LEN(" using "));
+ str->append(collation.collation->csname);
+ }
+ str->append(')');
+}
+
+
String *Item_func_char::val_str(String *str)
{
DBUG_ASSERT(fixed == 1);
@@ -4517,20 +4531,19 @@ bool Item_func_dyncol_create::prepare_arguments(THD *thd, bool force_names_arg)
if (res)
{
// guaranty UTF-8 string for names
- if (my_charset_same(res->charset(), &my_charset_utf8_general_ci))
+ if (my_charset_same(res->charset(), DYNCOL_UTF))
{
keys_str[i].length= res->length();
keys_str[i].str= thd->strmake(res->ptr(), res->length());
}
else
{
- uint strlen= res->length() * my_charset_utf8_general_ci.mbmaxlen + 1;
+ uint strlen= res->length() * DYNCOL_UTF->mbmaxlen + 1;
uint dummy_errors;
- char *str= (char *) thd->alloc(strlen);
- if (str)
+ if (char *str= (char *) thd->alloc(strlen))
{
keys_str[i].length=
- copy_and_convert(str, strlen, &my_charset_utf8_general_ci,
+ copy_and_convert(str, strlen, DYNCOL_UTF,
res->ptr(), res->length(), res->charset(),
&dummy_errors);
keys_str[i].str= str;
@@ -4750,9 +4763,10 @@ String *Item_func_dyncol_json::val_str(String *str)
char *ptr;
size_t length, alloc_length;
dynstr_reassociate(&json, &ptr, &length, &alloc_length);
- str->reset(ptr, length, alloc_length, &my_charset_utf8_general_ci);
+ str->reset(ptr, length, alloc_length, DYNCOL_UTF);
null_value= FALSE;
}
+ str->set_charset(DYNCOL_UTF);
return str;
null:
@@ -4852,20 +4866,20 @@ bool Item_dyncol_get::get_dyn_value(THD *thd, DYNAMIC_COLUMN_VALUE *val,
return 1;
}
- if (my_charset_same(nm->charset(), &my_charset_utf8_general_ci))
+ if (my_charset_same(nm->charset(), DYNCOL_UTF))
{
buf.str= (char *) nm->ptr();
buf.length= nm->length();
}
else
{
- uint strlen= nm->length() * my_charset_utf8_general_ci.mbmaxlen + 1;
+ uint strlen= nm->length() * DYNCOL_UTF->mbmaxlen + 1;
uint dummy_errors;
buf.str= (char *) thd->alloc(strlen);
if (buf.str)
{
buf.length=
- copy_and_convert(buf.str, strlen, &my_charset_utf8_general_ci,
+ copy_and_convert(buf.str, strlen, DYNCOL_UTF,
nm->ptr(), nm->length(), nm->charset(),
&dummy_errors);
}
@@ -5289,7 +5303,6 @@ String *Item_func_dyncol_list::val_str(String *str)
goto null;
str->length(0);
- str->set_charset(&my_charset_utf8_general_ci);
for (i= 0; i < count; i++)
{
append_identifier(current_thd, str, names[i].str, names[i].length);
@@ -5299,6 +5312,7 @@ String *Item_func_dyncol_list::val_str(String *str)
null_value= FALSE;
if (names)
my_free(names);
+ str->set_charset(DYNCOL_UTF);
return str;
null:
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index 5b5826b4637..faad324403a 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -978,6 +978,7 @@ public:
max_length= arg_count * 4;
}
const char *func_name() const { return "char"; }
+ void print(String *str, enum_query_type query_type);
Item *get_copy(THD *thd)
{ return get_item_copy<Item_func_char>(thd, this); }
};
@@ -1585,14 +1586,14 @@ public:
class Item_func_dyncol_json: public Item_str_func
{
public:
- Item_func_dyncol_json(THD *thd, Item *str): Item_str_func(thd, str) {}
+ Item_func_dyncol_json(THD *thd, Item *str): Item_str_func(thd, str)
+ {collation.set(DYNCOL_UTF);}
const char *func_name() const{ return "column_json"; }
String *val_str(String *);
void fix_length_and_dec()
{
max_length= MAX_BLOB_WIDTH;
maybe_null= 1;
- collation.set(&my_charset_bin);
decimals= 0;
}
Item *get_copy(THD *thd)
@@ -1645,7 +1646,8 @@ public:
class Item_func_dyncol_list: public Item_str_func
{
public:
- Item_func_dyncol_list(THD *thd, Item *str): Item_str_func(thd, str) {};
+ Item_func_dyncol_list(THD *thd, Item *str): Item_str_func(thd, str)
+ {collation.set(DYNCOL_UTF);}
void fix_length_and_dec() { maybe_null= 1; max_length= MAX_BLOB_WIDTH; };
const char *func_name() const{ return "column_list"; }
String *val_str(String *);
diff --git a/sql/sql_load.cc b/sql/sql_load.cc
index d972947c718..9a15d4b9c0d 100644
--- a/sql/sql_load.cc
+++ b/sql/sql_load.cc
@@ -1015,7 +1015,6 @@ continue_loop:;
}
-
static int
read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
List<Item> &fields_vars, List<Item> &set_fields,
@@ -1094,28 +1093,9 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
}
else
{
- Field *field= real_item->field;
- if (field->reset())
- {
- my_error(ER_WARN_NULL_TO_NOTNULL, MYF(0), field->field_name.str,
- thd->get_stmt_da()->current_row_for_warning());
+ DBUG_ASSERT(real_item->field->table == table);
+ if (real_item->field->load_data_set_null(thd))
DBUG_RETURN(1);
- }
- field->set_null();
- if (!field->maybe_null())
- {
- /*
- Timestamp fields that are NOT NULL are autoupdated if there is no
- corresponding value in the data file.
- */
- if (field->type() == MYSQL_TYPE_TIMESTAMP)
- field->set_time();
- else if (field != table->next_number_field)
- field->set_warning(Sql_condition::WARN_LEVEL_WARN,
- ER_WARN_NULL_TO_NOTNULL, 1);
- }
- /* Do not auto-update this field. */
- field->set_has_explicit_value();
}
continue;
@@ -1262,6 +1242,7 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
for ( ; ; it.rewind())
{
+ bool err;
if (thd->killed)
{
thd->send_kill_message();
@@ -1313,21 +1294,9 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
}
else
{
- Field *field= real_item->field;
- field->reset();
- field->set_null();
- if (field == table->next_number_field)
- table->auto_increment_field_not_null= TRUE;
- if (!field->maybe_null())
- {
- if (field->type() == FIELD_TYPE_TIMESTAMP)
- field->set_time();
- else if (field != table->next_number_field)
- field->set_warning(Sql_condition::WARN_LEVEL_WARN,
- ER_WARN_NULL_TO_NOTNULL, 1);
- }
- /* Do not auto-update this field. */
- field->set_has_explicit_value();
+ DBUG_ASSERT(real_item->field->table == table);
+ if (real_item->field->load_data_set_null(thd))
+ DBUG_RETURN(1);
}
continue;
}
@@ -1361,39 +1330,8 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
skip_lines--;
continue;
}
-
- if (item)
- {
- /* Have not read any field, thus input file is simply ended */
- if (item == fields_vars.head())
- break;
-
- for ( ; item; item= it++)
- {
- Item_field *real_item= item->field_for_view_update();
- if (item->type() == Item::STRING_ITEM)
- ((Item_user_var_as_out_param *)item)->set_null_value(cs);
- else if (!real_item)
- {
- my_error(ER_NONUPDATEABLE_COLUMN, MYF(0), item->name.str);
- DBUG_RETURN(1);
- }
- else
- {
- /*
- QQ: We probably should not throw warning for each field.
- But how about intention to always have the same number
- of warnings in THD::cuted_fields (and get rid of cuted_fields
- in the end ?)
- */
- thd->cuted_fields++;
- push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
- ER_WARN_TOO_FEW_RECORDS,
- ER_THD(thd, ER_WARN_TOO_FEW_RECORDS),
- thd->get_stmt_da()->current_row_for_warning());
- }
- }
- }
+
+ DBUG_ASSERT(!item);
if (thd->killed ||
fill_record_n_invoke_before_triggers(thd, table, set_fields, set_values,
@@ -1410,7 +1348,9 @@ read_xml_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list,
DBUG_RETURN(-1);
}
- if (write_record(thd, table, &info))
+ err= write_record(thd, table, &info);
+ table->auto_increment_field_not_null= false;
+ if (err)
DBUG_RETURN(1);
/*
diff --git a/sql/sql_show.cc b/sql/sql_show.cc
index c374425f74a..8ac472bd626 100644
--- a/sql/sql_show.cc
+++ b/sql/sql_show.cc
@@ -2791,6 +2791,7 @@ void mysqld_list_processes(THD *thd,const char *user, bool verbose)
{
thd_info->proc_info= "Busy";
thd_info->progress= 0.0;
+ thd_info->db= "";
}
thd_info->state_info= thread_state_info(tmp);
diff --git a/storage/innobase/ha/ha0ha.cc b/storage/innobase/ha/ha0ha.cc
index f620db6f62e..da542d4f742 100644
--- a/storage/innobase/ha/ha0ha.cc
+++ b/storage/innobase/ha/ha0ha.cc
@@ -489,62 +489,4 @@ ha_validate(
return(ok);
}
#endif /* defined UNIV_AHI_DEBUG || defined UNIV_DEBUG */
-
-/*************************************************************//**
-Prints info of a hash table. */
-void
-ha_print_info(
-/*==========*/
- FILE* file, /*!< in: file where to print */
- hash_table_t* table) /*!< in: hash table */
-{
-#ifdef UNIV_DEBUG
-/* Some of the code here is disabled for performance reasons in production
-builds, see http://bugs.mysql.com/36941 */
-#define PRINT_USED_CELLS
-#endif /* UNIV_DEBUG */
-
-#ifdef PRINT_USED_CELLS
- hash_cell_t* cell;
- ulint cells = 0;
- ulint i;
-#endif /* PRINT_USED_CELLS */
- ulint n_bufs;
-
- ut_ad(table);
- ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
-#ifdef PRINT_USED_CELLS
- for (i = 0; i < hash_get_n_cells(table); i++) {
-
- cell = hash_get_nth_cell(table, i);
-
- if (cell->node) {
-
- cells++;
- }
- }
-#endif /* PRINT_USED_CELLS */
-
- fprintf(file, "Hash table size %lu",
- (ulong) hash_get_n_cells(table));
-
-#ifdef PRINT_USED_CELLS
- fprintf(file, ", used cells %lu", (ulong) cells);
-#endif /* PRINT_USED_CELLS */
-
- if (table->heaps == NULL && table->heap != NULL) {
-
- /* This calculation is intended for the adaptive hash
- index: how many buffer frames we have reserved? */
-
- n_bufs = UT_LIST_GET_LEN(table->heap->base) - 1;
-
- if (table->heap->free_block) {
- n_bufs++;
- }
-
- fprintf(file, ", node heap has %lu buffer(s)\n",
- (ulong) n_bufs);
- }
-}
#endif /* BTR_CUR_HASH_ADAPT */
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 49f3e1f055c..351655004b4 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -3746,8 +3746,7 @@ innobase_init(
/* Currently, Galera does not support VATS lock schedule algorithm. */
if (innodb_lock_schedule_algorithm == INNODB_LOCK_SCHEDULE_ALGORITHM_VATS
&& global_system_variables.wsrep_on) {
- ib::info() << "In Galera environment Variance-Aware-Transaction-Sheduling Algorithm"
- " is not supported. Falling back to First-Come-First-Served order. ";
+ ib::info() << "For Galera, using innodb_lock_schedule_algorithm=fcfs";
innodb_lock_schedule_algorithm = INNODB_LOCK_SCHEDULE_ALGORITHM_FCFS;
}
#endif /* WITH_WSREP */
diff --git a/storage/innobase/include/ha0ha.h b/storage/innobase/include/ha0ha.h
index db53b6c6580..ca4cb0a5f8f 100644
--- a/storage/innobase/include/ha0ha.h
+++ b/storage/innobase/include/ha0ha.h
@@ -198,13 +198,6 @@ ha_validate(
ulint start_index, /*!< in: start index */
ulint end_index); /*!< in: end index */
#endif /* defined UNIV_AHI_DEBUG || defined UNIV_DEBUG */
-/*************************************************************//**
-Prints info of a hash table. */
-void
-ha_print_info(
-/*==========*/
- FILE* file, /*!< in: file where to print */
- hash_table_t* table); /*!< in: hash table */
/** The hash table external chain node */
struct ha_node_t {
diff --git a/storage/innobase/include/que0que.h b/storage/innobase/include/que0que.h
index 763b16820d8..13be7291f00 100644
--- a/storage/innobase/include/que0que.h
+++ b/storage/innobase/include/que0que.h
@@ -381,9 +381,6 @@ struct que_thr_t{
thrs; /*!< list of thread nodes of the fork
node */
UT_LIST_NODE_T(que_thr_t)
- trx_thrs; /*!< lists of threads in wait list of
- the trx */
- UT_LIST_NODE_T(que_thr_t)
queue; /*!< list of runnable thread nodes in
the server task queue */
ulint fk_cascade_depth; /*!< maximum cascading call depth
diff --git a/storage/innobase/include/trx0roll.h b/storage/innobase/include/trx0roll.h
index 8908376bff1..f7b999ae70a 100644
--- a/storage/innobase/include/trx0roll.h
+++ b/storage/innobase/include/trx0roll.h
@@ -33,7 +33,8 @@ Created 3/26/1996 Heikki Tuuri
#include "mtr0mtr.h"
#include "trx0sys.h"
-extern bool trx_rollback_or_clean_is_active;
+extern bool trx_rollback_or_clean_is_active;
+extern const trx_t* trx_roll_crash_recv_trx;
/*******************************************************************//**
Determines if this transaction is rolling back an incomplete transaction
@@ -62,6 +63,10 @@ trx_undo_rec_t*
trx_roll_pop_top_rec_of_trx(trx_t* trx, roll_ptr_t* roll_ptr, mem_heap_t* heap)
MY_ATTRIBUTE((nonnull, warn_unused_result));
+/** Report progress when rolling back a row of a recovered transaction.
+@return whether the rollback should be aborted due to pending shutdown */
+bool
+trx_roll_must_shutdown();
/*******************************************************************//**
Rollback or clean up any incomplete transactions which were
encountered in crash recovery. If the transaction already was
diff --git a/storage/innobase/row/row0quiesce.cc b/storage/innobase/row/row0quiesce.cc
index dd6289c91e6..21cc67620f6 100644
--- a/storage/innobase/row/row0quiesce.cc
+++ b/storage/innobase/row/row0quiesce.cc
@@ -520,7 +520,7 @@ row_quiesce_table_start(
ut_ad(fil_space_get(table->space) != NULL);
ib::info() << "Sync to disk of " << table->name << " started.";
- if (trx_purge_state() != PURGE_STATE_DISABLED) {
+ if (srv_undo_sources) {
trx_purge_stop();
}
@@ -603,7 +603,7 @@ row_quiesce_table_complete(
ib::info() << "Deleting the meta-data file '" << cfg_name << "'";
}
- if (trx_purge_state() != PURGE_STATE_DISABLED) {
+ if (srv_undo_sources) {
trx_purge_run();
}
diff --git a/storage/innobase/row/row0umod.cc b/storage/innobase/row/row0umod.cc
index 0b1d800212f..c614f75d005 100644
--- a/storage/innobase/row/row0umod.cc
+++ b/storage/innobase/row/row0umod.cc
@@ -1192,7 +1192,16 @@ close_table:
if (!row_undo_search_clust_to_pcur(node)) {
/* As long as this rolling-back transaction exists,
the PRIMARY KEY value pointed to by the undo log
- record must exist. But, it is possible that the record
+ record should exist.
+
+ However, if InnoDB is killed during a rollback, or
+ shut down during the rollback of recovered
+ transactions, then after restart we may try to roll
+ back some of the same undo log records again, because
+ trx_roll_try_truncate() is not being invoked after
+ every undo log record.
+
+ It is also possible that the record
was not modified yet (the DB_ROLL_PTR does not match
node->roll_ptr) and thus there is nothing to roll back.
@@ -1200,8 +1209,11 @@ close_table:
record after successfully acquiring an exclusive lock
on the the clustered index record. That lock will not
be released before the transaction is committed or
- fully rolled back. */
- ut_ad(node->pcur.btr_cur.low_match == node->ref->n_fields);
+ fully rolled back. (Exception: if the server was
+ killed, restarted, and shut down again before the
+ rollback of the recovered transaction was completed,
+ it is possible that the transaction was partially
+ rolled back and locks released.) */
goto close_table;
}
diff --git a/storage/innobase/row/row0undo.cc b/storage/innobase/row/row0undo.cc
index a1bb4cb7dbd..91c0a5f50ae 100644
--- a/storage/innobase/row/row0undo.cc
+++ b/storage/innobase/row/row0undo.cc
@@ -343,6 +343,13 @@ row_undo_step(
ut_ad(que_node_get_type(node) == QUE_NODE_UNDO);
+ if (UNIV_UNLIKELY(trx == trx_roll_crash_recv_trx)
+ && trx_roll_must_shutdown()) {
+ /* Shutdown has been initiated. */
+ trx->error_state = DB_INTERRUPTED;
+ return(NULL);
+ }
+
err = row_undo(node, thr);
trx->error_state = err;
diff --git a/storage/innobase/srv/srv0srv.cc b/storage/innobase/srv/srv0srv.cc
index c2a56a808e9..8ed5c30634b 100644
--- a/storage/innobase/srv/srv0srv.cc
+++ b/storage/innobase/srv/srv0srv.cc
@@ -1301,9 +1301,28 @@ srv_printf_innodb_monitor(
#ifdef BTR_CUR_HASH_ADAPT
for (ulint i = 0; i < btr_ahi_parts; ++i) {
- rw_lock_s_lock(btr_search_latches[i]);
- ha_print_info(file, btr_search_sys->hash_tables[i]);
- rw_lock_s_unlock(btr_search_latches[i]);
+ const hash_table_t* table = btr_search_sys->hash_tables[i];
+
+ ut_ad(table->magic_n == HASH_TABLE_MAGIC_N);
+ /* this is only used for buf_pool->page_hash */
+ ut_ad(!table->heaps);
+ /* this is used for the adaptive hash index */
+ ut_ad(table->heap);
+
+ const mem_heap_t* heap = table->heap;
+ /* The heap may change during the following call,
+ so the data displayed may be garbage. We intentionally
+ avoid acquiring btr_search_latches[] so that the
+ diagnostic output will not stop here even in case another
+ thread hangs while holding btr_search_latches[].
+
+ This should be safe from crashes, because
+ table->heap will be pointing to the same object
+ for the full lifetime of the server. Even during
+ btr_search_disable() the heap will stay valid. */
+ fprintf(file, "Hash table size " ULINTPF
+ ", node heap has " ULINTPF " buffer(s)\n",
+ table->n_cells, heap->base.count - !heap->free_block);
}
fprintf(file,
@@ -2831,6 +2850,9 @@ DECLARE_THREAD(srv_purge_coordinator_thread)(
purge_sys->running = false;
+ /* Ensure that the wait in trx_purge_stop() will terminate. */
+ os_event_set(purge_sys->event);
+
rw_lock_x_unlock(&purge_sys->latch);
#ifdef UNIV_DEBUG_THREAD_CREATION
diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc
index 6982754d795..9135f2e19f7 100644
--- a/storage/innobase/srv/srv0start.cc
+++ b/storage/innobase/srv/srv0start.cc
@@ -2618,8 +2618,6 @@ files_checked:
srv_start_state_set(SRV_START_STATE_MASTER);
}
- srv_is_being_started = false;
-
if (!srv_read_only_mode && srv_operation == SRV_OPERATION_NORMAL
&& srv_force_recovery < SRV_FORCE_NO_BACKGROUND) {
@@ -2647,6 +2645,8 @@ files_checked:
purge_sys->state = PURGE_STATE_DISABLED;
}
+ srv_is_being_started = false;
+
if (!srv_read_only_mode) {
/* wake main loop of page cleaner up */
os_event_set(buf_flush_event);
diff --git a/storage/innobase/trx/trx0purge.cc b/storage/innobase/trx/trx0purge.cc
index 4e51796a400..27a081c809f 100644
--- a/storage/innobase/trx/trx0purge.cc
+++ b/storage/innobase/trx/trx0purge.cc
@@ -1724,52 +1724,48 @@ void
trx_purge_stop(void)
/*================*/
{
- ut_a(srv_n_purge_threads > 0);
-
rw_lock_x_lock(&purge_sys->latch);
- const int64_t sig_count = os_event_reset(purge_sys->event);
- const purge_state_t state = purge_sys->state;
-
- ut_a(state == PURGE_STATE_RUN || state == PURGE_STATE_STOP);
-
- ++purge_sys->n_stop;
-
- if (state == PURGE_STATE_RUN) {
+ switch (purge_sys->state) {
+ case PURGE_STATE_INIT:
+ case PURGE_STATE_DISABLED:
+ ut_error;
+ case PURGE_STATE_EXIT:
+ /* Shutdown must have been initiated during
+ FLUSH TABLES FOR EXPORT. */
+ ut_ad(!srv_undo_sources);
+unlock:
+ rw_lock_x_unlock(&purge_sys->latch);
+ break;
+ case PURGE_STATE_STOP:
+ ut_ad(srv_n_purge_threads > 0);
+ ++purge_sys->n_stop;
+ purge_sys->state = PURGE_STATE_STOP;
+ if (!purge_sys->running) {
+ goto unlock;
+ }
+ ib::info() << "Waiting for purge to stop";
+ do {
+ rw_lock_x_unlock(&purge_sys->latch);
+ os_thread_sleep(10000);
+ rw_lock_x_lock(&purge_sys->latch);
+ } while (purge_sys->running);
+ goto unlock;
+ case PURGE_STATE_RUN:
+ ut_ad(srv_n_purge_threads > 0);
+ ++purge_sys->n_stop;
ib::info() << "Stopping purge";
/* We need to wakeup the purge thread in case it is suspended,
so that it can acknowledge the state change. */
+ const int64_t sig_count = os_event_reset(purge_sys->event);
+ purge_sys->state = PURGE_STATE_STOP;
srv_purge_wakeup();
- }
-
- purge_sys->state = PURGE_STATE_STOP;
-
- if (state != PURGE_STATE_STOP) {
rw_lock_x_unlock(&purge_sys->latch);
/* Wait for purge coordinator to signal that it
is suspended. */
os_event_wait_low(purge_sys->event, sig_count);
- } else {
- bool once = true;
-
- /* Wait for purge to signal that it has actually stopped. */
- while (purge_sys->running) {
-
- if (once) {
- ib::info() << "Waiting for purge to stop";
- once = false;
- }
-
- rw_lock_x_unlock(&purge_sys->latch);
-
- os_thread_sleep(10000);
-
- rw_lock_x_lock(&purge_sys->latch);
- }
-
- rw_lock_x_unlock(&purge_sys->latch);
}
MONITOR_INC_VALUE(MONITOR_PURGE_STOP_COUNT, 1);
@@ -1784,8 +1780,12 @@ trx_purge_run(void)
rw_lock_x_lock(&purge_sys->latch);
switch (purge_sys->state) {
- case PURGE_STATE_INIT:
case PURGE_STATE_EXIT:
+ /* Shutdown must have been initiated during
+ FLUSH TABLES FOR EXPORT. */
+ ut_ad(!srv_undo_sources);
+ break;
+ case PURGE_STATE_INIT:
case PURGE_STATE_DISABLED:
ut_error;
diff --git a/storage/innobase/trx/trx0roll.cc b/storage/innobase/trx/trx0roll.cc
index 97ab08c8329..caa1d6f3233 100644
--- a/storage/innobase/trx/trx0roll.cc
+++ b/storage/innobase/trx/trx0roll.cc
@@ -24,8 +24,10 @@ Transaction rollback
Created 3/26/1996 Heikki Tuuri
*******************************************************/
-#include "ha_prototypes.h"
+#include "my_config.h"
+#include <my_systemd.h>
+#include "ha_prototypes.h"
#include "trx0roll.h"
#include <mysql/service_wsrep.h>
@@ -56,14 +58,7 @@ static const ulint TRX_ROLL_TRUNC_THRESHOLD = 1;
bool trx_rollback_or_clean_is_active;
/** In crash recovery, the current trx to be rolled back; NULL otherwise */
-static const trx_t* trx_roll_crash_recv_trx = NULL;
-
-/** In crash recovery we set this to the undo n:o of the current trx to be
-rolled back. Then we can print how many % the rollback has progressed. */
-static undo_no_t trx_roll_max_undo_no;
-
-/** Auxiliary variable which tells the previous progress % we printed */
-static ulint trx_roll_progress_printed_pct;
+const trx_t* trx_roll_crash_recv_trx;
/****************************************************************//**
Finishes a transaction rollback. */
@@ -642,8 +637,6 @@ trx_rollback_active(
que_thr_t* thr;
roll_node_t* roll_node;
dict_table_t* table;
- int64_t rows_to_undo;
- const char* unit = "";
ibool dictionary_locked = FALSE;
heap = mem_heap_create(512);
@@ -662,28 +655,8 @@ trx_rollback_active(
ut_a(thr == que_fork_start_command(fork));
- trx_sys_mutex_enter();
-
trx_roll_crash_recv_trx = trx;
- trx_roll_max_undo_no = trx->undo_no;
-
- trx_roll_progress_printed_pct = 0;
-
- rows_to_undo = trx_roll_max_undo_no;
-
- trx_sys_mutex_exit();
-
- if (rows_to_undo > 1000000000) {
- rows_to_undo = rows_to_undo / 1000000;
- unit = "M";
- }
-
- const trx_id_t trx_id = trx_get_id_for_print(trx);
-
- ib::info() << "Rolling back trx with id " << trx_id << ", "
- << rows_to_undo << unit << " rows to undo";
-
if (trx_get_dict_operation(trx) != TRX_DICT_OP_NONE) {
row_mysql_lock_data_dictionary(trx);
dictionary_locked = TRUE;
@@ -694,6 +667,17 @@ trx_rollback_active(
que_run_threads(roll_node->undo_thr);
+ if (trx->error_state != DB_SUCCESS) {
+ ut_ad(trx->error_state == DB_INTERRUPTED);
+ ut_ad(!srv_is_being_started);
+ ut_ad(!srv_undo_sources);
+ ut_ad(srv_fast_shutdown);
+ ut_ad(!dictionary_locked);
+ que_graph_free(static_cast<que_t*>(
+ roll_node->undo_thr->common.parent));
+ goto func_exit;
+ }
+
trx_rollback_finish(thr_get_trx(roll_node->undo_thr));
/* Free the memory reserved by the undo graph */
@@ -725,11 +709,13 @@ trx_rollback_active(
}
}
+func_exit:
if (dictionary_locked) {
row_mysql_unlock_data_dictionary(trx);
}
- ib::info() << "Rollback of trx with id " << trx_id << " completed";
+ ib::info() << "Rollback of trx with id " << ib::hex(trx->id)
+ << " completed";
mem_heap_free(heap);
@@ -747,7 +733,7 @@ ibool
trx_rollback_resurrected(
/*=====================*/
trx_t* trx, /*!< in: transaction to rollback or clean */
- ibool all) /*!< in: FALSE=roll back dictionary transactions;
+ ibool* all) /*!< in/out: FALSE=roll back dictionary transactions;
TRUE=roll back all non-PREPARED transactions */
{
ut_ad(trx_sys_mutex_own());
@@ -758,40 +744,102 @@ trx_rollback_resurrected(
to accidentally clean up a non-recovered transaction here. */
trx_mutex_enter(trx);
- bool is_recovered = trx->is_recovered;
- trx_state_t state = trx->state;
- trx_mutex_exit(trx);
-
- if (!is_recovered) {
+ if (!trx->is_recovered) {
+func_exit:
+ trx_mutex_exit(trx);
return(FALSE);
}
- switch (state) {
+ switch (trx->state) {
case TRX_STATE_COMMITTED_IN_MEMORY:
+ trx_mutex_exit(trx);
trx_sys_mutex_exit();
- ib::info() << "Cleaning up trx with id "
- << trx_get_id_for_print(trx);
+ ib::info() << "Cleaning up trx with id " << ib::hex(trx->id);
trx_cleanup_at_db_startup(trx);
trx_free_resurrected(trx);
return(TRUE);
case TRX_STATE_ACTIVE:
- if (all || trx_get_dict_operation(trx) != TRX_DICT_OP_NONE) {
+ if (!srv_is_being_started
+ && !srv_undo_sources && srv_fast_shutdown) {
+fake_prepared:
+ trx->state = TRX_STATE_PREPARED;
+ trx_sys->n_prepared_trx++;
+ trx_sys->n_prepared_recovered_trx++;
+ *all = FALSE;
+ goto func_exit;
+ }
+ trx_mutex_exit(trx);
+
+ if (*all || trx_get_dict_operation(trx) != TRX_DICT_OP_NONE) {
trx_sys_mutex_exit();
trx_rollback_active(trx);
+ if (trx->error_state != DB_SUCCESS) {
+ ut_ad(trx->error_state == DB_INTERRUPTED);
+ trx->error_state = DB_SUCCESS;
+ ut_ad(!srv_undo_sources);
+ ut_ad(srv_fast_shutdown);
+ mutex_enter(&trx_sys->mutex);
+ trx_mutex_enter(trx);
+ goto fake_prepared;
+ }
trx_free_for_background(trx);
return(TRUE);
}
return(FALSE);
case TRX_STATE_PREPARED:
- return(FALSE);
+ goto func_exit;
case TRX_STATE_NOT_STARTED:
case TRX_STATE_FORCED_ROLLBACK:
break;
}
ut_error;
- return(FALSE);
+ goto func_exit;
+}
+
+/** Report progress when rolling back a row of a recovered transaction.
+@return whether the rollback should be aborted due to pending shutdown */
+bool
+trx_roll_must_shutdown()
+{
+ const trx_t* trx = trx_roll_crash_recv_trx;
+ ut_ad(trx);
+ ut_ad(trx_state_eq(trx, TRX_STATE_ACTIVE));
+ ut_ad(trx->in_rollback);
+
+ if (trx_get_dict_operation(trx) == TRX_DICT_OP_NONE
+ && !srv_is_being_started
+ && !srv_undo_sources && srv_fast_shutdown) {
+ return true;
+ }
+
+ ib_time_t time = ut_time();
+ mutex_enter(&trx_sys->mutex);
+ mutex_enter(&recv_sys->mutex);
+
+ if (recv_sys->report(time)) {
+ ulint n_trx = 0, n_rows = 0;
+ for (const trx_t* t = UT_LIST_GET_FIRST(trx_sys->rw_trx_list);
+ t != NULL;
+ t = UT_LIST_GET_NEXT(trx_list, t)) {
+
+ assert_trx_in_rw_list(t);
+ if (t->is_recovered
+ && trx_state_eq(t, TRX_STATE_ACTIVE)) {
+ n_trx++;
+ n_rows += t->undo_no;
+ }
+ }
+ ib::info() << "To roll back: " << n_trx << " transactions, "
+ << n_rows << " rows";
+ sd_notifyf(0, "STATUS=To roll back: " ULINTPF " transactions, "
+ ULINTPF " rows", n_trx, n_rows);
+ }
+
+ mutex_exit(&recv_sys->mutex);
+ mutex_exit(&trx_sys->mutex);
+ return false;
}
/*******************************************************************//**
@@ -836,17 +884,11 @@ trx_rollback_or_clean_recovered(
assert_trx_in_rw_list(trx);
- if (srv_shutdown_state != SRV_SHUTDOWN_NONE
- && srv_fast_shutdown != 0) {
- all = FALSE;
- break;
- }
-
/* If this function does a cleanup or rollback
then it will release the trx_sys->mutex, therefore
we need to reacquire it before retrying the loop. */
- if (trx_rollback_resurrected(trx, all)) {
+ if (trx_rollback_resurrected(trx, &all)) {
trx_sys_mutex_enter();
@@ -1056,27 +1098,6 @@ trx_roll_pop_top_rec_of_trx(trx_t* trx, roll_ptr_t* roll_ptr, mem_heap_t* heap)
ut_ad(trx_roll_check_undo_rec_ordering(
undo_no, undo->rseg->space, trx));
- /* We print rollback progress info if we are in a crash recovery
- and the transaction has at least 1000 row operations to undo. */
-
- if (trx == trx_roll_crash_recv_trx && trx_roll_max_undo_no > 1000) {
-
- ulint progress_pct = 100 - (ulint)
- ((undo_no * 100) / trx_roll_max_undo_no);
- if (progress_pct != trx_roll_progress_printed_pct) {
- if (trx_roll_progress_printed_pct == 0) {
- fprintf(stderr,
- "\nInnoDB: Progress in percents:"
- " %lu", (ulong) progress_pct);
- } else {
- fprintf(stderr,
- " %lu", (ulong) progress_pct);
- }
- fflush(stderr);
- trx_roll_progress_printed_pct = progress_pct;
- }
- }
-
trx->undo_no = undo_no;
trx->undo_rseg_space = undo->rseg->space;
mutex_exit(&trx->undo_mutex);
diff --git a/storage/innobase/trx/trx0undo.cc b/storage/innobase/trx/trx0undo.cc
index 9b0c43e4609..6dcdf4c51a6 100644
--- a/storage/innobase/trx/trx0undo.cc
+++ b/storage/innobase/trx/trx0undo.cc
@@ -1602,10 +1602,14 @@ trx_undo_free_prepared(
/* fall through */
case TRX_UNDO_ACTIVE:
/* lock_trx_release_locks() assigns
- trx->is_recovered=false */
+ trx->is_recovered=false and
+ trx->state = TRX_STATE_COMMITTED_IN_MEMORY,
+ also for transactions that we faked
+ to TRX_STATE_PREPARED in trx_rollback_resurrected(). */
ut_a(!srv_was_started
|| srv_read_only_mode
- || srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO);
+ || srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO
+ || srv_fast_shutdown);
break;
default:
ut_error;
@@ -1628,10 +1632,14 @@ trx_undo_free_prepared(
/* fall through */
case TRX_UNDO_ACTIVE:
/* lock_trx_release_locks() assigns
- trx->is_recovered=false */
+ trx->is_recovered=false and
+ trx->state = TRX_STATE_COMMITTED_IN_MEMORY,
+ also for transactions that we faked
+ to TRX_STATE_PREPARED in trx_rollback_resurrected(). */
ut_a(!srv_was_started
|| srv_read_only_mode
- || srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO);
+ || srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO
+ || srv_fast_shutdown);
break;
default:
ut_error;
diff --git a/storage/maria/ma_loghandler.c b/storage/maria/ma_loghandler.c
index d3a0531c73d..778a98f7cc9 100644
--- a/storage/maria/ma_loghandler.c
+++ b/storage/maria/ma_loghandler.c
@@ -6342,7 +6342,6 @@ my_bool translog_write_record(LSN *lsn,
short_trid, &parts, trn, hook_arg);
break;
case LOGRECTYPE_NOT_ALLOWED:
- DBUG_ASSERT(0);
default:
DBUG_ASSERT(0);
rc= 1;
diff --git a/storage/rocksdb/mysql-test/storage_engine/disabled.def b/storage/rocksdb/mysql-test/storage_engine/disabled.def
index 0643b2052e2..930e1d82b87 100644
--- a/storage/rocksdb/mysql-test/storage_engine/disabled.def
+++ b/storage/rocksdb/mysql-test/storage_engine/disabled.def
@@ -14,6 +14,7 @@ lock_concurrent : MDEV-13148 - LOCK TABLE on RocksDB table fails with a bog
optimize_table : MDEV-13148 - LOCK TABLE on RocksDB table fails with a bogus error message
repair_table : MDEV-13148 - LOCK TABLE on RocksDB table fails with a bogus error message
select_high_prio : Not supported
+show_engine : SHOW ENGINE produces different number of lines depending on previous tests
show_table_status : MDEV-13152 - Indeterministic row number in SHOW TABLE STATUS on RocksDB table
tbl_opt_data_dir : Not supported
tbl_opt_index_dir : Not supported
diff --git a/storage/rocksdb/mysql-test/storage_engine/type_bit_indexes.rdiff b/storage/rocksdb/mysql-test/storage_engine/type_bit_indexes.rdiff
new file mode 100644
index 00000000000..e53a33b4fba
--- /dev/null
+++ b/storage/rocksdb/mysql-test/storage_engine/type_bit_indexes.rdiff
@@ -0,0 +1,20 @@
+--- suite/storage_engine/type_bit_indexes.result 2017-12-12 20:34:34.000000000 +0200
++++ suite/storage_engine/type_bit_indexes.reject 2017-12-12 20:35:24.539330056 +0200
+@@ -69,7 +69,7 @@
+ (1,0xFFFF,0xFFFFFFFF,0xFFFFFFFFFFFFFFFF);
+ EXPLAIN SELECT HEX(b+c) FROM t1 WHERE c > 1 OR HEX(b) < 0xFFFFFF;
+ id select_type table type possible_keys key key_len ref rows Extra
+-# # # # # b_c # # # #
++# # # # # NULL # # # #
+ SELECT HEX(b+c) FROM t1 WHERE c > 1 OR HEX(b) < 0xFFFFFF;
+ HEX(b+c)
+ 10
+@@ -98,7 +98,7 @@
+ (1,0xFFFF,0xFFFFFFFF,0xFFFFFFFFFFFFFFFF);
+ EXPLAIN SELECT DISTINCT a+0 FROM t1 ORDER BY a;
+ id select_type table type possible_keys key key_len ref rows Extra
+-# # # # # a # # # #
++# # # # # NULL # # # #
+ SELECT DISTINCT a+0 FROM t1 ORDER BY a;
+ a+0
+ 0
diff --git a/storage/rocksdb/mysql-test/storage_engine/type_enum_indexes.rdiff b/storage/rocksdb/mysql-test/storage_engine/type_enum_indexes.rdiff
new file mode 100644
index 00000000000..be83fb6e212
--- /dev/null
+++ b/storage/rocksdb/mysql-test/storage_engine/type_enum_indexes.rdiff
@@ -0,0 +1,11 @@
+--- suite/storage_engine/type_enum_indexes.result 2017-03-12 04:38:50.000000000 +0200
++++ suite/storage_engine/type_enum_indexes.reject 2017-12-12 20:36:47.455331726 +0200
+@@ -30,7 +30,7 @@
+ t1 0 a_b 2 b # # NULL NULL # #
+ EXPLAIN SELECT a FROM t1 WHERE b > 'test2' ORDER BY a;
+ id select_type table type possible_keys key key_len ref rows Extra
+-# # # # # a_b # # # #
++# # # # # NULL # # # #
+ SELECT a FROM t1 WHERE b > 'test2' ORDER BY a;
+ a
+ Africa
diff --git a/storage/rocksdb/mysql-test/storage_engine/type_set_indexes.rdiff b/storage/rocksdb/mysql-test/storage_engine/type_set_indexes.rdiff
new file mode 100644
index 00000000000..2703e81b745
--- /dev/null
+++ b/storage/rocksdb/mysql-test/storage_engine/type_set_indexes.rdiff
@@ -0,0 +1,20 @@
+--- suite/storage_engine/type_set_indexes.result 2017-03-12 04:38:50.000000000 +0200
++++ suite/storage_engine/type_set_indexes.reject 2017-12-12 20:37:16.187332305 +0200
+@@ -97,7 +97,7 @@
+ Warning 1265 Data truncated for column 'b' at row 7
+ EXPLAIN SELECT a FROM t1 WHERE FIND_IN_SET('Europe',a) > 0;
+ id select_type table type possible_keys key key_len ref rows Extra
+-# # # # # a # # # #
++# # # # # NULL # # # #
+ SELECT a FROM t1 WHERE FIND_IN_SET('Europe',a) > 0;
+ a
+ Africa,Europe,Asia
+@@ -124,7 +124,7 @@
+ Warning 1265 Data truncated for column 'b' at row 7
+ EXPLAIN SELECT DISTINCT a, b FROM t1 ORDER BY b DESC, a;
+ id select_type table type possible_keys key key_len ref rows Extra
+-# # # # # b_a # # # #
++# # # # # NULL # # # #
+ SELECT DISTINCT a, b FROM t1 ORDER BY b DESC, a;
+ a b
+ test1,test3
diff --git a/storage/tokudb/mysql-test/rpl/r/rpl_tokudb_row_log.result b/storage/tokudb/mysql-test/rpl/r/rpl_tokudb_row_log.result
index 73c010c6eb7..ab33725fa3f 100644
--- a/storage/tokudb/mysql-test/rpl/r/rpl_tokudb_row_log.result
+++ b/storage/tokudb/mysql-test/rpl/r/rpl_tokudb_row_log.result
@@ -226,7 +226,6 @@ master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Rotate # # master-bin.000002;pos=POS
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000002 # Binlog_checkpoint # # master-bin.000002
master-bin.000002 # Gtid # # GTID #-#-#
master-bin.000002 # Query # # use `test`; create table t3 (a int)ENGINE=TokuDB
master-bin.000002 # Gtid # # GTID #-#-#
@@ -268,7 +267,6 @@ slave-bin.000001 # Query # # use `test`; create table t3 (a int)ENGINE=TokuDB
slave-bin.000001 # Rotate # # slave-bin.000002;pos=POS
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
-slave-bin.000002 # Binlog_checkpoint # # slave-bin.000002
slave-bin.000002 # Gtid # # GTID #-#-#
slave-bin.000002 # Query # # use `test`; create table t2 (n int)ENGINE=TokuDB
slave-bin.000002 # Gtid # # BEGIN GTID #-#-#
diff --git a/storage/tokudb/mysql-test/rpl/r/rpl_tokudb_stm_log.result b/storage/tokudb/mysql-test/rpl/r/rpl_tokudb_stm_log.result
index 83335b0237c..652ef18c039 100644
--- a/storage/tokudb/mysql-test/rpl/r/rpl_tokudb_stm_log.result
+++ b/storage/tokudb/mysql-test/rpl/r/rpl_tokudb_stm_log.result
@@ -222,7 +222,6 @@ master-bin.000001 # Xid # # COMMIT /* XID */
master-bin.000001 # Rotate # # master-bin.000002;pos=POS
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
-master-bin.000002 # Binlog_checkpoint # # master-bin.000002
master-bin.000002 # Gtid # # GTID #-#-#
master-bin.000002 # Query # # use `test`; create table t3 (a int)ENGINE=TokuDB
master-bin.000002 # Gtid # # GTID #-#-#
@@ -260,7 +259,6 @@ slave-bin.000001 # Query # # use `test`; create table t3 (a int)ENGINE=TokuDB
slave-bin.000001 # Rotate # # slave-bin.000002;pos=POS
include/show_binlog_events.inc
Log_name Pos Event_type Server_id End_log_pos Info
-slave-bin.000002 # Binlog_checkpoint # # slave-bin.000002
slave-bin.000002 # Gtid # # GTID #-#-#
slave-bin.000002 # Query # # use `test`; create table t2 (n int)ENGINE=TokuDB
slave-bin.000002 # Gtid # # BEGIN GTID #-#-#