From ff6f4d7db11c1b8960376de3035b9e498fac5d34 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Mon, 3 Apr 2017 15:18:46 +0000 Subject: [PATCH 1/8] Windows : Fix compiling with VS2013 We do not use it now, but there is still no reason to break compilation for other users. --- storage/xtradb/btr/btr0cur.cc | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/storage/xtradb/btr/btr0cur.cc b/storage/xtradb/btr/btr0cur.cc index 1705de7ce3657..dcb197a761fcf 100644 --- a/storage/xtradb/btr/btr0cur.cc +++ b/storage/xtradb/btr/btr0cur.cc @@ -3863,7 +3863,7 @@ static const unsigned rows_in_range_max_retries = 4; /** We pretend that a range has that many records if the tree keeps changing for rows_in_range_max_retries retries while we try to estimate the records in a given range. */ -static const int64_t rows_in_range_arbitrary_ret_val = 10; +static const ib_int64_t rows_in_range_arbitrary_ret_val = 10; /** Estimates the number of rows in a given index range. @param[in] index index @@ -3881,7 +3881,7 @@ rows_in_range_arbitrary_ret_val as a result (if nth_attempt >= rows_in_range_max_retries and the tree is modified between the two dives). */ static -int64_t +ib_int64_t btr_estimate_n_rows_in_range_low( dict_index_t* index, const dtuple_t* tuple1, @@ -4017,7 +4017,7 @@ btr_estimate_n_rows_in_range_low( return(rows_in_range_arbitrary_ret_val); } - const int64_t ret = + const ib_int64_t ret = btr_estimate_n_rows_in_range_low( index, tuple1, mode1, tuple2, mode2, trx, @@ -4083,7 +4083,7 @@ btr_estimate_n_rows_in_range_low( @param[in] mode2 search mode for range end @param[in] trx trx @return estimated number of rows */ -int64_t +ib_int64_t btr_estimate_n_rows_in_range( dict_index_t* index, const dtuple_t* tuple1, @@ -4092,7 +4092,7 @@ btr_estimate_n_rows_in_range( ulint mode2, trx_t* trx) { - const int64_t ret = btr_estimate_n_rows_in_range_low( + const ib_int64_t ret = btr_estimate_n_rows_in_range_low( index, tuple1, mode1, tuple2, mode2, trx, 1 /* first attempt */); From f2dc04abea172e4c5d701a749902c88f4a626c2c Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Mon, 3 Apr 2017 18:48:48 +0000 Subject: [PATCH 2/8] Compiling, Windows . Avoid unnecessary rebuilds with MSVC. To export symbols from the mysqld.exe, use lib.exe with /DEF, rather than pre-link step when building mysqld.exe. This helps to avoid relinking all plugins, if mysqld.exe was recompiled but the list of its exports has not changed. Also removed unnecessary DEPENDS in some ADD_CUSTOM_COMMAND (gen_lex_token, gen_lex_hash etc). They confuse VS generator which tends to recreate headers and do unnecessary recompilations. --- cmake/plugin.cmake | 11 +++++- sql/CMakeLists.txt | 83 +++++++++++++++++++++++++++++++----------- win/create_def_file.js | 46 ++++++++++++++++++++--- 3 files changed, 111 insertions(+), 29 deletions(-) diff --git a/cmake/plugin.cmake b/cmake/plugin.cmake index e1d2af2add645..ba7bac837b1c5 100644 --- a/cmake/plugin.cmake +++ b/cmake/plugin.cmake @@ -179,8 +179,15 @@ MACRO(MYSQL_ADD_PLUGIN) # executable to the linker command line (it would result into link error). # Thus we skip TARGET_LINK_LIBRARIES on Linux, as it would only generate # an additional dependency. - IF(NOT CMAKE_SYSTEM_NAME STREQUAL "Linux") - TARGET_LINK_LIBRARIES (${target} mysqld ${ARG_LINK_LIBRARIES}) + IF(MSVC) + ADD_DEPENDENCIES(${target} gen_mysqld_lib) + TARGET_LINK_LIBRARIES(${target} mysqld_import_lib) + ELSEIF(NOT CMAKE_SYSTEM_NAME STREQUAL "Linux") + TARGET_LINK_LIBRARIES (${target} mysqld) + ENDIF() + + IF(ARG_LINK_LIBRARIES) + TARGET_LINK_LIBRARIES (${target} ${ARG_LINK_LIBRARIES}) ENDIF() ADD_DEPENDENCIES(${target} GenError ${ARG_DEPENDENCIES}) diff --git a/sql/CMakeLists.txt b/sql/CMakeLists.txt index 652664fa43818..5cdf597301fad 100644 --- a/sql/CMakeLists.txt +++ b/sql/CMakeLists.txt @@ -46,7 +46,6 @@ ENDIF() ADD_CUSTOM_COMMAND( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/lex_token.h COMMAND gen_lex_token > lex_token.h - DEPENDS gen_lex_token ) ADD_DEFINITIONS(-DMYSQL_SERVER -DHAVE_EVENT_SCHEDULER) @@ -150,6 +149,63 @@ ELSE() SET(MYSQLD_SOURCE main.cc ${DTRACE_PROBES_ALL}) ENDIF() + +IF(MSVC AND NOT WITHOUT_DYNAMIC_PLUGINS) + + # mysqld.exe must to export symbols from some specific libs. + # These symbols are used by dynamic plugins, that "link" to mysqld. + # + # To do that, we + # + # 1. Generate mysqld_lib.def text file with all symbols from static + # libraries mysys, dbug, strings, sql. + # 2. Then we call + # lib.exe /DEF:mysqld_lib.def ... + # to create import library mysqld_lib.lib and export library mysqld_lib.exp + # 3. mysqld.exe links with mysqld_lib.exp (exporting symbols) + # 4. plugins link with mysqld_lib.lib (importing symbols) + # + # We do not not regenerate .def, .lib and .exp + # without necessity.E.g source modifications, that do not + # change list of exported symbols, will not result in a relink for plugins. + + SET(MYSQLD_DEF ${CMAKE_CURRENT_BINARY_DIR}/mysqld_lib.def) + SET(MYSQLD_EXP ${CMAKE_CURRENT_BINARY_DIR}/mysqld_lib.exp) + SET(MYSQLD_LIB ${CMAKE_CURRENT_BINARY_DIR}/mysqld_lib.lib) + SET(MYSQLD_CORELIBS sql mysys mysys_ssl dbug strings) + FOREACH (CORELIB ${MYSQLD_CORELIBS}) + GET_TARGET_PROPERTY(LOC ${CORELIB} LOCATION) + FILE(TO_NATIVE_PATH ${LOC} LOC) + SET (LIB_LOCATIONS ${LIB_LOCATIONS} ${LOC}) + ENDFOREACH (CORELIB) + + SET(_PLATFORM x86) + IF(CMAKE_SIZEOF_VOID_P EQUAL 8) + SET(_PLATFORM x64) + ENDIF() + + ADD_CUSTOM_COMMAND( + OUTPUT ${MYSQLD_DEF} + COMMAND cscript ARGS //nologo ${PROJECT_SOURCE_DIR}/win/create_def_file.js + ${_PLATFORM} /forLib ${LIB_LOCATIONS} > mysqld_lib.def.tmp + COMMAND ${CMAKE_COMMAND} -E copy_if_different mysqld_lib.def.tmp mysqld_lib.def + COMMAND ${CMAKE_COMMAND} -E remove mysqld_lib.def.tmp + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS ${MYSQLD_CORELIBS} + ) + + ADD_CUSTOM_COMMAND( + OUTPUT ${MYSQLD_LIB} + COMMAND lib + ARGS /NAME:mysqld.exe "/DEF:${MYSQLD_DEF}" "/MACHINE:${_PLATFORM}" + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} + DEPENDS ${MYSQLD_DEF} + ) + ADD_CUSTOM_TARGET(gen_mysqld_lib DEPENDS ${MYSQLD_LIB}) + ADD_LIBRARY(mysqld_import_lib UNKNOWN IMPORTED GLOBAL) + SET_TARGET_PROPERTIES(mysqld_import_lib PROPERTIES IMPORTED_LOCATION ${MYSQLD_LIB}) +ENDIF() + MYSQL_ADD_EXECUTABLE(mysqld ${MYSQLD_SOURCE} DESTINATION ${INSTALL_SBINDIR} COMPONENT Server) IF(APPLE) @@ -170,25 +226,9 @@ IF(NOT WITHOUT_DYNAMIC_PLUGINS) SET_TARGET_PROPERTIES(mysqld PROPERTIES LINK_FLAGS "${mysqld_link_flags} -Wl,--export-all-symbols") ENDIF() IF(MSVC) - # Set module definition file. Also use non-incremental linker, - # incremental appears to crash from time to time,if used with /DEF option - SET_TARGET_PROPERTIES(mysqld PROPERTIES LINK_FLAGS "${mysqld_link_flags} /DEF:mysqld.def /INCREMENTAL:NO") - - FOREACH (CORELIB sql mysys mysys_ssl dbug strings) - GET_TARGET_PROPERTY(LOC ${CORELIB} LOCATION) - FILE(TO_NATIVE_PATH ${LOC} LOC) - SET (LIB_LOCATIONS ${LIB_LOCATIONS} ${LOC}) - ENDFOREACH (CORELIB ${MYSQLD_CORE_LIBS}) - SET(_PLATFORM x86) - IF(CMAKE_SIZEOF_VOID_P EQUAL 8) - SET(_PLATFORM x64) - ENDIF() - ADD_CUSTOM_COMMAND(TARGET mysqld PRE_LINK - COMMAND echo ${_PLATFORM} && cscript ARGS //nologo ${PROJECT_SOURCE_DIR}/win/create_def_file.js - ${_PLATFORM} ${LIB_LOCATIONS} > mysqld.def - WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}) - ADD_DEPENDENCIES(sql GenError) - ENDIF(MSVC) + SET_TARGET_PROPERTIES(mysqld PROPERTIES LINK_FLAGS "${mysqld_link_flags} \"${MYSQLD_EXP}\"") + ADD_DEPENDENCIES(mysqld gen_mysqld_lib) + ENDIF() ENDIF(NOT WITHOUT_DYNAMIC_PLUGINS) SET_TARGET_PROPERTIES(mysqld PROPERTIES ENABLE_EXPORTS TRUE) @@ -254,7 +294,6 @@ ENDIF() ADD_CUSTOM_COMMAND( OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/lex_hash.h COMMAND gen_lex_hash > lex_hash.h - DEPENDS gen_lex_hash ) MYSQL_ADD_EXECUTABLE(mysql_tzinfo_to_sql tztime.cc COMPONENT Server) @@ -379,7 +418,7 @@ IF(WIN32) ${CMAKE_CURRENT_BINARY_DIR}/my_bootstrap.sql mysql_bootstrap_sql.c WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR} - DEPENDS comp_sql ${my_bootstrap_sql} + DEPENDS ${my_bootstrap_sql} ) MYSQL_ADD_EXECUTABLE(mysql_install_db diff --git a/win/create_def_file.js b/win/create_def_file.js index 5fb28ef0bee8f..25bbbb4eb3d50 100644 --- a/win/create_def_file.js +++ b/win/create_def_file.js @@ -54,6 +54,22 @@ var is64 = args.Item(0).toLowerCase() == "x64"; var shell = new ActiveXObject("WScript.Shell"); var fso = new ActiveXObject("Scripting.FileSystemObject"); +/* + If .def file is used with together with lib.exe + the name mangling for stdcall is slightly different. + + Undescore prefix for stdcall function name must be removed for + lib.exe but not link.exe (see ScrubSymbol()) + + This difference is not documented anywhere and could + be a bug in compiler tools. + + We use a parameter /forLib, if the resulting .def file is used + with lib.exe . +*/ +var forLib = false; + + OutputSymbols(CollectSymbols()); @@ -62,8 +78,8 @@ function OutputSymbols(symbols) { var out = WScript.StdOut; out.WriteLine("EXPORTS"); - for (var sym in symbols) - out.WriteLine(sym); + for (var i= 0; i < symbols.length; i++) + out.WriteLine(symbols[i]); } function echo(message) @@ -72,9 +88,10 @@ function echo(message) } // Extract global symbol names and type from objects +// Returns string array with symbol names function CollectSymbols() { - var uniqueSymbols = new Array(); + var uniqueSymbols = new Object(); try { @@ -146,7 +163,19 @@ function CollectSymbols() uniqueSymbols[symbol] = 1; } fso.DeleteFile(rspfilename); - return uniqueSymbols; + // Sort symbols names + var keys=[]; + var sorted = {}; + for (key in uniqueSymbols) + { + if (uniqueSymbols.hasOwnProperty(key)) + { + keys.push(key); + } + } + keys.sort(); + + return keys; } // performs necessary cleanup on the symbol name @@ -156,6 +185,9 @@ function ScrubSymbol(symbol) if (symbol.charAt(0) != "_") return symbol; + if (forLib) + return symbol.substring(1, symbol.length); + var atSign = symbol.indexOf("@"); if (atSign != -1) { @@ -189,7 +221,11 @@ function CreateResponseFile(filename) var index = 1; for (; index < args.length; index++) { - addToResponseFile(args.Item(index),responseFile); + var param = args.Item(index); + if (param == "/forLib") + forLib = true; + else + addToResponseFile(args.Item(index),responseFile); } responseFile.Close(); } From 9a218f4fb871c1169dd6015a3be9d965929dbd1f Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Tue, 4 Apr 2017 15:47:21 +1000 Subject: [PATCH 3/8] fil_crypt_rotate_page - space_id should be compared to TRX_SYS_SPACE not space Fixes compile error that highlights problem: /source/storage/innobase/fil/fil0crypt.cc: In function 'void fil_crypt_rotate_page(const key_state_t*, rotate_thread_t*)': /source/storage/innobase/fil/fil0crypt.cc:1770:15: error: ISO C++ forbids comparison between pointer and integer [-fpermissive] if (space == TRX_SYS_SPACE && offset == TRX_SYS_PAGE_NO) { Signed-off-by: Daniel Black --- storage/innobase/fil/fil0crypt.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/innobase/fil/fil0crypt.cc b/storage/innobase/fil/fil0crypt.cc index 7bef91f47ff87..9c5f782da32fa 100644 --- a/storage/innobase/fil/fil0crypt.cc +++ b/storage/innobase/fil/fil0crypt.cc @@ -1951,7 +1951,7 @@ fil_crypt_rotate_page( return; } - if (space == TRX_SYS_SPACE && offset == TRX_SYS_PAGE_NO) { + if (space_id == TRX_SYS_SPACE && offset == TRX_SYS_PAGE_NO) { /* don't encrypt this as it contains address to dblwr buffer */ return; } From a7bb9e8fdbdd5a3a01910117ef54c0fe09374de2 Mon Sep 17 00:00:00 2001 From: Daniel Black Date: Wed, 5 Apr 2017 16:29:08 +1000 Subject: [PATCH 4/8] xtradb: fil_crypt_rotate_page, space_id should be compared to TRX_SYS_SPACE not space like 9a218f4fb871c1169dd6015a3be9d965929dbd1f fil_crypt_rotate_page - space_id should be compared to TRX_SYS_SPACE not space Signed-off-by: Daniel Black --- storage/xtradb/fil/fil0crypt.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/storage/xtradb/fil/fil0crypt.cc b/storage/xtradb/fil/fil0crypt.cc index 7bef91f47ff87..9c5f782da32fa 100644 --- a/storage/xtradb/fil/fil0crypt.cc +++ b/storage/xtradb/fil/fil0crypt.cc @@ -1951,7 +1951,7 @@ fil_crypt_rotate_page( return; } - if (space == TRX_SYS_SPACE && offset == TRX_SYS_PAGE_NO) { + if (space_id == TRX_SYS_SPACE && offset == TRX_SYS_PAGE_NO) { /* don't encrypt this as it contains address to dblwr buffer */ return; } From cd494f4cefb36faa9e4fa343050a30201d4bdebd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20Lindstr=C3=B6m?= Date: Wed, 5 Apr 2017 08:54:20 +0300 Subject: [PATCH 5/8] fix warning "ignoring return value" of fwrite. Merge pull request https://github.com/MariaDB/server/pull/343 contributed by Eric Herman. --- sql/wsrep_binlog.cc | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/sql/wsrep_binlog.cc b/sql/wsrep_binlog.cc index d3f59cee5f2d6..b6aee3a74abd9 100644 --- a/sql/wsrep_binlog.cc +++ b/sql/wsrep_binlog.cc @@ -329,9 +329,13 @@ void wsrep_dump_rbr_buf(THD *thd, const void* rbr_buf, size_t buf_len) } FILE *of= fopen(filename, "wb"); + if (of) { - fwrite (rbr_buf, buf_len, 1, of); + if (fwrite(rbr_buf, buf_len, 1, of) == 0) + WSREP_ERROR("Failed to write buffer of length %llu to '%s'", + (unsigned long long)buf_len, filename); + fclose(of); } else From 8e36216a06603942613f8157b9b790e98f90d608 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 5 Apr 2017 14:46:35 +0300 Subject: [PATCH 6/8] =?UTF-8?q?Import=20two=20ALTER=20TABLE=E2=80=A6ALGORI?= =?UTF-8?q?THM=3DINPLACE=20tests=20from=20MySQL=205.6.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Also, revert part of MDEV-7685 that added an InnoDB abort when ALTER TABLE…ALGORITHM=INPLACE is reporting that it ran out of file space. --- .../suite/innodb/r/innodb-alter-debug.result | 56 +++++++++++++ .../innodb/r/innodb-alter-nullable.result | 53 +++++++++++++ .../suite/innodb/t/innodb-alter-debug.test | 79 +++++++++++++++++++ .../suite/innodb/t/innodb-alter-nullable.test | 76 ++++++++++++++++++ storage/innobase/handler/handler0alter.cc | 1 - storage/xtradb/handler/handler0alter.cc | 1 - 6 files changed, 264 insertions(+), 2 deletions(-) create mode 100644 mysql-test/suite/innodb/r/innodb-alter-debug.result create mode 100644 mysql-test/suite/innodb/r/innodb-alter-nullable.result create mode 100644 mysql-test/suite/innodb/t/innodb-alter-debug.test create mode 100644 mysql-test/suite/innodb/t/innodb-alter-nullable.test diff --git a/mysql-test/suite/innodb/r/innodb-alter-debug.result b/mysql-test/suite/innodb/r/innodb-alter-debug.result new file mode 100644 index 0000000000000..78976030ac8fc --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb-alter-debug.result @@ -0,0 +1,56 @@ +SET NAMES utf8; +CREATE TABLE ① ( +c1 INT PRIMARY KEY, c2 INT DEFAULT 1, ct TEXT, INDEX(c2)) +ENGINE = InnoDB; +CREATE TABLE t1ć (c1 INT PRIMARY KEY, c2 INT, INDEX(c2), +CONSTRAINT t1c2 FOREIGN KEY (c2) REFERENCES ①(c2)) +ENGINE=InnoDB; +INSERT INTO ① SET c1 = 1; +SET @saved_debug_dbug = @@SESSION.debug_dbug; +SET DEBUG_DBUG = '+d,ib_drop_foreign_error'; +ALTER TABLE t1ć DROP FOREIGN KEY t1c2, RENAME TO ②; +ERROR HY000: The table 't1ć' is full +SET DEBUG_DBUG = @saved_debug_dbug; +SET DEBUG_DBUG = '+d,ib_rename_column_error'; +ALTER TABLE ① CHANGE c2 š INT; +ERROR HY000: The table '①' is full +SET DEBUG_DBUG = @saved_debug_dbug; +SHOW CREATE TABLE t1ć; +Table Create Table +t1ć CREATE TABLE `t1ć` ( + `c1` int(11) NOT NULL, + `c2` int(11) DEFAULT NULL, + PRIMARY KEY (`c1`), + KEY `c2` (`c2`), + CONSTRAINT `t1c2` FOREIGN KEY (`c2`) REFERENCES `①` (`c2`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1 +DROP TABLE t1ć, ①; +# +# Bug #21364096 THE BOGUS DUPLICATE KEY ERROR IN ONLINE DDL +# WITH INCORRECT KEY NAME +create table t1 (id int auto_increment primary key, a int, unique key uk(a)) +engine = innodb; +insert into t1 select 1, 1; +insert into t1 select 2, 2; +SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL s1 WAIT_FOR s2'; +alter table t1 add b int, ALGORITHM=inplace; +/* connection con1 */ +SET DEBUG_SYNC = 'now WAIT_FOR s1'; +insert into t1 select NULL, 1; +ERROR 23000: Duplicate entry '1' for key 'uk' +SET DEBUG_SYNC = 'now SIGNAL s2'; +/* connection default */ +/* reap */ alter table t1 add b int, ALGORITHM=inplace; +ERROR 23000: Duplicate entry '1' for key 'uk' +SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL s1 WAIT_FOR s2'; +alter table t1 add b int, ALGORITHM=inplace;; +/* connection con1 */ +set DEBUG_SYNC = 'now WAIT_FOR s1'; +update t1 set a=1 where id=2; +ERROR 23000: Duplicate entry '1' for key 'uk' +SET DEBUG_SYNC = 'now SIGNAL s2'; +/* connection default */ +/* reap */ alter table t1 add b int, ALGORITHM=inplace; +ERROR 23000: Duplicate entry '1' for key 'uk' +SET DEBUG_SYNC = 'RESET'; +drop table t1; diff --git a/mysql-test/suite/innodb/r/innodb-alter-nullable.result b/mysql-test/suite/innodb/r/innodb-alter-nullable.result new file mode 100644 index 0000000000000..e9711b2ac31bd --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb-alter-nullable.result @@ -0,0 +1,53 @@ +CREATE TABLE t (c1 INT PRIMARY KEY, c2 INT NOT NULL, c3 INT) ENGINE=InnoDB; +INSERT INTO t VALUES (1,2,3),(4,5,6),(7,8,9); +ALTER TABLE t CHANGE c1 c1 INT NULL FIRST, ALGORITHM=INPLACE; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +set @old_sql_mode = @@sql_mode; +set @@sql_mode = 'STRICT_TRANS_TABLES'; +ALTER TABLE t MODIFY c3 INT NOT NULL, ALGORITHM=INPLACE; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +set @@sql_mode = @old_sql_mode; +ALTER TABLE t CHANGE c2 c2 INT, CHANGE c2 c2 INT NOT NULL; +ERROR 42S22: Unknown column 'c2' in 't' +ALTER TABLE t MODIFY c2 INT, MODIFY c2 INT NOT NULL; +ERROR 42S22: Unknown column 'c2' in 't' +ALTER TABLE t MODIFY c2 INT UNSIGNED, MODIFY c2 INT; +ERROR 42S22: Unknown column 'c2' in 't' +ALTER TABLE t MODIFY c2 CHAR(1) NOT NULL, MODIFY c2 INT NOT NULL; +ERROR 42S22: Unknown column 'c2' in 't' +ALTER TABLE t CHANGE c2 c2 INT NOT NULL; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +ALTER TABLE t MODIFY c2 INT NOT NULL; +affected rows: 0 +info: Records: 0 Duplicates: 0 Warnings: 0 +SET SQL_MODE='STRICT_ALL_TABLES'; +UPDATE t SET c2=NULL; +ERROR 23000: Column 'c2' cannot be null +SELECT * FROM t; +c1 c2 c3 +1 2 3 +4 5 6 +7 8 9 +ALTER TABLE t MODIFY c2 INT, ALGORITHM=INPLACE; +BEGIN; +UPDATE t SET c2=NULL; +SELECT * FROM t; +c1 c2 c3 +1 NULL 3 +4 NULL 6 +7 NULL 9 +ROLLBACK; +SELECT * FROM t; +c1 c2 c3 +1 2 3 +4 5 6 +7 8 9 +ALTER TABLE t MODIFY c2 INT NULL, ALGORITHM=INPLACE; +SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES +WHERE NAME='test/t'; +TABLE_ID NAME FLAG N_COLS SPACE FILE_FORMAT ROW_FORMAT ZIP_PAGE_SIZE +# test/t 1 6 # Antelope Compact 0 +DROP TABLE t; diff --git a/mysql-test/suite/innodb/t/innodb-alter-debug.test b/mysql-test/suite/innodb/t/innodb-alter-debug.test new file mode 100644 index 0000000000000..70017ffba3543 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-alter-debug.test @@ -0,0 +1,79 @@ +--source include/have_innodb.inc +--source include/have_debug.inc +--source include/have_debug_sync.inc + +--source include/count_sessions.inc + +SET NAMES utf8; + +CREATE TABLE ① ( + c1 INT PRIMARY KEY, c2 INT DEFAULT 1, ct TEXT, INDEX(c2)) +ENGINE = InnoDB; + +CREATE TABLE t1ć (c1 INT PRIMARY KEY, c2 INT, INDEX(c2), + CONSTRAINT t1c2 FOREIGN KEY (c2) REFERENCES ①(c2)) +ENGINE=InnoDB; + +INSERT INTO ① SET c1 = 1; + +SET @saved_debug_dbug = @@SESSION.debug_dbug; +SET DEBUG_DBUG = '+d,ib_drop_foreign_error'; +--error ER_RECORD_FILE_FULL +ALTER TABLE t1ć DROP FOREIGN KEY t1c2, RENAME TO ②; +SET DEBUG_DBUG = @saved_debug_dbug; + +SET DEBUG_DBUG = '+d,ib_rename_column_error'; +--error ER_RECORD_FILE_FULL +ALTER TABLE ① CHANGE c2 š INT; +SET DEBUG_DBUG = @saved_debug_dbug; + +SHOW CREATE TABLE t1ć; + +DROP TABLE t1ć, ①; + +--echo # +--echo # Bug #21364096 THE BOGUS DUPLICATE KEY ERROR IN ONLINE DDL +--echo # WITH INCORRECT KEY NAME + +create table t1 (id int auto_increment primary key, a int, unique key uk(a)) +engine = innodb; +insert into t1 select 1, 1; +insert into t1 select 2, 2; +SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL s1 WAIT_FOR s2'; +--send alter table t1 add b int, ALGORITHM=inplace + +--echo /* connection con1 */ +connect (con1,localhost,root,,); +SET DEBUG_SYNC = 'now WAIT_FOR s1'; +--error ER_DUP_ENTRY +insert into t1 select NULL, 1; +SET DEBUG_SYNC = 'now SIGNAL s2'; + +--echo /* connection default */ +connection default; +--echo /* reap */ alter table t1 add b int, ALGORITHM=inplace; +--error ER_DUP_ENTRY +--reap + +SET DEBUG_SYNC = 'row_log_table_apply1_before SIGNAL s1 WAIT_FOR s2'; +--send alter table t1 add b int, ALGORITHM=inplace; + +--echo /* connection con1 */ +connection con1; +set DEBUG_SYNC = 'now WAIT_FOR s1'; +--error ER_DUP_ENTRY +update t1 set a=1 where id=2; +SET DEBUG_SYNC = 'now SIGNAL s2'; +disconnect con1; + +--echo /* connection default */ +connection default; +--echo /* reap */ alter table t1 add b int, ALGORITHM=inplace; +--error ER_DUP_ENTRY +--reap +SET DEBUG_SYNC = 'RESET'; + +drop table t1; + +# Wait till all disconnects are completed +--source include/wait_until_count_sessions.inc diff --git a/mysql-test/suite/innodb/t/innodb-alter-nullable.test b/mysql-test/suite/innodb/t/innodb-alter-nullable.test new file mode 100644 index 0000000000000..3f1e82b3183d6 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb-alter-nullable.test @@ -0,0 +1,76 @@ +--source include/have_innodb.inc + +# Save the initial number of concurrent sessions. +--source include/count_sessions.inc + +CREATE TABLE t (c1 INT PRIMARY KEY, c2 INT NOT NULL, c3 INT) ENGINE=InnoDB; +INSERT INTO t VALUES (1,2,3),(4,5,6),(7,8,9); + +--enable_info +# This one will be a no-op. +# MySQL should perhaps issue an error, because it refuses to modify +# the PRIMARY KEY column c1 from NOT NULL to NULL. +ALTER TABLE t CHANGE c1 c1 INT NULL FIRST, ALGORITHM=INPLACE; + +# NULL -> NOT NULL only allowed INPLACE if strict sql_mode is on. +--disable_info +set @old_sql_mode = @@sql_mode; +set @@sql_mode = 'STRICT_TRANS_TABLES'; +--enable_info +ALTER TABLE t MODIFY c3 INT NOT NULL, ALGORITHM=INPLACE; +--disable_info +set @@sql_mode = @old_sql_mode; +--enable_info + +# Request some conflicting changes for a single column. +--error ER_BAD_FIELD_ERROR +ALTER TABLE t CHANGE c2 c2 INT, CHANGE c2 c2 INT NOT NULL; +--error ER_BAD_FIELD_ERROR +ALTER TABLE t MODIFY c2 INT, MODIFY c2 INT NOT NULL; +--error ER_BAD_FIELD_ERROR +ALTER TABLE t MODIFY c2 INT UNSIGNED, MODIFY c2 INT; +--error ER_BAD_FIELD_ERROR +ALTER TABLE t MODIFY c2 CHAR(1) NOT NULL, MODIFY c2 INT NOT NULL; + +# No-ops. +ALTER TABLE t CHANGE c2 c2 INT NOT NULL; +ALTER TABLE t MODIFY c2 INT NOT NULL; +--disable_info + +connect (con1,localhost,root,,); +connection con1; + +SET SQL_MODE='STRICT_ALL_TABLES'; + +--error ER_BAD_NULL_ERROR +UPDATE t SET c2=NULL; + +SELECT * FROM t; + +connection default; + +# This should change the column to NULL. +ALTER TABLE t MODIFY c2 INT, ALGORITHM=INPLACE; + +connection con1; +BEGIN; +UPDATE t SET c2=NULL; +SELECT * FROM t; +ROLLBACK; +SELECT * FROM t; + +disconnect con1; +connection default; + +# This should be no-op. +ALTER TABLE t MODIFY c2 INT NULL, ALGORITHM=INPLACE; + +--replace_column 1 # 5 # +SELECT * FROM INFORMATION_SCHEMA.INNODB_SYS_TABLES +WHERE NAME='test/t'; + +DROP TABLE t; + +# Check that all connections opened by test cases in this file are really +# gone so execution of other tests won't be affected by their presence. +--source include/wait_until_count_sessions.inc diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index cc00b841579d5..dc084dc1b9514 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -129,7 +129,6 @@ my_error_innodb( break; case DB_OUT_OF_FILE_SPACE: my_error(ER_RECORD_FILE_FULL, MYF(0), table); - ut_error; break; case DB_TEMP_FILE_WRITE_FAILURE: my_error(ER_GET_ERRMSG, MYF(0), diff --git a/storage/xtradb/handler/handler0alter.cc b/storage/xtradb/handler/handler0alter.cc index cfae2725b056e..3d20c9abccfa5 100644 --- a/storage/xtradb/handler/handler0alter.cc +++ b/storage/xtradb/handler/handler0alter.cc @@ -130,7 +130,6 @@ my_error_innodb( break; case DB_OUT_OF_FILE_SPACE: my_error(ER_RECORD_FILE_FULL, MYF(0), table); - ut_error; break; case DB_TEMP_FILE_WRITE_FAILURE: my_error(ER_GET_ERRMSG, MYF(0), From 57a699b0a0f3300404948775356d31fb478e80c6 Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Fri, 17 Jun 2016 16:51:11 +0200 Subject: [PATCH 7/8] MDEV-8642: WHERE Clause not applied on View - Empty result set returned An attempt to mark reference as dependent lead to transfering this property to original view field and through it to other references of this field which can't be dependent. --- mysql-test/r/view.result | 37 +++++++++++++++++++++++++++++++++++++ mysql-test/t/view.test | 38 ++++++++++++++++++++++++++++++++++++++ sql/item.cc | 13 ------------- 3 files changed, 75 insertions(+), 13 deletions(-) diff --git a/mysql-test/r/view.result b/mysql-test/r/view.result index 3c6eb235a575d..d6da2a03b4689 100644 --- a/mysql-test/r/view.result +++ b/mysql-test/r/view.result @@ -5907,6 +5907,43 @@ a 2 DROP VIEW v1; DROP TABLE t1; +# +# MDEV-8642: WHERE Clause not applied on View - Empty result set returned +# +CREATE TABLE `t1` ( +`id` int(20) NOT NULL AUTO_INCREMENT, +`use_case` int(11) DEFAULT NULL, +`current_deadline` date DEFAULT NULL, +`ts_create` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, +PRIMARY KEY (`id`), +UNIQUE KEY `id_UNIQUE` (`id`) +) ENGINE=MyISAM AUTO_INCREMENT=13976 DEFAULT CHARSET=latin1; +INSERT INTO `t1` VALUES (1,10,'2015-12-18','2015-08-18 08:38:16'); +INSERT INTO `t1` VALUES (2,20,'2015-10-18','2015-08-18 08:43:30'); +CREATE VIEW v1 AS SELECT +use_case as use_case_id, +( +SELECT +deadline_sub.current_deadline +FROM +t1 deadline_sub +WHERE +deadline_sub.use_case = use_case_id +AND ts_create = (SELECT +MIN(ts_create) +FROM +t1 startdate_sub +WHERE +startdate_sub.use_case = use_case_id +) +) AS InitialDeadline +FROM +t1; +SELECT * FROM v1 where use_case_id = 10; +use_case_id InitialDeadline +10 2015-12-18 +drop view v1; +drop table t1; # ----------------------------------------------------------------- # -- End of 10.0 tests. # ----------------------------------------------------------------- diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index 630c247e85b37..89a8e0c9ffc5c 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -5775,6 +5775,44 @@ DROP VIEW v1; DROP TABLE t1; +--echo # +--echo # MDEV-8642: WHERE Clause not applied on View - Empty result set returned +--echo # + +CREATE TABLE `t1` ( + `id` int(20) NOT NULL AUTO_INCREMENT, + `use_case` int(11) DEFAULT NULL, + `current_deadline` date DEFAULT NULL, + `ts_create` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, + PRIMARY KEY (`id`), + UNIQUE KEY `id_UNIQUE` (`id`) +) ENGINE=MyISAM AUTO_INCREMENT=13976 DEFAULT CHARSET=latin1; +INSERT INTO `t1` VALUES (1,10,'2015-12-18','2015-08-18 08:38:16'); +INSERT INTO `t1` VALUES (2,20,'2015-10-18','2015-08-18 08:43:30'); +CREATE VIEW v1 AS SELECT + use_case as use_case_id, + ( + SELECT + deadline_sub.current_deadline + FROM + t1 deadline_sub + WHERE + deadline_sub.use_case = use_case_id + AND ts_create = (SELECT + MIN(ts_create) + FROM + t1 startdate_sub + WHERE + startdate_sub.use_case = use_case_id + ) + ) AS InitialDeadline +FROM + t1; + +SELECT * FROM v1 where use_case_id = 10; + +drop view v1; +drop table t1; --echo # ----------------------------------------------------------------- --echo # -- End of 10.0 tests. diff --git a/sql/item.cc b/sql/item.cc index 86f1795a4dac7..dbec742e4a2af 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -7141,19 +7141,6 @@ bool Item_ref::fix_fields(THD *thd, Item **reference) last_checked_context->select_lex->nest_level); } } - else if (ref_type() != VIEW_REF) - { - /* - It could be that we're referring to something that's in ancestor selects. - We must make an appropriate mark_as_dependent() call for each such - outside reference. - */ - Dependency_marker dep_marker; - dep_marker.current_select= current_sel; - dep_marker.thd= thd; - (*ref)->walk(&Item::enumerate_field_refs_processor, FALSE, - (uchar*)&dep_marker); - } DBUG_ASSERT(*ref); /* From 25d69ea0124941cca54dbf0c2ebb2aa20ab2d6a8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 4 Apr 2017 10:13:53 +0300 Subject: [PATCH 8/8] MDEV-12198 innodb_defragment=1 crashes server on OPTIMIZE TABLE when FULLTEXT index exists ha_innobase::defragment_table(): Skip corrupted indexes and FULLTEXT INDEX. In InnoDB, FULLTEXT INDEX is implemented with auxiliary tables. We will not defragment them on OPTIMIZE TABLE. --- .../suite/innodb/r/innodb_defragment.result | 1 - .../innodb/r/innodb_defragment_small.result | 24 ++++++++++++++++ .../innodb/t/innodb_defragment-master.opt | 2 -- .../suite/innodb/t/innodb_defragment.opt | 1 + .../suite/innodb/t/innodb_defragment.test | 19 ++----------- .../innodb/t/innodb_defragment_small.test | 28 +++++++++++++++++++ storage/innobase/handler/ha_innodb.cc | 11 ++++++++ storage/xtradb/handler/ha_innodb.cc | 11 ++++++++ 8 files changed, 77 insertions(+), 20 deletions(-) create mode 100644 mysql-test/suite/innodb/r/innodb_defragment_small.result delete mode 100644 mysql-test/suite/innodb/t/innodb_defragment-master.opt create mode 100644 mysql-test/suite/innodb/t/innodb_defragment_small.test diff --git a/mysql-test/suite/innodb/r/innodb_defragment.result b/mysql-test/suite/innodb/r/innodb_defragment.result index 5f3fd523946d8..5d53fde35494f 100644 --- a/mysql-test/suite/innodb/r/innodb_defragment.result +++ b/mysql-test/suite/innodb/r/innodb_defragment.result @@ -1,4 +1,3 @@ -DROP TABLE if exists t1; set global innodb_defragment_stats_accuracy = 80; CREATE TABLE t1 (a INT NOT NULL PRIMARY KEY AUTO_INCREMENT, b VARCHAR(256), KEY SECOND(a, b)) ENGINE=INNODB; optimize table t1; diff --git a/mysql-test/suite/innodb/r/innodb_defragment_small.result b/mysql-test/suite/innodb/r/innodb_defragment_small.result new file mode 100644 index 0000000000000..3f594f79e7028 --- /dev/null +++ b/mysql-test/suite/innodb/r/innodb_defragment_small.result @@ -0,0 +1,24 @@ +SET @innodb_defragment_orig=@@GLOBAL.innodb_defragment; +SET GLOBAL innodb_defragment = 1; +CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(256), KEY(a, b)) ENGINE=INNODB; +OPTIMIZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 optimize status OK +INSERT INTO t1 VALUES (100000, REPEAT('A', 256)); +INSERT INTO t1 VALUES (200000, REPEAT('A', 256)); +INSERT INTO t1 VALUES (300000, REPEAT('A', 256)); +INSERT INTO t1 VALUES (400000, REPEAT('A', 256)); +OPTIMIZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 optimize status OK +DROP TABLE t1; +# +# MDEV-12198 innodb_defragment=1 crashes server on +# OPTIMIZE TABLE when FULLTEXT index exists +# +CREATE TABLE t1 (c TEXT, FULLTEXT KEY (c)) ENGINE=InnoDB; +OPTIMIZE TABLE t1; +Table Op Msg_type Msg_text +test.t1 optimize status OK +DROP TABLE t1; +SET GLOBAL innodb_defragment = @innodb_defragment_orig; diff --git a/mysql-test/suite/innodb/t/innodb_defragment-master.opt b/mysql-test/suite/innodb/t/innodb_defragment-master.opt deleted file mode 100644 index 6fc7f343b2405..0000000000000 --- a/mysql-test/suite/innodb/t/innodb_defragment-master.opt +++ /dev/null @@ -1,2 +0,0 @@ ---innodb_file_per_table ---innodb-defragment=1 \ No newline at end of file diff --git a/mysql-test/suite/innodb/t/innodb_defragment.opt b/mysql-test/suite/innodb/t/innodb_defragment.opt index 6426bac41a07c..aea3d480c244b 100644 --- a/mysql-test/suite/innodb/t/innodb_defragment.opt +++ b/mysql-test/suite/innodb/t/innodb_defragment.opt @@ -1,4 +1,5 @@ --loose-innodb-buffer-pool-stats --loose-innodb-buffer-page --loose-innodb-buffer-page-lru +--innodb-file-per-table --innodb-defragment=1 \ No newline at end of file diff --git a/mysql-test/suite/innodb/t/innodb_defragment.test b/mysql-test/suite/innodb/t/innodb_defragment.test index 22b72a4aa6b76..d9f5f56316ef2 100644 --- a/mysql-test/suite/innodb/t/innodb_defragment.test +++ b/mysql-test/suite/innodb/t/innodb_defragment.test @@ -1,17 +1,7 @@ --source include/have_innodb.inc --source include/big_test.inc ---source include/not_valgrind.inc --source include/not_embedded.inc ---disable_warnings -DROP TABLE if exists t1; ---enable_warnings - ---disable_query_log -let $innodb_defragment_n_pages_orig=`select @@innodb_defragment_n_pages`; -let $innodb_defragment_stats_accuracy_orig=`select @@innodb_defragment_stats_accuracy`; ---enable_query_log - set global innodb_defragment_stats_accuracy = 80; # Create table. @@ -47,12 +37,14 @@ delimiter ;// # Populate table. let $i = $data_size; --disable_query_log +BEGIN; while ($i) { eval INSERT INTO t1 VALUES ($data_size + 1 - $i, REPEAT('A', 256)); dec $i; } +COMMIT; --enable_query_log select count(stat_value) from mysql.innodb_index_stats where table_name like '%t1%' and stat_name in ('n_pages_freed'); @@ -161,10 +153,3 @@ select count(stat_value) = 0 from mysql.innodb_index_stats where table_name like DROP PROCEDURE defragment; DROP TABLE t1; - -# reset system ---disable_query_log -EVAL SET GLOBAL innodb_defragment_n_pages = $innodb_defragment_n_pages_orig; -EVAL SET GLOBAL innodb_defragment_stats_accuracy = $innodb_defragment_stats_accuracy_orig; ---enable_query_log - diff --git a/mysql-test/suite/innodb/t/innodb_defragment_small.test b/mysql-test/suite/innodb/t/innodb_defragment_small.test new file mode 100644 index 0000000000000..454333d698608 --- /dev/null +++ b/mysql-test/suite/innodb/t/innodb_defragment_small.test @@ -0,0 +1,28 @@ +--source include/have_innodb.inc + +SET @innodb_defragment_orig=@@GLOBAL.innodb_defragment; +SET GLOBAL innodb_defragment = 1; + +# Small tests copied from innodb.innodb_defragment +CREATE TABLE t1 (a INT PRIMARY KEY, b VARCHAR(256), KEY(a, b)) ENGINE=INNODB; +OPTIMIZE TABLE t1; + +INSERT INTO t1 VALUES (100000, REPEAT('A', 256)); +INSERT INTO t1 VALUES (200000, REPEAT('A', 256)); +INSERT INTO t1 VALUES (300000, REPEAT('A', 256)); +INSERT INTO t1 VALUES (400000, REPEAT('A', 256)); + +OPTIMIZE TABLE t1; +DROP TABLE t1; + +--echo # +--echo # MDEV-12198 innodb_defragment=1 crashes server on +--echo # OPTIMIZE TABLE when FULLTEXT index exists +--echo # + +CREATE TABLE t1 (c TEXT, FULLTEXT KEY (c)) ENGINE=InnoDB; + +OPTIMIZE TABLE t1; +DROP TABLE t1; + +SET GLOBAL innodb_defragment = @innodb_defragment_orig; diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index e447af9bdad76..f198a18656c87 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -12599,6 +12599,17 @@ ha_innobase::defragment_table( for (index = dict_table_get_first_index(table); index; index = dict_table_get_next_index(index)) { + if (dict_index_is_corrupted(index)) { + continue; + } + + if (index->page == FIL_NULL) { + /* Do not defragment auxiliary tables related + to FULLTEXT INDEX. */ + ut_ad(index->type & DICT_FTS); + continue; + } + if (one_index && strcasecmp(index_name, index->name) != 0) { continue; } diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index 3130dc980d29e..d2cd1951bd7f5 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -13272,6 +13272,17 @@ ha_innobase::defragment_table( for (index = dict_table_get_first_index(table); index; index = dict_table_get_next_index(index)) { + if (dict_index_is_corrupted(index)) { + continue; + } + + if (index->page == FIL_NULL) { + /* Do not defragment auxiliary tables related + to FULLTEXT INDEX. */ + ut_ad(index->type & DICT_FTS); + continue; + } + if (one_index && strcasecmp(index_name, index->name) != 0) { continue; }