From b253a0c3a90818611b0854fb6c1edc5c458a8398 Mon Sep 17 00:00:00 2001 From: Daniel Bartholomew Date: Tue, 6 Feb 2018 12:44:43 -0500 Subject: [PATCH 1/4] bump the VERSION --- VERSION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/VERSION b/VERSION index 244d28b6ba5..95c724d2776 100644 --- a/VERSION +++ b/VERSION @@ -1,3 +1,3 @@ MYSQL_VERSION_MAJOR=10 MYSQL_VERSION_MINOR=1 -MYSQL_VERSION_PATCH=31 +MYSQL_VERSION_PATCH=32 From b6455479e588fe1309157e8cc77cca10b90942b6 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Wed, 7 Feb 2018 18:14:45 +0100 Subject: [PATCH 2/4] MDEV-15230: column_json breaks cyrillic in 10.1.31 Use unsigned comparison. --- mysql-test/r/dyncol.result | 10 ++++++++++ mysql-test/t/dyncol.test | 9 +++++++++ mysys/ma_dyncol.c | 2 +- 3 files changed, 20 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/dyncol.result b/mysql-test/r/dyncol.result index 81446da9e14..fe4ee3f7de2 100644 --- a/mysql-test/r/dyncol.result +++ b/mysql-test/r/dyncol.result @@ -1883,5 +1883,15 @@ SELECT COLUMN_JSON(COLUMN_CREATE('test','First line\nSecond line')) AS json; json {"test":"First line\u000ASecond line"} # +# MDEV-15230: column_json breaks cyrillic in 10.1.31 +# +set names utf8; +create table t1 (b blob); +insert into t1 values (column_create('description',column_create('title','Описание'))); +select column_json(b) from t1; +column_json(b) +{"description":{"title":"Описание"}} +drop table t1; +# # end of 10.0 tests # diff --git a/mysql-test/t/dyncol.test b/mysql-test/t/dyncol.test index 2c93f75cb5a..7807d1a9f9e 100644 --- a/mysql-test/t/dyncol.test +++ b/mysql-test/t/dyncol.test @@ -928,6 +928,15 @@ SELECT COLUMN_JSON(COLUMN_CREATE('a',1 AS DECIMAL,'b',1 AS DECIMAL)); SELECT COLUMN_JSON(COLUMN_CREATE('test','"\\\t\n\Z')) AS json; SELECT COLUMN_JSON(COLUMN_CREATE('test','First line\nSecond line')) AS json; +--echo # +--echo # MDEV-15230: column_json breaks cyrillic in 10.1.31 +--echo # +set names utf8; +create table t1 (b blob); +insert into t1 values (column_create('description',column_create('title','Описание'))); +select column_json(b) from t1; +drop table t1; + --echo # --echo # end of 10.0 tests --echo # diff --git a/mysys/ma_dyncol.c b/mysys/ma_dyncol.c index 0c54bd7a581..909f9dcac41 100644 --- a/mysys/ma_dyncol.c +++ b/mysys/ma_dyncol.c @@ -3834,7 +3834,7 @@ my_bool dynstr_append_json_quoted(DYNAMIC_STRING *str, for (i= 0; i < len; i++) { register char c= append[i]; - if (unlikely(c <= 0x1F)) + if (unlikely(((uchar)c) <= 0x1F)) { if (lim < 5) { From 5421e3aee7b44c3c400c5dc82b8af00436790ab0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 8 Feb 2018 12:51:19 +0200 Subject: [PATCH 3/4] MDEV-15249 Crash in MVCC read after IMPORT TABLESPACE PageConverter::adjust_cluster_record(): Instead of writing the invalid value DB_ROLL_PTR=0, write a value that indicates a fresh insert, that is, prevents the DB_ROLL_PTR from being dereferenced in any circumstances. It can be argued that IMPORT TABLESPACE should actually update the dict_index_t::trx_id to prevent older transactions from accessing the table, similar to what I did on table rebuild in MySQL 5.6.6 in https://github.com/mysql/mysql-server/commit/03f81a55f221095d397c375afe8a10c8038da339 --- mysql-test/suite/innodb/r/mvcc.result | 26 ++++++++++++++ mysql-test/suite/innodb/t/mvcc.test | 52 +++++++++++++++++++++++++++ storage/innobase/include/row0upd.h | 4 +-- storage/innobase/include/row0upd.ic | 4 +-- storage/innobase/row/row0import.cc | 2 +- storage/xtradb/include/row0upd.h | 4 +-- storage/xtradb/include/row0upd.ic | 4 +-- storage/xtradb/row/row0import.cc | 2 +- 8 files changed, 88 insertions(+), 10 deletions(-) create mode 100644 mysql-test/suite/innodb/r/mvcc.result create mode 100644 mysql-test/suite/innodb/t/mvcc.test diff --git a/mysql-test/suite/innodb/r/mvcc.result b/mysql-test/suite/innodb/r/mvcc.result new file mode 100644 index 00000000000..6bbabc8d87a --- /dev/null +++ b/mysql-test/suite/innodb/r/mvcc.result @@ -0,0 +1,26 @@ +SET @save_per_table= @@GLOBAL.innodb_file_per_table; +SET GLOBAL innodb_file_per_table= 1; +# +# MDEV-15249 Crash in MVCC read after IMPORT TABLESPACE +# +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES(0); +FLUSH TABLES t1 WITH READ LOCK; +UNLOCK TABLES; +START TRANSACTION WITH CONSISTENT SNAPSHOT; +ALTER TABLE t1 FORCE, ALGORITHM=COPY; +SELECT * FROM t1; +ERROR HY000: Table definition has changed, please retry transaction +COMMIT; +START TRANSACTION WITH CONSISTENT SNAPSHOT; +ALTER TABLE t1 DISCARD TABLESPACE; +ALTER TABLE t1 IMPORT TABLESPACE; +# FIXME: Block this with ER_TABLE_DEF_CHANGED +SELECT * FROM t1; +a +COMMIT; +SELECT * FROM t1; +a +0 +DROP TABLE t1; +SET GLOBAL innodb_file_per_table= @save_per_table; diff --git a/mysql-test/suite/innodb/t/mvcc.test b/mysql-test/suite/innodb/t/mvcc.test new file mode 100644 index 00000000000..bf76a5de798 --- /dev/null +++ b/mysql-test/suite/innodb/t/mvcc.test @@ -0,0 +1,52 @@ +--source include/have_innodb.inc + +SET @save_per_table= @@GLOBAL.innodb_file_per_table; +SET GLOBAL innodb_file_per_table= 1; + +let MYSQLD_DATADIR =`SELECT @@datadir`; + +--echo # +--echo # MDEV-15249 Crash in MVCC read after IMPORT TABLESPACE +--echo # + +CREATE TABLE t1 (a INT PRIMARY KEY) ENGINE=InnoDB; +INSERT INTO t1 VALUES(0); +FLUSH TABLES t1 WITH READ LOCK; +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_backup_tablespace("test", "t1"); +EOF +UNLOCK TABLES; + +START TRANSACTION WITH CONSISTENT SNAPSHOT; + +connect (con1,localhost,root,,); +ALTER TABLE t1 FORCE, ALGORITHM=COPY; + +connection default; +--error ER_TABLE_DEF_CHANGED +SELECT * FROM t1; +COMMIT; +START TRANSACTION WITH CONSISTENT SNAPSHOT; + +connection con1; + +ALTER TABLE t1 DISCARD TABLESPACE; + +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_restore_tablespace("test", "t1"); +EOF + +ALTER TABLE t1 IMPORT TABLESPACE; +disconnect con1; + +connection default; +--echo # FIXME: Block this with ER_TABLE_DEF_CHANGED +SELECT * FROM t1; +COMMIT; +SELECT * FROM t1; + +DROP TABLE t1; + +SET GLOBAL innodb_file_per_table= @save_per_table; diff --git a/storage/innobase/include/row0upd.h b/storage/innobase/include/row0upd.h index e59ec58b63c..0a99e0ebd56 100644 --- a/storage/innobase/include/row0upd.h +++ b/storage/innobase/include/row0upd.h @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2018, 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 @@ -119,8 +120,7 @@ row_upd_rec_sys_fields( dict_index_t* index, /*!< in: clustered index */ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */ const trx_t* trx, /*!< in: transaction */ - roll_ptr_t roll_ptr);/*!< in: roll ptr of the undo log record, - can be 0 during IMPORT */ + roll_ptr_t roll_ptr);/*!< in: DB_ROLL_PTR to the undo log */ /*********************************************************************//** Sets the trx id or roll ptr field of a clustered index entry. */ UNIV_INTERN diff --git a/storage/innobase/include/row0upd.ic b/storage/innobase/include/row0upd.ic index 618a77fa4bf..efc6c1be4b5 100644 --- a/storage/innobase/include/row0upd.ic +++ b/storage/innobase/include/row0upd.ic @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2018, 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 @@ -153,8 +154,7 @@ row_upd_rec_sys_fields( dict_index_t* index, /*!< in: clustered index */ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */ const trx_t* trx, /*!< in: transaction */ - roll_ptr_t roll_ptr)/*!< in: roll ptr of the undo log record, - can be 0 during IMPORT */ + roll_ptr_t roll_ptr)/*!< in: DB_ROLL_PTR to the undo log */ { ut_ad(dict_index_is_clust(index)); ut_ad(rec_offs_validate(rec, index, offsets)); diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index c2ea6c35ccb..c901a0a84a4 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -1798,7 +1798,7 @@ PageConverter::adjust_cluster_record( row_upd_rec_sys_fields( rec, m_page_zip_ptr, m_cluster_index, m_offsets, - m_trx, 0); + m_trx, roll_ptr_t(1) << 55); } return(err); diff --git a/storage/xtradb/include/row0upd.h b/storage/xtradb/include/row0upd.h index 4312fcf7339..9efaaa41cf0 100644 --- a/storage/xtradb/include/row0upd.h +++ b/storage/xtradb/include/row0upd.h @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2018, 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 @@ -119,8 +120,7 @@ row_upd_rec_sys_fields( dict_index_t* index, /*!< in: clustered index */ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */ const trx_t* trx, /*!< in: transaction */ - roll_ptr_t roll_ptr);/*!< in: roll ptr of the undo log record, - can be 0 during IMPORT */ + roll_ptr_t roll_ptr);/*!< in: DB_ROLL_PTR to the undo log */ /*********************************************************************//** Sets the trx id or roll ptr field of a clustered index entry. */ UNIV_INTERN diff --git a/storage/xtradb/include/row0upd.ic b/storage/xtradb/include/row0upd.ic index 618a77fa4bf..efc6c1be4b5 100644 --- a/storage/xtradb/include/row0upd.ic +++ b/storage/xtradb/include/row0upd.ic @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2018, 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 @@ -153,8 +154,7 @@ row_upd_rec_sys_fields( dict_index_t* index, /*!< in: clustered index */ const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */ const trx_t* trx, /*!< in: transaction */ - roll_ptr_t roll_ptr)/*!< in: roll ptr of the undo log record, - can be 0 during IMPORT */ + roll_ptr_t roll_ptr)/*!< in: DB_ROLL_PTR to the undo log */ { ut_ad(dict_index_is_clust(index)); ut_ad(rec_offs_validate(rec, index, offsets)); diff --git a/storage/xtradb/row/row0import.cc b/storage/xtradb/row/row0import.cc index c381b941a8d..26ed99a483c 100644 --- a/storage/xtradb/row/row0import.cc +++ b/storage/xtradb/row/row0import.cc @@ -1798,7 +1798,7 @@ PageConverter::adjust_cluster_record( row_upd_rec_sys_fields( rec, m_page_zip_ptr, m_cluster_index, m_offsets, - m_trx, 0); + m_trx, roll_ptr_t(1) << 55); } return(err); From 9216a4f69f113390cc55bd9c58c9f347ef4321c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 8 Feb 2018 13:26:44 +0200 Subject: [PATCH 4/4] Make the test innodb.recovery_shutdown more robust Before killing the server, we have to FLUSH TABLES in order to prevent the corruption of any MyISAM system tables. --- mysql-test/suite/innodb/r/recovery_shutdown.result | 2 +- mysql-test/suite/innodb/t/recovery_shutdown.test | 6 +++++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/mysql-test/suite/innodb/r/recovery_shutdown.result b/mysql-test/suite/innodb/r/recovery_shutdown.result index 861461dd072..47398c1ca23 100644 --- a/mysql-test/suite/innodb/r/recovery_shutdown.result +++ b/mysql-test/suite/innodb/r/recovery_shutdown.result @@ -52,5 +52,5 @@ INSERT INTO t1(a) SELECT NULL FROM t1; INSERT INTO t1(a) SELECT NULL FROM t1; SET GLOBAL innodb_flush_log_at_trx_commit=1; CREATE TABLE u(a SERIAL) ENGINE=INNODB; -# Kill and restart +FLUSH TABLES; DROP TABLE t,u; diff --git a/mysql-test/suite/innodb/t/recovery_shutdown.test b/mysql-test/suite/innodb/t/recovery_shutdown.test index 28b80cd3818..42d98ca34c7 100644 --- a/mysql-test/suite/innodb/t/recovery_shutdown.test +++ b/mysql-test/suite/innodb/t/recovery_shutdown.test @@ -41,7 +41,11 @@ INSERT INTO t1(a) SELECT NULL FROM t1; SET GLOBAL innodb_flush_log_at_trx_commit=1; CREATE TABLE u(a SERIAL) ENGINE=INNODB; ---source include/kill_and_restart_mysqld.inc +FLUSH TABLES; + +--let $shutdown_timeout=0 +--source include/restart_mysqld.inc +--let $shutdown_timeout=60 --source include/restart_mysqld.inc --disable_query_log