From c4c48e974013a1a3d62ae6b2fc9a705c3bdd1689 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Tue, 7 Mar 2017 19:21:42 +0100 Subject: [PATCH 01/35] MDEV-11965 -Werror should not appear in released tarballs --- .../tokudb/PerconaFT/cmake_modules/TokuSetupCompiler.cmake | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/storage/tokudb/PerconaFT/cmake_modules/TokuSetupCompiler.cmake b/storage/tokudb/PerconaFT/cmake_modules/TokuSetupCompiler.cmake index 769bdffa5d9..c17e119d1cd 100644 --- a/storage/tokudb/PerconaFT/cmake_modules/TokuSetupCompiler.cmake +++ b/storage/tokudb/PerconaFT/cmake_modules/TokuSetupCompiler.cmake @@ -196,9 +196,9 @@ if (NOT CMAKE_CXX_COMPILER_ID STREQUAL Clang) set_cflags_if_supported(-Wcast-align) endif () -## always want these -set(CMAKE_C_FLAGS "-Wall -Werror ${CMAKE_C_FLAGS}") -set(CMAKE_CXX_FLAGS "-Wall -Werror ${CMAKE_CXX_FLAGS}") +## always want these in debug builds +set(CMAKE_C_FLAGS_DEBUG "-Wall -Werror ${CMAKE_C_FLAGS_DEBUG}") +set(CMAKE_CXX_FLAGS_DEBUG "-Wall -Werror ${CMAKE_CXX_FLAGS_DEBUG}") # pick language dialect set(CMAKE_C_FLAGS "-std=c99 ${CMAKE_C_FLAGS}") From d8a9b524f2e4efec675725c4c32acefe1d8dcb15 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Thu, 2 Nov 2017 16:58:37 +0400 Subject: [PATCH 02/35] MDEV-14221 Assertion `0' failed in Item::field_type_for_temporal_comparison --- mysql-test/r/type_date.result | 11 +++++++++++ mysql-test/t/type_date.test | 9 +++++++++ sql/item.h | 11 +++++++++++ 3 files changed, 31 insertions(+) diff --git a/mysql-test/r/type_date.result b/mysql-test/r/type_date.result index d2587d7199e..661dcabbcfe 100644 --- a/mysql-test/r/type_date.result +++ b/mysql-test/r/type_date.result @@ -843,5 +843,16 @@ Warning 1292 Incorrect datetime value: '1' Warning 1292 Incorrect datetime value: '1' DROP TABLE t1; # +# MDEV-14221 Assertion `0' failed in Item::field_type_for_temporal_comparison +# +CREATE TABLE t1 (d DATE); +INSERT INTO t1 VALUES ('1985-05-13'),('1989-12-24'); +SELECT d, COUNT(*) FROM t1 GROUP BY d WITH ROLLUP HAVING CASE d WHEN '2017-05-25' THEN 0 ELSE 1 END; +d COUNT(*) +1985-05-13 1 +1989-12-24 1 +NULL 2 +DROP TABLE t1; +# # End of 10.1 tests # diff --git a/mysql-test/t/type_date.test b/mysql-test/t/type_date.test index 63c89f318fc..8248386a93f 100644 --- a/mysql-test/t/type_date.test +++ b/mysql-test/t/type_date.test @@ -576,6 +576,15 @@ SELECT DATE(a), DATE(b), DATE(c) FROM t1; SELECT DATE(COALESCE(a)), DATE(COALESCE(b)), DATE(COALESCE(c)) FROM t1; DROP TABLE t1; +--echo # +--echo # MDEV-14221 Assertion `0' failed in Item::field_type_for_temporal_comparison +--echo # + +CREATE TABLE t1 (d DATE); +INSERT INTO t1 VALUES ('1985-05-13'),('1989-12-24'); +SELECT d, COUNT(*) FROM t1 GROUP BY d WITH ROLLUP HAVING CASE d WHEN '2017-05-25' THEN 0 ELSE 1 END; +DROP TABLE t1; + --echo # --echo # End of 10.1 tests diff --git a/sql/item.h b/sql/item.h index da2de2f25c5..17d97fe56e3 100644 --- a/sql/item.h +++ b/sql/item.h @@ -2581,6 +2581,17 @@ public: Field *result_field; Item_null_result(THD *thd): Item_null(thd), result_field(0) {} bool is_result_field() { return result_field != 0; } +#if MARIADB_VERSION_ID < 100300 + enum_field_types field_type() const + { + return result_field->type(); + } +#else + const Type_handler *type_handler() const + { + return result_field->type_handler(); + } +#endif void save_in_result_field(bool no_conversions) { save_in_field(result_field, no_conversions); From 5d0153c408ff8c7282fc387c4041fdbffd35727d Mon Sep 17 00:00:00 2001 From: Monty Date: Thu, 2 Nov 2017 14:39:54 +0200 Subject: [PATCH 03/35] MDEV-12633 Error from valgrind related to dd_frm_type "Conditional jump or move depends on uninitialised value in my_scan_weight_utf8_general_ci, main.mysql_client_test fails in biuldbot with valgrind" - Fixed by ensuring that engine_name is set to empty string even in case errors in the .frm file - Added some error checking to ha_table_exists() --- sql/datadict.cc | 15 ++++++++++++++- sql/handler.cc | 9 +++++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/sql/datadict.cc b/sql/datadict.cc index ee0d8805f95..f01d61f531b 100644 --- a/sql/datadict.cc +++ b/sql/datadict.cc @@ -45,6 +45,8 @@ static int read_string(File file, uchar**to, size_t length) engine_name is a LEX_STRING, where engine_name->str must point to a buffer of at least NAME_CHAR_LEN+1 bytes. + If engine_name is 0, then the function will only test if the file is a + view or not @retval FRMTYPE_ERROR error @retval FRMTYPE_TABLE table @@ -72,12 +74,23 @@ frm_type_enum dd_frm_type(THD *thd, char *path, LEX_STRING *engine_name) goto err; } + /* + We return FRMTYPE_TABLE if we can read the .frm file. This allows us + to drop a bad .frm file with DROP TABLE + */ type= FRMTYPE_TABLE; - if (!is_binary_frm_header(header) || !engine_name) + /* engine_name is 0 if we only want to know if table is view or not */ + if (!engine_name) goto err; + /* Initialize engine name in case we are not able to find it out */ engine_name->length= 0; + engine_name->str[0]= 0; + + if (!is_binary_frm_header(header)) + goto err; + dbt= header[3]; /* cannot use ha_resolve_by_legacy_type without a THD */ diff --git a/sql/handler.cc b/sql/handler.cc index 4e35780b1e2..a5a28ceb777 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -5063,10 +5063,15 @@ bool ha_table_exists(THD *thd, const char *db, const char *table_name, { char engine_buf[NAME_CHAR_LEN + 1]; LEX_STRING engine= { engine_buf, 0 }; + frm_type_enum type; - if (dd_frm_type(thd, path, &engine) != FRMTYPE_VIEW) + if ((type= dd_frm_type(thd, path, &engine)) == FRMTYPE_ERROR) + DBUG_RETURN(0); + + if (type != FRMTYPE_VIEW) { - plugin_ref p= plugin_lock_by_name(thd, &engine, MYSQL_STORAGE_ENGINE_PLUGIN); + plugin_ref p= plugin_lock_by_name(thd, &engine, + MYSQL_STORAGE_ENGINE_PLUGIN); *hton= p ? plugin_hton(p) : NULL; if (*hton) // verify that the table really exists From 80d61515ac07eeeb2ba9870c5a2ba33e160c2fa1 Mon Sep 17 00:00:00 2001 From: Sergei Petrunia Date: Thu, 2 Nov 2017 19:11:01 +0300 Subject: [PATCH 04/35] Make rocksdb.read_only_tx pass and enable it - FB/MySQL 5.6' MyRocks has START TRANSACTION WITH CONSISTENT ROCKSDB SNAPSHOT, which returns binlog position. - MariaDB has a cross-engine START TRANSACTION WITH CONSISTENT SNAPSHOT. It can be used for the same purpose. Binlog position can be obtained from Binlog_snapshot_file/position status vars. --- .../mysql-test/rocksdb/r/read_only_tx.result | 14 +++++++++++--- storage/rocksdb/mysql-test/rocksdb/t/disabled.def | 2 +- .../mysql-test/rocksdb/t/read_only_tx-master.opt | 2 +- .../rocksdb/mysql-test/rocksdb/t/read_only_tx.test | 8 ++++---- 4 files changed, 17 insertions(+), 9 deletions(-) diff --git a/storage/rocksdb/mysql-test/rocksdb/r/read_only_tx.result b/storage/rocksdb/mysql-test/rocksdb/r/read_only_tx.result index b83f0a474cc..db21c3c01d4 100644 --- a/storage/rocksdb/mysql-test/rocksdb/r/read_only_tx.result +++ b/storage/rocksdb/mysql-test/rocksdb/r/read_only_tx.result @@ -1,11 +1,14 @@ DROP TABLE IF EXISTS t1; +connect con1,localhost,root,,; +connect con2,localhost,root,,; +connection con1; CREATE TABLE t1 (id INT, value int, PRIMARY KEY (id), INDEX (value)) ENGINE=RocksDB; INSERT INTO t1 VALUES (1,1); select variable_value into @p from information_schema.global_status where variable_name='rocksdb_number_sst_entry_put'; select variable_value into @s from information_schema.global_status where variable_name='rocksdb_number_sst_entry_singledelete'; -START TRANSACTION WITH CONSISTENT ROCKSDB SNAPSHOT; -File Position Gtid_executed -master-bin.000001 734 uuid:1-3 +START TRANSACTION WITH CONSISTENT SNAPSHOT; +connection con2; +connection con1; select case when variable_value-@p < 1000 then 'true' else variable_value-@p end from information_schema.global_status where variable_name='rocksdb_number_sst_entry_put'; case when variable_value-@p < 1000 then 'true' else variable_value-@p end true @@ -27,10 +30,15 @@ id value 1 10001 2 2 BEGIN; +connection con2; +connection con1; SELECT COUNT(*) FROM t1; COUNT(*) 9998 COMMIT; +connection default; +disconnect con1; +disconnect con2; OPTIMIZE TABLE t1; Table Op Msg_type Msg_text test.t1 optimize status OK diff --git a/storage/rocksdb/mysql-test/rocksdb/t/disabled.def b/storage/rocksdb/mysql-test/rocksdb/t/disabled.def index 3af1d99ff22..a0810fe63ec 100644 --- a/storage/rocksdb/mysql-test/rocksdb/t/disabled.def +++ b/storage/rocksdb/mysql-test/rocksdb/t/disabled.def @@ -80,7 +80,7 @@ blind_delete_without_tx_api: MDEV-12286: rocksdb.blind_delete_without_tx_api tes ## information_schema : MariaRocks: requires GTIDs mysqlbinlog_gtid_skip_empty_trans_rocksdb : MariaRocks: requires GTIDs -read_only_tx : MariaRocks: requires GTIDs +#read_only_tx : MariaRocks: requires GTIDs rpl_row_triggers : MariaRocks: requires GTIDs diff --git a/storage/rocksdb/mysql-test/rocksdb/t/read_only_tx-master.opt b/storage/rocksdb/mysql-test/rocksdb/t/read_only_tx-master.opt index 52f4895dc2f..221b35c672a 100644 --- a/storage/rocksdb/mysql-test/rocksdb/t/read_only_tx-master.opt +++ b/storage/rocksdb/mysql-test/rocksdb/t/read_only_tx-master.opt @@ -1 +1 @@ ---rocksdb_default_cf_options=write_buffer_size=16k --log-bin --binlog_format=row --gtid_mode=ON --enforce_gtid_consistency --log-slave-updates +--rocksdb_default_cf_options=write_buffer_size=16k --log-bin --binlog_format=row --log-slave-updates diff --git a/storage/rocksdb/mysql-test/rocksdb/t/read_only_tx.test b/storage/rocksdb/mysql-test/rocksdb/t/read_only_tx.test index 52f65095d33..3a1025a3623 100644 --- a/storage/rocksdb/mysql-test/rocksdb/t/read_only_tx.test +++ b/storage/rocksdb/mysql-test/rocksdb/t/read_only_tx.test @@ -2,9 +2,9 @@ --source include/have_rocksdb.inc --source include/count_sessions.inc --disable_warnings ---source include/have_gtid.inc +#--source include/have_gtid.inc --enable_warnings --- let $uuid = `select @@server_uuid;` +#-- let $uuid = `select @@server_uuid;` --disable_warnings DROP TABLE IF EXISTS t1; @@ -20,8 +20,8 @@ INSERT INTO t1 VALUES (1,1); # Read-only, long-running transaction. SingleDelete/Put shouldn't increase much. select variable_value into @p from information_schema.global_status where variable_name='rocksdb_number_sst_entry_put'; select variable_value into @s from information_schema.global_status where variable_name='rocksdb_number_sst_entry_singledelete'; --- replace_result $uuid uuid -START TRANSACTION WITH CONSISTENT ROCKSDB SNAPSHOT; +#-- replace_result $uuid uuid +START TRANSACTION WITH CONSISTENT SNAPSHOT; connection con2; --disable_query_log From 04daf30e9bca85b3241981c53f2293cee1f2de00 Mon Sep 17 00:00:00 2001 From: Alexey Botchkov Date: Fri, 3 Nov 2017 17:05:41 +0400 Subject: [PATCH 05/35] MDEV-13921 Audit log writes invalid SQL if single-line comments are present. Escape special characters (like \r \n \t) instead of replacing them with spaces. --- .../suite/plugins/r/server_audit.result | 9 +++-- mysql-test/suite/plugins/t/server_audit.test | 5 ++- plugin/server_audit/server_audit.c | 39 ++++++++++--------- 3 files changed, 31 insertions(+), 22 deletions(-) diff --git a/mysql-test/suite/plugins/r/server_audit.result b/mysql-test/suite/plugins/r/server_audit.result index ceb75176b43..3971504b238 100644 --- a/mysql-test/suite/plugins/r/server_audit.result +++ b/mysql-test/suite/plugins/r/server_audit.result @@ -47,6 +47,7 @@ alter table t1 rename renamed_t1; set global server_audit_events='connect,query'; select 1, 2, +# comment 3; 1 2 3 1 2 3 @@ -161,7 +162,9 @@ id 2 CREATE USER u1 IDENTIFIED BY 'pwd-123'; GRANT ALL ON sa_db TO u2 IDENTIFIED BY "pwd-321"; -SET PASSWORD FOR u1 = PASSWORD('pwd 098'); +SET PASSWORD +# comment +FOR u1 = PASSWORD('pwd 098'); SET PASSWORD FOR u1=; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1 CREATE USER u3 IDENTIFIED BY ''; @@ -253,7 +256,7 @@ TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,index_stats, TIME,HOSTNAME,root,localhost,ID,ID,RENAME,test,t1|test.renamed_t1, TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'alter table t1 rename renamed_t1',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'set global server_audit_events=\'connect,query\'',0 -TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select 1, 2, 3',0 +TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select 1,\n2,\n# comment\n3',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'insert into t2 values (1), (2)',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select * from t2',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select * from t_doesnt_exist',ID @@ -336,7 +339,7 @@ TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'/*! select 2*/',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'/*comment*/ select 2',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'CREATE USER u1 IDENTIFIED BY *****',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'GRANT ALL ON sa_db TO u2 IDENTIFIED BY *****',0 -TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'SET PASSWORD FOR u1 = PASSWORD(*****)',0 +TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'SET PASSWORD \n# comment\nFOR u1 = PASSWORD(*****)',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'SET PASSWORD FOR u1=',ID TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'CREATE USER u3 IDENTIFIED BY *****',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'drop user u1, u2, u3',0 diff --git a/mysql-test/suite/plugins/t/server_audit.test b/mysql-test/suite/plugins/t/server_audit.test index 52428909c3b..9be0d5556f0 100644 --- a/mysql-test/suite/plugins/t/server_audit.test +++ b/mysql-test/suite/plugins/t/server_audit.test @@ -38,6 +38,7 @@ alter table t1 rename renamed_t1; set global server_audit_events='connect,query'; select 1, 2, +# comment 3; insert into t2 values (1), (2); select * from t2; @@ -106,7 +107,9 @@ insert into t1 values (1), (2); select * from t1; CREATE USER u1 IDENTIFIED BY 'pwd-123'; GRANT ALL ON sa_db TO u2 IDENTIFIED BY "pwd-321"; -SET PASSWORD FOR u1 = PASSWORD('pwd 098'); +SET PASSWORD +# comment +FOR u1 = PASSWORD('pwd 098'); --error 1064 SET PASSWORD FOR u1=; CREATE USER u3 IDENTIFIED BY ''; diff --git a/plugin/server_audit/server_audit.c b/plugin/server_audit/server_audit.c index 6a2ed16cb00..152cc75b710 100644 --- a/plugin/server_audit/server_audit.c +++ b/plugin/server_audit/server_audit.c @@ -1121,6 +1121,21 @@ do { \ } while(0) +#define ESC_MAP_SIZE 0x60 +static const char esc_map[ESC_MAP_SIZE]= +{ + 0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, '\'', 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '\\', 0, 0, 0 +}; + +static char escaped_char(char c) +{ + return ((unsigned char ) c) >= ESC_MAP_SIZE ? 0 : esc_map[(unsigned char) c]; +} static void setup_connection_initdb(struct connection_info *cn, @@ -1327,21 +1342,16 @@ static size_t escape_string(const char *str, unsigned int len, const char *res_end= result + result_len - 2; while (len) { + char esc_c; + if (result >= res_end) break; - if (*str == '\'') + if ((esc_c= escaped_char(*str))) { if (result+1 >= res_end) break; *(result++)= '\\'; - *(result++)= '\''; - } - else if (*str == '\\') - { - if (result+1 >= res_end) - break; - *(result++)= '\\'; - *(result++)= '\\'; + *(result++)= esc_c; } else if (is_space(*str)) *(result++)= ' '; @@ -1430,19 +1440,12 @@ static size_t escape_string_hide_passwords(const char *str, unsigned int len, no_password: if (result >= res_end) break; - if (*str == '\'') + if ((b_char= escaped_char(*str))) { if (result+1 >= res_end) break; *(result++)= '\\'; - *(result++)= '\''; - } - else if (*str == '\\') - { - if (result+1 >= res_end) - break; - *(result++)= '\\'; - *(result++)= '\\'; + *(result++)= b_char; } else if (is_space(*str)) *(result++)= ' '; From 3a3f1328fe1b4c9cfc1175cc5acc3f47acd750e8 Mon Sep 17 00:00:00 2001 From: Alexey Botchkov Date: Fri, 3 Nov 2017 17:05:41 +0400 Subject: [PATCH 06/35] MDEV-13921 Audit log writes invalid SQL if single-line comments are present. Escape special characters (like \r \n \t) instead of replacing them with spaces. --- .../suite/plugins/r/server_audit.result | 9 +++-- mysql-test/suite/plugins/t/server_audit.test | 5 ++- plugin/server_audit/server_audit.c | 39 ++++++++++--------- 3 files changed, 31 insertions(+), 22 deletions(-) diff --git a/mysql-test/suite/plugins/r/server_audit.result b/mysql-test/suite/plugins/r/server_audit.result index ceb75176b43..3971504b238 100644 --- a/mysql-test/suite/plugins/r/server_audit.result +++ b/mysql-test/suite/plugins/r/server_audit.result @@ -47,6 +47,7 @@ alter table t1 rename renamed_t1; set global server_audit_events='connect,query'; select 1, 2, +# comment 3; 1 2 3 1 2 3 @@ -161,7 +162,9 @@ id 2 CREATE USER u1 IDENTIFIED BY 'pwd-123'; GRANT ALL ON sa_db TO u2 IDENTIFIED BY "pwd-321"; -SET PASSWORD FOR u1 = PASSWORD('pwd 098'); +SET PASSWORD +# comment +FOR u1 = PASSWORD('pwd 098'); SET PASSWORD FOR u1=; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1 CREATE USER u3 IDENTIFIED BY ''; @@ -253,7 +256,7 @@ TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,index_stats, TIME,HOSTNAME,root,localhost,ID,ID,RENAME,test,t1|test.renamed_t1, TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'alter table t1 rename renamed_t1',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'set global server_audit_events=\'connect,query\'',0 -TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select 1, 2, 3',0 +TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select 1,\n2,\n# comment\n3',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'insert into t2 values (1), (2)',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select * from t2',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select * from t_doesnt_exist',ID @@ -336,7 +339,7 @@ TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'/*! select 2*/',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'/*comment*/ select 2',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'CREATE USER u1 IDENTIFIED BY *****',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'GRANT ALL ON sa_db TO u2 IDENTIFIED BY *****',0 -TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'SET PASSWORD FOR u1 = PASSWORD(*****)',0 +TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'SET PASSWORD \n# comment\nFOR u1 = PASSWORD(*****)',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'SET PASSWORD FOR u1=',ID TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'CREATE USER u3 IDENTIFIED BY *****',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'drop user u1, u2, u3',0 diff --git a/mysql-test/suite/plugins/t/server_audit.test b/mysql-test/suite/plugins/t/server_audit.test index 52428909c3b..9be0d5556f0 100644 --- a/mysql-test/suite/plugins/t/server_audit.test +++ b/mysql-test/suite/plugins/t/server_audit.test @@ -38,6 +38,7 @@ alter table t1 rename renamed_t1; set global server_audit_events='connect,query'; select 1, 2, +# comment 3; insert into t2 values (1), (2); select * from t2; @@ -106,7 +107,9 @@ insert into t1 values (1), (2); select * from t1; CREATE USER u1 IDENTIFIED BY 'pwd-123'; GRANT ALL ON sa_db TO u2 IDENTIFIED BY "pwd-321"; -SET PASSWORD FOR u1 = PASSWORD('pwd 098'); +SET PASSWORD +# comment +FOR u1 = PASSWORD('pwd 098'); --error 1064 SET PASSWORD FOR u1=; CREATE USER u3 IDENTIFIED BY ''; diff --git a/plugin/server_audit/server_audit.c b/plugin/server_audit/server_audit.c index 95ccb9607bf..812f6fdaac8 100644 --- a/plugin/server_audit/server_audit.c +++ b/plugin/server_audit/server_audit.c @@ -1121,6 +1121,21 @@ do { \ } while(0) +#define ESC_MAP_SIZE 0x60 +static const char esc_map[ESC_MAP_SIZE]= +{ + 0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, '\'', 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '\\', 0, 0, 0 +}; + +static char escaped_char(char c) +{ + return ((unsigned char ) c) >= ESC_MAP_SIZE ? 0 : esc_map[(unsigned char) c]; +} static void setup_connection_initdb(struct connection_info *cn, @@ -1327,21 +1342,16 @@ static size_t escape_string(const char *str, unsigned int len, const char *res_end= result + result_len - 2; while (len) { + char esc_c; + if (result >= res_end) break; - if (*str == '\'') + if ((esc_c= escaped_char(*str))) { if (result+1 >= res_end) break; *(result++)= '\\'; - *(result++)= '\''; - } - else if (*str == '\\') - { - if (result+1 >= res_end) - break; - *(result++)= '\\'; - *(result++)= '\\'; + *(result++)= esc_c; } else if (is_space(*str)) *(result++)= ' '; @@ -1430,19 +1440,12 @@ static size_t escape_string_hide_passwords(const char *str, unsigned int len, no_password: if (result >= res_end) break; - if (*str == '\'') + if ((b_char= escaped_char(*str))) { if (result+1 >= res_end) break; *(result++)= '\\'; - *(result++)= '\''; - } - else if (*str == '\\') - { - if (result+1 >= res_end) - break; - *(result++)= '\\'; - *(result++)= '\\'; + *(result++)= b_char; } else if (is_space(*str)) *(result++)= ' '; From ffb1eebe05e93d182d0c1fa59a1b368bbc52ec14 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Fri, 3 Nov 2017 16:02:19 +0000 Subject: [PATCH 07/35] MDEV-13560 Copy all innodb undo tablespaces from the backup directory to destination. Do not check or rely on innodb_undo_tablespaces in copy-back, there is no good reason for that. --- extra/mariabackup/backup_copy.cc | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) diff --git a/extra/mariabackup/backup_copy.cc b/extra/mariabackup/backup_copy.cc index 156e0b20e7c..c019209faad 100644 --- a/extra/mariabackup/backup_copy.cc +++ b/extra/mariabackup/backup_copy.cc @@ -1700,26 +1700,28 @@ copy_back() ut_crc32_init(); /* copy undo tablespaces */ - if (srv_undo_tablespaces > 0) { - dst_dir = (srv_undo_dir && *srv_undo_dir) - ? srv_undo_dir : mysql_data_home; - ds_data = ds_create(dst_dir, DS_TYPE_LOCAL); + dst_dir = (srv_undo_dir && *srv_undo_dir) + ? srv_undo_dir : mysql_data_home; - for (i = 1; i <= srv_undo_tablespaces; i++) { - char filename[20]; - sprintf(filename, "undo%03u", (uint)i); - if (!(ret = copy_or_move_file(filename, filename, - dst_dir, 1))) { - goto cleanup; - } + ds_data = ds_create(dst_dir, DS_TYPE_LOCAL); + + for (i = 1; ; i++) { + char filename[20]; + sprintf(filename, "undo%03u", (uint)i); + if (!file_exists(filename)) { + break; + } + if (!(ret = copy_or_move_file(filename, filename, + dst_dir, 1))) { + goto cleanup; } - - ds_destroy(ds_data); - ds_data = NULL; } + ds_destroy(ds_data); + ds_data = NULL; + /* copy redo logs */ dst_dir = (srv_log_group_home_dir && *srv_log_group_home_dir) @@ -1844,7 +1846,7 @@ copy_back() } } - /* copy buufer pool dump */ + /* copy buffer pool dump */ if (innobase_buffer_pool_filename) { const char *src_name; From 1394ea696565bdf67ba2a9ef8caca79a22f5787e Mon Sep 17 00:00:00 2001 From: Alexey Botchkov Date: Fri, 3 Nov 2017 22:36:58 +0400 Subject: [PATCH 08/35] MDEV-13921 Audit log writes invalid SQL if single-line comments are present. thread_pool_server_audit.test fixed. plugin version updated. --- .../suite/plugins/r/thread_pool_server_audit.result | 9 ++++++--- mysql-test/suite/plugins/t/thread_pool_server_audit.test | 5 ++++- plugin/server_audit/server_audit.c | 2 +- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/mysql-test/suite/plugins/r/thread_pool_server_audit.result b/mysql-test/suite/plugins/r/thread_pool_server_audit.result index ceb75176b43..912cef2761a 100644 --- a/mysql-test/suite/plugins/r/thread_pool_server_audit.result +++ b/mysql-test/suite/plugins/r/thread_pool_server_audit.result @@ -47,6 +47,7 @@ alter table t1 rename renamed_t1; set global server_audit_events='connect,query'; select 1, 2, +# comment 3; 1 2 3 1 2 3 @@ -161,7 +162,9 @@ id 2 CREATE USER u1 IDENTIFIED BY 'pwd-123'; GRANT ALL ON sa_db TO u2 IDENTIFIED BY "pwd-321"; -SET PASSWORD FOR u1 = PASSWORD('pwd 098'); +SET PASSWORD +# comment +FOR u1 = PASSWORD('pwd 098'); SET PASSWORD FOR u1=; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1 CREATE USER u3 IDENTIFIED BY ''; @@ -253,7 +256,7 @@ TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,index_stats, TIME,HOSTNAME,root,localhost,ID,ID,RENAME,test,t1|test.renamed_t1, TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'alter table t1 rename renamed_t1',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'set global server_audit_events=\'connect,query\'',0 -TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select 1, 2, 3',0 +TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select 1,\n2,\n# comment\n3',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'insert into t2 values (1), (2)',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select * from t2',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select * from t_doesnt_exist',ID @@ -336,7 +339,7 @@ TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'/*! select 2*/',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'/*comment*/ select 2',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'CREATE USER u1 IDENTIFIED BY *****',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'GRANT ALL ON sa_db TO u2 IDENTIFIED BY *****',0 -TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'SET PASSWORD FOR u1 = PASSWORD(*****)',0 +TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'SET PASSWORD\n# comment\nFOR u1 = PASSWORD(*****)',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'SET PASSWORD FOR u1=',ID TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'CREATE USER u3 IDENTIFIED BY *****',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'drop user u1, u2, u3',0 diff --git a/mysql-test/suite/plugins/t/thread_pool_server_audit.test b/mysql-test/suite/plugins/t/thread_pool_server_audit.test index 626d4136c47..724000c9789 100644 --- a/mysql-test/suite/plugins/t/thread_pool_server_audit.test +++ b/mysql-test/suite/plugins/t/thread_pool_server_audit.test @@ -38,6 +38,7 @@ alter table t1 rename renamed_t1; set global server_audit_events='connect,query'; select 1, 2, +# comment 3; insert into t2 values (1), (2); select * from t2; @@ -106,7 +107,9 @@ insert into t1 values (1), (2); select * from t1; CREATE USER u1 IDENTIFIED BY 'pwd-123'; GRANT ALL ON sa_db TO u2 IDENTIFIED BY "pwd-321"; -SET PASSWORD FOR u1 = PASSWORD('pwd 098'); +SET PASSWORD +# comment +FOR u1 = PASSWORD('pwd 098'); --error 1064 SET PASSWORD FOR u1=; CREATE USER u3 IDENTIFIED BY ''; diff --git a/plugin/server_audit/server_audit.c b/plugin/server_audit/server_audit.c index 152cc75b710..323179d5f84 100644 --- a/plugin/server_audit/server_audit.c +++ b/plugin/server_audit/server_audit.c @@ -15,7 +15,7 @@ #define PLUGIN_VERSION 0x104 -#define PLUGIN_STR_VERSION "1.4.2" +#define PLUGIN_STR_VERSION "1.4.3" #define _my_thread_var loc_thread_var From 6ceb49a941f5b5aa93364ef1f4b57dc1d780cf25 Mon Sep 17 00:00:00 2001 From: Alexey Botchkov Date: Fri, 3 Nov 2017 22:36:58 +0400 Subject: [PATCH 09/35] MDEV-13921 Audit log writes invalid SQL if single-line comments are present. thread_pool_server_audit.test fixed. plugin version updated. --- .../suite/plugins/r/thread_pool_server_audit.result | 9 ++++++--- mysql-test/suite/plugins/t/thread_pool_server_audit.test | 5 ++++- plugin/server_audit/server_audit.c | 2 +- 3 files changed, 11 insertions(+), 5 deletions(-) diff --git a/mysql-test/suite/plugins/r/thread_pool_server_audit.result b/mysql-test/suite/plugins/r/thread_pool_server_audit.result index ceb75176b43..912cef2761a 100644 --- a/mysql-test/suite/plugins/r/thread_pool_server_audit.result +++ b/mysql-test/suite/plugins/r/thread_pool_server_audit.result @@ -47,6 +47,7 @@ alter table t1 rename renamed_t1; set global server_audit_events='connect,query'; select 1, 2, +# comment 3; 1 2 3 1 2 3 @@ -161,7 +162,9 @@ id 2 CREATE USER u1 IDENTIFIED BY 'pwd-123'; GRANT ALL ON sa_db TO u2 IDENTIFIED BY "pwd-321"; -SET PASSWORD FOR u1 = PASSWORD('pwd 098'); +SET PASSWORD +# comment +FOR u1 = PASSWORD('pwd 098'); SET PASSWORD FOR u1=; ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 1 CREATE USER u3 IDENTIFIED BY ''; @@ -253,7 +256,7 @@ TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,index_stats, TIME,HOSTNAME,root,localhost,ID,ID,RENAME,test,t1|test.renamed_t1, TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'alter table t1 rename renamed_t1',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'set global server_audit_events=\'connect,query\'',0 -TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select 1, 2, 3',0 +TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select 1,\n2,\n# comment\n3',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'insert into t2 values (1), (2)',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select * from t2',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select * from t_doesnt_exist',ID @@ -336,7 +339,7 @@ TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'/*! select 2*/',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'/*comment*/ select 2',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'CREATE USER u1 IDENTIFIED BY *****',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'GRANT ALL ON sa_db TO u2 IDENTIFIED BY *****',0 -TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'SET PASSWORD FOR u1 = PASSWORD(*****)',0 +TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'SET PASSWORD\n# comment\nFOR u1 = PASSWORD(*****)',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'SET PASSWORD FOR u1=',ID TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'CREATE USER u3 IDENTIFIED BY *****',0 TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'drop user u1, u2, u3',0 diff --git a/mysql-test/suite/plugins/t/thread_pool_server_audit.test b/mysql-test/suite/plugins/t/thread_pool_server_audit.test index 626d4136c47..724000c9789 100644 --- a/mysql-test/suite/plugins/t/thread_pool_server_audit.test +++ b/mysql-test/suite/plugins/t/thread_pool_server_audit.test @@ -38,6 +38,7 @@ alter table t1 rename renamed_t1; set global server_audit_events='connect,query'; select 1, 2, +# comment 3; insert into t2 values (1), (2); select * from t2; @@ -106,7 +107,9 @@ insert into t1 values (1), (2); select * from t1; CREATE USER u1 IDENTIFIED BY 'pwd-123'; GRANT ALL ON sa_db TO u2 IDENTIFIED BY "pwd-321"; -SET PASSWORD FOR u1 = PASSWORD('pwd 098'); +SET PASSWORD +# comment +FOR u1 = PASSWORD('pwd 098'); --error 1064 SET PASSWORD FOR u1=; CREATE USER u3 IDENTIFIED BY ''; diff --git a/plugin/server_audit/server_audit.c b/plugin/server_audit/server_audit.c index 812f6fdaac8..0a266ab19fe 100644 --- a/plugin/server_audit/server_audit.c +++ b/plugin/server_audit/server_audit.c @@ -15,7 +15,7 @@ #define PLUGIN_VERSION 0x104 -#define PLUGIN_STR_VERSION "1.4.2" +#define PLUGIN_STR_VERSION "1.4.3" #define _my_thread_var loc_thread_var From 0ed5c09b28163726977ffc1754decda200b2beff Mon Sep 17 00:00:00 2001 From: Elena Stepanova Date: Wed, 1 Nov 2017 19:57:47 +0200 Subject: [PATCH 10/35] MDEV-11864 main.view test uses CHECK PARTITION but does not check for the partition plugin The test would pass even with skipped partitioning, because CHECK PARTITION for a view works identically with enabled/disabled partitioning; but if the server is compiled without partitioning at all, it cannot execute the statement, and the test would fail. Check for the presence of partitioning allows to skip the test in this case, rather than let it fail --- mysql-test/t/view.test | 1 + 1 file changed, 1 insertion(+) diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test index cbccbb5d656..1d199c3bac5 100644 --- a/mysql-test/t/view.test +++ b/mysql-test/t/view.test @@ -1,3 +1,4 @@ +--source include/have_partition.inc --disable_warnings drop table if exists t1,t2,t3,t4,t5,t6,t9,`t1a``b`,v1,v2,v3,v4,v5,v6; From 5e5adfa7293d2b8d981cbce6ef3fede3daf5b7a5 Mon Sep 17 00:00:00 2001 From: Elena Stepanova Date: Wed, 1 Nov 2017 18:40:09 +0200 Subject: [PATCH 11/35] MDEV-14029 Server does not remove #sql*.frm files after crash during ALTER TABLE Add a check for #sql* files in test and mysql subdirs to the testcase check --- mysql-test/include/check-testcase.test | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/mysql-test/include/check-testcase.test b/mysql-test/include/check-testcase.test index dcf6bd154ce..3a9ec419bb1 100644 --- a/mysql-test/include/check-testcase.test +++ b/mysql-test/include/check-testcase.test @@ -73,5 +73,10 @@ if (!$tmp) { } call mtr.check_testcase(); + +let $datadir=`select @@datadir`; +list_files $datadir/test #sql*; +list_files $datadir/mysql #sql*; + --enable_query_log From bfde65c0ae09800b45748a153f6179f3ef3b64fa Mon Sep 17 00:00:00 2001 From: Elena Stepanova Date: Sat, 4 Nov 2017 02:39:16 +0200 Subject: [PATCH 12/35] MDEV-10651, MDEV-14196 sys_vars.innodb_buffer_pool_* tests fail - innodb_buffer_pool_dump_now_basic is modified to make sure it really performs a dump and waits till it completion, to avoid the apparent or hidden failure similar to MDEV-9713 / MDEV-10651 - innodb_buffer_pool_dump_pct_basic is modified to re-use the new code from innodb_buffer_pool_dump_now_basic and thus avoid the failure MDEV-10651 - innodb_buffer_pool_load_now_basic is re-written to simplify the logic by re-using the code innodb_buffer_pool_dump_now_basic and is given an opt file to avoid race conditions with buffer pool load performed upon server startup, which causes MDEV-14196 failure --- .../innodb_buffer_pool_dump_now_basic.result | 7 +-- .../innodb_buffer_pool_dump_pct_basic.result | 3 +- .../innodb_buffer_pool_load_now_basic.result | 6 +-- .../t/innodb_buffer_pool_dump_now_basic.test | 31 +++++++++++-- .../t/innodb_buffer_pool_dump_pct_basic.test | 18 +++----- .../t/innodb_buffer_pool_load_now_basic.opt | 1 + .../t/innodb_buffer_pool_load_now_basic.test | 44 +++++-------------- 7 files changed, 55 insertions(+), 55 deletions(-) create mode 100644 mysql-test/suite/sys_vars/t/innodb_buffer_pool_load_now_basic.opt diff --git a/mysql-test/suite/sys_vars/r/innodb_buffer_pool_dump_now_basic.result b/mysql-test/suite/sys_vars/r/innodb_buffer_pool_dump_now_basic.result index 9c3a37f892b..522d5731a6d 100644 --- a/mysql-test/suite/sys_vars/r/innodb_buffer_pool_dump_now_basic.result +++ b/mysql-test/suite/sys_vars/r/innodb_buffer_pool_dump_now_basic.result @@ -1,7 +1,8 @@ -SET @orig = @@global.innodb_buffer_pool_dump_now; -SELECT @orig; -@orig +SELECT @@global.innodb_buffer_pool_dump_now; +@@global.innodb_buffer_pool_dump_now 0 +SELECT variable_value INTO @old_dump_status FROM information_schema.global_status +WHERE LOWER(variable_name) = 'innodb_buffer_pool_dump_status'; SET GLOBAL innodb_buffer_pool_dump_now = ON; SELECT @@global.innodb_buffer_pool_dump_now; @@global.innodb_buffer_pool_dump_now diff --git a/mysql-test/suite/sys_vars/r/innodb_buffer_pool_dump_pct_basic.result b/mysql-test/suite/sys_vars/r/innodb_buffer_pool_dump_pct_basic.result index 51c72cfe791..70fcdd3cb56 100644 --- a/mysql-test/suite/sys_vars/r/innodb_buffer_pool_dump_pct_basic.result +++ b/mysql-test/suite/sys_vars/r/innodb_buffer_pool_dump_pct_basic.result @@ -2,7 +2,8 @@ SET @orig = @@global.innodb_buffer_pool_dump_pct; SELECT @orig; @orig 100 -SET GLOBAL innodb_buffer_pool_dump_pct=3, GLOBAL innodb_buffer_pool_dump_now = ON; +SET GLOBAL innodb_buffer_pool_dump_pct=3; +# Do the dump SET GLOBAL innodb_buffer_pool_dump_pct=0; SELECT @@global.innodb_buffer_pool_dump_pct; @@global.innodb_buffer_pool_dump_pct diff --git a/mysql-test/suite/sys_vars/r/innodb_buffer_pool_load_now_basic.result b/mysql-test/suite/sys_vars/r/innodb_buffer_pool_load_now_basic.result index 3185d1ca170..eebed4d0f4a 100644 --- a/mysql-test/suite/sys_vars/r/innodb_buffer_pool_load_now_basic.result +++ b/mysql-test/suite/sys_vars/r/innodb_buffer_pool_load_now_basic.result @@ -1,8 +1,6 @@ -SET @orig = @@global.innodb_buffer_pool_load_now; -SELECT @orig; -@orig +SELECT @@global.innodb_buffer_pool_load_now; +@@global.innodb_buffer_pool_load_now 0 -SET GLOBAL innodb_buffer_pool_dump_now = ON; SET GLOBAL innodb_buffer_pool_load_now = ON; SELECT variable_value FROM information_schema.global_status diff --git a/mysql-test/suite/sys_vars/t/innodb_buffer_pool_dump_now_basic.test b/mysql-test/suite/sys_vars/t/innodb_buffer_pool_dump_now_basic.test index 0bae347428e..8c5f8fa7bf0 100644 --- a/mysql-test/suite/sys_vars/t/innodb_buffer_pool_dump_now_basic.test +++ b/mysql-test/suite/sys_vars/t/innodb_buffer_pool_dump_now_basic.test @@ -5,8 +5,31 @@ -- source include/have_innodb.inc # Check the default value -SET @orig = @@global.innodb_buffer_pool_dump_now; -SELECT @orig; +SELECT @@global.innodb_buffer_pool_dump_now; + +-- let $file = `SELECT CONCAT(@@datadir, @@global.innodb_buffer_pool_filename)` +-- error 0,1 +-- remove_file $file + +SELECT variable_value INTO @old_dump_status FROM information_schema.global_status + WHERE LOWER(variable_name) = 'innodb_buffer_pool_dump_status'; + +# A previous test could have run buffer pool dump already; +# in this case we want to make sure that the current time is different +# from the timestamp in the status variable. +# We should have had a smart wait condition here, like the commented one below, +# let $wait_condition = +# SELECT TRIM(SUBSTR('$old_status', -8)) != DATE_FORMAT(CURTIME(), '%k:%i:%s'); +# -- source include/wait_condition.inc + +# ... but we can't because of MDEV-9867, so there will be just sleep instead. +# And it might be not enough to sleep one second, so we'll have to sleep two. + +if (`SELECT variable_value LIKE '%completed at%' FROM information_schema.global_status + WHERE LOWER(variable_name) = 'innodb_buffer_pool_dump_status'`) +{ + -- sleep 2 +} # Do the dump SET GLOBAL innodb_buffer_pool_dump_now = ON; @@ -15,11 +38,11 @@ SELECT @@global.innodb_buffer_pool_dump_now; # Wait for the dump to complete let $wait_condition = - SELECT SUBSTR(variable_value, 1, 33) = 'Buffer pool(s) dump completed at ' + SELECT variable_value != @old_dump_status + AND SUBSTR(variable_value, 1, 33) = 'Buffer pool(s) dump completed at ' FROM information_schema.global_status WHERE LOWER(variable_name) = 'innodb_buffer_pool_dump_status'; -- source include/wait_condition.inc # Confirm that the dump file has been created --- let $file = `SELECT CONCAT(@@datadir, @@global.innodb_buffer_pool_filename)` -- file_exists $file diff --git a/mysql-test/suite/sys_vars/t/innodb_buffer_pool_dump_pct_basic.test b/mysql-test/suite/sys_vars/t/innodb_buffer_pool_dump_pct_basic.test index d2f5cb4a0de..1cf6775e06d 100644 --- a/mysql-test/suite/sys_vars/t/innodb_buffer_pool_dump_pct_basic.test +++ b/mysql-test/suite/sys_vars/t/innodb_buffer_pool_dump_pct_basic.test @@ -8,19 +8,15 @@ SET @orig = @@global.innodb_buffer_pool_dump_pct; SELECT @orig; -# Do the dump -SET GLOBAL innodb_buffer_pool_dump_pct=3, GLOBAL innodb_buffer_pool_dump_now = ON; +SET GLOBAL innodb_buffer_pool_dump_pct=3; -# Wait for the dump to complete -let $wait_condition = - SELECT SUBSTR(variable_value, 1, 33) = 'Buffer pool(s) dump completed at ' - FROM information_schema.global_status - WHERE LOWER(variable_name) = 'innodb_buffer_pool_dump_status'; --- source include/wait_condition.inc +--echo # Do the dump -# Confirm that the dump file has been created --- let $file = `SELECT CONCAT(@@datadir, @@global.innodb_buffer_pool_filename)` --- file_exists $file +--disable_query_log +--disable_result_log +--source innodb_buffer_pool_dump_now_basic.test +--enable_result_log +--enable_query_log --disable_warnings SET GLOBAL innodb_buffer_pool_dump_pct=0; diff --git a/mysql-test/suite/sys_vars/t/innodb_buffer_pool_load_now_basic.opt b/mysql-test/suite/sys_vars/t/innodb_buffer_pool_load_now_basic.opt new file mode 100644 index 00000000000..e462be3c368 --- /dev/null +++ b/mysql-test/suite/sys_vars/t/innodb_buffer_pool_load_now_basic.opt @@ -0,0 +1 @@ +--innodb-buffer-pool-load-at-startup=off diff --git a/mysql-test/suite/sys_vars/t/innodb_buffer_pool_load_now_basic.test b/mysql-test/suite/sys_vars/t/innodb_buffer_pool_load_now_basic.test index a0409901865..abb78ce5260 100644 --- a/mysql-test/suite/sys_vars/t/innodb_buffer_pool_load_now_basic.test +++ b/mysql-test/suite/sys_vars/t/innodb_buffer_pool_load_now_basic.test @@ -5,42 +5,22 @@ -- source include/have_innodb.inc # Check the default value -SET @orig = @@global.innodb_buffer_pool_load_now; -SELECT @orig; +SELECT @@global.innodb_buffer_pool_load_now; -let $old_status= `SELECT variable_value FROM information_schema.global_status - WHERE LOWER(variable_name) = 'innodb_buffer_pool_dump_status'`; +# Make sure there is a dump file to load -# A previous test could have run buffer pool dump already; -# in this case we want to make sure that the current time is different -# from the timestamp in the status variable. -# We should have had a smart wait condition here, like the commented one below, -# but we can't because of MDEV-9867, so there will be just sleep instead. -# And it might be not enough to sleep one second, so we'll have to sleep two. -# let $wait_condition = -# SELECT TRIM(SUBSTR('$old_status', -8)) != DATE_FORMAT(CURTIME(), '%k:%i:%s'); -# -- source include/wait_condition.inc - -if (`SELECT variable_value LIKE '%dump completed at%' FROM information_schema.global_status - WHERE LOWER(variable_name) = 'innodb_buffer_pool_dump_status'`) -{ - -- sleep 2 -} - -# Do the dump -SET GLOBAL innodb_buffer_pool_dump_now = ON; - -# Wait for the dump to complete -let $wait_condition = - SELECT variable_value != '$old_status' - AND SUBSTR(variable_value, 1, 33) = 'Buffer pool(s) dump completed at ' - FROM information_schema.global_status - WHERE LOWER(variable_name) = 'innodb_buffer_pool_dump_status'; --- source include/wait_condition.inc - -# Confirm the file is really created -- let $file = `SELECT CONCAT(@@datadir, @@global.innodb_buffer_pool_filename)` +-- error 0,1 -- file_exists $file +if ($errno) +{ + # Dump file does not exist, get it created + --disable_query_log + --disable_result_log + --source innodb_buffer_pool_dump_now_basic.test + --enable_result_log + --enable_query_log +} # Load the dump SET GLOBAL innodb_buffer_pool_load_now = ON; From e0cd6f4b0767b62723f9e332b94d8f34f59edbbc Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Sun, 5 Nov 2017 18:45:12 -0800 Subject: [PATCH 13/35] Fixed bugs: mdev-13780 CTE not found, mdev-14184 recursive CTE not found The support of embedded CTEs was not correct in the cases when embedded CTEs were used multiple times. The problems occurred with both non-recursive (bug mdev-13780) and recursive (bug mdev-14184) embedded CTEs. --- mysql-test/r/cte_nonrecursive.result | 49 ++++++++++++++++++++++++++++ mysql-test/r/cte_recursive.result | 22 +++++++++++++ mysql-test/t/cte_nonrecursive.test | 28 ++++++++++++++++ mysql-test/t/cte_recursive.test | 19 +++++++++++ sql/sql_cte.cc | 22 +++++++++---- 5 files changed, 133 insertions(+), 7 deletions(-) diff --git a/mysql-test/r/cte_nonrecursive.result b/mysql-test/r/cte_nonrecursive.result index 453f1319ccb..36982d3673b 100644 --- a/mysql-test/r/cte_nonrecursive.result +++ b/mysql-test/r/cte_nonrecursive.result @@ -1079,3 +1079,52 @@ id select_type table type possible_keys key key_len ref rows Extra 3 DERIVED t2 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join) NULL UNION RESULT ALL NULL NULL NULL NULL NULL DROP TABLE t1,t2; +# +# MDEV-13780: tower of embedding CTEs with multiple usage of them +# +create table t1 (a int); +insert into t1 values (3), (2), (4), (7), (1), (2), (5); +with cte_e as +( +with cte_o as +( +with cte_i as (select * from t1 where a < 7) +select * from cte_i where a > 1 +) +select * from cte_o as cto_o1 where a < 3 +union +select * from cte_o as cto_o2 where a > 4 +) +select * from cte_e as cte_e1 where a > 1 +union +select * from cte_e as cte_e2; +a +2 +5 +explain extended with cte_e as +( +with cte_o as +( +with cte_i as (select * from t1 where a < 7) +select * from cte_i where a > 1 +) +select * from cte_o as cto_o1 where a < 3 +union +select * from cte_o as cto_o2 where a > 4 +) +select * from cte_e as cte_e1 where a > 1 +union +select * from cte_e as cte_e2; +id select_type table type possible_keys key key_len ref rows filtered Extra +1 PRIMARY ALL NULL NULL NULL NULL 14 100.00 Using where +2 DERIVED t1 ALL NULL NULL NULL NULL 7 100.00 Using where +5 UNION t1 ALL NULL NULL NULL NULL 7 100.00 Using where +NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL +6 UNION ALL NULL NULL NULL NULL 14 100.00 +9 DERIVED t1 ALL NULL NULL NULL NULL 7 100.00 Using where +12 UNION t1 ALL NULL NULL NULL NULL 7 100.00 Using where +NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL +NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL +Warnings: +Note 1003 with cte_e as (with cte_o as (with cte_i as (select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` < 7)select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > 1)select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` < 3 and `test`.`t1`.`a` > 1 and `test`.`t1`.`a` < 7 and `test`.`t1`.`a` > 1 union select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > 4 and `test`.`t1`.`a` > 1 and `test`.`t1`.`a` < 7 and `test`.`t1`.`a` > 1)select `cte_e1`.`a` AS `a` from `cte_e` `cte_e1` where `cte_e1`.`a` > 1 union select `cte_e2`.`a` AS `a` from `cte_e` `cte_e2` +drop table t1; diff --git a/mysql-test/r/cte_recursive.result b/mysql-test/r/cte_recursive.result index 057e3fe034c..b744f24bb57 100644 --- a/mysql-test/r/cte_recursive.result +++ b/mysql-test/r/cte_recursive.result @@ -2875,3 +2875,25 @@ f 2 set standard_compliant_cte=default; DROP TABLE t; +# +# mdev-14184: recursive CTE embedded into CTE with multiple references +# +WITH +cte1 AS ( +SELECT n FROM ( +WITH RECURSIVE rec_cte(n) AS ( +SELECT 1 as n1 +UNION ALL +SELECT n+1 as n2 FROM rec_cte WHERE n < 3 +) SELECT n FROM rec_cte +) AS X +), +cte2 as ( +SELECT 2 FROM cte1 +) +SELECT * +FROM cte1; +n +1 +2 +3 diff --git a/mysql-test/t/cte_nonrecursive.test b/mysql-test/t/cte_nonrecursive.test index 57b7ae1658f..c9639f50a19 100644 --- a/mysql-test/t/cte_nonrecursive.test +++ b/mysql-test/t/cte_nonrecursive.test @@ -743,3 +743,31 @@ eval $q; eval explain $q; DROP TABLE t1,t2; + +--echo # +--echo # MDEV-13780: tower of embedding CTEs with multiple usage of them +--echo # + +create table t1 (a int); +insert into t1 values (3), (2), (4), (7), (1), (2), (5); + +let $q= +with cte_e as +( + with cte_o as + ( + with cte_i as (select * from t1 where a < 7) + select * from cte_i where a > 1 + ) + select * from cte_o as cto_o1 where a < 3 + union + select * from cte_o as cto_o2 where a > 4 +) +select * from cte_e as cte_e1 where a > 1 +union +select * from cte_e as cte_e2; + +eval $q; +eval explain extended $q; + +drop table t1; diff --git a/mysql-test/t/cte_recursive.test b/mysql-test/t/cte_recursive.test index 5701ee896cb..36d948251c3 100644 --- a/mysql-test/t/cte_recursive.test +++ b/mysql-test/t/cte_recursive.test @@ -1928,3 +1928,22 @@ set standard_compliant_cte=default; DROP TABLE t; +--echo # +--echo # mdev-14184: recursive CTE embedded into CTE with multiple references +--echo # + +WITH +cte1 AS ( + SELECT n FROM ( + WITH RECURSIVE rec_cte(n) AS ( + SELECT 1 as n1 + UNION ALL + SELECT n+1 as n2 FROM rec_cte WHERE n < 3 + ) SELECT n FROM rec_cte + ) AS X +), +cte2 as ( + SELECT 2 FROM cte1 +) +SELECT * +FROM cte1; diff --git a/sql/sql_cte.cc b/sql/sql_cte.cc index e1af30123f6..6fe08e3c0ed 100644 --- a/sql/sql_cte.cc +++ b/sql/sql_cte.cc @@ -349,7 +349,10 @@ void With_element::check_dependencies_in_select(st_select_lex *sl, /* Now look for the dependencies in the subqueries of sl */ st_select_lex_unit *inner_unit= sl->first_inner_unit(); for (; inner_unit; inner_unit= inner_unit->next_unit()) - check_dependencies_in_unit(inner_unit, ctxt, in_subq, dep_map); + { + if (!inner_unit->with_element) + check_dependencies_in_unit(inner_unit, ctxt, in_subq, dep_map); + } } @@ -838,7 +841,6 @@ st_select_lex_unit *With_element::clone_parsed_spec(THD *thd, with_table->next_global= spec_tables; } res= &lex->unit; - res->set_with_clause(owner); lex->unit.include_down(with_table->select_lex); lex->unit.set_slave(with_select); @@ -847,6 +849,8 @@ st_select_lex_unit *With_element::clone_parsed_spec(THD *thd, insert_chain_before( (st_select_lex_node **) &(old_lex->all_selects_list), with_select)); + if (check_dependencies_in_with_clauses(lex->with_clauses_list)) + res= NULL; lex_end(lex); err: if (arena) @@ -990,14 +994,18 @@ With_element *st_select_lex::find_table_def_in_with_clauses(TABLE_LIST *table) and it was unsuccesful. Yet for units cloned from the spec it has not been done yet. */ - if (with_elem && sl->master_unit() == with_elem->spec) + With_clause *attached_with_clause=sl->get_with_clause(); + if (attached_with_clause && + (found= attached_with_clause->find_table_def(table, NULL))) break; - With_clause *with_clause=sl->get_with_clause(); - if (with_clause) + if (with_elem) { - With_element *barrier= with_clause->with_recursive ? NULL : with_elem; - if ((found= with_clause->find_table_def(table, barrier))) + With_clause *containing_with_clause= with_elem->get_owner(); + With_element *barrier= containing_with_clause->with_recursive ? + NULL : with_elem; + if ((found= containing_with_clause->find_table_def(table, barrier))) break; + sl= sl->master_unit()->outer_select(); } master_unit= sl->master_unit(); /* Do not look for the table's definition beyond the scope of the view */ From 343bcb152f87a0ec44f940b73993d684d04def43 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Sun, 5 Nov 2017 22:52:41 -0800 Subject: [PATCH 14/35] Fixed mdev-14237 Server crash on query with regexp_substr It's better to prohibit pushdown of conditions that involve regexp_substr() and regexp_replace() into materialized derived tables / views until proper implementations of the get_copy() virtual method are provided for those functions. --- mysql-test/r/derived_cond_pushdown.result | 41 +++++++++++++++++++++++ mysql-test/t/derived_cond_pushdown.test | 17 ++++++++++ sql/item_strfunc.h | 6 ++-- 3 files changed, 60 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/derived_cond_pushdown.result b/mysql-test/r/derived_cond_pushdown.result index b94cb46acea..42662b84a31 100644 --- a/mysql-test/r/derived_cond_pushdown.result +++ b/mysql-test/r/derived_cond_pushdown.result @@ -8766,3 +8766,44 @@ EXPLAIN } DROP VIEW v2; DROP TABLE t1,t2; +# +# MDEV-14237: derived with regexp_substr() in select list +# +create table t1 (a char(8)); +insert into t1 values ('b'), ('a'), ('xx'); +select * +from ( select distinct regexp_substr(t1.a,'^[A-Za-z]+') as f from t1) as t +where t.f = 'a' or t.f = 'b'; +f +b +a +explain format=json select * +from ( select distinct regexp_substr(t1.a,'^[A-Za-z]+') as f from t1) as t +where t.f = 'a' or t.f = 'b'; +EXPLAIN +{ + "query_block": { + "select_id": 1, + "table": { + "table_name": "", + "access_type": "ALL", + "rows": 3, + "filtered": 100, + "attached_condition": "t.f = 'a' or t.f = 'b'", + "materialized": { + "query_block": { + "select_id": 2, + "temporary_table": { + "table": { + "table_name": "t1", + "access_type": "ALL", + "rows": 3, + "filtered": 100 + } + } + } + } + } + } +} +drop table t1; diff --git a/mysql-test/t/derived_cond_pushdown.test b/mysql-test/t/derived_cond_pushdown.test index de8a479614e..9eb332b72d1 100644 --- a/mysql-test/t/derived_cond_pushdown.test +++ b/mysql-test/t/derived_cond_pushdown.test @@ -1548,3 +1548,20 @@ eval explain format=json $q; DROP VIEW v2; DROP TABLE t1,t2; + +--echo # +--echo # MDEV-14237: derived with regexp_substr() in select list +--echo # + +create table t1 (a char(8)); +insert into t1 values ('b'), ('a'), ('xx'); + +let $q= +select * +from ( select distinct regexp_substr(t1.a,'^[A-Za-z]+') as f from t1) as t +where t.f = 'a' or t.f = 'b'; + +eval $q; +eval explain format=json $q; + +drop table t1; diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index e2dcab01e3b..181a4e2a747 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -333,8 +333,7 @@ public: bool fix_fields(THD *thd, Item **ref); void fix_length_and_dec(); const char *func_name() const { return "regexp_replace"; } - Item *get_copy(THD *thd, MEM_ROOT *mem_root) - { return get_item_copy(thd, mem_root, this); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return 0;} }; @@ -356,8 +355,7 @@ public: bool fix_fields(THD *thd, Item **ref); void fix_length_and_dec(); const char *func_name() const { return "regexp_substr"; } - Item *get_copy(THD *thd, MEM_ROOT *mem_root) - { return get_item_copy(thd, mem_root, this); } + Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return 0; } }; From 30a8764b924a8d90cdd1ad7ad356e6a32b1b29ff Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 2 Nov 2017 16:18:41 +0200 Subject: [PATCH 15/35] MDEV-14244 MariaDB fails to run with O_DIRECT os_file_set_size(): If posix_fallocate() returns EINVAL, fall back to writing zero bytes to the file. Also, remove some error log output, and make it possible for a server shutdown to interrupt the fall-back code. MariaDB used to ignore any possible return value from posix_fallocate() ever since innodb_use_fallocate was introduced in MDEV-4338. If EINVAL was returned, the file would not be extended. Starting with MDEV-11520, MariaDB would treat EINVAL as a hard error. Why is the EINVAL returned? The GNU posix_fallocate() function would first try the fallocate() system call, which would return -EOPNOTSUPP for many file systems (notably, not ext4). Then, it would fall back to extending the file one block at a time by invoking pwrite(fd, "", 1, offset) where offset is 1 less than a multiple of the file block size. This would fail with EINVAL if the file is in O_DIRECT mode, because O_DIRECT requires aligned operation. --- storage/innobase/os/os0file.cc | 20 ++++++++++++++------ storage/xtradb/os/os0file.cc | 20 ++++++++++++++------ 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc index 2a13746516f..7edf69a4571 100644 --- a/storage/innobase/os/os0file.cc +++ b/storage/innobase/os/os0file.cc @@ -2394,15 +2394,22 @@ os_file_set_size( } while (err == EINTR && srv_shutdown_state == SRV_SHUTDOWN_NONE); - if (err) { + switch (err) { + case 0: + return true; + default: ib_logf(IB_LOG_LEVEL_ERROR, "preallocating " INT64PF " bytes for" "file %s failed with error %d", size, name, err); + /* fall through */ + case EINTR: + errno = err; + return false; + case EINVAL: + /* fall back to the code below */ + break; } - /* Set errno because posix_fallocate() does not do it.*/ - errno = err; - return(!err); } # endif @@ -2444,11 +2451,12 @@ os_file_set_size( } current_size += n_bytes; - } while (current_size < size); + } while (current_size < size + && srv_shutdown_state == SRV_SHUTDOWN_NONE); free(buf2); - return(ret && os_file_flush(file)); + return(ret && current_size >= size && os_file_flush(file)); #endif } diff --git a/storage/xtradb/os/os0file.cc b/storage/xtradb/os/os0file.cc index 183f65bcbd8..69b8a9da671 100644 --- a/storage/xtradb/os/os0file.cc +++ b/storage/xtradb/os/os0file.cc @@ -2629,15 +2629,22 @@ os_file_set_size( } while (err == EINTR && srv_shutdown_state == SRV_SHUTDOWN_NONE); - if (err) { + switch (err) { + case 0: + return true; + default: ib_logf(IB_LOG_LEVEL_ERROR, "preallocating " INT64PF " bytes for" "file %s failed with error %d", size, name, err); + /* fall through */ + case EINTR: + errno = err; + return false; + case EINVAL: + /* fall back to the code below */ + break; } - /* Set errno because posix_fallocate() does not do it.*/ - errno = err; - return(!err); } # endif @@ -2679,11 +2686,12 @@ os_file_set_size( } current_size += n_bytes; - } while (current_size < size); + } while (current_size < size + && srv_shutdown_state == SRV_SHUTDOWN_NONE); free(buf2); - return(ret && os_file_flush(file)); + return(ret && current_size >= size && os_file_flush(file)); #endif } From 51679e5c380e3a140c78a611c28d99bd3a8be2da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Fri, 3 Nov 2017 16:09:43 +0200 Subject: [PATCH 16/35] MDEV-14132 InnoDB page corruption On some old GNU/Linux systems, invoking posix_fallocate() with offset=0 would sometimes cause already allocated bytes in the data file to be overwritten. Fix a correctness regression that was introduced in commit 420798a81ac9a81d20629535fac3032e025e7733 by invoking posix_fallocate() in a safer way. A similar change was made in MDEV-5746 earlier. os_file_get_size(): Avoid changing the state of the file handle, by invoking fstat() instead of lseek(). os_file_set_size(): Determine the current size of the file by os_file_get_size(), and then extend the file from that point onwards. --- storage/innobase/os/os0file.cc | 9 ++++++--- storage/xtradb/os/os0file.cc | 9 ++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/storage/innobase/os/os0file.cc b/storage/innobase/os/os0file.cc index 7edf69a4571..e9abdc91ff8 100644 --- a/storage/innobase/os/os0file.cc +++ b/storage/innobase/os/os0file.cc @@ -2335,8 +2335,8 @@ os_file_get_size( return(offset); #else - return((os_offset_t) lseek(file, 0, SEEK_END)); - + struct stat statbuf; + return fstat(file, &statbuf) ? os_offset_t(-1) : statbuf.st_size; #endif /* __WIN__ */ } @@ -2390,7 +2390,10 @@ os_file_set_size( if (srv_use_posix_fallocate) { int err; do { - err = posix_fallocate(file, 0, size); + os_offset_t current_size = os_file_get_size(file); + err = current_size >= size + ? 0 : posix_fallocate(file, current_size, + size - current_size); } while (err == EINTR && srv_shutdown_state == SRV_SHUTDOWN_NONE); diff --git a/storage/xtradb/os/os0file.cc b/storage/xtradb/os/os0file.cc index 69b8a9da671..8b0fa059100 100644 --- a/storage/xtradb/os/os0file.cc +++ b/storage/xtradb/os/os0file.cc @@ -2570,8 +2570,8 @@ os_file_get_size( return(offset); #else - return((os_offset_t) lseek(file, 0, SEEK_END)); - + struct stat statbuf; + return fstat(file, &statbuf) ? os_offset_t(-1) : statbuf.st_size; #endif /* __WIN__ */ } @@ -2625,7 +2625,10 @@ os_file_set_size( if (srv_use_posix_fallocate) { int err; do { - err = posix_fallocate(file, 0, size); + os_offset_t current_size = os_file_get_size(file); + err = current_size >= size + ? 0 : posix_fallocate(file, current_size, + size - current_size); } while (err == EINTR && srv_shutdown_state == SRV_SHUTDOWN_NONE); From 6a524fcfdde539c6448aa4126ccb5ed79055b9ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 6 Nov 2017 14:55:34 +0200 Subject: [PATCH 17/35] MDEV-14140 IMPORT TABLESPACE must not go beyond FSP_FREE_LIMIT ibuf_check_bitmap_on_import(): Only access the pages that are below FSP_FREE_LIMIT. It is possible that especially with ROW_FORMAT=COMPRESSED, the FSP_SIZE will be much bigger than the FSP_FREE_LIMIT, and the bitmap pages (page_size*N, 1+page_size*N) are filled with zero bytes. buf_page_is_corrupted(), buf_page_io_complete(): Make the fault injection compatible with MariaDB 10.2. Backport the IMPORT tests from 10.2. --- .../suite/innodb/r/innodb-wl5522-debug.result | 134 +++++------- .../suite/innodb/t/innodb-wl5522-debug.test | 204 +++++++----------- .../r/wl5522_debug_zip.result} | 95 ++++---- .../t/wl5522_debug_zip.test} | 176 +++++++-------- storage/innobase/buf/buf0buf.cc | 8 +- storage/innobase/ibuf/ibuf0ibuf.cc | 16 +- storage/xtradb/buf/buf0buf.cc | 8 +- storage/xtradb/ibuf/ibuf0ibuf.cc | 16 +- 8 files changed, 298 insertions(+), 359 deletions(-) rename mysql-test/suite/{innodb/r/innodb-wl5522-debug-zip.result => innodb_zip/r/wl5522_debug_zip.result} (86%) rename mysql-test/suite/{innodb/t/innodb-wl5522-debug-zip.test => innodb_zip/t/wl5522_debug_zip.test} (79%) diff --git a/mysql-test/suite/innodb/r/innodb-wl5522-debug.result b/mysql-test/suite/innodb/r/innodb-wl5522-debug.result index 0c914ebc7a6..43958f60578 100644 --- a/mysql-test/suite/innodb/r/innodb-wl5522-debug.result +++ b/mysql-test/suite/innodb/r/innodb-wl5522-debug.result @@ -1,33 +1,19 @@ SET GLOBAL innodb_file_per_table = 1; -SELECT @@innodb_file_per_table; -@@innodb_file_per_table -1 -DROP DATABASE IF EXISTS test_wl5522; -Warnings: -Note 1008 Can't drop database 'test_wl5522'; database doesn't exist CREATE DATABASE test_wl5522; +CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = InnoDB; +INSERT INTO test_wl5522.t1 VALUES(1),(2),(3); SET SESSION debug_dbug="+d,ib_discard_before_commit_crash"; -CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = InnoDB; -INSERT INTO test_wl5522.t1 VALUES(1),(2),(3); ALTER TABLE test_wl5522.t1 DISCARD TABLESPACE; ERROR HY000: Lost connection to MySQL server during query -SET SESSION debug_dbug="-d,ib_discard_before_commit_crash"; DROP TABLE test_wl5522.t1; SET GLOBAL innodb_file_per_table = 1; -SELECT @@innodb_file_per_table; -@@innodb_file_per_table -1 +CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = InnoDB; +INSERT INTO test_wl5522.t1 VALUES(1),(2),(3); SET SESSION debug_dbug="+d,ib_discard_after_commit_crash"; -CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = InnoDB; -INSERT INTO test_wl5522.t1 VALUES(1),(2),(3); ALTER TABLE test_wl5522.t1 DISCARD TABLESPACE; ERROR HY000: Lost connection to MySQL server during query -SET SESSION debug_dbug="-d,ib_discard_after_commit_crash"; DROP TABLE test_wl5522.t1; SET GLOBAL innodb_file_per_table = 1; -SELECT @@innodb_file_per_table; -@@innodb_file_per_table -1 CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = Innodb; INSERT INTO test_wl5522.t1 VALUES (1), (2), (3), (4); FLUSH TABLES test_wl5522.t1 FOR EXPORT; @@ -40,21 +26,18 @@ ALTER TABLE test_wl5522.t1 DISCARD TABLESPACE; SELECT COUNT(*) FROM test_wl5522.t1; ERROR HY000: Tablespace has been discarded for table 't1' restore: t1 .ibd and .cfg files -SET SESSION debug_dbug="+d,ib_import_before_commit_crash"; SELECT * FROM test_wl5522.t1; ERROR HY000: Tablespace has been discarded for table 't1' +SET SESSION debug_dbug="+d,ib_import_before_commit_crash"; ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: Lost connection to MySQL server during query -SET SESSION debug_dbug="-d,ib_import_before_commit_crash"; -SET SESSION debug_dbug="+d,ib_import_before_checkpoint_crash"; SELECT COUNT(*) FROM test_wl5522.t1; ERROR HY000: Tablespace has been discarded for table 't1' +SET SESSION debug_dbug="+d,ib_import_before_checkpoint_crash"; ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: Lost connection to MySQL server during query unlink: t1.ibd unlink: t1.cfg -# Restart and reconnect to the server -SET SESSION debug_dbug="-d,ib_import_before_checkpoint_crash"; DROP TABLE test_wl5522.t1; SET GLOBAL innodb_file_per_table = 1; SELECT @@innodb_file_per_table; @@ -83,13 +66,14 @@ c1 DROP TABLE test_wl5522.t1; CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = Innodb; INSERT INTO test_wl5522.t1 VALUES (1); +SET @saved_debug_dbug = @@SESSION.debug_dbug; SET SESSION debug_dbug="+d,ib_export_io_write_failure_1"; FLUSH TABLES test_wl5522.t1 FOR EXPORT; Warnings: Warning 1811 IO Write error: (9, Bad file descriptor) t1.cfg flush() failed Warning 1811 IO Write error: (9, Bad file descriptor) t1.cfg flose() failed UNLOCK TABLES; -SET SESSION debug_dbug="-d,ib_export_io_write_failure_1"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = Innodb; INSERT INTO test_wl5522.t1 VALUES (1); @@ -99,7 +83,7 @@ Warnings: Warning 1811 IO Write error: (9, Bad file descriptor) t1.cfg flush() failed Warning 1811 IO Write error: (9, Bad file descriptor) t1.cfg flose() failed UNLOCK TABLES; -SET SESSION debug_dbug="-d,ib_export_io_write_failure_2"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = Innodb; INSERT INTO test_wl5522.t1 VALUES (1); @@ -109,7 +93,7 @@ Warnings: Warning 1811 IO Write error: (9, Bad file descriptor) t1.cfg flush() failed Warning 1811 IO Write error: (9, Bad file descriptor) t1.cfg flose() failed UNLOCK TABLES; -SET SESSION debug_dbug="-d,ib_export_io_write_failure_3"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = Innodb; INSERT INTO test_wl5522.t1 VALUES (1); @@ -119,7 +103,7 @@ Warnings: Warning 1811 IO Write error: (9, Bad file descriptor) t1.cfg flush() failed Warning 1811 IO Write error: (9, Bad file descriptor) t1.cfg flose() failed UNLOCK TABLES; -SET SESSION debug_dbug="-d,ib_export_io_write_failure_4"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = Innodb; INSERT INTO test_wl5522.t1 VALUES (1); @@ -129,7 +113,7 @@ Warnings: Warning 1811 IO Write error: (9, Bad file descriptor) t1.cfg flush() failed Warning 1811 IO Write error: (9, Bad file descriptor) t1.cfg flose() failed UNLOCK TABLES; -SET SESSION debug_dbug="-d,ib_export_io_write_failure_5"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = Innodb; INSERT INTO test_wl5522.t1 VALUES (1); @@ -139,7 +123,7 @@ Warnings: Warning 1811 IO Write error: (9, Bad file descriptor) t1.cfg flush() failed Warning 1811 IO Write error: (9, Bad file descriptor) t1.cfg flose() failed UNLOCK TABLES; -SET SESSION debug_dbug="-d,ib_export_io_write_failure_6"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = Innodb; INSERT INTO test_wl5522.t1 VALUES (1); @@ -149,7 +133,7 @@ Warnings: Warning 1811 IO Write error: (9, Bad file descriptor) t1.cfg flush() failed Warning 1811 IO Write error: (9, Bad file descriptor) t1.cfg flose() failed UNLOCK TABLES; -SET SESSION debug_dbug="-d,ib_export_io_write_failure_7"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = Innodb; INSERT INTO test_wl5522.t1 VALUES (1); @@ -159,7 +143,7 @@ Warnings: Warning 1811 IO Write error: (9, Bad file descriptor) t1.cfg flush() failed Warning 1811 IO Write error: (9, Bad file descriptor) t1.cfg flose() failed UNLOCK TABLES; -SET SESSION debug_dbug="-d,ib_export_io_write_failure_8"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = Innodb; INSERT INTO test_wl5522.t1 VALUES (1); @@ -169,7 +153,7 @@ Warnings: Warning 1811 IO Write error: (9, Bad file descriptor) t1.cfg flush() failed Warning 1811 IO Write error: (9, Bad file descriptor) t1.cfg flose() failed UNLOCK TABLES; -SET SESSION debug_dbug="-d,ib_export_io_write_failure_9"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = Innodb; INSERT INTO test_wl5522.t1 VALUES (1); @@ -179,7 +163,7 @@ Warnings: Warning 1811 IO Write error: (9, Bad file descriptor) t1.cfg flush() failed Warning 1811 IO Write error: (9, Bad file descriptor) t1.cfg flose() failed UNLOCK TABLES; -SET SESSION debug_dbug="-d,ib_export_io_write_failure_10"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = Innodb; INSERT INTO test_wl5522.t1 VALUES (1); @@ -189,7 +173,7 @@ Warnings: Warning 1811 IO Write error: (9, Bad file descriptor) t1.cfg flush() failed Warning 1811 IO Write error: (9, Bad file descriptor) t1.cfg flose() failed UNLOCK TABLES; -SET SESSION debug_dbug="-d,ib_export_io_write_failure_11"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = Innodb; INSERT INTO test_wl5522.t1 VALUES (1); @@ -199,7 +183,7 @@ Warnings: Warning 1811 IO Write error: (9, Bad file descriptor) t1.cfg flush() failed Warning 1811 IO Write error: (9, Bad file descriptor) t1.cfg flose() failed UNLOCK TABLES; -SET SESSION debug_dbug="-d,ib_export_io_write_failure_12"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = Innodb; INSERT INTO test_wl5522.t1 VALUES (100), (200), (300); @@ -219,7 +203,7 @@ SET SESSION debug_dbug="+d,ib_import_io_read_error_1"; restore: t1 .cfg file ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: IO Read error: while reading index fields. -SET SESSION debug_dbug="-d,ib_import_io_read_error_1"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = Innodb; INSERT INTO test_wl5522.t1 VALUES (1); @@ -230,7 +214,7 @@ SET SESSION debug_dbug="+d,ib_import_io_read_error_2"; restore: t1 .cfg file ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: IO Read error: while reading index meta-data, expected to read 44 bytes but read only 0 bytes -SET SESSION debug_dbug="-d,ib_import_io_read_error_2"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = Innodb; INSERT INTO test_wl5522.t1 VALUES (1); @@ -241,7 +225,7 @@ SET SESSION debug_dbug="+d,ib_import_io_read_error_3"; restore: t1 .cfg file ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: IO Read error: while reading number of indexes. -SET SESSION debug_dbug="-d,ib_import_io_read_error_3"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = Innodb; INSERT INTO test_wl5522.t1 VALUES (1); @@ -252,7 +236,7 @@ SET SESSION debug_dbug="+d,ib_import_io_read_error_4"; restore: t1 .cfg file ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: IO Read error: while reading table column meta-data. -SET SESSION debug_dbug="-d,ib_import_io_read_error_4"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = Innodb; INSERT INTO test_wl5522.t1 VALUES (1); @@ -263,7 +247,7 @@ SET SESSION debug_dbug="+d,ib_import_io_read_error_5"; restore: t1 .cfg file ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: IO Read error: while reading meta-data export hostname length. -SET SESSION debug_dbug="-d,ib_import_io_read_error_5"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = Innodb; INSERT INTO test_wl5522.t1 VALUES (1); @@ -274,7 +258,7 @@ SET SESSION debug_dbug="+d,ib_import_io_read_error_6"; restore: t1 .cfg file ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: IO Read error: while reading meta-data table name length. -SET SESSION debug_dbug="-d,ib_import_io_read_error_6"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = Innodb; INSERT INTO test_wl5522.t1 VALUES (1); @@ -285,7 +269,7 @@ SET SESSION debug_dbug="+d,ib_import_io_read_error_7"; restore: t1 .cfg file ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: IO Read error: while reading autoinc value. -SET SESSION debug_dbug="-d,ib_import_io_read_error_7"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = Innodb; INSERT INTO test_wl5522.t1 VALUES (1); @@ -296,7 +280,7 @@ SET SESSION debug_dbug="+d,ib_import_io_read_error_8"; restore: t1 .cfg file ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: IO Read error: while reading meta-data header. -SET SESSION debug_dbug="-d,ib_import_io_read_error_8"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = Innodb; INSERT INTO test_wl5522.t1 VALUES (1); @@ -307,7 +291,7 @@ SET SESSION debug_dbug="+d,ib_import_io_read_error_9"; restore: t1 .cfg file ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: IO Read error: while reading meta-data version. -SET SESSION debug_dbug="-d,ib_import_io_read_error_9"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = Innodb; INSERT INTO test_wl5522.t1 VALUES (1); @@ -318,7 +302,7 @@ SET SESSION debug_dbug="+d,ib_import_string_read_error"; restore: t1 .cfg file ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: IO Read error: while parsing export hostname. -SET SESSION debug_dbug="-d,ib_import_string_read_error"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = Innodb; INSERT INTO test_wl5522.t1 VALUES (1); @@ -329,7 +313,7 @@ restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,ib_import_OOM_1"; ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: Out of memory; check if mysqld or some other process uses all available memory; if not, you may have to use 'ulimit' to allow mysqld to use more memory or you can add more swap space -SET SESSION debug_dbug="-d,ib_import_OOM_1"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; unlink: t1.ibd unlink: t1.cfg @@ -342,7 +326,7 @@ restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,ib_import_OOM_2"; ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: Out of memory; check if mysqld or some other process uses all available memory; if not, you may have to use 'ulimit' to allow mysqld to use more memory or you can add more swap space -SET SESSION debug_dbug="-d,ib_import_OOM_2"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; unlink: t1.ibd unlink: t1.cfg @@ -355,7 +339,7 @@ restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,ib_import_OOM_4"; ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: Out of memory; check if mysqld or some other process uses all available memory; if not, you may have to use 'ulimit' to allow mysqld to use more memory or you can add more swap space -SET SESSION debug_dbug="-d,ib_import_OOM_4"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; unlink: t1.ibd unlink: t1.cfg @@ -368,7 +352,7 @@ restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,ib_import_OOM_5"; ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: Out of memory; check if mysqld or some other process uses all available memory; if not, you may have to use 'ulimit' to allow mysqld to use more memory or you can add more swap space -SET SESSION debug_dbug="-d,ib_import_OOM_5"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; unlink: t1.ibd unlink: t1.cfg @@ -381,7 +365,7 @@ restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,ib_import_OOM_6"; ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: Out of memory; check if mysqld or some other process uses all available memory; if not, you may have to use 'ulimit' to allow mysqld to use more memory or you can add more swap space -SET SESSION debug_dbug="-d,ib_import_OOM_6"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; unlink: t1.ibd unlink: t1.cfg @@ -394,7 +378,7 @@ restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,ib_import_OOM_7"; ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: Out of memory; check if mysqld or some other process uses all available memory; if not, you may have to use 'ulimit' to allow mysqld to use more memory or you can add more swap space -SET SESSION debug_dbug="-d,ib_import_OOM_7"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; unlink: t1.ibd unlink: t1.cfg @@ -407,7 +391,7 @@ restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,ib_import_OOM_8"; ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: Out of memory; check if mysqld or some other process uses all available memory; if not, you may have to use 'ulimit' to allow mysqld to use more memory or you can add more swap space -SET SESSION debug_dbug="-d,ib_import_OOM_8"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; unlink: t1.ibd unlink: t1.cfg @@ -420,7 +404,7 @@ restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,ib_import_OOM_9"; ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: Out of memory; check if mysqld or some other process uses all available memory; if not, you may have to use 'ulimit' to allow mysqld to use more memory or you can add more swap space -SET SESSION debug_dbug="-d,ib_import_OOM_9"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; unlink: t1.ibd unlink: t1.cfg @@ -433,7 +417,7 @@ restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,ib_import_OOM_10"; ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: Out of memory; check if mysqld or some other process uses all available memory; if not, you may have to use 'ulimit' to allow mysqld to use more memory or you can add more swap space -SET SESSION debug_dbug="-d,ib_import_OOM_10"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; unlink: t1.ibd unlink: t1.cfg @@ -445,7 +429,7 @@ restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,ib_import_internal_error"; ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: Internal error: While updating the of index "GEN_CLUST_INDEX" - Generic error -SET SESSION debug_dbug="-d,ib_import_internal_error"; +SET SESSION debug_dbug=@saved_debug_dbug; restore: t1 .ibd and .cfg files ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; DROP TABLE test_wl5522.t1; @@ -458,36 +442,36 @@ SET SESSION debug_dbug="+d,ib_import_reset_space_and_lsn_failure"; ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: Internal error: Cannot reset LSNs in table '"test_wl5522"."t1"' : Too many concurrent transactions restore: t1 .ibd and .cfg files -SET SESSION debug_dbug="-d,ib_import_reset_space_and_lsn_failure"; +SET SESSION debug_dbug=@saved_debug_dbug; SET SESSION debug_dbug="+d,ib_import_open_tablespace_failure"; ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: Got error 44 'Tablespace not found' from ./test_wl5522/t1.ibd -SET SESSION debug_dbug="-d,ib_import_open_tablespace_failure"; +SET SESSION debug_dbug=@saved_debug_dbug; restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,ib_import_check_bitmap_failure"; ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: Incorrect key file for table 't1'; try to repair it -SET SESSION debug_dbug="-d,ib_import_check_bitmap_failure"; +SET SESSION debug_dbug=@saved_debug_dbug; restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,ib_import_cluster_root_adjust_failure"; ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: Incorrect key file for table 't1'; try to repair it -SET SESSION debug_dbug="-d,ib_import_cluster_root_adjust_failure"; +SET SESSION debug_dbug=@saved_debug_dbug; restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,ib_import_cluster_failure"; ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: Incorrect key file for table 't1'; try to repair it -SET SESSION debug_dbug="-d,ib_import_cluster_failure"; +SET SESSION debug_dbug=@saved_debug_dbug; restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,ib_import_sec_root_adjust_failure"; ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: Incorrect key file for table 't1'; try to repair it -SET SESSION debug_dbug="-d,ib_import_sec_root_adjust_failure"; +SET SESSION debug_dbug=@saved_debug_dbug; restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,ib_import_set_max_rowid_failure"; ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: Incorrect key file for table 't1'; try to repair it -SET SESSION debug_dbug="-d,ib_import_set_max_rowid_failure"; +SET SESSION debug_dbug=@saved_debug_dbug; unlink: t1.ibd unlink: t1.cfg DROP TABLE test_wl5522.t1; @@ -499,7 +483,7 @@ c4 VARCHAR(2048), INDEX idx1(c2), INDEX idx2(c3(512)), INDEX idx3(c4(512))) Engine=InnoDB; -SET GLOBAL INNODB_PURGE_STOP_NOW=ON; +START TRANSACTION WITH CONSISTENT SNAPSHOT; SET GLOBAL innodb_disable_background_merge=ON; SET GLOBAL innodb_monitor_reset = ibuf_merges; SET GLOBAL innodb_monitor_reset = ibuf_merges_insert; @@ -664,7 +648,7 @@ FROM information_schema.innodb_metrics WHERE name = 'ibuf_merges_inserts' AND count > 0; name SET GLOBAL innodb_disable_background_merge=OFF; -SET GLOBAL INNODB_PURGE_RUN_NOW=ON; +COMMIT; DROP TABLE test_wl5522.t1; CREATE TABLE test_wl5522.t1 ( c1 BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, @@ -800,8 +784,8 @@ t1 CREATE TABLE `t1` ( ) ENGINE=InnoDB AUTO_INCREMENT=185 DEFAULT CHARSET=latin1 DROP TABLE test_wl5522.t1; CREATE TABLE test_wl5522.t1 (c1 INT, c2 VARCHAR(1024), c3 BLOB) ENGINE = Innodb; -INSERT INTO test_wl5522.t1 VALUES -(100, REPEAT('Karanbir', 899), REPEAT('Ajeeth', 1200)); +INSERT IGNORE INTO test_wl5522.t1 VALUES +(100, REPEAT('Karanbir', 899), REPEAT('Ajeeth', 2731)); Warnings: Warning 1265 Data truncated for column 'c2' at row 1 INSERT INTO test_wl5522.t1 SELECT * FROM test_wl5522.t1; @@ -827,7 +811,7 @@ restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,ib_import_trigger_corruption_1"; ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: Internal error: Cannot reset LSNs in table '"test_wl5522"."t1"' : Data structure corruption -SET SESSION debug_dbug="-d,ib_import_trigger_corruption_1"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; unlink: t1.ibd unlink: t1.cfg @@ -836,10 +820,10 @@ ALTER TABLE test_wl5522.t1 DISCARD TABLESPACE; SELECT COUNT(*) FROM test_wl5522.t1; ERROR HY000: Tablespace has been discarded for table 't1' restore: t1 .ibd and .cfg files -SET SESSION debug_dbug="+d,buf_page_is_corrupt_failure"; +SET SESSION debug_dbug="+d,buf_page_import_corrupt_failure"; ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: Internal error: Cannot reset LSNs in table '"test_wl5522"."t1"' : Data structure corruption -SET SESSION debug_dbug="-d,buf_page_is_corrupt_failure"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; unlink: t1.ibd unlink: t1.cfg @@ -851,7 +835,7 @@ restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,ib_import_trigger_corruption_2"; ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: Index corrupt: Externally stored column(5) has a reference length of 19 in the cluster index "GEN_CLUST_INDEX" -SET SESSION debug_dbug="-d,ib_import_trigger_corruption_2"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; unlink: t1.ibd unlink: t1.cfg @@ -863,7 +847,7 @@ restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,ib_import_trigger_corruption_3"; ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: Incorrect key file for table 't1'; try to repair it -SET SESSION debug_dbug="-d,ib_import_trigger_corruption_3"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; unlink: t1.ibd unlink: t1.cfg @@ -875,7 +859,7 @@ SET SESSION debug_dbug="+d,ib_import_create_index_failure_1"; ALTER TABLE test_wl5522.t1 ADD INDEX idx(c1); Warnings: Warning 1814 Tablespace has been discarded for table 't1' -SET SESSION debug_dbug="-d,ib_import_create_index_failure_1"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; unlink: t1.ibd unlink: t1.cfg @@ -887,7 +871,7 @@ restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,fil_space_create_failure"; ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: Got error 11 'Generic error' from ./test_wl5522/t1.ibd -SET SESSION debug_dbug="-d,fil_space_create_failure"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; unlink: t1.ibd unlink: t1.cfg @@ -899,7 +883,7 @@ restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,dict_tf_to_fsp_flags_failure"; ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: Got error 39 'Data structure corruption' from ./test_wl5522/t1.ibd -SET SESSION debug_dbug="-d,dict_tf_to_fsp_flags_failure"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; unlink: t1.ibd unlink: t1.cfg @@ -911,7 +895,7 @@ restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,fsp_flags_is_valid_failure"; ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: Internal error: Cannot reset LSNs in table '"test_wl5522"."t1"' : Unsupported -SET SESSION debug_dbug="-d,fsp_flags_is_valid_failure"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; unlink: t1.ibd unlink: t1.cfg diff --git a/mysql-test/suite/innodb/t/innodb-wl5522-debug.test b/mysql-test/suite/innodb/t/innodb-wl5522-debug.test index 9c0c11fadab..e7bc705b89a 100644 --- a/mysql-test/suite/innodb/t/innodb-wl5522-debug.test +++ b/mysql-test/suite/innodb/t/innodb-wl5522-debug.test @@ -1,4 +1,4 @@ -# Not supported in embedded +# mysql-test-run.pl --embedded cannot restart the server. --source include/not_embedded.inc # Adding big test option for this test. @@ -21,58 +21,39 @@ let $pathfix=/: '.*test_wl5522.*t1.ibd'/: 'test_wl5522\\t1.ibd'/; let $strerrfix=/ (\(.+\))//; SET GLOBAL innodb_file_per_table = 1; -SELECT @@innodb_file_per_table; -DROP DATABASE IF EXISTS test_wl5522; CREATE DATABASE test_wl5522; -##### Before DISCARD commit crash +CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = InnoDB; +INSERT INTO test_wl5522.t1 VALUES(1),(2),(3); + +--let $_server_id= `SELECT @@server_id` +--let $_expect_file_name= $MYSQLTEST_VARDIR/tmp/mysqld.$_server_id.expect + +--exec echo wait > $_expect_file_name SET SESSION debug_dbug="+d,ib_discard_before_commit_crash"; +--error 2013 +ALTER TABLE test_wl5522.t1 DISCARD TABLESPACE; + +--source include/start_mysqld.inc + +DROP TABLE test_wl5522.t1; + +SET GLOBAL innodb_file_per_table = 1; CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = InnoDB; INSERT INTO test_wl5522.t1 VALUES(1),(2),(3); -# Write file to make mysql-test-run.pl start up the server again ---exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect - -# Execute the statement that causes the crash ---error 2013 -ALTER TABLE test_wl5522.t1 DISCARD TABLESPACE; - ---enable_reconnect ---source include/wait_until_connected_again.inc ---disable_reconnect - -SET SESSION debug_dbug="-d,ib_discard_before_commit_crash"; -DROP TABLE test_wl5522.t1; -#### Before DISCARD commit crash - -##### After DISCARD commit crash -SET GLOBAL innodb_file_per_table = 1; -SELECT @@innodb_file_per_table; - +--exec echo wait > $_expect_file_name SET SESSION debug_dbug="+d,ib_discard_after_commit_crash"; - -CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = InnoDB; -INSERT INTO test_wl5522.t1 VALUES(1),(2),(3); - -# Write file to make mysql-test-run.pl start up the server again ---exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect - -# Execute the statement that causes the crash --error 2013 ALTER TABLE test_wl5522.t1 DISCARD TABLESPACE; ---enable_reconnect ---source include/wait_until_connected_again.inc ---disable_reconnect +--source include/start_mysqld.inc -SET SESSION debug_dbug="-d,ib_discard_after_commit_crash"; DROP TABLE test_wl5522.t1; -#### After DISCARD commit crash SET GLOBAL innodb_file_per_table = 1; -SELECT @@innodb_file_per_table; # Create the table that we will use for crash recovery (during IMPORT) CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = Innodb; @@ -104,61 +85,35 @@ do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; ib_restore_tablespaces("test_wl5522", "t1"); EOF -##### Before commit crash -SET SESSION debug_dbug="+d,ib_import_before_commit_crash"; - --error ER_TABLESPACE_DISCARDED SELECT * FROM test_wl5522.t1; -# Write file to make mysql-test-run.pl start up the server again ---exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect - -# Execute the statement that causes the crash +--exec echo wait > $_expect_file_name +SET SESSION debug_dbug="+d,ib_import_before_commit_crash"; --error 2013 ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ---enable_reconnect ---source include/wait_until_connected_again.inc ---disable_reconnect - -SET SESSION debug_dbug="-d,ib_import_before_commit_crash"; -#### Before commit crash +--source include/start_mysqld.inc # Check that the DD is consistent after recovery -##### Before checkpoint crash -SET SESSION debug_dbug="+d,ib_import_before_checkpoint_crash"; - --error ER_TABLESPACE_DISCARDED SELECT COUNT(*) FROM test_wl5522.t1; -# Don't start up the server right away. ---exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect - -# Execute the statement that causes the crash +--exec echo wait > $_expect_file_name +SET SESSION debug_dbug="+d,ib_import_before_checkpoint_crash"; --error 2013 ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; # After the above test the results are non-deterministic, # delete the old tablespace files and drop the table, # recreate the table and do a proper import. --- source include/wait_until_disconnected.inc perl; do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; ib_unlink_tablespace("test_wl5522", "t1"); EOF ---echo # Restart and reconnect to the server ---enable_reconnect ---exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect ---source include/wait_until_connected_again.inc ---disable_reconnect - -SET SESSION debug_dbug="-d,ib_import_before_checkpoint_crash"; -#### Before checkpoint crash - -# After the above test the results are non-deterministic, recreate the table -# and do a proper import. +--source include/start_mysqld.inc DROP TABLE test_wl5522.t1; @@ -190,6 +145,7 @@ DROP TABLE test_wl5522.t1; CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = Innodb; INSERT INTO test_wl5522.t1 VALUES (1); +SET @saved_debug_dbug = @@SESSION.debug_dbug; SET SESSION debug_dbug="+d,ib_export_io_write_failure_1"; --replace_regex /, .*\).*t1.cfg/, Bad file descriptor) t1.cfg/ @@ -198,7 +154,7 @@ FLUSH TABLES test_wl5522.t1 FOR EXPORT; UNLOCK TABLES; -SET SESSION debug_dbug="-d,ib_export_io_write_failure_1"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; @@ -214,7 +170,7 @@ FLUSH TABLES test_wl5522.t1 FOR EXPORT; UNLOCK TABLES; -SET SESSION debug_dbug="-d,ib_export_io_write_failure_2"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; @@ -229,7 +185,7 @@ FLUSH TABLES test_wl5522.t1 FOR EXPORT; UNLOCK TABLES; -SET SESSION debug_dbug="-d,ib_export_io_write_failure_3"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; @@ -244,7 +200,7 @@ FLUSH TABLES test_wl5522.t1 FOR EXPORT; UNLOCK TABLES; -SET SESSION debug_dbug="-d,ib_export_io_write_failure_4"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; @@ -259,7 +215,7 @@ FLUSH TABLES test_wl5522.t1 FOR EXPORT; UNLOCK TABLES; -SET SESSION debug_dbug="-d,ib_export_io_write_failure_5"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; @@ -275,7 +231,7 @@ FLUSH TABLES test_wl5522.t1 FOR EXPORT; UNLOCK TABLES; -SET SESSION debug_dbug="-d,ib_export_io_write_failure_6"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; @@ -291,7 +247,7 @@ FLUSH TABLES test_wl5522.t1 FOR EXPORT; UNLOCK TABLES; -SET SESSION debug_dbug="-d,ib_export_io_write_failure_7"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; @@ -307,7 +263,7 @@ FLUSH TABLES test_wl5522.t1 FOR EXPORT; UNLOCK TABLES; -SET SESSION debug_dbug="-d,ib_export_io_write_failure_8"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; @@ -322,7 +278,7 @@ FLUSH TABLES test_wl5522.t1 FOR EXPORT; UNLOCK TABLES; -SET SESSION debug_dbug="-d,ib_export_io_write_failure_9"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; @@ -338,7 +294,7 @@ FLUSH TABLES test_wl5522.t1 FOR EXPORT; UNLOCK TABLES; -SET SESSION debug_dbug="-d,ib_export_io_write_failure_10"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; @@ -354,7 +310,7 @@ FLUSH TABLES test_wl5522.t1 FOR EXPORT; UNLOCK TABLES; -SET SESSION debug_dbug="-d,ib_export_io_write_failure_11"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; @@ -370,7 +326,7 @@ FLUSH TABLES test_wl5522.t1 FOR EXPORT; UNLOCK TABLES; -SET SESSION debug_dbug="-d,ib_export_io_write_failure_12"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; @@ -410,7 +366,7 @@ EOF --error ER_IO_READ_ERROR ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,ib_import_io_read_error_1"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; @@ -434,7 +390,7 @@ EOF --error ER_IO_READ_ERROR ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,ib_import_io_read_error_2"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; @@ -458,7 +414,7 @@ EOF --error ER_IO_READ_ERROR ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,ib_import_io_read_error_3"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; @@ -482,7 +438,7 @@ EOF --error ER_IO_READ_ERROR ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,ib_import_io_read_error_4"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; @@ -506,7 +462,7 @@ EOF --error ER_IO_READ_ERROR ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,ib_import_io_read_error_5"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; @@ -530,7 +486,7 @@ EOF --error ER_IO_READ_ERROR ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,ib_import_io_read_error_6"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; @@ -554,7 +510,7 @@ EOF --error ER_IO_READ_ERROR ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,ib_import_io_read_error_7"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; @@ -578,7 +534,7 @@ EOF --error ER_IO_READ_ERROR ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,ib_import_io_read_error_8"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; @@ -602,7 +558,7 @@ EOF --error ER_IO_READ_ERROR ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,ib_import_io_read_error_9"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; @@ -627,7 +583,7 @@ EOF --error ER_IO_READ_ERROR ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,ib_import_string_read_error"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; @@ -654,7 +610,7 @@ SET SESSION debug_dbug="+d,ib_import_OOM_1"; --error ER_OUT_OF_RESOURCES ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,ib_import_OOM_1"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; @@ -686,7 +642,7 @@ SET SESSION debug_dbug="+d,ib_import_OOM_2"; --error ER_OUT_OF_RESOURCES ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,ib_import_OOM_2"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; @@ -718,7 +674,7 @@ SET SESSION debug_dbug="+d,ib_import_OOM_4"; --error ER_OUT_OF_RESOURCES ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,ib_import_OOM_4"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; @@ -750,7 +706,7 @@ SET SESSION debug_dbug="+d,ib_import_OOM_5"; --error ER_OUT_OF_RESOURCES ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,ib_import_OOM_5"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; @@ -781,7 +737,7 @@ SET SESSION debug_dbug="+d,ib_import_OOM_6"; --error ER_OUT_OF_RESOURCES ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,ib_import_OOM_6"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; @@ -811,7 +767,7 @@ SET SESSION debug_dbug="+d,ib_import_OOM_7"; --error ER_OUT_OF_RESOURCES ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,ib_import_OOM_7"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; @@ -841,7 +797,7 @@ SET SESSION debug_dbug="+d,ib_import_OOM_8"; --error ER_OUT_OF_RESOURCES ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,ib_import_OOM_8"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; @@ -871,7 +827,7 @@ SET SESSION debug_dbug="+d,ib_import_OOM_9"; --error ER_OUT_OF_RESOURCES ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,ib_import_OOM_9"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; @@ -901,7 +857,7 @@ SET SESSION debug_dbug="+d,ib_import_OOM_10"; --error ER_OUT_OF_RESOURCES ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,ib_import_OOM_10"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; @@ -933,7 +889,7 @@ SET SESSION debug_dbug="+d,ib_import_internal_error"; --error ER_INTERNAL_ERROR ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,ib_import_internal_error"; +SET SESSION debug_dbug=@saved_debug_dbug; # Restore files perl; @@ -974,7 +930,7 @@ do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; ib_restore_tablespaces("test_wl5522", "t1"); EOF -SET SESSION debug_dbug="-d,ib_import_reset_space_and_lsn_failure"; +SET SESSION debug_dbug=@saved_debug_dbug; # Test failure after attempting a tablespace open SET SESSION debug_dbug="+d,ib_import_open_tablespace_failure"; @@ -984,7 +940,7 @@ SET SESSION debug_dbug="+d,ib_import_open_tablespace_failure"; --error ER_GET_ERRMSG ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,ib_import_open_tablespace_failure"; +SET SESSION debug_dbug=@saved_debug_dbug; # Restore files perl; @@ -999,7 +955,7 @@ SET SESSION debug_dbug="+d,ib_import_check_bitmap_failure"; --error ER_NOT_KEYFILE ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,ib_import_check_bitmap_failure"; +SET SESSION debug_dbug=@saved_debug_dbug; # Restore files perl; @@ -1013,7 +969,7 @@ SET SESSION debug_dbug="+d,ib_import_cluster_root_adjust_failure"; --error ER_NOT_KEYFILE ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,ib_import_cluster_root_adjust_failure"; +SET SESSION debug_dbug=@saved_debug_dbug; # Restore files perl; @@ -1027,7 +983,7 @@ SET SESSION debug_dbug="+d,ib_import_cluster_failure"; --error ER_NOT_KEYFILE ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,ib_import_cluster_failure"; +SET SESSION debug_dbug=@saved_debug_dbug; # Restore files perl; @@ -1041,7 +997,7 @@ SET SESSION debug_dbug="+d,ib_import_sec_root_adjust_failure"; --error ER_NOT_KEYFILE ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,ib_import_sec_root_adjust_failure"; +SET SESSION debug_dbug=@saved_debug_dbug; # Restore files perl; @@ -1055,7 +1011,7 @@ SET SESSION debug_dbug="+d,ib_import_set_max_rowid_failure"; --error ER_NOT_KEYFILE ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,ib_import_set_max_rowid_failure"; +SET SESSION debug_dbug=@saved_debug_dbug; # Left over from the failed IMPORT perl; @@ -1087,7 +1043,9 @@ CREATE TABLE test_wl5522.t1 ( INDEX idx3(c4(512))) Engine=InnoDB; # Stop purge so that it doesn't remove the delete marked entries. -SET GLOBAL INNODB_PURGE_STOP_NOW=ON; +connect (purge_control,localhost,root); +START TRANSACTION WITH CONSISTENT SNAPSHOT; +connection default; # Disable change buffer merge from the master thread, additionally # enable aggressive flushing so that more changes are buffered. @@ -1157,7 +1115,10 @@ SELECT name SET GLOBAL innodb_disable_background_merge=OFF; # Enable normal operation -SET GLOBAL INNODB_PURGE_RUN_NOW=ON; +connection purge_control; +COMMIT; +disconnect purge_control; +connection default; DROP TABLE test_wl5522.t1; @@ -1195,8 +1156,8 @@ DROP TABLE test_wl5522.t1; # a Btree that has several levels CREATE TABLE test_wl5522.t1 (c1 INT, c2 VARCHAR(1024), c3 BLOB) ENGINE = Innodb; -INSERT INTO test_wl5522.t1 VALUES - (100, REPEAT('Karanbir', 899), REPEAT('Ajeeth', 1200)); +INSERT IGNORE INTO test_wl5522.t1 VALUES + (100, REPEAT('Karanbir', 899), REPEAT('Ajeeth', 2731)); INSERT INTO test_wl5522.t1 SELECT * FROM test_wl5522.t1; INSERT INTO test_wl5522.t1 SELECT * FROM test_wl5522.t1; @@ -1238,7 +1199,7 @@ SET SESSION debug_dbug="+d,ib_import_trigger_corruption_1"; --error ER_INTERNAL_ERROR ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,ib_import_trigger_corruption_1"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; @@ -1262,14 +1223,14 @@ do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; ib_restore_tablespaces("test_wl5522", "t1"); EOF -SET SESSION debug_dbug="+d,buf_page_is_corrupt_failure"; +SET SESSION debug_dbug="+d,buf_page_import_corrupt_failure"; --replace_regex /'.*t1.cfg'/'t1.cfg'/ --error ER_INTERNAL_ERROR ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,buf_page_is_corrupt_failure"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; @@ -1299,7 +1260,7 @@ SET SESSION debug_dbug="+d,ib_import_trigger_corruption_2"; --error ER_INNODB_INDEX_CORRUPT ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,ib_import_trigger_corruption_2"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; @@ -1329,7 +1290,7 @@ SET SESSION debug_dbug="+d,ib_import_trigger_corruption_3"; --error ER_NOT_KEYFILE ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,ib_import_trigger_corruption_3"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; @@ -1349,7 +1310,7 @@ SET SESSION debug_dbug="+d,ib_import_create_index_failure_1"; ALTER TABLE test_wl5522.t1 ADD INDEX idx(c1); -SET SESSION debug_dbug="-d,ib_import_create_index_failure_1"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; @@ -1380,7 +1341,7 @@ SET SESSION debug_dbug="+d,fil_space_create_failure"; --error ER_GET_ERRMSG ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,fil_space_create_failure"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; @@ -1411,7 +1372,7 @@ SET SESSION debug_dbug="+d,dict_tf_to_fsp_flags_failure"; --error ER_GET_ERRMSG ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,dict_tf_to_fsp_flags_failure"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; @@ -1442,7 +1403,7 @@ SET SESSION debug_dbug="+d,fsp_flags_is_valid_failure"; --error ER_INTERNAL_ERROR ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,fsp_flags_is_valid_failure"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; @@ -1491,4 +1452,3 @@ call mtr.add_suppression("while reading index meta-data, expected to read 44 byt --remove_file $MYSQLTEST_VARDIR/tmp/t1.ibd eval SET GLOBAL INNODB_FILE_PER_TABLE=$innodb_file_per_table; - diff --git a/mysql-test/suite/innodb/r/innodb-wl5522-debug-zip.result b/mysql-test/suite/innodb_zip/r/wl5522_debug_zip.result similarity index 86% rename from mysql-test/suite/innodb/r/innodb-wl5522-debug-zip.result rename to mysql-test/suite/innodb_zip/r/wl5522_debug_zip.result index 3ce55ef0409..1778437927e 100644 --- a/mysql-test/suite/innodb/r/innodb-wl5522-debug-zip.result +++ b/mysql-test/suite/innodb_zip/r/wl5522_debug_zip.result @@ -1,21 +1,12 @@ -call mtr.add_suppression("InnoDB: Page for tablespace .* "); -call mtr.add_suppression("InnoSB: Warning: database page corruption or a failed .*"); +call mtr.add_suppression("InnoDB: Tablespace for table .* is set as discarded."); +call mtr.add_suppression("InnoDB: Cannot calculate statistics for table .* because the .ibd file is missing. Please refer to .* for how to resolve the issue."); +call mtr.add_suppression("InnoDB: Page 0 at offset 0 looks corrupted in file .*"); +call mtr.add_suppression("InnoDB: Page for tablespace "); +call mtr.add_suppression("InnoDB: Invalid FSP_SPACE_FLAGS=0x"); FLUSH TABLES; -SET GLOBAL innodb_file_per_table = 1; -SELECT @@innodb_file_per_table; -@@innodb_file_per_table -1 -SET GLOBAL innodb_file_format = `Barracuda`; -SELECT @@innodb_file_format; -@@innodb_file_format -Barracuda +SET GLOBAL innodb_file_per_table=1; +SET GLOBAL innodb_file_format=Barracuda; SET SESSION innodb_strict_mode=1; -SELECT @@SESSION.innodb_strict_mode; -@@SESSION.innodb_strict_mode -1 -DROP DATABASE IF EXISTS test_wl5522; -Warnings: -Note 1008 Can't drop database 'test_wl5522'; database doesn't exist CREATE DATABASE test_wl5522; CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = Innodb ROW_FORMAT=COMPRESSED; @@ -36,7 +27,6 @@ SELECT * FROM test_wl5522.t1; ERROR HY000: Tablespace has been discarded for table 't1' ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: Lost connection to MySQL server during query -SET SESSION debug_dbug="-d,ib_import_before_commit_crash"; SET SESSION debug_dbug="+d,ib_import_before_checkpoint_crash"; SELECT COUNT(*) FROM test_wl5522.t1; ERROR HY000: Tablespace has been discarded for table 't1' @@ -45,20 +35,12 @@ ERROR HY000: Lost connection to MySQL server during query unlink: t1.ibd unlink: t1.cfg # Restart and reconnect to the server -SET SESSION debug_dbug="-d,ib_import_before_checkpoint_crash"; DROP TABLE test_wl5522.t1; -SET GLOBAL innodb_file_per_table = 1; -SELECT @@innodb_file_per_table; -@@innodb_file_per_table -1 -SET GLOBAL innodb_file_format = `Barracuda`; -SELECT @@innodb_file_format; -@@innodb_file_format -Barracuda SET SESSION innodb_strict_mode=1; -SELECT @@SESSION.innodb_strict_mode; -@@SESSION.innodb_strict_mode -1 +SET @file_per_table = @@GLOBAL.innodb_file_per_table; +SET @file_format = @@GLOBAL.innodb_file_format; +SET GLOBAL innodb_file_per_table=1; +SET GLOBAL innodb_file_format=Barracuda; CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = Innodb ROW_FORMAT=COMPRESSED; ALTER TABLE test_wl5522.t1 DISCARD TABLESPACE; @@ -87,10 +69,11 @@ ALTER TABLE test_wl5522.t1 DISCARD TABLESPACE; SELECT COUNT(*) FROM test_wl5522.t1; ERROR HY000: Tablespace has been discarded for table 't1' restore: t1 .ibd and .cfg files +SET @saved_debug_dbug = @@SESSION.debug_dbug; SET SESSION debug_dbug="+d,ib_import_internal_error"; ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: Internal error: While updating the of index "GEN_CLUST_INDEX" - Generic error -SET SESSION debug_dbug="-d,ib_import_internal_error"; +SET SESSION debug_dbug=@saved_debug_dbug; restore: t1 .ibd and .cfg files ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; DROP TABLE test_wl5522.t1; @@ -104,36 +87,36 @@ SET SESSION debug_dbug="+d,ib_import_reset_space_and_lsn_failure"; ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: Internal error: Cannot reset LSNs in table '"test_wl5522"."t1"' : Too many concurrent transactions restore: t1 .ibd and .cfg files -SET SESSION debug_dbug="-d,ib_import_reset_space_and_lsn_failure"; +SET SESSION debug_dbug=@saved_debug_dbug; SET SESSION debug_dbug="+d,ib_import_open_tablespace_failure"; ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: Got error 44 't1.ibd -SET SESSION debug_dbug="-d,ib_import_open_tablespace_failure"; +SET SESSION debug_dbug=@saved_debug_dbug; restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,ib_import_check_bitmap_failure"; ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: Incorrect key file for table 't1'; try to repair it -SET SESSION debug_dbug="-d,ib_import_check_bitmap_failure"; +SET SESSION debug_dbug=@saved_debug_dbug; restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,ib_import_cluster_root_adjust_failure"; ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: Incorrect key file for table 't1'; try to repair it -SET SESSION debug_dbug="-d,ib_import_cluster_root_adjust_failure"; +SET SESSION debug_dbug=@saved_debug_dbug; restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,ib_import_cluster_failure"; ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: Incorrect key file for table 't1'; try to repair it -SET SESSION debug_dbug="-d,ib_import_cluster_failure"; +SET SESSION debug_dbug=@saved_debug_dbug; restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,ib_import_sec_root_adjust_failure"; ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: Incorrect key file for table 't1'; try to repair it -SET SESSION debug_dbug="-d,ib_import_sec_root_adjust_failure"; +SET SESSION debug_dbug=@saved_debug_dbug; restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,ib_import_set_max_rowid_failure"; ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: Incorrect key file for table 't1'; try to repair it -SET SESSION debug_dbug="-d,ib_import_set_max_rowid_failure"; +SET SESSION debug_dbug=@saved_debug_dbug; unlink: t1.ibd unlink: t1.cfg DROP TABLE test_wl5522.t1; @@ -145,8 +128,8 @@ c4 VARCHAR(2048), INDEX idx1(c2), INDEX idx2(c3(512)), INDEX idx3(c4(512))) Engine=InnoDB -ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8; -SET GLOBAL INNODB_PURGE_STOP_NOW=ON; +ROW_FORMAT=COMPRESSED; +START TRANSACTION WITH CONSISTENT SNAPSHOT; SET GLOBAL innodb_disable_background_merge=ON; SET GLOBAL innodb_monitor_reset = ibuf_merges; SET GLOBAL innodb_monitor_reset = ibuf_merges_insert; @@ -189,7 +172,7 @@ t1 CREATE TABLE `t1` ( KEY `idx1` (`c2`), KEY `idx2` (`c3`(512)), KEY `idx3` (`c4`(512)) -) ENGINE=InnoDB AUTO_INCREMENT=248 DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8 +) ENGINE=InnoDB AUTO_INCREMENT=248 DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED SELECT c1, c2 FROM test_wl5522.t1; c1 c2 2 32 @@ -311,7 +294,7 @@ FROM information_schema.innodb_metrics WHERE name = 'ibuf_merges_inserts' AND count > 0; name SET GLOBAL innodb_disable_background_merge=OFF; -SET GLOBAL INNODB_PURGE_RUN_NOW=ON; +COMMIT; DROP TABLE test_wl5522.t1; CREATE TABLE test_wl5522.t1 ( c1 BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, @@ -321,7 +304,7 @@ c4 VARCHAR(2048), INDEX idx1(c2), INDEX idx2(c3(512)), INDEX idx3(c4(512))) Engine=InnoDB -ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8; +ROW_FORMAT=COMPRESSED; SELECT c1, c2 FROM test_wl5522.t1; c1 c2 ALTER TABLE test_wl5522.t1 DISCARD TABLESPACE; @@ -445,11 +428,11 @@ t1 CREATE TABLE `t1` ( KEY `idx1` (`c2`), KEY `idx2` (`c3`(512)), KEY `idx3` (`c4`(512)) -) ENGINE=InnoDB AUTO_INCREMENT=185 DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8 +) ENGINE=InnoDB AUTO_INCREMENT=185 DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED DROP TABLE test_wl5522.t1; CREATE TABLE test_wl5522.t1 (c1 INT, c2 VARCHAR(1024), c3 BLOB) ENGINE = Innodb ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4; -INSERT INTO test_wl5522.t1 VALUES +INSERT IGNORE INTO test_wl5522.t1 VALUES (100, REPEAT('Karanbir', 899), REPEAT('Ajeeth', 1200)); Warnings: Warning 1265 Data truncated for column 'c2' at row 1 @@ -477,7 +460,7 @@ restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,ib_import_trigger_corruption_1"; ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: Internal error: Cannot reset LSNs in table '"test_wl5522"."t1"' : Data structure corruption -SET SESSION debug_dbug="-d,ib_import_trigger_corruption_1"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; unlink: t1.ibd unlink: t1.cfg @@ -487,9 +470,10 @@ ALTER TABLE test_wl5522.t1 DISCARD TABLESPACE; SELECT COUNT(*) FROM test_wl5522.t1; ERROR HY000: Tablespace has been discarded for table 't1' restore: t1 .ibd and .cfg files -SET SESSION debug_dbug="+d,buf_page_is_corrupt_failure"; +SET SESSION debug_dbug="+d,buf_page_import_corrupt_failure"; ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,buf_page_is_corrupt_failure"; +ERROR HY000: Internal error: Cannot reset LSNs in table '"test_wl5522"."t1"' : Data structure corruption +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; unlink: t1.ibd unlink: t1.cfg @@ -502,7 +486,7 @@ restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,ib_import_trigger_corruption_2"; ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: Index corrupt: Externally stored column(5) has a reference length of 19 in the cluster index "GEN_CLUST_INDEX" -SET SESSION debug_dbug="-d,ib_import_trigger_corruption_2"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; unlink: t1.ibd unlink: t1.cfg @@ -515,7 +499,7 @@ restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,ib_import_trigger_corruption_3"; ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: Incorrect key file for table 't1'; try to repair it -SET SESSION debug_dbug="-d,ib_import_trigger_corruption_3"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; unlink: t1.ibd unlink: t1.cfg @@ -528,7 +512,7 @@ SET SESSION debug_dbug="+d,ib_import_create_index_failure_1"; ALTER TABLE test_wl5522.t1 ADD INDEX idx(c1); Warnings: Warning 1814 Tablespace has been discarded for table 't1' -SET SESSION debug_dbug="-d,ib_import_create_index_failure_1"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; unlink: t1.ibd unlink: t1.cfg @@ -541,7 +525,7 @@ restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,fil_space_create_failure"; ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: Got error 11 't1.ibd -SET SESSION debug_dbug="-d,fil_space_create_failure"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; unlink: t1.ibd unlink: t1.cfg @@ -554,7 +538,7 @@ restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,dict_tf_to_fsp_flags_failure"; ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: Got error 39 't1.ibd -SET SESSION debug_dbug="-d,dict_tf_to_fsp_flags_failure"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; unlink: t1.ibd unlink: t1.cfg @@ -567,7 +551,7 @@ restore: t1 .ibd and .cfg files SET SESSION debug_dbug="+d,fsp_flags_is_valid_failure"; ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; ERROR HY000: Internal error: Cannot reset LSNs in table '"test_wl5522"."t1"' : Unsupported -SET SESSION debug_dbug="-d,fsp_flags_is_valid_failure"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; unlink: t1.ibd unlink: t1.cfg @@ -578,6 +562,5 @@ set global innodb_monitor_enable = default; set global innodb_monitor_disable = default; set global innodb_monitor_reset = default; set global innodb_monitor_reset_all = default; -SET GLOBAL INNODB_FILE_PER_TABLE=1; -SET GLOBAL INNODB_FILE_FORMAT=Antelope; -SET SESSION innodb_strict_mode=0; +SET GLOBAL innodb_file_per_table = @file_per_table; +SET GLOBAL innodb_file_format = @file_format; diff --git a/mysql-test/suite/innodb/t/innodb-wl5522-debug-zip.test b/mysql-test/suite/innodb_zip/t/wl5522_debug_zip.test similarity index 79% rename from mysql-test/suite/innodb/t/innodb-wl5522-debug-zip.test rename to mysql-test/suite/innodb_zip/t/wl5522_debug_zip.test index 37b630ad47b..65b030c018f 100644 --- a/mysql-test/suite/innodb/t/innodb-wl5522-debug-zip.test +++ b/mysql-test/suite/innodb_zip/t/wl5522_debug_zip.test @@ -1,45 +1,32 @@ -# Not supported in embedded +# mysql-test-run.pl --embedded cannot restart the server. --source include/not_embedded.inc # This test case needs to crash the server. Needs a debug server. --source include/have_debug.inc -# Don't test this under valgrind, memory leaks will occur. +# Valgrind can hang or return spurious messages on DBUG_SUICIDE --source include/not_valgrind.inc # Avoid CrashReporter popup on Mac --source include/not_crashrep.inc --- source include/have_innodb.inc +-- source include/innodb_page_size_small.inc -# compressed table in tests are with sizes KEY_BLOCK_SIZE 1,2,4,8,16 -# Table creatation fails if KEY_BLOCK_SIZE > innodb-page-size,so -# allow test to run only when innodb-page-size=16 ---source include/have_innodb_16k.inc - -# Test intentionally crashes the server, corrupted pages possible -call mtr.add_suppression("InnoDB: Page for tablespace .* "); -call mtr.add_suppression("InnoSB: Warning: database page corruption or a failed .*"); +call mtr.add_suppression("InnoDB: Tablespace for table .* is set as discarded."); +call mtr.add_suppression("InnoDB: Cannot calculate statistics for table .* because the .ibd file is missing. Please refer to .* for how to resolve the issue."); +call mtr.add_suppression("InnoDB: Page 0 at offset 0 looks corrupted in file .*"); +call mtr.add_suppression("InnoDB: Page for tablespace "); +call mtr.add_suppression("InnoDB: Invalid FSP_SPACE_FLAGS=0x"); FLUSH TABLES; +SET GLOBAL innodb_file_per_table=1; +SET GLOBAL innodb_file_format=Barracuda; + let MYSQLD_DATADIR =`SELECT @@datadir`; -let $innodb_file_per_table = `SELECT @@innodb_file_per_table`; -let $innodb_file_format = `SELECT @@innodb_file_format`; -let $innodb_strict_mode_orig=`select @@session.innodb_strict_mode`; let $pathfix=/: '.*test_wl5522.*t1.ibd'/: 'test_wl5522_t1.ibd'/; -SET GLOBAL innodb_file_per_table = 1; -SELECT @@innodb_file_per_table; - -SET GLOBAL innodb_file_format = `Barracuda`; -SELECT @@innodb_file_format; - SET SESSION innodb_strict_mode=1; -SELECT @@SESSION.innodb_strict_mode; - - -DROP DATABASE IF EXISTS test_wl5522; CREATE DATABASE test_wl5522; # Create the table that we will use for crash recovery (during IMPORT) @@ -52,7 +39,7 @@ INSERT INTO test_wl5522.t1 VALUES (1), (2), (3), (4); FLUSH TABLES test_wl5522.t1 FOR EXPORT; perl; -do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl"; ib_backup_tablespaces("test_wl5522", "t1"); EOF UNLOCK TABLES; @@ -66,7 +53,7 @@ INSERT INTO test_wl5522.t1 VALUES (1); ALTER TABLE test_wl5522.t1 DISCARD TABLESPACE; perl; -do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl"; ib_discard_tablespaces("test_wl5522", "t1"); EOF @@ -75,7 +62,7 @@ SELECT COUNT(*) FROM test_wl5522.t1; # Restore files perl; -do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl"; ib_restore_tablespaces("test_wl5522", "t1"); EOF @@ -96,7 +83,6 @@ ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; --source include/wait_until_connected_again.inc --disable_reconnect -SET SESSION debug_dbug="-d,ib_import_before_commit_crash"; #### Before commit crash # Check that the DD is consistent after recovery @@ -119,7 +105,7 @@ ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; # recreate the table and do a proper import. -- source include/wait_until_disconnected.inc perl; -do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl"; ib_unlink_tablespace("test_wl5522", "t1"); EOF @@ -129,7 +115,6 @@ EOF --source include/wait_until_connected_again.inc --disable_reconnect -SET SESSION debug_dbug="-d,ib_import_before_checkpoint_crash"; #### Before checkpoint crash # After the above test the results are non-deterministic, recreate the table @@ -137,14 +122,12 @@ SET SESSION debug_dbug="-d,ib_import_before_checkpoint_crash"; DROP TABLE test_wl5522.t1; -SET GLOBAL innodb_file_per_table = 1; -SELECT @@innodb_file_per_table; - -SET GLOBAL innodb_file_format = `Barracuda`; -SELECT @@innodb_file_format; - SET SESSION innodb_strict_mode=1; -SELECT @@SESSION.innodb_strict_mode; +SET @file_per_table = @@GLOBAL.innodb_file_per_table; +SET @file_format = @@GLOBAL.innodb_file_format; + +SET GLOBAL innodb_file_per_table=1; +SET GLOBAL innodb_file_format=Barracuda; CREATE TABLE test_wl5522.t1 (c1 INT) ENGINE = Innodb ROW_FORMAT=COMPRESSED; @@ -152,7 +135,7 @@ ROW_FORMAT=COMPRESSED; ALTER TABLE test_wl5522.t1 DISCARD TABLESPACE; perl; -do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl"; ib_restore_tablespaces("test_wl5522", "t1"); EOF @@ -178,11 +161,12 @@ SELECT COUNT(*) FROM test_wl5522.t1; # Restore files perl; -do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl"; ib_restore_tablespaces("test_wl5522", "t1"); EOF # Test failure after reset of space id and LSN in the tablespace +SET @saved_debug_dbug = @@SESSION.debug_dbug; SET SESSION debug_dbug="+d,ib_import_internal_error"; --replace_regex /'.*t1.cfg'/'t1.cfg'/ @@ -190,11 +174,11 @@ SET SESSION debug_dbug="+d,ib_import_internal_error"; --error ER_INTERNAL_ERROR ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,ib_import_internal_error"; +SET SESSION debug_dbug=@saved_debug_dbug; # Restore files perl; -do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl"; ib_restore_tablespaces("test_wl5522", "t1"); EOF @@ -214,7 +198,7 @@ SELECT COUNT(*) FROM test_wl5522.t1; # Restore files perl; -do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl"; ib_restore_tablespaces("test_wl5522", "t1"); EOF @@ -228,11 +212,11 @@ ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; # Restore files perl; -do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl"; ib_restore_tablespaces("test_wl5522", "t1"); EOF -SET SESSION debug_dbug="-d,ib_import_reset_space_and_lsn_failure"; +SET SESSION debug_dbug=@saved_debug_dbug; # Test failure after attempting a tablespace open SET SESSION debug_dbug="+d,ib_import_open_tablespace_failure"; @@ -241,11 +225,11 @@ SET SESSION debug_dbug="+d,ib_import_open_tablespace_failure"; --error ER_GET_ERRMSG ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,ib_import_open_tablespace_failure"; +SET SESSION debug_dbug=@saved_debug_dbug; # Restore files perl; -do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl"; ib_restore_tablespaces("test_wl5522", "t1"); EOF @@ -256,11 +240,11 @@ SET SESSION debug_dbug="+d,ib_import_check_bitmap_failure"; --error ER_NOT_KEYFILE ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,ib_import_check_bitmap_failure"; +SET SESSION debug_dbug=@saved_debug_dbug; # Restore files perl; -do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl"; ib_restore_tablespaces("test_wl5522", "t1"); EOF @@ -270,11 +254,11 @@ SET SESSION debug_dbug="+d,ib_import_cluster_root_adjust_failure"; --error ER_NOT_KEYFILE ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,ib_import_cluster_root_adjust_failure"; +SET SESSION debug_dbug=@saved_debug_dbug; # Restore files perl; -do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl"; ib_restore_tablespaces("test_wl5522", "t1"); EOF @@ -284,11 +268,11 @@ SET SESSION debug_dbug="+d,ib_import_cluster_failure"; --error ER_NOT_KEYFILE ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,ib_import_cluster_failure"; +SET SESSION debug_dbug=@saved_debug_dbug; # Restore files perl; -do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl"; ib_restore_tablespaces("test_wl5522", "t1"); EOF @@ -298,11 +282,11 @@ SET SESSION debug_dbug="+d,ib_import_sec_root_adjust_failure"; --error ER_NOT_KEYFILE ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,ib_import_sec_root_adjust_failure"; +SET SESSION debug_dbug=@saved_debug_dbug; # Restore files perl; -do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl"; ib_restore_tablespaces("test_wl5522", "t1"); EOF @@ -312,11 +296,11 @@ SET SESSION debug_dbug="+d,ib_import_set_max_rowid_failure"; --error ER_NOT_KEYFILE ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,ib_import_set_max_rowid_failure"; +SET SESSION debug_dbug=@saved_debug_dbug; # Left over from the failed IMPORT perl; -do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl"; ib_unlink_tablespace("test_wl5522", "t1"); EOF @@ -342,10 +326,12 @@ CREATE TABLE test_wl5522.t1 ( INDEX idx1(c2), INDEX idx2(c3(512)), INDEX idx3(c4(512))) Engine=InnoDB - ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8; + ROW_FORMAT=COMPRESSED; # Stop purge so that it doesn't remove the delete marked entries. -SET GLOBAL INNODB_PURGE_STOP_NOW=ON; +connect (purge_control,localhost,root); +START TRANSACTION WITH CONSISTENT SNAPSHOT; +connection default; # Disable change buffer merge from the master thread, additionally # enable aggressive flushing so that more changes are buffered. @@ -398,7 +384,7 @@ SELECT name FLUSH TABLES test_wl5522.t1 FOR EXPORT; perl; -do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl"; ib_backup_tablespaces("test_wl5522", "t1"); EOF @@ -415,7 +401,10 @@ SELECT name SET GLOBAL innodb_disable_background_merge=OFF; # Enable normal operation -SET GLOBAL INNODB_PURGE_RUN_NOW=ON; +connection purge_control; +COMMIT; +disconnect purge_control; +connection default; DROP TABLE test_wl5522.t1; @@ -427,14 +416,14 @@ CREATE TABLE test_wl5522.t1 ( INDEX idx1(c2), INDEX idx2(c3(512)), INDEX idx3(c4(512))) Engine=InnoDB - ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=8; + ROW_FORMAT=COMPRESSED; SELECT c1, c2 FROM test_wl5522.t1; ALTER TABLE test_wl5522.t1 DISCARD TABLESPACE; perl; -do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl"; ib_restore_tablespaces("test_wl5522", "t1"); EOF @@ -455,7 +444,7 @@ DROP TABLE test_wl5522.t1; CREATE TABLE test_wl5522.t1 (c1 INT, c2 VARCHAR(1024), c3 BLOB) ENGINE = Innodb ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=4; -INSERT INTO test_wl5522.t1 VALUES +INSERT IGNORE INTO test_wl5522.t1 VALUES (100, REPEAT('Karanbir', 899), REPEAT('Ajeeth', 1200)); INSERT INTO test_wl5522.t1 SELECT * FROM test_wl5522.t1; @@ -470,7 +459,7 @@ SELECT COUNT(*) FROM test_wl5522.t1; FLUSH TABLES test_wl5522.t1 FOR EXPORT; perl; -do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl"; ib_backup_tablespaces("test_wl5522", "t1"); EOF @@ -488,7 +477,7 @@ SELECT COUNT(*) FROM test_wl5522.t1; # Restore files perl; -do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl"; ib_restore_tablespaces("test_wl5522", "t1"); EOF @@ -499,12 +488,12 @@ SET SESSION debug_dbug="+d,ib_import_trigger_corruption_1"; --error ER_INTERNAL_ERROR ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,ib_import_trigger_corruption_1"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; perl; -do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl"; ib_unlink_tablespace("test_wl5522", "t1"); EOF @@ -520,24 +509,24 @@ SELECT COUNT(*) FROM test_wl5522.t1; # Restore files perl; -do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl"; ib_restore_tablespaces("test_wl5522", "t1"); EOF -SET SESSION debug_dbug="+d,buf_page_is_corrupt_failure"; +SET SESSION debug_dbug="+d,buf_page_import_corrupt_failure"; --replace_regex /'.*t1.cfg'/'t1.cfg'/ -# Following alter is not failing -#--error ER_INTERNAL_ERROR +# Following alter is failing +--error ER_INTERNAL_ERROR ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,buf_page_is_corrupt_failure"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; perl; -do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl"; ib_unlink_tablespace("test_wl5522", "t1"); EOF @@ -551,7 +540,7 @@ SELECT COUNT(*) FROM test_wl5522.t1; # Restore files perl; -do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl"; ib_restore_tablespaces("test_wl5522", "t1"); EOF @@ -562,12 +551,12 @@ SET SESSION debug_dbug="+d,ib_import_trigger_corruption_2"; --error ER_INNODB_INDEX_CORRUPT ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,ib_import_trigger_corruption_2"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; perl; -do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl"; ib_unlink_tablespace("test_wl5522", "t1"); EOF @@ -581,7 +570,7 @@ SELECT COUNT(*) FROM test_wl5522.t1; # Restore files perl; -do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl"; ib_restore_tablespaces("test_wl5522", "t1"); EOF @@ -592,12 +581,12 @@ SET SESSION debug_dbug="+d,ib_import_trigger_corruption_3"; --error ER_NOT_KEYFILE ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,ib_import_trigger_corruption_3"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; perl; -do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl"; ib_unlink_tablespace("test_wl5522", "t1"); EOF @@ -613,12 +602,12 @@ SET SESSION debug_dbug="+d,ib_import_create_index_failure_1"; ALTER TABLE test_wl5522.t1 ADD INDEX idx(c1); -SET SESSION debug_dbug="-d,ib_import_create_index_failure_1"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; perl; -do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl"; ib_unlink_tablespace("test_wl5522", "t1"); EOF @@ -634,7 +623,7 @@ SELECT COUNT(*) FROM test_wl5522.t1; # Restore files perl; -do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl"; ib_restore_tablespaces("test_wl5522", "t1"); EOF @@ -644,12 +633,12 @@ SET SESSION debug_dbug="+d,fil_space_create_failure"; --error ER_GET_ERRMSG ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,fil_space_create_failure"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; perl; -do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl"; ib_unlink_tablespace("test_wl5522", "t1"); EOF @@ -665,7 +654,7 @@ SELECT COUNT(*) FROM test_wl5522.t1; # Restore files perl; -do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl"; ib_restore_tablespaces("test_wl5522", "t1"); EOF @@ -675,12 +664,12 @@ SET SESSION debug_dbug="+d,dict_tf_to_fsp_flags_failure"; --error ER_GET_ERRMSG ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,dict_tf_to_fsp_flags_failure"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; perl; -do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl"; ib_unlink_tablespace("test_wl5522", "t1"); EOF @@ -696,7 +685,7 @@ SELECT COUNT(*) FROM test_wl5522.t1; # Restore files perl; -do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl"; ib_restore_tablespaces("test_wl5522", "t1"); EOF @@ -707,12 +696,12 @@ SET SESSION debug_dbug="+d,fsp_flags_is_valid_failure"; --error ER_INTERNAL_ERROR ALTER TABLE test_wl5522.t1 IMPORT TABLESPACE; -SET SESSION debug_dbug="-d,fsp_flags_is_valid_failure"; +SET SESSION debug_dbug=@saved_debug_dbug; DROP TABLE test_wl5522.t1; perl; -do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +do "$ENV{MTR_SUITE_DIR}/../innodb/include/innodb-util.pl"; ib_unlink_tablespace("test_wl5522", "t1"); EOF @@ -747,13 +736,12 @@ call mtr.add_suppression("t1.ibd: Page .* at offset .* looks corrupted"); call mtr.add_suppression("but tablespace with that id or name does not exist"); call mtr.add_suppression("Failed to find tablespace for table '\"test_wl5522\".\"t1\"' in the cache"); call mtr.add_suppression("Could not find a valid tablespace file for 'test_wl5522.*t1'"); +call mtr.add_suppression("Index for table 't1' is corrupt; try to repair it"); --enable_query_log #cleanup --remove_file $MYSQLTEST_VARDIR/tmp/t1.cfg --remove_file $MYSQLTEST_VARDIR/tmp/t1.ibd -eval SET GLOBAL INNODB_FILE_PER_TABLE=$innodb_file_per_table; -eval SET GLOBAL INNODB_FILE_FORMAT=$innodb_file_format; -eval SET SESSION innodb_strict_mode=$innodb_strict_mode_orig; - +SET GLOBAL innodb_file_per_table = @file_per_table; +SET GLOBAL innodb_file_format = @file_format; diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 518d5ad323d..f534f8906f4 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -577,6 +577,8 @@ buf_page_is_corrupted( ulint zip_size) /*!< in: size of compressed page; 0 for uncompressed pages */ { + DBUG_EXECUTE_IF("buf_page_import_corrupt_failure", return(TRUE); ); + ulint checksum_field1; ulint checksum_field2; @@ -658,8 +660,6 @@ buf_page_is_corrupted( return(FALSE); } - DBUG_EXECUTE_IF("buf_page_is_corrupt_failure", return(TRUE); ); - ulint page_no = mach_read_from_4(read_buf + FIL_PAGE_OFFSET); ulint space_id = mach_read_from_4(read_buf + FIL_PAGE_SPACE_ID); const srv_checksum_algorithm_t curr_algo = @@ -4216,7 +4216,7 @@ buf_page_io_complete( /* Not a real corruption if it was triggered by error injection */ - DBUG_EXECUTE_IF("buf_page_is_corrupt_failure", + DBUG_EXECUTE_IF("buf_page_import_corrupt_failure", if (bpage->space > TRX_SYS_SPACE && buf_mark_space_corrupt(bpage)) { ib_logf(IB_LOG_LEVEL_INFO, @@ -4279,7 +4279,7 @@ corrupt: } } - DBUG_EXECUTE_IF("buf_page_is_corrupt_failure", + DBUG_EXECUTE_IF("buf_page_import_corrupt_failure", page_not_corrupt: bpage = bpage; ); if (recv_recovery_is_on()) { diff --git a/storage/innobase/ibuf/ibuf0ibuf.cc b/storage/innobase/ibuf/ibuf0ibuf.cc index ba4cc0924b9..f0b02d863d3 100644 --- a/storage/innobase/ibuf/ibuf0ibuf.cc +++ b/storage/innobase/ibuf/ibuf0ibuf.cc @@ -5099,7 +5099,20 @@ ibuf_check_bitmap_on_import( return(DB_TABLE_NOT_FOUND); } - size = fil_space_get_size(space_id); + mtr_t mtr; + mtr_start(&mtr); + { + buf_block_t* sp = buf_page_get(space_id, zip_size, 0, + RW_S_LATCH, &mtr); + if (sp) { + size = mach_read_from_4( + FSP_HEADER_OFFSET + FSP_FREE_LIMIT + + sp->frame); + } else { + size = 0; + } + } + mtr_commit(&mtr); if (size == 0) { return(DB_TABLE_NOT_FOUND); @@ -5110,7 +5123,6 @@ ibuf_check_bitmap_on_import( page_size = zip_size ? zip_size : UNIV_PAGE_SIZE; for (page_no = 0; page_no < size; page_no += page_size) { - mtr_t mtr; page_t* bitmap_page; ulint i; diff --git a/storage/xtradb/buf/buf0buf.cc b/storage/xtradb/buf/buf0buf.cc index d211bf382cf..4ad19c778ec 100644 --- a/storage/xtradb/buf/buf0buf.cc +++ b/storage/xtradb/buf/buf0buf.cc @@ -646,6 +646,8 @@ buf_page_is_corrupted( ulint zip_size) /*!< in: size of compressed page; 0 for uncompressed pages */ { + DBUG_EXECUTE_IF("buf_page_import_corrupt_failure", return(TRUE); ); + ulint checksum_field1; ulint checksum_field2; @@ -727,8 +729,6 @@ buf_page_is_corrupted( return(FALSE); } - DBUG_EXECUTE_IF("buf_page_is_corrupt_failure", return(TRUE); ); - ulint page_no = mach_read_from_4(read_buf + FIL_PAGE_OFFSET); ulint space_id = mach_read_from_4(read_buf + FIL_PAGE_SPACE_ID); const srv_checksum_algorithm_t curr_algo = @@ -4421,7 +4421,7 @@ buf_page_io_complete( /* Not a real corruption if it was triggered by error injection */ - DBUG_EXECUTE_IF("buf_page_is_corrupt_failure", + DBUG_EXECUTE_IF("buf_page_import_corrupt_failure", if (bpage->space > TRX_SYS_SPACE && buf_mark_space_corrupt(bpage)) { ib_logf(IB_LOG_LEVEL_INFO, @@ -4502,7 +4502,7 @@ corrupt: } } /**/ - DBUG_EXECUTE_IF("buf_page_is_corrupt_failure", + DBUG_EXECUTE_IF("buf_page_import_corrupt_failure", page_not_corrupt: bpage = bpage; ); if (recv_recovery_is_on()) { diff --git a/storage/xtradb/ibuf/ibuf0ibuf.cc b/storage/xtradb/ibuf/ibuf0ibuf.cc index fb5d4ffa3af..fabe468fb0c 100644 --- a/storage/xtradb/ibuf/ibuf0ibuf.cc +++ b/storage/xtradb/ibuf/ibuf0ibuf.cc @@ -5141,7 +5141,20 @@ ibuf_check_bitmap_on_import( return(DB_TABLE_NOT_FOUND); } - size = fil_space_get_size(space_id); + mtr_t mtr; + mtr_start(&mtr); + { + buf_block_t* sp = buf_page_get(space_id, zip_size, 0, + RW_S_LATCH, &mtr); + if (sp) { + size = mach_read_from_4( + FSP_HEADER_OFFSET + FSP_FREE_LIMIT + + sp->frame); + } else { + size = 0; + } + } + mtr_commit(&mtr); if (size == 0) { return(DB_TABLE_NOT_FOUND); @@ -5152,7 +5165,6 @@ ibuf_check_bitmap_on_import( page_size = zip_size ? zip_size : UNIV_PAGE_SIZE; for (page_no = 0; page_no < size; page_no += page_size) { - mtr_t mtr; page_t* bitmap_page; ulint i; From 9f3c014ca3e5b58cfbbe33ee6ffccbb99cc4a356 Mon Sep 17 00:00:00 2001 From: Vesa Pentti Date: Fri, 3 Nov 2017 08:18:50 +0000 Subject: [PATCH 18/35] MDEV-10728 -- mysqlbinlog can't be input to mysql client String comparison with utf8_bin collation is case sensitive. Hence "DELIMITER" did not match with "delimiter". The delimiter command matching now uses my_charset_latin1. --- client/mysql.cc | 2 +- mysql-test/r/delimiter_command_case_sensitivity.result | 2 ++ mysql-test/t/delimiter_case_mdev_10728.sql | 3 +++ mysql-test/t/delimiter_command_case_sensitivity.test | 2 ++ 4 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 mysql-test/r/delimiter_command_case_sensitivity.result create mode 100644 mysql-test/t/delimiter_case_mdev_10728.sql create mode 100644 mysql-test/t/delimiter_command_case_sensitivity.test diff --git a/client/mysql.cc b/client/mysql.cc index f581bfcafae..c043d054ea5 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -1094,7 +1094,7 @@ inline bool is_delimiter_command(char *name, ulong len) only name(first DELIMITER_NAME_LEN bytes) is checked. */ return (len >= DELIMITER_NAME_LEN && - !my_strnncoll(charset_info, (uchar*) name, DELIMITER_NAME_LEN, + !my_strnncoll(&my_charset_latin1, (uchar*) name, DELIMITER_NAME_LEN, (uchar *) DELIMITER_NAME, DELIMITER_NAME_LEN)); } diff --git a/mysql-test/r/delimiter_command_case_sensitivity.result b/mysql-test/r/delimiter_command_case_sensitivity.result new file mode 100644 index 00000000000..6ed281c757a --- /dev/null +++ b/mysql-test/r/delimiter_command_case_sensitivity.result @@ -0,0 +1,2 @@ +1 +1 diff --git a/mysql-test/t/delimiter_case_mdev_10728.sql b/mysql-test/t/delimiter_case_mdev_10728.sql new file mode 100644 index 00000000000..72a1dcd9a9e --- /dev/null +++ b/mysql-test/t/delimiter_case_mdev_10728.sql @@ -0,0 +1,3 @@ +DeLiMiTeR A; +SELECT 1 A; +delimiter ; diff --git a/mysql-test/t/delimiter_command_case_sensitivity.test b/mysql-test/t/delimiter_command_case_sensitivity.test new file mode 100644 index 00000000000..2b06a35c723 --- /dev/null +++ b/mysql-test/t/delimiter_command_case_sensitivity.test @@ -0,0 +1,2 @@ +# MDEV-10728 +--exec $MYSQL --default-character-set=binary < "t/delimiter_case_mdev_10728.sql" From 57ba66b9abdaa513f6f9e2dbfd953ebd59106145 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 2 Nov 2017 22:51:34 +0200 Subject: [PATCH 19/35] Remove redundant function parameters buf_flush_or_remove_pages(), buf_flush_dirty_pages(): Remove the redundant parameter flush=(trx!=NULL). --- storage/innobase/buf/buf0lru.cc | 63 ++++++++++++++------------------- storage/xtradb/buf/buf0lru.cc | 63 ++++++++++++++------------------- 2 files changed, 52 insertions(+), 74 deletions(-) diff --git a/storage/innobase/buf/buf0lru.cc b/storage/innobase/buf/buf0lru.cc index 8c2b5df4bce..98f20f444cb 100644 --- a/storage/innobase/buf/buf0lru.cc +++ b/storage/innobase/buf/buf0lru.cc @@ -528,26 +528,20 @@ buf_flush_or_remove_page( return(processed); } -/******************************************************************//** -Remove all dirty pages belonging to a given tablespace inside a specific +/** Remove all dirty pages belonging to a given tablespace inside a specific buffer pool instance when we are deleting the data file(s) of that tablespace. The pages still remain a part of LRU and are evicted from the list as they age towards the tail of the LRU. +@param[in,out] buf_pool buffer pool +@param[in] id tablespace identifier +@param[in] trx transaction (to check for interrupt), + or NULL if the files should not be written to @retval DB_SUCCESS if all freed @retval DB_FAIL if not all freed @retval DB_INTERRUPTED if the transaction was interrupted */ static MY_ATTRIBUTE((nonnull(1), warn_unused_result)) dberr_t -buf_flush_or_remove_pages( -/*======================*/ - buf_pool_t* buf_pool, /*!< buffer pool instance */ - ulint id, /*!< in: target space id for which - to remove or flush pages */ - bool flush, /*!< in: flush to disk if true but - don't remove else remove without - flushing to disk */ - const trx_t* trx) /*!< to check if the operation must - be interrupted, can be 0 */ +buf_flush_or_remove_pages(buf_pool_t* buf_pool, ulint id, const trx_t* trx) { buf_page_t* prev; buf_page_t* bpage; @@ -574,7 +568,7 @@ rescan: /* Skip this block, as it does not belong to the target space. */ - } else if (!buf_flush_or_remove_page(buf_pool, bpage, flush)) { + } else if (!buf_flush_or_remove_page(buf_pool, bpage, trx)) { /* Remove was unsuccessful, we have to try again by scanning the entire list from the end. @@ -597,7 +591,7 @@ rescan: iteration. */ all_freed = false; - } else if (flush) { + } else if (trx) { /* The processing was successful. And during the processing we have released the buf_pool mutex @@ -616,19 +610,17 @@ rescan: processed = 0; } -#ifdef DBUG_OFF - if (flush) { + if (trx) { DBUG_EXECUTE_IF("ib_export_flush_crash", static ulint n_pages; if (++n_pages == 4) {DBUG_SUICIDE();}); - } -#endif /* DBUG_OFF */ - /* The check for trx is interrupted is expensive, we want - to check every N iterations. */ - if (!processed && trx && trx_is_interrupted(trx)) { - buf_flush_list_mutex_exit(buf_pool); - return(DB_INTERRUPTED); + /* The check for trx is interrupted is + expensive, we want to check every N iterations. */ + if (!processed && trx_is_interrupted(trx)) { + buf_flush_list_mutex_exit(buf_pool); + return(DB_INTERRUPTED); + } } } @@ -637,28 +629,25 @@ rescan: return(all_freed ? DB_SUCCESS : DB_FAIL); } -/******************************************************************//** -Remove or flush all the dirty pages that belong to a given tablespace +/** Remove or flush all the dirty pages that belong to a given tablespace inside a specific buffer pool instance. The pages will remain in the LRU list and will be evicted from the LRU list as they age and move towards -the tail of the LRU list. */ +the tail of the LRU list. +@param[in,out] buf_pool buffer pool +@param[in] id tablespace identifier +@param[in] trx transaction (to check for interrupt), + or NULL if the files should not be written to +*/ static MY_ATTRIBUTE((nonnull(1))) void -buf_flush_dirty_pages( -/*==================*/ - buf_pool_t* buf_pool, /*!< buffer pool instance */ - ulint id, /*!< in: space id */ - bool flush, /*!< in: flush to disk if true otherwise - remove the pages without flushing */ - const trx_t* trx) /*!< to check if the operation must - be interrupted */ +buf_flush_dirty_pages(buf_pool_t* buf_pool, ulint id, const trx_t* trx) { dberr_t err; do { buf_pool_mutex_enter(buf_pool); - err = buf_flush_or_remove_pages(buf_pool, id, flush, trx); + err = buf_flush_or_remove_pages(buf_pool, id, trx); buf_pool_mutex_exit(buf_pool); @@ -847,12 +836,12 @@ buf_LRU_remove_pages( case BUF_REMOVE_FLUSH_NO_WRITE: ut_a(trx == 0); - buf_flush_dirty_pages(buf_pool, id, false, NULL); + buf_flush_dirty_pages(buf_pool, id, NULL); break; case BUF_REMOVE_FLUSH_WRITE: ut_a(trx != 0); - buf_flush_dirty_pages(buf_pool, id, true, trx); + buf_flush_dirty_pages(buf_pool, id, trx); /* Ensure that all asynchronous IO is completed. */ os_aio_wait_until_no_pending_writes(); fil_flush(id); diff --git a/storage/xtradb/buf/buf0lru.cc b/storage/xtradb/buf/buf0lru.cc index d979eb44a96..078e5f999f8 100644 --- a/storage/xtradb/buf/buf0lru.cc +++ b/storage/xtradb/buf/buf0lru.cc @@ -571,26 +571,20 @@ buf_flush_or_remove_page( return(processed); } -/******************************************************************//** -Remove all dirty pages belonging to a given tablespace inside a specific +/** Remove all dirty pages belonging to a given tablespace inside a specific buffer pool instance when we are deleting the data file(s) of that tablespace. The pages still remain a part of LRU and are evicted from the list as they age towards the tail of the LRU. +@param[in,out] buf_pool buffer pool +@param[in] id tablespace identifier +@param[in] trx transaction (to check for interrupt), + or NULL if the files should not be written to @retval DB_SUCCESS if all freed @retval DB_FAIL if not all freed @retval DB_INTERRUPTED if the transaction was interrupted */ static MY_ATTRIBUTE((nonnull(1), warn_unused_result)) dberr_t -buf_flush_or_remove_pages( -/*======================*/ - buf_pool_t* buf_pool, /*!< buffer pool instance */ - ulint id, /*!< in: target space id for which - to remove or flush pages */ - bool flush, /*!< in: flush to disk if true but - don't remove else remove without - flushing to disk */ - const trx_t* trx) /*!< to check if the operation must - be interrupted, can be 0 */ +buf_flush_or_remove_pages(buf_pool_t* buf_pool, ulint id, const trx_t* trx) { buf_page_t* prev; buf_page_t* bpage; @@ -621,7 +615,7 @@ rescan: /* Skip this block, as it does not belong to the target space. */ - } else if (!buf_flush_or_remove_page(buf_pool, bpage, flush, + } else if (!buf_flush_or_remove_page(buf_pool, bpage, trx, &must_restart)) { /* Remove was unsuccessful, we have to try again @@ -647,7 +641,7 @@ rescan: /* Cannot trust the prev pointer */ break; } - } else if (flush) { + } else if (trx) { /* The processing was successful. And during the processing we have released all the buf_pool mutexes @@ -674,19 +668,17 @@ rescan: break; } -#ifdef DBUG_OFF - if (flush) { + if (trx) { DBUG_EXECUTE_IF("ib_export_flush_crash", static ulint n_pages; if (++n_pages == 4) {DBUG_SUICIDE();}); - } -#endif /* DBUG_OFF */ - /* The check for trx is interrupted is expensive, we want - to check every N iterations. */ - if (!processed && trx && trx_is_interrupted(trx)) { - buf_flush_list_mutex_exit(buf_pool); - return(DB_INTERRUPTED); + /* The check for trx is interrupted is + expensive, we want to check every N iterations. */ + if (!processed && trx_is_interrupted(trx)) { + buf_flush_list_mutex_exit(buf_pool); + return(DB_INTERRUPTED); + } } } @@ -695,28 +687,25 @@ rescan: return(all_freed ? DB_SUCCESS : DB_FAIL); } -/******************************************************************//** -Remove or flush all the dirty pages that belong to a given tablespace +/** Remove or flush all the dirty pages that belong to a given tablespace inside a specific buffer pool instance. The pages will remain in the LRU list and will be evicted from the LRU list as they age and move towards -the tail of the LRU list. */ +the tail of the LRU list. +@param[in,out] buf_pool buffer pool +@param[in] id tablespace identifier +@param[in] trx transaction (to check for interrupt), + or NULL if the files should not be written to +*/ static MY_ATTRIBUTE((nonnull(1))) void -buf_flush_dirty_pages( -/*==================*/ - buf_pool_t* buf_pool, /*!< buffer pool instance */ - ulint id, /*!< in: space id */ - bool flush, /*!< in: flush to disk if true otherwise - remove the pages without flushing */ - const trx_t* trx) /*!< to check if the operation must - be interrupted */ +buf_flush_dirty_pages(buf_pool_t* buf_pool, ulint id, const trx_t* trx) { dberr_t err; do { mutex_enter(&buf_pool->LRU_list_mutex); - err = buf_flush_or_remove_pages(buf_pool, id, flush, trx); + err = buf_flush_or_remove_pages(buf_pool, id, trx); mutex_exit(&buf_pool->LRU_list_mutex); @@ -913,12 +902,12 @@ buf_LRU_remove_pages( case BUF_REMOVE_FLUSH_NO_WRITE: ut_a(trx == 0); - buf_flush_dirty_pages(buf_pool, id, false, NULL); + buf_flush_dirty_pages(buf_pool, id, NULL); break; case BUF_REMOVE_FLUSH_WRITE: ut_a(trx != 0); - buf_flush_dirty_pages(buf_pool, id, true, trx); + buf_flush_dirty_pages(buf_pool, id, trx); /* Ensure that all asynchronous IO is completed. */ os_aio_wait_until_no_pending_writes(); fil_flush(id); From 51b4366bfb8a77c6341d7811f71c851e52f36f68 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 2 Nov 2017 22:38:37 +0200 Subject: [PATCH 20/35] =?UTF-8?q?MDEV-13328=20ALTER=20TABLE=E2=80=A6DISCAR?= =?UTF-8?q?D=20TABLESPACE=20takes=20a=20lot=20of=20time?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With a big buffer pool that contains many data pages, DISCARD TABLESPACE took a long time, because it would scan the entire buffer pool to remove any pages that belong to the tablespace. With a large buffer pool, this would take a lot of time, especially when the table-to-discard is empty. The minimum amount of work that DISCARD TABLESPACE must do is to remove the pages of the to-be-discarded table from the buf_pool->flush_list because any writes to the data file must be prevented before the file is deleted. If DISCARD TABLESPACE does not evict the pages from the buffer pool, then IMPORT TABLESPACE must do it, because we must prevent pre-DISCARD, not-yet-evicted pages from being mistaken for pages of the imported tablespace. It would not be a useful fix to simply move the buffer pool scan to the IMPORT TABLESPACE step. What we can do is to actively evict those pages that could be mistaken for imported pages. In this way, when importing a small table into a big buffer pool, the import should still run relatively fast. Import is bypassing the buffer pool when reading pages for the adjustment phase. In the adjustment phase, if a page exists in the buffer pool, we could replace it with the page from the imported file. Unfortunately I did not get this to work properly, so instead we will simply evict any matching page from the buffer pool. buf_page_get_gen(): Implement BUF_EVICT_IF_IN_POOL, a new mode where the requested page will be evicted if it is found. There must be no unwritten changes for the page. buf_remove_t: Remove. Instead, use trx!=NULL to signify that a write to file is desired, and use a separate parameter bool drop_ahi. buf_LRU_flush_or_remove_pages(), fil_delete_tablespace(): Replace buf_remove_t. buf_LRU_remove_pages(), buf_LRU_remove_all_pages(): Remove. PageConverter::m_mtr: A dummy mini-transaction buffer PageConverter::PageConverter(): Complete the member initialization list. PageConverter::operator()(): Evict any 'shadow' pages from the buffer pool so that pre-existing (garbage) pages cannot be mistaken for pages that exist in the being-imported file. row_discard_tablespace(): Remove a bogus comment that seems to refer to IMPORT TABLESPACE, not DISCARD TABLESPACE. --- storage/innobase/buf/buf0buf.cc | 47 ++++-- storage/innobase/buf/buf0lru.cc | 232 ++------------------------ storage/innobase/dict/dict0dict.cc | 2 +- storage/innobase/fil/fil0fil.cc | 22 +-- storage/innobase/include/buf0buf.h | 1 + storage/innobase/include/buf0lru.h | 18 +- storage/innobase/include/buf0types.h | 11 -- storage/innobase/include/fil0fil.h | 15 +- storage/innobase/row/row0import.cc | 27 +-- storage/innobase/row/row0mysql.cc | 12 +- storage/innobase/row/row0quiesce.cc | 4 +- storage/xtradb/buf/buf0buf.cc | 50 ++++-- storage/xtradb/buf/buf0lru.cc | 240 ++------------------------- storage/xtradb/dict/dict0dict.cc | 2 +- storage/xtradb/fil/fil0fil.cc | 22 +-- storage/xtradb/include/buf0buf.h | 1 + storage/xtradb/include/buf0lru.h | 18 +- storage/xtradb/include/buf0types.h | 11 -- storage/xtradb/include/fil0fil.h | 15 +- storage/xtradb/row/row0import.cc | 27 +-- storage/xtradb/row/row0mysql.cc | 12 +- storage/xtradb/row/row0quiesce.cc | 4 +- 22 files changed, 187 insertions(+), 606 deletions(-) diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 46df26922b5..f79e6e13d84 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -3060,8 +3060,8 @@ buf_page_get_gen( ib_mutex_t* fix_mutex = NULL; buf_pool_t* buf_pool = buf_pool_get(space, offset); - ut_ad(mtr); - ut_ad(mtr->state == MTR_ACTIVE); + ut_ad((mtr == NULL) == (mode == BUF_EVICT_IF_IN_POOL)); + ut_ad(!mtr || mtr->state == MTR_ACTIVE); ut_ad((rw_latch == RW_S_LATCH) || (rw_latch == RW_X_LATCH) || (rw_latch == RW_NO_LATCH)); @@ -3072,23 +3072,29 @@ buf_page_get_gen( #ifdef UNIV_DEBUG switch (mode) { + case BUF_EVICT_IF_IN_POOL: + /* After DISCARD TABLESPACE, the tablespace would not exist, + but in IMPORT TABLESPACE, PageConverter::operator() must + replace any old pages, which were not evicted during DISCARD. + Skip the assertion on zip_size. */ + break; case BUF_GET_NO_LATCH: ut_ad(rw_latch == RW_NO_LATCH); - break; + /* fall through */ case BUF_GET: case BUF_GET_IF_IN_POOL: case BUF_PEEK_IF_IN_POOL: case BUF_GET_IF_IN_POOL_OR_WATCH: case BUF_GET_POSSIBLY_FREED: + ut_ad(zip_size == fil_space_get_zip_size(space)); break; default: ut_error; } #endif /* UNIV_DEBUG */ - ut_ad(zip_size == fil_space_get_zip_size(space)); ut_ad(ut_is_2pow(zip_size)); #ifndef UNIV_LOG_DEBUG - ut_ad(!ibuf_inside(mtr) + ut_ad(!mtr || !ibuf_inside(mtr) || ibuf_page_low(space, zip_size, offset, FALSE, file, line, NULL)); #endif @@ -3153,9 +3159,11 @@ loop: rw_lock_x_unlock(hash_lock); } - if (mode == BUF_GET_IF_IN_POOL - || mode == BUF_PEEK_IF_IN_POOL - || mode == BUF_GET_IF_IN_POOL_OR_WATCH) { + switch (mode) { + case BUF_GET_IF_IN_POOL: + case BUF_GET_IF_IN_POOL_OR_WATCH: + case BUF_PEEK_IF_IN_POOL: + case BUF_EVICT_IF_IN_POOL: #ifdef UNIV_SYNC_DEBUG ut_ad(!rw_lock_own(hash_lock, RW_LOCK_EX)); ut_ad(!rw_lock_own(hash_lock, RW_LOCK_SHARED)); @@ -3244,8 +3252,10 @@ got_block: ut_ad(page_zip_get_size(&block->page.zip) == zip_size); - if (mode == BUF_GET_IF_IN_POOL || mode == BUF_PEEK_IF_IN_POOL) { - + switch (mode) { + case BUF_GET_IF_IN_POOL: + case BUF_PEEK_IF_IN_POOL: + case BUF_EVICT_IF_IN_POOL: bool must_read; { @@ -3274,6 +3284,19 @@ got_block: buf_page_t* bpage; case BUF_BLOCK_FILE_PAGE: + if (UNIV_UNLIKELY(mode == BUF_EVICT_IF_IN_POOL)) { +evict_from_pool: + ut_ad(!fix_block->page.oldest_modification); + buf_pool_mutex_enter(buf_pool); + buf_block_unfix(fix_block); + + if (!buf_LRU_free_page(&fix_block->page, true)) { + ut_ad(0); + } + + buf_pool_mutex_exit(buf_pool); + return(NULL); + } break; case BUF_BLOCK_ZIP_PAGE: @@ -3306,6 +3329,10 @@ got_block: goto loop; } + if (UNIV_UNLIKELY(mode == BUF_EVICT_IF_IN_POOL)) { + goto evict_from_pool; + } + /* Buffer-fix the block so that it cannot be evicted or relocated while we are attempting to allocate an uncompressed page. */ diff --git a/storage/innobase/buf/buf0lru.cc b/storage/innobase/buf/buf0lru.cc index 98f20f444cb..a047b28f4fd 100644 --- a/storage/innobase/buf/buf0lru.cc +++ b/storage/innobase/buf/buf0lru.cc @@ -668,231 +668,27 @@ buf_flush_dirty_pages(buf_pool_t* buf_pool, ulint id, const trx_t* trx) || buf_pool_get_dirty_pages_count(buf_pool, id) == 0); } -/******************************************************************//** -Remove all pages that belong to a given tablespace inside a specific -buffer pool instance when we are DISCARDing the tablespace. */ -static MY_ATTRIBUTE((nonnull)) +/** Empty the flush list for all pages belonging to a tablespace. +@param[in] id tablespace identifier +@param[in] trx transaction, for checking for user interrupt; + or NULL if nothing is to be written +@param[in] drop_ahi whether to drop the adaptive hash index */ +UNIV_INTERN void -buf_LRU_remove_all_pages( -/*=====================*/ - buf_pool_t* buf_pool, /*!< buffer pool instance */ - ulint id) /*!< in: space id */ +buf_LRU_flush_or_remove_pages(ulint id, const trx_t* trx, bool drop_ahi) { - buf_page_t* bpage; - ibool all_freed; - -scan_again: - buf_pool_mutex_enter(buf_pool); - - all_freed = TRUE; - - for (bpage = UT_LIST_GET_LAST(buf_pool->LRU); - bpage != NULL; - /* No op */) { - - rw_lock_t* hash_lock; - buf_page_t* prev_bpage; - ib_mutex_t* block_mutex = NULL; - - ut_a(buf_page_in_file(bpage)); - ut_ad(bpage->in_LRU_list); - - prev_bpage = UT_LIST_GET_PREV(LRU, bpage); - - /* bpage->space and bpage->io_fix are protected by - buf_pool->mutex and the block_mutex. It is safe to check - them while holding buf_pool->mutex only. */ - - if (buf_page_get_space(bpage) != id) { - /* Skip this block, as it does not belong to - the space that is being invalidated. */ - goto next_page; - } else if (buf_page_get_io_fix(bpage) != BUF_IO_NONE) { - /* We cannot remove this page during this scan - yet; maybe the system is currently reading it - in, or flushing the modifications to the file */ - - all_freed = FALSE; - goto next_page; - } else { - ulint fold = buf_page_address_fold( - bpage->space, bpage->offset); - - hash_lock = buf_page_hash_lock_get(buf_pool, fold); - - rw_lock_x_lock(hash_lock); - - block_mutex = buf_page_get_mutex(bpage); - mutex_enter(block_mutex); - - if (bpage->buf_fix_count > 0) { - - mutex_exit(block_mutex); - - rw_lock_x_unlock(hash_lock); - - /* We cannot remove this page during - this scan yet; maybe the system is - currently reading it in, or flushing - the modifications to the file */ - - all_freed = FALSE; - - goto next_page; - } + for (ulint i = 0; i < srv_buf_pool_instances; i++) { + buf_pool_t* buf_pool = buf_pool_from_array(i); + if (drop_ahi) { + buf_LRU_drop_page_hash_for_tablespace(buf_pool, id); } - - ut_ad(mutex_own(block_mutex)); - -#ifdef UNIV_DEBUG - if (buf_debug_prints) { - fprintf(stderr, - "Dropping space %lu page %lu\n", - (ulong) buf_page_get_space(bpage), - (ulong) buf_page_get_page_no(bpage)); - } -#endif - if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) { - /* Do nothing, because the adaptive hash index - covers uncompressed pages only. */ - } else if (((buf_block_t*) bpage)->index) { - ulint page_no; - ulint zip_size; - - buf_pool_mutex_exit(buf_pool); - - zip_size = buf_page_get_zip_size(bpage); - page_no = buf_page_get_page_no(bpage); - - rw_lock_x_unlock(hash_lock); - - mutex_exit(block_mutex); - - /* Note that the following call will acquire - and release block->lock X-latch. */ - - btr_search_drop_page_hash_when_freed( - id, zip_size, page_no); - - goto scan_again; - } - - if (bpage->oldest_modification != 0) { - - buf_flush_remove(bpage); - } - - ut_ad(!bpage->in_flush_list); - - /* Remove from the LRU list. */ - - if (buf_LRU_block_remove_hashed(bpage, true)) { - buf_LRU_block_free_hashed_page((buf_block_t*) bpage); - } else { - ut_ad(block_mutex == &buf_pool->zip_mutex); - } - - ut_ad(!mutex_own(block_mutex)); - -#ifdef UNIV_SYNC_DEBUG - /* buf_LRU_block_remove_hashed() releases the hash_lock */ - ut_ad(!rw_lock_own(hash_lock, RW_LOCK_EX)); - ut_ad(!rw_lock_own(hash_lock, RW_LOCK_SHARED)); -#endif /* UNIV_SYNC_DEBUG */ - -next_page: - bpage = prev_bpage; - } - - buf_pool_mutex_exit(buf_pool); - - if (!all_freed) { - os_thread_sleep(20000); - - goto scan_again; - } -} - -/******************************************************************//** -Remove pages belonging to a given tablespace inside a specific -buffer pool instance when we are deleting the data file(s) of that -tablespace. The pages still remain a part of LRU and are evicted from -the list as they age towards the tail of the LRU only if buf_remove -is BUF_REMOVE_FLUSH_NO_WRITE. */ -static MY_ATTRIBUTE((nonnull(1))) -void -buf_LRU_remove_pages( -/*=================*/ - buf_pool_t* buf_pool, /*!< buffer pool instance */ - ulint id, /*!< in: space id */ - buf_remove_t buf_remove, /*!< in: remove or flush strategy */ - const trx_t* trx) /*!< to check if the operation must - be interrupted */ -{ - switch (buf_remove) { - case BUF_REMOVE_ALL_NO_WRITE: - buf_LRU_remove_all_pages(buf_pool, id); - break; - - case BUF_REMOVE_FLUSH_NO_WRITE: - ut_a(trx == 0); - buf_flush_dirty_pages(buf_pool, id, NULL); - break; - - case BUF_REMOVE_FLUSH_WRITE: - ut_a(trx != 0); buf_flush_dirty_pages(buf_pool, id, trx); + } + + if (trx && !trx_is_interrupted(trx)) { /* Ensure that all asynchronous IO is completed. */ os_aio_wait_until_no_pending_writes(); fil_flush(id); - break; - } -} - -/******************************************************************//** -Flushes all dirty pages or removes all pages belonging -to a given tablespace. A PROBLEM: if readahead is being started, what -guarantees that it will not try to read in pages after this operation -has completed? */ -UNIV_INTERN -void -buf_LRU_flush_or_remove_pages( -/*==========================*/ - ulint id, /*!< in: space id */ - buf_remove_t buf_remove, /*!< in: remove or flush strategy */ - const trx_t* trx) /*!< to check if the operation must - be interrupted */ -{ - ulint i; - - /* Before we attempt to drop pages one by one we first - attempt to drop page hash index entries in batches to make - it more efficient. The batching attempt is a best effort - attempt and does not guarantee that all pages hash entries - will be dropped. We get rid of remaining page hash entries - one by one below. */ - for (i = 0; i < srv_buf_pool_instances; i++) { - buf_pool_t* buf_pool; - - buf_pool = buf_pool_from_array(i); - - switch (buf_remove) { - case BUF_REMOVE_ALL_NO_WRITE: - buf_LRU_drop_page_hash_for_tablespace(buf_pool, id); - break; - - case BUF_REMOVE_FLUSH_NO_WRITE: - /* It is a DROP TABLE for a single table - tablespace. No AHI entries exist because - we already dealt with them when freeing up - extents. */ - case BUF_REMOVE_FLUSH_WRITE: - /* We allow read-only queries against the - table, there is no need to drop the AHI entries. */ - break; - } - - buf_LRU_remove_pages(buf_pool, id, buf_remove, trx); } } diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc index 1f467429104..8d7c1275c3b 100644 --- a/storage/innobase/dict/dict0dict.cc +++ b/storage/innobase/dict/dict0dict.cc @@ -1673,7 +1673,7 @@ dict_table_rename_in_cache( filepath = fil_make_ibd_name(table->name, false); } - fil_delete_tablespace(table->space, BUF_REMOVE_ALL_NO_WRITE); + fil_delete_tablespace(table->space, true); /* Delete any temp file hanging around. */ if (os_file_status(filepath, &exists, &ftype) diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index b2576f6bd81..ac30f3c7a25 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -2526,8 +2526,7 @@ fil_op_log_parse_or_replay( switch (type) { case MLOG_FILE_DELETE: if (fil_tablespace_exists_in_mem(space_id)) { - dberr_t err = fil_delete_tablespace( - space_id, BUF_REMOVE_FLUSH_NO_WRITE); + dberr_t err = fil_delete_tablespace(space_id); ut_a(err == DB_SUCCESS); } @@ -2805,7 +2804,7 @@ fil_close_tablespace( completely and permanently. The flag stop_new_ops also prevents fil_flush() from being applied to this tablespace. */ - buf_LRU_flush_or_remove_pages(id, BUF_REMOVE_FLUSH_WRITE, trx); + buf_LRU_flush_or_remove_pages(id, trx); #endif mutex_enter(&fil_system->mutex); @@ -2832,18 +2831,13 @@ fil_close_tablespace( return(err); } -/*******************************************************************//** -Deletes a single-table tablespace. The tablespace must be cached in the -memory cache. +/** Delete a tablespace and associated .ibd file. +@param[in] id tablespace identifier +@param[in] drop_ahi whether to drop the adaptive hash index @return DB_SUCCESS or error */ UNIV_INTERN dberr_t -fil_delete_tablespace( -/*==================*/ - ulint id, /*!< in: space id */ - buf_remove_t buf_remove) /*!< in: specify the action to take - on the tables pages in the buffer - pool */ +fil_delete_tablespace(ulint id, bool drop_ahi) { char* path = 0; fil_space_t* space = 0; @@ -2899,7 +2893,7 @@ fil_delete_tablespace( To deal with potential read requests by checking the ::stop_new_ops flag in fil_io() */ - buf_LRU_flush_or_remove_pages(id, buf_remove, 0); + buf_LRU_flush_or_remove_pages(id, NULL, drop_ahi); #endif /* !UNIV_HOTBACKUP */ @@ -3010,7 +3004,7 @@ fil_discard_tablespace( { dberr_t err; - switch (err = fil_delete_tablespace(id, BUF_REMOVE_ALL_NO_WRITE)) { + switch (err = fil_delete_tablespace(id, true)) { case DB_SUCCESS: break; diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h index 002e562f283..857bdf9d2be 100644 --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h @@ -59,6 +59,7 @@ Created 11/5/1995 Heikki Tuuri #define BUF_GET_POSSIBLY_FREED 16 /*!< Like BUF_GET, but do not mind if the file page has been freed. */ +#define BUF_EVICT_IF_IN_POOL 20 /*!< evict a clean block if found */ /* @} */ /** @name Modes for buf_page_get_known_nowait */ /* @{ */ diff --git a/storage/innobase/include/buf0lru.h b/storage/innobase/include/buf0lru.h index a7a65df33aa..308bda20c7b 100644 --- a/storage/innobase/include/buf0lru.h +++ b/storage/innobase/include/buf0lru.h @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -51,19 +52,14 @@ These are low-level functions /** Minimum LRU list length for which the LRU_old pointer is defined */ #define BUF_LRU_OLD_MIN_LEN 512 /* 8 megabytes of 16k pages */ -/******************************************************************//** -Flushes all dirty pages or removes all pages belonging -to a given tablespace. A PROBLEM: if readahead is being started, what -guarantees that it will not try to read in pages after this operation -has completed? */ +/** Empty the flush list for all pages belonging to a tablespace. +@param[in] id tablespace identifier +@param[in] trx transaction, for checking for user interrupt; + or NULL if nothing is to be written +@param[in] drop_ahi whether to drop the adaptive hash index */ UNIV_INTERN void -buf_LRU_flush_or_remove_pages( -/*==========================*/ - ulint id, /*!< in: space id */ - buf_remove_t buf_remove, /*!< in: remove or flush strategy */ - const trx_t* trx); /*!< to check if the operation must - be interrupted */ +buf_LRU_flush_or_remove_pages(ulint id, const trx_t* trx, bool drop_ahi=false); #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG /********************************************************************//** diff --git a/storage/innobase/include/buf0types.h b/storage/innobase/include/buf0types.h index 11bbc9b5c8a..511240d669d 100644 --- a/storage/innobase/include/buf0types.h +++ b/storage/innobase/include/buf0types.h @@ -58,17 +58,6 @@ enum buf_flush_t { BUF_FLUSH_N_TYPES /*!< index of last element + 1 */ }; -/** Algorithm to remove the pages for a tablespace from the buffer pool. -See buf_LRU_flush_or_remove_pages(). */ -enum buf_remove_t { - BUF_REMOVE_ALL_NO_WRITE, /*!< Remove all pages from the buffer - pool, don't write or sync to disk */ - BUF_REMOVE_FLUSH_NO_WRITE, /*!< Remove only, from the flush list, - don't write or sync to disk */ - BUF_REMOVE_FLUSH_WRITE /*!< Flush dirty pages to disk only - don't remove from the buffer pool */ -}; - /** Flags for io_fix types */ enum buf_io_fix { BUF_IO_NONE = 0, /**< no pending I/O */ diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h index 38250949380..81f207d1e20 100644 --- a/storage/innobase/include/fil0fil.h +++ b/storage/innobase/include/fil0fil.h @@ -851,18 +851,13 @@ fil_op_log_parse_or_replay( only be parsed but not replayed */ ulint log_flags); /*!< in: redo log flags (stored in the page number parameter) */ -/*******************************************************************//** -Deletes a single-table tablespace. The tablespace must be cached in the -memory cache. -@return TRUE if success */ +/** Delete a tablespace and associated .ibd file. +@param[in] id tablespace identifier +@param[in] drop_ahi whether to drop the adaptive hash index +@return DB_SUCCESS or error */ UNIV_INTERN dberr_t -fil_delete_tablespace( -/*==================*/ - ulint id, /*!< in: space id */ - buf_remove_t buf_remove); /*!< in: specify the action to take - on the tables pages in the buffer - pool */ +fil_delete_tablespace(ulint id, bool drop_ahi = false); /*******************************************************************//** Closes a single-table tablespace. The tablespace must be cached in the memory cache. Free all pages used by the tablespace. diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index 801ac1ecc35..9cf55699d3f 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -1601,18 +1601,16 @@ PageConverter::PageConverter( : AbstractCallback(trx), m_cfg(cfg), + m_index(cfg->m_indexes), + m_current_lsn(log_get_lsn()), m_page_zip_ptr(0), - m_heap(0) UNIV_NOTHROW + m_rec_iter(), + m_offsets_(), m_offsets(m_offsets_), + m_heap(0), + m_cluster_index(dict_table_get_first_index(cfg->m_table)) UNIV_NOTHROW { - m_index = m_cfg->m_indexes; - - m_current_lsn = log_get_lsn(); ut_a(m_current_lsn > 0); - - m_offsets = m_offsets_; rec_offs_init(m_offsets_); - - m_cluster_index = dict_table_get_first_index(m_cfg->m_table); } /** @@ -2103,7 +2101,7 @@ PageConverter::operator() ( we can work on them */ if ((err = update_page(block, page_type)) != DB_SUCCESS) { - return(err); + break; } /* Note: For compressed pages this function will write to the @@ -2140,9 +2138,15 @@ PageConverter::operator() ( "%s: Page %lu at offset " UINT64PF " looks corrupted.", m_filepath, (ulong) (offset / m_page_size), offset); - return(DB_CORRUPTION); + err = DB_CORRUPTION; } + /* If we already had and old page with matching number + in the buffer pool, evict it now, because + we no longer evict the pages on DISCARD TABLESPACE. */ + buf_page_get_gen(get_space_id(), get_zip_size(), block->page.offset, + RW_NO_LATCH, NULL, BUF_EVICT_IF_IN_POOL, + __FILE__, __LINE__, NULL); return(err); } @@ -3716,8 +3720,7 @@ row_import_for_mysql( The only dirty pages generated should be from the pessimistic purge of delete marked records that couldn't be purged in Phase I. */ - buf_LRU_flush_or_remove_pages( - prebuilt->table->space, BUF_REMOVE_FLUSH_WRITE, trx); + buf_LRU_flush_or_remove_pages(prebuilt->table->space, trx); if (trx_is_interrupted(trx)) { ib_logf(IB_LOG_LEVEL_INFO, "Phase III - Flush interrupted"); diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 8172d8a7c11..dcf4413a1c4 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -2477,10 +2477,7 @@ err_exit: /* We already have .ibd file here. it should be deleted. */ if (table->space - && fil_delete_tablespace( - table->space, - BUF_REMOVE_FLUSH_NO_WRITE) - != DB_SUCCESS) { + && fil_delete_tablespace(table->space) != DB_SUCCESS) { ut_print_timestamp(stderr); fprintf(stderr, @@ -3109,9 +3106,6 @@ row_discard_tablespace( 4) FOREIGN KEY operations: if table->n_foreign_key_checks_running > 0, we do not allow the discard. */ - /* Play safe and remove all insert buffer entries, though we should - have removed them already when DISCARD TABLESPACE was called */ - ibuf_delete_for_discarded_space(table->space); table_id_t new_id; @@ -4496,9 +4490,7 @@ row_drop_table_for_mysql( fil_delete_file(filepath); - } else if (fil_delete_tablespace( - space_id, - BUF_REMOVE_FLUSH_NO_WRITE) + } else if (fil_delete_tablespace(space_id) != DB_SUCCESS) { fprintf(stderr, "InnoDB: We removed now the InnoDB" diff --git a/storage/innobase/row/row0quiesce.cc b/storage/innobase/row/row0quiesce.cc index 583fbe60fb3..6c4e6adb96c 100644 --- a/storage/innobase/row/row0quiesce.cc +++ b/storage/innobase/row/row0quiesce.cc @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -542,8 +543,7 @@ row_quiesce_table_start( } if (!trx_is_interrupted(trx)) { - buf_LRU_flush_or_remove_pages( - table->space, BUF_REMOVE_FLUSH_WRITE, trx); + buf_LRU_flush_or_remove_pages(table->space, trx); if (trx_is_interrupted(trx)) { diff --git a/storage/xtradb/buf/buf0buf.cc b/storage/xtradb/buf/buf0buf.cc index 8b33efe04b2..7498f841671 100644 --- a/storage/xtradb/buf/buf0buf.cc +++ b/storage/xtradb/buf/buf0buf.cc @@ -2953,8 +2953,8 @@ buf_page_get_gen( ib_mutex_t* fix_mutex = NULL; buf_pool_t* buf_pool = buf_pool_get(space, offset); - ut_ad(mtr); - ut_ad(mtr->state == MTR_ACTIVE); + ut_ad((mtr == NULL) == (mode == BUF_EVICT_IF_IN_POOL)); + ut_ad(!mtr || mtr->state == MTR_ACTIVE); ut_ad((rw_latch == RW_S_LATCH) || (rw_latch == RW_X_LATCH) || (rw_latch == RW_NO_LATCH)); @@ -2965,23 +2965,29 @@ buf_page_get_gen( #ifdef UNIV_DEBUG switch (mode) { + case BUF_EVICT_IF_IN_POOL: + /* After DISCARD TABLESPACE, the tablespace would not exist, + but in IMPORT TABLESPACE, PageConverter::operator() must + replace any old pages, which were not evicted during DISCARD. + Skip the assertion on zip_size. */ + break; case BUF_GET_NO_LATCH: ut_ad(rw_latch == RW_NO_LATCH); - break; + /* fall through */ case BUF_GET: case BUF_GET_IF_IN_POOL: case BUF_PEEK_IF_IN_POOL: case BUF_GET_IF_IN_POOL_OR_WATCH: case BUF_GET_POSSIBLY_FREED: + ut_ad(zip_size == fil_space_get_zip_size(space)); break; default: ut_error; } #endif /* UNIV_DEBUG */ - ut_ad(zip_size == fil_space_get_zip_size(space)); ut_ad(ut_is_2pow(zip_size)); #ifndef UNIV_LOG_DEBUG - ut_ad(!ibuf_inside(mtr) + ut_ad(!mtr || !ibuf_inside(mtr) || ibuf_page_low(space, zip_size, offset, FALSE, file, line, NULL)); #endif @@ -3051,9 +3057,11 @@ loop: rw_lock_x_unlock(hash_lock); } - if (mode == BUF_GET_IF_IN_POOL - || mode == BUF_PEEK_IF_IN_POOL - || mode == BUF_GET_IF_IN_POOL_OR_WATCH) { + switch (mode) { + case BUF_GET_IF_IN_POOL: + case BUF_GET_IF_IN_POOL_OR_WATCH: + case BUF_PEEK_IF_IN_POOL: + case BUF_EVICT_IF_IN_POOL: #ifdef UNIV_SYNC_DEBUG ut_ad(!rw_lock_own(hash_lock, RW_LOCK_EX)); ut_ad(!rw_lock_own(hash_lock, RW_LOCK_SHARED)); @@ -3142,8 +3150,10 @@ got_block: ut_ad(page_zip_get_size(&block->page.zip) == zip_size); - if (mode == BUF_GET_IF_IN_POOL || mode == BUF_PEEK_IF_IN_POOL) { - + switch (mode) { + case BUF_GET_IF_IN_POOL: + case BUF_PEEK_IF_IN_POOL: + case BUF_EVICT_IF_IN_POOL: bool must_read; { @@ -3181,6 +3191,22 @@ got_block: case BUF_BLOCK_FILE_PAGE: ut_ad(fix_mutex != &buf_pool->zip_mutex); + + if (UNIV_UNLIKELY(mode == BUF_EVICT_IF_IN_POOL)) { +evict_from_pool: + ut_ad(!fix_block->page.oldest_modification); + mutex_enter(&buf_pool->LRU_list_mutex); + buf_block_unfix(fix_block); + mutex_enter(fix_mutex); + + if (!buf_LRU_free_page(&fix_block->page, true)) { + ut_ad(0); + mutex_exit(&buf_pool->LRU_list_mutex); + } + + mutex_exit(fix_mutex); + return(NULL); + } break; case BUF_BLOCK_ZIP_PAGE: @@ -3215,6 +3241,10 @@ got_block: goto loop; } + if (UNIV_UNLIKELY(mode == BUF_EVICT_IF_IN_POOL)) { + goto evict_from_pool; + } + /* Buffer-fix the block so that it cannot be evicted or relocated while we are attempting to allocate an uncompressed page. */ diff --git a/storage/xtradb/buf/buf0lru.cc b/storage/xtradb/buf/buf0lru.cc index 078e5f999f8..c71d45009e4 100644 --- a/storage/xtradb/buf/buf0lru.cc +++ b/storage/xtradb/buf/buf0lru.cc @@ -726,239 +726,27 @@ buf_flush_dirty_pages(buf_pool_t* buf_pool, ulint id, const trx_t* trx) || buf_pool_get_dirty_pages_count(buf_pool, id) == 0); } -/******************************************************************//** -Remove all pages that belong to a given tablespace inside a specific -buffer pool instance when we are DISCARDing the tablespace. */ -static MY_ATTRIBUTE((nonnull)) +/** Empty the flush list for all pages belonging to a tablespace. +@param[in] id tablespace identifier +@param[in] trx transaction, for checking for user interrupt; + or NULL if nothing is to be written +@param[in] drop_ahi whether to drop the adaptive hash index */ +UNIV_INTERN void -buf_LRU_remove_all_pages( -/*=====================*/ - buf_pool_t* buf_pool, /*!< buffer pool instance */ - ulint id) /*!< in: space id */ +buf_LRU_flush_or_remove_pages(ulint id, const trx_t* trx, bool drop_ahi) { - buf_page_t* bpage; - ibool all_freed; - -scan_again: - mutex_enter(&buf_pool->LRU_list_mutex); - - all_freed = TRUE; - - for (bpage = UT_LIST_GET_LAST(buf_pool->LRU); - bpage != NULL; - /* No op */) { - - prio_rw_lock_t* hash_lock; - buf_page_t* prev_bpage; - ib_mutex_t* block_mutex = NULL; - - ut_a(buf_page_in_file(bpage)); - ut_ad(bpage->in_LRU_list); - - prev_bpage = UT_LIST_GET_PREV(LRU, bpage); - - /* It is safe to check bpage->space and bpage->io_fix while - holding buf_pool->LRU_list_mutex only and later recheck - while holding the buf_page_get_mutex() mutex. */ - - if (buf_page_get_space(bpage) != id) { - /* Skip this block, as it does not belong to - the space that is being invalidated. */ - goto next_page; - } else if (UNIV_UNLIKELY(buf_page_get_io_fix_unlocked(bpage) - != BUF_IO_NONE)) { - /* We cannot remove this page during this scan - yet; maybe the system is currently reading it - in, or flushing the modifications to the file */ - - all_freed = FALSE; - goto next_page; - } else { - ulint fold = buf_page_address_fold( - bpage->space, bpage->offset); - - hash_lock = buf_page_hash_lock_get(buf_pool, fold); - - rw_lock_x_lock(hash_lock); - - block_mutex = buf_page_get_mutex(bpage); - mutex_enter(block_mutex); - - if (UNIV_UNLIKELY( - buf_page_get_space(bpage) != id - || bpage->buf_fix_count > 0 - || (buf_page_get_io_fix(bpage) - != BUF_IO_NONE))) { - - mutex_exit(block_mutex); - - rw_lock_x_unlock(hash_lock); - - /* We cannot remove this page during - this scan yet; maybe the system is - currently reading it in, or flushing - the modifications to the file */ - - all_freed = FALSE; - - goto next_page; - } + for (ulint i = 0; i < srv_buf_pool_instances; i++) { + buf_pool_t* buf_pool = buf_pool_from_array(i); + if (drop_ahi) { + buf_LRU_drop_page_hash_for_tablespace(buf_pool, id); } - - ut_ad(mutex_own(block_mutex)); - -#ifdef UNIV_DEBUG - if (buf_debug_prints) { - fprintf(stderr, - "Dropping space %lu page %lu\n", - (ulong) buf_page_get_space(bpage), - (ulong) buf_page_get_page_no(bpage)); - } -#endif - if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) { - /* Do nothing, because the adaptive hash index - covers uncompressed pages only. */ - } else if (((buf_block_t*) bpage)->index) { - ulint page_no; - ulint zip_size; - - mutex_exit(&buf_pool->LRU_list_mutex); - - zip_size = buf_page_get_zip_size(bpage); - page_no = buf_page_get_page_no(bpage); - - mutex_exit(block_mutex); - - rw_lock_x_unlock(hash_lock); - - /* Note that the following call will acquire - and release block->lock X-latch. */ - - btr_search_drop_page_hash_when_freed( - id, zip_size, page_no); - - goto scan_again; - } - - if (bpage->oldest_modification != 0) { - - buf_flush_remove(bpage); - } - - ut_ad(!bpage->in_flush_list); - - /* Remove from the LRU list. */ - - if (buf_LRU_block_remove_hashed(bpage, true)) { - - mutex_enter(block_mutex); - buf_LRU_block_free_hashed_page((buf_block_t*) bpage); - mutex_exit(block_mutex); - } else { - ut_ad(block_mutex == &buf_pool->zip_mutex); - } - - ut_ad(!mutex_own(block_mutex)); - -#ifdef UNIV_SYNC_DEBUG - /* buf_LRU_block_remove_hashed() releases the hash_lock */ - ut_ad(!rw_lock_own(hash_lock, RW_LOCK_EX)); - ut_ad(!rw_lock_own(hash_lock, RW_LOCK_SHARED)); -#endif /* UNIV_SYNC_DEBUG */ - -next_page: - bpage = prev_bpage; - } - - mutex_exit(&buf_pool->LRU_list_mutex); - - if (!all_freed) { - os_thread_sleep(20000); - - goto scan_again; - } -} - -/******************************************************************//** -Remove pages belonging to a given tablespace inside a specific -buffer pool instance when we are deleting the data file(s) of that -tablespace. The pages still remain a part of LRU and are evicted from -the list as they age towards the tail of the LRU only if buf_remove -is BUF_REMOVE_FLUSH_NO_WRITE. */ -static MY_ATTRIBUTE((nonnull(1))) -void -buf_LRU_remove_pages( -/*=================*/ - buf_pool_t* buf_pool, /*!< buffer pool instance */ - ulint id, /*!< in: space id */ - buf_remove_t buf_remove, /*!< in: remove or flush strategy */ - const trx_t* trx) /*!< to check if the operation must - be interrupted */ -{ - switch (buf_remove) { - case BUF_REMOVE_ALL_NO_WRITE: - buf_LRU_remove_all_pages(buf_pool, id); - break; - - case BUF_REMOVE_FLUSH_NO_WRITE: - ut_a(trx == 0); - buf_flush_dirty_pages(buf_pool, id, NULL); - break; - - case BUF_REMOVE_FLUSH_WRITE: - ut_a(trx != 0); buf_flush_dirty_pages(buf_pool, id, trx); + } + + if (trx && !trx_is_interrupted(trx)) { /* Ensure that all asynchronous IO is completed. */ os_aio_wait_until_no_pending_writes(); fil_flush(id); - break; - } -} - -/******************************************************************//** -Flushes all dirty pages or removes all pages belonging -to a given tablespace. A PROBLEM: if readahead is being started, what -guarantees that it will not try to read in pages after this operation -has completed? */ -UNIV_INTERN -void -buf_LRU_flush_or_remove_pages( -/*==========================*/ - ulint id, /*!< in: space id */ - buf_remove_t buf_remove, /*!< in: remove or flush strategy */ - const trx_t* trx) /*!< to check if the operation must - be interrupted */ -{ - ulint i; - - /* Before we attempt to drop pages one by one we first - attempt to drop page hash index entries in batches to make - it more efficient. The batching attempt is a best effort - attempt and does not guarantee that all pages hash entries - will be dropped. We get rid of remaining page hash entries - one by one below. */ - for (i = 0; i < srv_buf_pool_instances; i++) { - buf_pool_t* buf_pool; - - buf_pool = buf_pool_from_array(i); - - switch (buf_remove) { - case BUF_REMOVE_ALL_NO_WRITE: - buf_LRU_drop_page_hash_for_tablespace(buf_pool, id); - break; - - case BUF_REMOVE_FLUSH_NO_WRITE: - /* It is a DROP TABLE for a single table - tablespace. No AHI entries exist because - we already dealt with them when freeing up - extents. */ - case BUF_REMOVE_FLUSH_WRITE: - /* We allow read-only queries against the - table, there is no need to drop the AHI entries. */ - break; - } - - buf_LRU_remove_pages(buf_pool, id, buf_remove, trx); } } diff --git a/storage/xtradb/dict/dict0dict.cc b/storage/xtradb/dict/dict0dict.cc index 1558c6d50ac..5af3a635a96 100644 --- a/storage/xtradb/dict/dict0dict.cc +++ b/storage/xtradb/dict/dict0dict.cc @@ -1679,7 +1679,7 @@ dict_table_rename_in_cache( filepath = fil_make_ibd_name(table->name, false); } - fil_delete_tablespace(table->space, BUF_REMOVE_ALL_NO_WRITE); + fil_delete_tablespace(table->space, true); /* Delete any temp file hanging around. */ if (os_file_status(filepath, &exists, &ftype) diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc index 38cfc13383c..b9e8db22726 100644 --- a/storage/xtradb/fil/fil0fil.cc +++ b/storage/xtradb/fil/fil0fil.cc @@ -2572,8 +2572,7 @@ fil_op_log_parse_or_replay( switch (type) { case MLOG_FILE_DELETE: if (fil_tablespace_exists_in_mem(space_id)) { - dberr_t err = fil_delete_tablespace( - space_id, BUF_REMOVE_FLUSH_NO_WRITE); + dberr_t err = fil_delete_tablespace(space_id); ut_a(err == DB_SUCCESS); } @@ -2851,7 +2850,7 @@ fil_close_tablespace( completely and permanently. The flag stop_new_ops also prevents fil_flush() from being applied to this tablespace. */ - buf_LRU_flush_or_remove_pages(id, BUF_REMOVE_FLUSH_WRITE, trx); + buf_LRU_flush_or_remove_pages(id, trx); #endif mutex_enter(&fil_system->mutex); @@ -2878,18 +2877,13 @@ fil_close_tablespace( return(err); } -/*******************************************************************//** -Deletes a single-table tablespace. The tablespace must be cached in the -memory cache. +/** Delete a tablespace and associated .ibd file. +@param[in] id tablespace identifier +@param[in] drop_ahi whether to drop the adaptive hash index @return DB_SUCCESS or error */ UNIV_INTERN dberr_t -fil_delete_tablespace( -/*==================*/ - ulint id, /*!< in: space id */ - buf_remove_t buf_remove) /*!< in: specify the action to take - on the tables pages in the buffer - pool */ +fil_delete_tablespace(ulint id, bool drop_ahi) { char* path = 0; fil_space_t* space = 0; @@ -2945,7 +2939,7 @@ fil_delete_tablespace( To deal with potential read requests by checking the ::stop_new_ops flag in fil_io() */ - buf_LRU_flush_or_remove_pages(id, buf_remove, 0); + buf_LRU_flush_or_remove_pages(id, NULL, drop_ahi); #endif /* !UNIV_HOTBACKUP */ @@ -3056,7 +3050,7 @@ fil_discard_tablespace( { dberr_t err; - switch (err = fil_delete_tablespace(id, BUF_REMOVE_ALL_NO_WRITE)) { + switch (err = fil_delete_tablespace(id, true)) { case DB_SUCCESS: break; diff --git a/storage/xtradb/include/buf0buf.h b/storage/xtradb/include/buf0buf.h index 88ee042e8c3..7661ba1785d 100644 --- a/storage/xtradb/include/buf0buf.h +++ b/storage/xtradb/include/buf0buf.h @@ -58,6 +58,7 @@ Created 11/5/1995 Heikki Tuuri #define BUF_GET_POSSIBLY_FREED 16 /*!< Like BUF_GET, but do not mind if the file page has been freed. */ +#define BUF_EVICT_IF_IN_POOL 20 /*!< evict a clean block if found */ /* @} */ /** @name Modes for buf_page_get_known_nowait */ /* @{ */ diff --git a/storage/xtradb/include/buf0lru.h b/storage/xtradb/include/buf0lru.h index f056c6c4116..1bc11937fa1 100644 --- a/storage/xtradb/include/buf0lru.h +++ b/storage/xtradb/include/buf0lru.h @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -53,19 +54,14 @@ These are low-level functions /** Minimum LRU list length for which the LRU_old pointer is defined */ #define BUF_LRU_OLD_MIN_LEN 512 /* 8 megabytes of 16k pages */ -/******************************************************************//** -Flushes all dirty pages or removes all pages belonging -to a given tablespace. A PROBLEM: if readahead is being started, what -guarantees that it will not try to read in pages after this operation -has completed? */ +/** Empty the flush list for all pages belonging to a tablespace. +@param[in] id tablespace identifier +@param[in] trx transaction, for checking for user interrupt; + or NULL if nothing is to be written +@param[in] drop_ahi whether to drop the adaptive hash index */ UNIV_INTERN void -buf_LRU_flush_or_remove_pages( -/*==========================*/ - ulint id, /*!< in: space id */ - buf_remove_t buf_remove, /*!< in: remove or flush strategy */ - const trx_t* trx); /*!< to check if the operation must - be interrupted */ +buf_LRU_flush_or_remove_pages(ulint id, const trx_t* trx, bool drop_ahi=false); #if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG /********************************************************************//** diff --git a/storage/xtradb/include/buf0types.h b/storage/xtradb/include/buf0types.h index 4eb5ea18cef..6db3cb1238c 100644 --- a/storage/xtradb/include/buf0types.h +++ b/storage/xtradb/include/buf0types.h @@ -58,17 +58,6 @@ enum buf_flush_t { BUF_FLUSH_N_TYPES /*!< index of last element + 1 */ }; -/** Algorithm to remove the pages for a tablespace from the buffer pool. -See buf_LRU_flush_or_remove_pages(). */ -enum buf_remove_t { - BUF_REMOVE_ALL_NO_WRITE, /*!< Remove all pages from the buffer - pool, don't write or sync to disk */ - BUF_REMOVE_FLUSH_NO_WRITE, /*!< Remove only, from the flush list, - don't write or sync to disk */ - BUF_REMOVE_FLUSH_WRITE /*!< Flush dirty pages to disk only - don't remove from the buffer pool */ -}; - /** Flags for io_fix types */ enum buf_io_fix { BUF_IO_NONE = 0, /**< no pending I/O */ diff --git a/storage/xtradb/include/fil0fil.h b/storage/xtradb/include/fil0fil.h index a33cec65ed5..5fe2d20b4f0 100644 --- a/storage/xtradb/include/fil0fil.h +++ b/storage/xtradb/include/fil0fil.h @@ -849,18 +849,13 @@ fil_op_log_parse_or_replay( only be parsed but not replayed */ ulint log_flags); /*!< in: redo log flags (stored in the page number parameter) */ -/*******************************************************************//** -Deletes a single-table tablespace. The tablespace must be cached in the -memory cache. -@return TRUE if success */ +/** Delete a tablespace and associated .ibd file. +@param[in] id tablespace identifier +@param[in] drop_ahi whether to drop the adaptive hash index +@return DB_SUCCESS or error */ UNIV_INTERN dberr_t -fil_delete_tablespace( -/*==================*/ - ulint id, /*!< in: space id */ - buf_remove_t buf_remove); /*!< in: specify the action to take - on the tables pages in the buffer - pool */ +fil_delete_tablespace(ulint id, bool drop_ahi = false); /*******************************************************************//** Closes a single-table tablespace. The tablespace must be cached in the memory cache. Free all pages used by the tablespace. diff --git a/storage/xtradb/row/row0import.cc b/storage/xtradb/row/row0import.cc index 193eab35115..3efc2a30037 100644 --- a/storage/xtradb/row/row0import.cc +++ b/storage/xtradb/row/row0import.cc @@ -1602,18 +1602,16 @@ PageConverter::PageConverter( : AbstractCallback(trx), m_cfg(cfg), + m_index(cfg->m_indexes), + m_current_lsn(log_get_lsn()), m_page_zip_ptr(0), - m_heap(0) UNIV_NOTHROW + m_rec_iter(), + m_offsets_(), m_offsets(m_offsets_), + m_heap(0), + m_cluster_index(dict_table_get_first_index(cfg->m_table)) UNIV_NOTHROW { - m_index = m_cfg->m_indexes; - - m_current_lsn = log_get_lsn(); ut_a(m_current_lsn > 0); - - m_offsets = m_offsets_; rec_offs_init(m_offsets_); - - m_cluster_index = dict_table_get_first_index(m_cfg->m_table); } /** @@ -2104,7 +2102,7 @@ PageConverter::operator() ( we can work on them */ if ((err = update_page(block, page_type)) != DB_SUCCESS) { - return(err); + break; } /* Note: For compressed pages this function will write to the @@ -2141,9 +2139,15 @@ PageConverter::operator() ( "%s: Page %lu at offset " UINT64PF " looks corrupted.", m_filepath, (ulong) (offset / m_page_size), offset); - return(DB_CORRUPTION); + err = DB_CORRUPTION; } + /* If we already had and old page with matching number + in the buffer pool, evict it now, because + we no longer evict the pages on DISCARD TABLESPACE. */ + buf_page_get_gen(get_space_id(), get_zip_size(), block->page.offset, + RW_NO_LATCH, NULL, BUF_EVICT_IF_IN_POOL, + __FILE__, __LINE__, NULL); return(err); } @@ -3717,8 +3721,7 @@ row_import_for_mysql( The only dirty pages generated should be from the pessimistic purge of delete marked records that couldn't be purged in Phase I. */ - buf_LRU_flush_or_remove_pages( - prebuilt->table->space, BUF_REMOVE_FLUSH_WRITE, trx); + buf_LRU_flush_or_remove_pages(prebuilt->table->space, trx); if (trx_is_interrupted(trx)) { ib_logf(IB_LOG_LEVEL_INFO, "Phase III - Flush interrupted"); diff --git a/storage/xtradb/row/row0mysql.cc b/storage/xtradb/row/row0mysql.cc index 67eb1d7de94..3f79c3af6c8 100644 --- a/storage/xtradb/row/row0mysql.cc +++ b/storage/xtradb/row/row0mysql.cc @@ -2494,10 +2494,7 @@ err_exit: /* We already have .ibd file here. it should be deleted. */ if (table->space - && fil_delete_tablespace( - table->space, - BUF_REMOVE_FLUSH_NO_WRITE) - != DB_SUCCESS) { + && fil_delete_tablespace(table->space) != DB_SUCCESS) { ut_print_timestamp(stderr); fprintf(stderr, @@ -3132,9 +3129,6 @@ row_discard_tablespace( 4) FOREIGN KEY operations: if table->n_foreign_key_checks_running > 0, we do not allow the discard. */ - /* Play safe and remove all insert buffer entries, though we should - have removed them already when DISCARD TABLESPACE was called */ - ibuf_delete_for_discarded_space(table->space); table_id_t new_id; @@ -4516,9 +4510,7 @@ row_drop_table_for_mysql( fil_delete_file(filepath); - } else if (fil_delete_tablespace( - space_id, - BUF_REMOVE_FLUSH_NO_WRITE) + } else if (fil_delete_tablespace(space_id) != DB_SUCCESS) { fprintf(stderr, "InnoDB: We removed now the InnoDB" diff --git a/storage/xtradb/row/row0quiesce.cc b/storage/xtradb/row/row0quiesce.cc index 583fbe60fb3..6c4e6adb96c 100644 --- a/storage/xtradb/row/row0quiesce.cc +++ b/storage/xtradb/row/row0quiesce.cc @@ -1,6 +1,7 @@ /***************************************************************************** Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved. +Copyright (c) 2017, MariaDB Corporation. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software @@ -542,8 +543,7 @@ row_quiesce_table_start( } if (!trx_is_interrupted(trx)) { - buf_LRU_flush_or_remove_pages( - table->space, BUF_REMOVE_FLUSH_WRITE, trx); + buf_LRU_flush_or_remove_pages(table->space, trx); if (trx_is_interrupted(trx)) { From 40bae98c3d8b1a13d7499dbd518aab03f2921d6e Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Mon, 6 Nov 2017 18:58:04 +0000 Subject: [PATCH 21/35] MDEV-12108 Fix backup for Innodb tables with DATA DIRECTORY --- .../suite/mariabackup/data_directory.result | 13 +++++++++++ .../suite/mariabackup/data_directory.test | 23 +++++++++++++++++++ .../suite/mariabackup/partition_datadir.opt | 1 + .../mariabackup/partition_datadir.result | 22 ++++++++++++++++++ .../suite/mariabackup/partition_datadir.test | 22 ++++++++++++++++++ storage/xtradb/fil/fil0fil.cc | 2 +- 6 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 mysql-test/suite/mariabackup/data_directory.result create mode 100644 mysql-test/suite/mariabackup/data_directory.test create mode 100644 mysql-test/suite/mariabackup/partition_datadir.opt create mode 100644 mysql-test/suite/mariabackup/partition_datadir.result create mode 100644 mysql-test/suite/mariabackup/partition_datadir.test diff --git a/mysql-test/suite/mariabackup/data_directory.result b/mysql-test/suite/mariabackup/data_directory.result new file mode 100644 index 00000000000..e7201918cbd --- /dev/null +++ b/mysql-test/suite/mariabackup/data_directory.result @@ -0,0 +1,13 @@ +CREATE TABLE t(a INT) ENGINE=InnoDB DATA DIRECTORY='table_data_dir'; +INSERT INTO t VALUES(1); +# xtrabackup backup +# xtrabackup prepare +DROP TABLE t; +# shutdown server +# remove datadir +# xtrabackup move back +# restart server +SELECT * FROM t; +a +1 +DROP TABLE t; diff --git a/mysql-test/suite/mariabackup/data_directory.test b/mysql-test/suite/mariabackup/data_directory.test new file mode 100644 index 00000000000..50789a34c78 --- /dev/null +++ b/mysql-test/suite/mariabackup/data_directory.test @@ -0,0 +1,23 @@ +let $table_data_dir=$MYSQLTEST_VARDIR/ddir; +mkdir $table_data_dir; +--replace_result $table_data_dir table_data_dir +EVAL CREATE TABLE t(a INT) ENGINE=InnoDB DATA DIRECTORY='$table_data_dir'; +INSERT INTO t VALUES(1); +echo # xtrabackup backup; +let $targetdir=$MYSQLTEST_VARDIR/tmp/backup; +--disable_result_log +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir; +--enable_result_log +--source include/shutdown_mysqld.inc +echo # xtrabackup prepare; +--disable_result_log +exec $XTRABACKUP --prepare --target-dir=$targetdir; +--source include/start_mysqld.inc +DROP TABLE t; +rmdir $table_data_dir; +-- source include/restart_and_restore.inc +--enable_result_log +SELECT * FROM t; +DROP TABLE t; +rmdir $targetdir; +rmdir $table_data_dir; diff --git a/mysql-test/suite/mariabackup/partition_datadir.opt b/mysql-test/suite/mariabackup/partition_datadir.opt new file mode 100644 index 00000000000..8a3240370eb --- /dev/null +++ b/mysql-test/suite/mariabackup/partition_datadir.opt @@ -0,0 +1 @@ +--partition \ No newline at end of file diff --git a/mysql-test/suite/mariabackup/partition_datadir.result b/mysql-test/suite/mariabackup/partition_datadir.result new file mode 100644 index 00000000000..b5113156068 --- /dev/null +++ b/mysql-test/suite/mariabackup/partition_datadir.result @@ -0,0 +1,22 @@ +CREATE TABLE t(i int) +ENGINE=InnoDB +PARTITION BY RANGE (i) +(PARTITION p0 VALUES LESS THAN (100), +PARTITION P1 VALUES LESS THAN (200), +PARTITION p2 VALUES LESS THAN (300) DATA DIRECTORY = "D:/work/10.1/xxx/mysql-test/var/partitdata", +PARTITION p3 VALUES LESS THAN (400) DATA DIRECTORY = "D:/work/10.1/xxx/mysql-test/var/partitdata", +PARTITION p4 VALUES LESS THAN MAXVALUE); +INSERT INTO t VALUES (1), (101), (201), (301), (401); +DROP TABLE t; +# shutdown server +# remove datadir +# xtrabackup move back +# restart server +SELECT * FROM t; +i +1 +101 +201 +301 +401 +DROP TABLE t; diff --git a/mysql-test/suite/mariabackup/partition_datadir.test b/mysql-test/suite/mariabackup/partition_datadir.test new file mode 100644 index 00000000000..4c814184b0b --- /dev/null +++ b/mysql-test/suite/mariabackup/partition_datadir.test @@ -0,0 +1,22 @@ +let $targetdir=$MYSQLTEST_VARDIR/backup; +mkdir $targetdir; +mkdir $MYSQLTEST_VARDIR/partitdata; +eval CREATE TABLE t(i int) +ENGINE=InnoDB +PARTITION BY RANGE (i) +(PARTITION p0 VALUES LESS THAN (100), + PARTITION P1 VALUES LESS THAN (200), + PARTITION p2 VALUES LESS THAN (300) DATA DIRECTORY = "$MYSQLTEST_VARDIR/partitdata", + PARTITION p3 VALUES LESS THAN (400) DATA DIRECTORY = "$MYSQLTEST_VARDIR/partitdata", + PARTITION p4 VALUES LESS THAN MAXVALUE); +INSERT INTO t VALUES (1), (101), (201), (301), (401); +exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir; +exec $XTRABACKUP --prepare --target-dir=$targetdir; +DROP TABLE t; +rmdir $MYSQLTEST_VARDIR/partitdata; +--source include/restart_and_restore.inc +--enable_result_log +SELECT * FROM t; +DROP TABLE t; +rmdir $targetdir; +rmdir $MYSQLTEST_VARDIR/partitdata; diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc index b9e8db22726..00f2c44637e 100644 --- a/storage/xtradb/fil/fil0fil.cc +++ b/storage/xtradb/fil/fil0fil.cc @@ -4857,7 +4857,7 @@ fil_load_single_table_tablespace( /* Check for a link file which locates a remote tablespace. */ - remote.success = fil_open_linked_file( + remote.success = (IS_XTRABACKUP() && !srv_backup_mode) ? 0 : fil_open_linked_file( tablename, &remote.filepath, &remote.file, FALSE); /* Read the first page of the remote tablespace */ From 8128ae48eff6029d29d6c1c509f04994614a0571 Mon Sep 17 00:00:00 2001 From: Igor Babaev Date: Mon, 6 Nov 2017 12:18:36 -0800 Subject: [PATCH 22/35] Test case for mdev-13753 CTE is not visible during view creation The bug was fixed by the patch for the bug mdev-13780. --- mysql-test/r/cte_nonrecursive.result | 19 +++++++++++++++++++ mysql-test/t/cte_nonrecursive.test | 19 +++++++++++++++++++ 2 files changed, 38 insertions(+) diff --git a/mysql-test/r/cte_nonrecursive.result b/mysql-test/r/cte_nonrecursive.result index 36982d3673b..ebe1aae1e8f 100644 --- a/mysql-test/r/cte_nonrecursive.result +++ b/mysql-test/r/cte_nonrecursive.result @@ -1128,3 +1128,22 @@ NULL UNION RESULT ALL NULL NULL NULL NULL NULL NULL Warnings: Note 1003 with cte_e as (with cte_o as (with cte_i as (select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` < 7)select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > 1)select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` < 3 and `test`.`t1`.`a` > 1 and `test`.`t1`.`a` < 7 and `test`.`t1`.`a` > 1 union select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > 4 and `test`.`t1`.`a` > 1 and `test`.`t1`.`a` < 7 and `test`.`t1`.`a` > 1)select `cte_e1`.`a` AS `a` from `cte_e` `cte_e1` where `cte_e1`.`a` > 1 union select `cte_e2`.`a` AS `a` from `cte_e` `cte_e2` drop table t1; +# +# MDEV-13753: embedded CTE in a VIEW created in prepared statement +# +SET @sql_query = " + CREATE OR REPLACE VIEW cte_test AS + WITH cte1 AS ( SELECT 1 as a from dual ) + , cte2 AS ( SELECT * FROM cte1 ) + SELECT * FROM cte2; +"; +PREPARE stmt FROM @sql_query; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; +SHOW CREATE VIEW cte_test; +View Create View character_set_client collation_connection +cte_test CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `cte_test` AS with cte1 as (select 1 AS `a`), cte2 as (select `cte1`.`a` AS `a` from `cte1`)select `cte2`.`a` AS `a` from `cte2` latin1 latin1_swedish_ci +SELECT * FROM cte_test; +a +1 +DROP VIEW cte_test; diff --git a/mysql-test/t/cte_nonrecursive.test b/mysql-test/t/cte_nonrecursive.test index c9639f50a19..742e8f6e4d7 100644 --- a/mysql-test/t/cte_nonrecursive.test +++ b/mysql-test/t/cte_nonrecursive.test @@ -771,3 +771,22 @@ eval $q; eval explain extended $q; drop table t1; + +--echo # +--echo # MDEV-13753: embedded CTE in a VIEW created in prepared statement +--echo # + +SET @sql_query = " + CREATE OR REPLACE VIEW cte_test AS + WITH cte1 AS ( SELECT 1 as a from dual ) + , cte2 AS ( SELECT * FROM cte1 ) + SELECT * FROM cte2; +"; +PREPARE stmt FROM @sql_query; +EXECUTE stmt; +DEALLOCATE PREPARE stmt; + +SHOW CREATE VIEW cte_test; +SELECT * FROM cte_test; + +DROP VIEW cte_test; From f830314fd5023b5d631d522fc3e263b650d5ccbc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 6 Nov 2017 22:35:03 +0200 Subject: [PATCH 23/35] Remove dead code for non-debug builds --- storage/innobase/lock/lock0lock.cc | 2 ++ storage/xtradb/lock/lock0lock.cc | 2 ++ 2 files changed, 4 insertions(+) diff --git a/storage/innobase/lock/lock0lock.cc b/storage/innobase/lock/lock0lock.cc index 47f48df27c5..6b2c309e432 100644 --- a/storage/innobase/lock/lock0lock.cc +++ b/storage/innobase/lock/lock0lock.cc @@ -2351,6 +2351,7 @@ lock_rec_insert_by_trx_age( return DB_SUCCESS; } +#ifdef UNIV_DEBUG static bool lock_queue_validate( @@ -2384,6 +2385,7 @@ lock_queue_validate( } return true; } +#endif /* UNIV_DEBUG */ /*********************************************************************//** Enqueues a waiting request for a lock which cannot be granted immediately. diff --git a/storage/xtradb/lock/lock0lock.cc b/storage/xtradb/lock/lock0lock.cc index 8759cea9e6d..ddaeff69f10 100644 --- a/storage/xtradb/lock/lock0lock.cc +++ b/storage/xtradb/lock/lock0lock.cc @@ -2141,6 +2141,7 @@ lock_rec_insert_by_trx_age( return DB_SUCCESS; } +#ifdef UNIV_DEBUG static bool lock_queue_validate( @@ -2174,6 +2175,7 @@ lock_queue_validate( } return true; } +#endif /* UNIV_DEBUG */ static void From 120f848f75ccbfb4f7aa1db3b0ac5dca8028a7d9 Mon Sep 17 00:00:00 2001 From: Vladislav Vaintroub Date: Mon, 6 Nov 2017 21:00:06 +0000 Subject: [PATCH 24/35] Fix test case --- mysql-test/suite/mariabackup/partition_datadir.result | 4 ++-- mysql-test/suite/mariabackup/partition_datadir.test | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/mysql-test/suite/mariabackup/partition_datadir.result b/mysql-test/suite/mariabackup/partition_datadir.result index b5113156068..3fc5fe30907 100644 --- a/mysql-test/suite/mariabackup/partition_datadir.result +++ b/mysql-test/suite/mariabackup/partition_datadir.result @@ -3,8 +3,8 @@ ENGINE=InnoDB PARTITION BY RANGE (i) (PARTITION p0 VALUES LESS THAN (100), PARTITION P1 VALUES LESS THAN (200), -PARTITION p2 VALUES LESS THAN (300) DATA DIRECTORY = "D:/work/10.1/xxx/mysql-test/var/partitdata", -PARTITION p3 VALUES LESS THAN (400) DATA DIRECTORY = "D:/work/10.1/xxx/mysql-test/var/partitdata", +PARTITION p2 VALUES LESS THAN (300) DATA DIRECTORY = 'MYSQLTEST_VARDIR/partitdata', +PARTITION p3 VALUES LESS THAN (400) DATA DIRECTORY = 'MYSQLTEST_VARDIR/partitdata', PARTITION p4 VALUES LESS THAN MAXVALUE); INSERT INTO t VALUES (1), (101), (201), (301), (401); DROP TABLE t; diff --git a/mysql-test/suite/mariabackup/partition_datadir.test b/mysql-test/suite/mariabackup/partition_datadir.test index 4c814184b0b..882b0111267 100644 --- a/mysql-test/suite/mariabackup/partition_datadir.test +++ b/mysql-test/suite/mariabackup/partition_datadir.test @@ -1,13 +1,15 @@ let $targetdir=$MYSQLTEST_VARDIR/backup; mkdir $targetdir; mkdir $MYSQLTEST_VARDIR/partitdata; + +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR eval CREATE TABLE t(i int) ENGINE=InnoDB PARTITION BY RANGE (i) (PARTITION p0 VALUES LESS THAN (100), PARTITION P1 VALUES LESS THAN (200), - PARTITION p2 VALUES LESS THAN (300) DATA DIRECTORY = "$MYSQLTEST_VARDIR/partitdata", - PARTITION p3 VALUES LESS THAN (400) DATA DIRECTORY = "$MYSQLTEST_VARDIR/partitdata", + PARTITION p2 VALUES LESS THAN (300) DATA DIRECTORY = '$MYSQLTEST_VARDIR/partitdata', + PARTITION p3 VALUES LESS THAN (400) DATA DIRECTORY = '$MYSQLTEST_VARDIR/partitdata', PARTITION p4 VALUES LESS THAN MAXVALUE); INSERT INTO t VALUES (1), (101), (201), (301), (401); exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir; From c09f22bab535bccc1687a3b06e03dbaf4fc3ae46 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Tue, 7 Nov 2017 12:57:11 +0400 Subject: [PATCH 25/35] MDEV-8867 Wrong field type or metadata for COALESCE(bit_column, 1) This problem was earlier fixed by the patch for MDEV-8910. Adding tests only. --- mysql-test/r/type_bit.result | 24 ++++++++++++++++++++++++ mysql-test/t/type_bit.test | 19 +++++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/mysql-test/r/type_bit.result b/mysql-test/r/type_bit.result index 639a97be27b..4136eb4dff7 100644 --- a/mysql-test/r/type_bit.result +++ b/mysql-test/r/type_bit.result @@ -806,3 +806,27 @@ SUM(a) NULL DROP TABLE t1; End of 5.1 tests +# +# Start of 10.1 tests +# +# +# MDEV-8867 Wrong field type or metadata for COALESCE(bit_column, 1) +# +CREATE TABLE t1 (val bit(1)); +INSERT INTO t1 VALUES (0); +CREATE TABLE t2 AS SELECT COALESCE(val, 1) AS c FROM t1; +SELECT * FROM t2; +c +0 +SHOW CREATE TABLE t2; +Table Create Table +t2 CREATE TABLE `t2` ( + `c` decimal(1,0) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t2; +SELECT COALESCE(val, 1) FROM t1; +Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr +def COALESCE(val, 1) 246 2 1 Y 32896 0 63 +COALESCE(val, 1) +0 +DROP TABLE t1; diff --git a/mysql-test/t/type_bit.test b/mysql-test/t/type_bit.test index 2ca608e76ff..01a610999bd 100644 --- a/mysql-test/t/type_bit.test +++ b/mysql-test/t/type_bit.test @@ -439,3 +439,22 @@ SELECT SUM(a) FROM t1 GROUP BY c, b, a; DROP TABLE t1; --echo End of 5.1 tests + +--echo # +--echo # Start of 10.1 tests +--echo # + +--echo # +--echo # MDEV-8867 Wrong field type or metadata for COALESCE(bit_column, 1) +--echo # + +CREATE TABLE t1 (val bit(1)); +INSERT INTO t1 VALUES (0); +CREATE TABLE t2 AS SELECT COALESCE(val, 1) AS c FROM t1; +SELECT * FROM t2; +SHOW CREATE TABLE t2; +DROP TABLE t2; +--enable_metadata +SELECT COALESCE(val, 1) FROM t1; +--disable_metadata +DROP TABLE t1; From fff7fc500b3ab0ead49685cbd1310d5b2dfa0972 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Tue, 7 Nov 2017 15:03:58 +0400 Subject: [PATCH 26/35] MDEV-10817 CAST(MAX(DATE'2001-01-01') AS TIME) returns a wrong result --- mysql-test/r/type_time.result | 14 ++++++++++++++ mysql-test/t/type_time.test | 11 +++++++++++ sql/item_func.h | 7 +++++++ sql/item_sum.cc | 12 ++++++++++++ sql/item_sum.h | 1 + 5 files changed, 45 insertions(+) diff --git a/mysql-test/r/type_time.result b/mysql-test/r/type_time.result index 2aabd98229d..8b80177104d 100644 --- a/mysql-test/r/type_time.result +++ b/mysql-test/r/type_time.result @@ -1245,5 +1245,19 @@ a b c 2070 00:00:00 00:00:00 DROP TABLE t1,t2; # +# MDEV-10817 CAST(MAX(DATE'2001-01-01') AS TIME) returns a wrong result +# +SELECT CAST(DATE'2001-01-01' AS TIME); +CAST(DATE'2001-01-01' AS TIME) +00:00:00 +SELECT CAST(MAX(DATE'2001-01-01') AS TIME); +CAST(MAX(DATE'2001-01-01') AS TIME) +00:00:00 +CREATE FUNCTION f1() RETURNS DATE RETURN DATE'2001-01-01'; +SELECT CAST(f1() AS TIME); +CAST(f1() AS TIME) +00:00:00 +DROP FUNCTION f1; +# # End of 10.2 tests # diff --git a/mysql-test/t/type_time.test b/mysql-test/t/type_time.test index fb96597e296..6841af41e11 100644 --- a/mysql-test/t/type_time.test +++ b/mysql-test/t/type_time.test @@ -746,6 +746,17 @@ SELECT * FROM t1; DROP TABLE t1,t2; +--echo # +--echo # MDEV-10817 CAST(MAX(DATE'2001-01-01') AS TIME) returns a wrong result +--echo # + +SELECT CAST(DATE'2001-01-01' AS TIME); +SELECT CAST(MAX(DATE'2001-01-01') AS TIME); +CREATE FUNCTION f1() RETURNS DATE RETURN DATE'2001-01-01'; +SELECT CAST(f1() AS TIME); +DROP FUNCTION f1; + + --echo # --echo # End of 10.2 tests --echo # diff --git a/sql/item_func.h b/sql/item_func.h index bee6dc4e524..ef703456818 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -2367,6 +2367,13 @@ public: return sp_result_field->val_decimal(dec_buf); } + bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) + { + if (execute()) + return true; + return sp_result_field->get_date(ltime, fuzzydate); + } + String *val_str(String *str) { String buf; diff --git a/sql/item_sum.cc b/sql/item_sum.cc index df09beeb274..20237435ba6 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -2065,6 +2065,18 @@ void Item_sum_hybrid::clear() null_value= 1; } +bool +Item_sum_hybrid::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) +{ + DBUG_ASSERT(fixed == 1); + if (null_value) + return 0; + bool retval= value->get_date(ltime, fuzzydate); + if ((null_value= value->null_value)) + DBUG_ASSERT(retval == true); + return retval; +} + double Item_sum_hybrid::val_real() { DBUG_ASSERT(fixed == 1); diff --git a/sql/item_sum.h b/sql/item_sum.h index 0c655ded153..5c446e5779d 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -1037,6 +1037,7 @@ protected: double val_real(); longlong val_int(); my_decimal *val_decimal(my_decimal *); + bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate); void reset_field(); String *val_str(String *); bool keep_field_type(void) const { return 1; } From 28c3459aa7c5db94319970dad3f201e7fb3b0923 Mon Sep 17 00:00:00 2001 From: Vesa Pentti Date: Tue, 7 Nov 2017 13:31:55 +0000 Subject: [PATCH 27/35] MDEV-10728 test excluded from embedded tests --- mysql-test/t/delimiter_command_case_sensitivity.test | 2 ++ 1 file changed, 2 insertions(+) diff --git a/mysql-test/t/delimiter_command_case_sensitivity.test b/mysql-test/t/delimiter_command_case_sensitivity.test index 2b06a35c723..11d1cf75aa0 100644 --- a/mysql-test/t/delimiter_command_case_sensitivity.test +++ b/mysql-test/t/delimiter_command_case_sensitivity.test @@ -1,2 +1,4 @@ +source include/not_embedded.inc; + # MDEV-10728 --exec $MYSQL --default-character-set=binary < "t/delimiter_case_mdev_10728.sql" From ca695888e00a4bdace1bc2143d91a0a871f39a6b Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Tue, 7 Nov 2017 21:57:42 +0400 Subject: [PATCH 28/35] MDEV-14116 INET6_NTOA output is set as null to varchar(39) variable --- mysql-test/r/func_misc.result | 14 ++++++++++++++ mysql-test/t/func_misc.test | 16 ++++++++++++++++ sql/item_inetfunc.cc | 7 ++++--- sql/item_inetfunc.h | 6 +++--- 4 files changed, 37 insertions(+), 6 deletions(-) diff --git a/mysql-test/r/func_misc.result b/mysql-test/r/func_misc.result index e44335f1b51..d54a70cab45 100644 --- a/mysql-test/r/func_misc.result +++ b/mysql-test/r/func_misc.result @@ -1407,3 +1407,17 @@ SELECT CONCAT(NAME_CONST('name',15),'오'); CONCAT(NAME_CONST('name',15),'오') 15오 SET NAMES latin1; +# +# MDEV-14116 INET6_NTOA output is set as null to varchar(39) variable +# +CREATE PROCEDURE p1() +BEGIN +DECLARE ip_full_addr varchar(39) DEFAULT ""; +SELECT INET6_NTOA(UNHEX('20000000000000000000000000000000')) into ip_full_addr; +SELECT ip_full_addr; +END; +$$ +CALL p1(); +ip_full_addr +2000:: +DROP PROCEDURE p1; diff --git a/mysql-test/t/func_misc.test b/mysql-test/t/func_misc.test index ebd5675e031..dc7202268d6 100644 --- a/mysql-test/t/func_misc.test +++ b/mysql-test/t/func_misc.test @@ -1091,3 +1091,19 @@ SELECT COERCIBILITY(NAME_CONST('name',TIME'00:00:00')); SELECT COERCIBILITY(NAME_CONST('name',15)); SELECT CONCAT(NAME_CONST('name',15),'오'); SET NAMES latin1; + +--echo # +--echo # MDEV-14116 INET6_NTOA output is set as null to varchar(39) variable +--echo # + +DELIMITER $$; +CREATE PROCEDURE p1() +BEGIN + DECLARE ip_full_addr varchar(39) DEFAULT ""; + SELECT INET6_NTOA(UNHEX('20000000000000000000000000000000')) into ip_full_addr; + SELECT ip_full_addr; +END; +$$ +DELIMITER ;$$ +CALL p1(); +DROP PROCEDURE p1; diff --git a/sql/item_inetfunc.cc b/sql/item_inetfunc.cc index 6a09747fa1a..4c4dfa4497b 100644 --- a/sql/item_inetfunc.cc +++ b/sql/item_inetfunc.cc @@ -181,7 +181,8 @@ String *Item_func_inet_str_base::val_str_ascii(String *buffer) return NULL; } - String *arg_str= args[0]->val_str(buffer); + StringBuffer tmp; + String *arg_str= args[0]->val_str(&tmp); if (!arg_str) // Out-of memory happened. The error has been reported. { // Or: the underlying field is NULL null_value= true; @@ -679,7 +680,7 @@ static void ipv6_to_str(const in6_addr *ipv6, char *str) @retval true The string has been converted sucessfully. */ -bool Item_func_inet6_aton::calc_value(String *arg, String *buffer) +bool Item_func_inet6_aton::calc_value(const String *arg, String *buffer) { // ipv4-string -> varbinary(4) // ipv6-string -> varbinary(16) @@ -719,7 +720,7 @@ bool Item_func_inet6_aton::calc_value(String *arg, String *buffer) @retval true The string has been converted sucessfully. */ -bool Item_func_inet6_ntoa::calc_value(String *arg, String *buffer) +bool Item_func_inet6_ntoa::calc_value(const String *arg, String *buffer) { if (arg->charset() != &my_charset_bin) return false; diff --git a/sql/item_inetfunc.h b/sql/item_inetfunc.h index 3a85d367ff1..d6fcc07a1c6 100644 --- a/sql/item_inetfunc.h +++ b/sql/item_inetfunc.h @@ -99,7 +99,7 @@ public: virtual String *val_str_ascii(String *buffer); protected: - virtual bool calc_value(String *arg, String *buffer) = 0; + virtual bool calc_value(const String *arg, String *buffer) = 0; }; @@ -126,7 +126,7 @@ public: } protected: - virtual bool calc_value(String *arg, String *buffer); + virtual bool calc_value(const String *arg, String *buffer); }; @@ -158,7 +158,7 @@ public: } protected: - virtual bool calc_value(String *arg, String *buffer); + virtual bool calc_value(const String *arg, String *buffer); }; From d04c4b3905980a6a3eaef39e6f6c24e1b64db1a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 7 Nov 2017 10:57:36 +0200 Subject: [PATCH 29/35] MDEV-14304 Unnecessary conditions in buf_page_get_gen() Ever since MDEV-10813 cleaned up InnoDB use of atomic memory operations and made buf_block_fix() an atomic operation, some conditions around buf_block_fix() have been unnecessary. --- storage/innobase/buf/buf0buf.cc | 33 ++------------------------------- 1 file changed, 2 insertions(+), 31 deletions(-) diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc index 5ce8b1d584d..684f3fe0b36 100644 --- a/storage/innobase/buf/buf0buf.cc +++ b/storage/innobase/buf/buf0buf.cc @@ -4263,24 +4263,7 @@ loop: sure that no state change takes place. */ fix_block = block; - if (fsp_is_system_temporary(page_id.space())) { - /* For temporary tablespace, - the mutex is being used for - synchronization between user - thread and flush thread, - instead of block->lock. See - buf_flush_page() for the flush - thread counterpart. */ - - BPageMutex* fix_mutex - = buf_page_get_mutex( - &fix_block->page); - mutex_enter(fix_mutex); - buf_block_fix(fix_block); - mutex_exit(fix_mutex); - } else { - buf_block_fix(fix_block); - } + buf_block_fix(fix_block); /* Now safe to release page_hash mutex */ rw_lock_x_unlock(hash_lock); @@ -4371,19 +4354,7 @@ loop: fix_block = block; } - if (fsp_is_system_temporary(page_id.space())) { - /* For temporary tablespace, the mutex is being used - for synchronization between user thread and flush - thread, instead of block->lock. See buf_flush_page() - for the flush thread counterpart. */ - BPageMutex* fix_mutex = buf_page_get_mutex( - &fix_block->page); - mutex_enter(fix_mutex); - buf_block_fix(fix_block); - mutex_exit(fix_mutex); - } else { - buf_block_fix(fix_block); - } + buf_block_fix(fix_block); /* Now safe to release page_hash mutex */ rw_lock_s_unlock(hash_lock); From a4feb04ace2e7759aee4dd74b71cbb1151b1886f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Tue, 7 Nov 2017 15:34:04 +0200 Subject: [PATCH 30/35] =?UTF-8?q?MDEV-14310=20ALTER=20TABLE=E2=80=A6ADD=20?= =?UTF-8?q?INDEX=20may=20corrupt=20the=20InnoDB=20system=20tablespace?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit FlushObserver::flush(): Never discard unwritten changes. We do not want to risk corrupting the system tablespace or .ibd files that are not part of a table-rebuilding ALTER. --- storage/innobase/buf/buf0flu.cc | 25 +++++++++---------------- 1 file changed, 9 insertions(+), 16 deletions(-) diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc index e7a2a844330..8fa9c0f3d20 100644 --- a/storage/innobase/buf/buf0flu.cc +++ b/storage/innobase/buf/buf0flu.cc @@ -3821,24 +3821,17 @@ FlushObserver::notify_remove( void FlushObserver::flush() { - buf_remove_t buf_remove; - - if (m_interrupted) { - buf_remove = BUF_REMOVE_FLUSH_NO_WRITE; - } else { - buf_remove = BUF_REMOVE_FLUSH_WRITE; - - if (m_stage != NULL) { - ulint pages_to_flush = - buf_flush_get_dirty_pages_count( - m_space_id, this); - - m_stage->begin_phase_flush(pages_to_flush); - } + if (!m_interrupted && m_stage) { + m_stage->begin_phase_flush(buf_flush_get_dirty_pages_count( + m_space_id, this)); } - /* Flush or remove dirty pages. */ - buf_LRU_flush_or_remove_pages(m_space_id, buf_remove, m_trx); + /* MDEV-14317 FIXME: Discard all changes to only those pages + that will be freed by the clean-up of the ALTER operation. + (Maybe, instead of buf_pool->flush_list, use a dedicated list + for pages on which redo logging has been disabled.) */ + buf_LRU_flush_or_remove_pages( + m_space_id, BUF_REMOVE_FLUSH_WRITE, m_trx); /* Wait for all dirty pages were flushed. */ for (ulint i = 0; i < srv_buf_pool_instances; i++) { From 644ffdeb9290a5fc861ecd286a5af4388b4339ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Wed, 8 Nov 2017 09:26:27 +0200 Subject: [PATCH 31/35] Fix integer type mismatch in WSREP debug output --- storage/innobase/handler/ha_innodb.cc | 7 ++++--- storage/xtradb/handler/ha_innodb.cc | 7 ++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 9f8f4a78d6b..9a7258bc924 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -10418,7 +10418,7 @@ wsrep_append_foreign_key( shared ? WSREP_KEY_SHARED : WSREP_KEY_EXCLUSIVE, copy); if (rcode) { - DBUG_PRINT("wsrep", ("row key failed: %lu", rcode)); + DBUG_PRINT("wsrep", ("row key failed: %zu", rcode)); WSREP_ERROR("Appending cascaded fk row key failed: %s, %lu", (wsrep_thd_query(thd)) ? wsrep_thd_query(thd) : "void", rcode); @@ -18709,7 +18709,7 @@ wsrep_innobase_kill_one_trx( wsrep_thd_awake(thd, signal); } else { /* abort currently executing query */ - DBUG_PRINT("wsrep",("sending KILL_QUERY to: %ld", + DBUG_PRINT("wsrep",("sending KILL_QUERY to: %lu", thd_get_thread_id(thd))); WSREP_DEBUG("kill query for: %ld", thd_get_thread_id(thd)); @@ -18840,7 +18840,8 @@ wsrep_fake_trx_id( mutex_enter(&trx_sys->mutex); trx_id_t trx_id = trx_sys_get_new_trx_id(); mutex_exit(&trx_sys->mutex); - WSREP_DEBUG("innodb fake trx id: %lu thd: %s", trx_id, wsrep_thd_query(thd)); + WSREP_DEBUG("innodb fake trx id: " TRX_ID_FMT " thd: %s", + trx_id, wsrep_thd_query(thd)); wsrep_ws_handle_for_trx(wsrep_thd_ws_handle(thd), trx_id); } diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc index f812343711c..28e3b23b667 100644 --- a/storage/xtradb/handler/ha_innodb.cc +++ b/storage/xtradb/handler/ha_innodb.cc @@ -10984,7 +10984,7 @@ wsrep_append_foreign_key( shared ? WSREP_KEY_SHARED : WSREP_KEY_EXCLUSIVE, copy); if (rcode) { - DBUG_PRINT("wsrep", ("row key failed: %lu", rcode)); + DBUG_PRINT("wsrep", ("row key failed: %zu", rcode)); WSREP_ERROR("Appending cascaded fk row key failed: %s, %lu", (wsrep_thd_query(thd)) ? wsrep_thd_query(thd) : "void", rcode); @@ -19751,7 +19751,7 @@ wsrep_innobase_kill_one_trx( wsrep_thd_awake(thd, signal); } else { /* abort currently executing query */ - DBUG_PRINT("wsrep",("sending KILL_QUERY to: %ld", + DBUG_PRINT("wsrep",("sending KILL_QUERY to: %lu", thd_get_thread_id(thd))); WSREP_DEBUG("kill query for: %ld", thd_get_thread_id(thd)); @@ -19878,7 +19878,8 @@ wsrep_fake_trx_id( mutex_enter(&trx_sys->mutex); trx_id_t trx_id = trx_sys_get_new_trx_id(); mutex_exit(&trx_sys->mutex); - WSREP_DEBUG("innodb fake trx id: %lu thd: %s", trx_id, wsrep_thd_query(thd)); + WSREP_DEBUG("innodb fake trx id: " TRX_ID_FMT " thd: %s", + trx_id, wsrep_thd_query(thd)); wsrep_ws_handle_for_trx(wsrep_thd_ws_handle(thd), trx_id); } From e6ab6c42522bd7b156f77f53969100a2b3893b38 Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Wed, 8 Nov 2017 15:00:26 +0400 Subject: [PATCH 32/35] MDEV-14320 main.subselect failed in buildbot, results mismatch There was a problem in the recent patch for MDEV-10817: get_date() must "return true" on null_value rather than "return 0" (forgot to fix Item_sum_hybrid::get_date() after copying and pasting from Item_sum_hybrid::val_str()). --- sql/item_sum.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 20237435ba6..c291e834e81 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -2070,7 +2070,7 @@ Item_sum_hybrid::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate) { DBUG_ASSERT(fixed == 1); if (null_value) - return 0; + return true; bool retval= value->get_date(ltime, fuzzydate); if ((null_value= value->null_value)) DBUG_ASSERT(retval == true); From c2c93fc6e460fd32b6ef179686c2b3b2045f75eb Mon Sep 17 00:00:00 2001 From: Oleksandr Byelkin Date: Wed, 8 Nov 2017 15:47:49 +0100 Subject: [PATCH 33/35] MDEV-14164: Unknown column error when adding aggregate to function in oracle style procedure FOR loop Make differentiation between pullout for merge and pulout of outer field during exists2in transformation. In last case the field was outer and so we can safely start from name resolution context of the SELECT where it was pulled. Old behavior lead to inconsistence between list of tables and outer name resolution context (which skips one SELECT for merge purposes) which creates problem vor name resolution. --- mysql-test/r/subselect_exists2in.result | 37 +++++++++++++++++++++++ mysql-test/t/subselect_exists2in.test | 40 +++++++++++++++++++++++++ sql/item.cc | 26 ++++++++++++---- sql/item.h | 14 +++++---- sql/item_cmpfunc.cc | 25 +++++++++------- sql/item_cmpfunc.h | 10 +++---- sql/item_func.cc | 5 ++-- sql/item_func.h | 2 +- sql/item_row.cc | 5 ++-- sql/item_row.h | 2 +- sql/item_subselect.cc | 15 ++++++---- sql/item_subselect.h | 4 +-- sql/opt_subselect.cc | 7 +++-- sql/sql_derived.cc | 6 ++-- 14 files changed, 153 insertions(+), 45 deletions(-) diff --git a/mysql-test/r/subselect_exists2in.result b/mysql-test/r/subselect_exists2in.result index 5deb2dfa9c5..d47e446fe8f 100644 --- a/mysql-test/r/subselect_exists2in.result +++ b/mysql-test/r/subselect_exists2in.result @@ -934,5 +934,42 @@ f2 foo set optimizer_switch= @optimizer_switch_save; DROP TABLE t1; +# +# MDEV-14164: Unknown column error when adding aggregate to function +# in oracle style procedure FOR loop +# +CREATE TABLE t1(id INT, val INT); +CREATE PROCEDURE p1() +BEGIN +DECLARE cur1 CURSOR FOR SELECT * FROM ( +SELECT DISTINCT id FROM t1) a +WHERE NOT EXISTS (SELECT * FROM ( SELECT id FROM t1) b +WHERE a.id=b.id); +OPEN cur1; +CLOSE cur1; +OPEN cur1; +CLOSE cur1; +END; +// +CALL p1(); +DROP PROCEDURE p1; +DROP TABLE t1; +CREATE TABLE t1(id INT, val INT); +CREATE PROCEDURE p1() +BEGIN +SELECT * FROM (SELECT DISTINCT id FROM t1) a +WHERE NOT a.id IN (SELECT b.id FROM t1 b); +SELECT * FROM (SELECT DISTINCT id FROM t1) a +WHERE NOT EXISTS (SELECT * FROM t1 b WHERE a.id=b.id); +END; +// +CALL p1(); +id +id +CALL p1(); +id +id +DROP PROCEDURE p1; +DROP TABLE t1; # End of 10.0 tests set optimizer_switch=default; diff --git a/mysql-test/t/subselect_exists2in.test b/mysql-test/t/subselect_exists2in.test index a4fdbe5c50b..5a8ddb3612f 100644 --- a/mysql-test/t/subselect_exists2in.test +++ b/mysql-test/t/subselect_exists2in.test @@ -786,6 +786,46 @@ set optimizer_switch= @optimizer_switch_save; DROP TABLE t1; +--echo # +--echo # MDEV-14164: Unknown column error when adding aggregate to function +--echo # in oracle style procedure FOR loop +--echo # + +CREATE TABLE t1(id INT, val INT); +DELIMITER //; +CREATE PROCEDURE p1() +BEGIN + DECLARE cur1 CURSOR FOR SELECT * FROM ( + SELECT DISTINCT id FROM t1) a + WHERE NOT EXISTS (SELECT * FROM ( SELECT id FROM t1) b + WHERE a.id=b.id); + OPEN cur1; + CLOSE cur1; + OPEN cur1; + CLOSE cur1; +END; +// +DELIMITER ;// +CALL p1(); +DROP PROCEDURE p1; +DROP TABLE t1; + +CREATE TABLE t1(id INT, val INT); +DELIMITER //; +CREATE PROCEDURE p1() +BEGIN + SELECT * FROM (SELECT DISTINCT id FROM t1) a + WHERE NOT a.id IN (SELECT b.id FROM t1 b); + SELECT * FROM (SELECT DISTINCT id FROM t1) a + WHERE NOT EXISTS (SELECT * FROM t1 b WHERE a.id=b.id); +END; +// +DELIMITER ;// +CALL p1(); +CALL p1(); +DROP PROCEDURE p1; +DROP TABLE t1; + --echo # End of 10.0 tests #restore defaults diff --git a/sql/item.cc b/sql/item.cc index 050b37f6124..a99bef5d904 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -2745,7 +2745,8 @@ table_map Item_field::all_used_tables() const return (get_depended_from() ? OUTER_REF_TABLE_BIT : field->table->map); } -void Item_field::fix_after_pullout(st_select_lex *new_parent, Item **ref) +void Item_field::fix_after_pullout(st_select_lex *new_parent, Item **ref, + bool merge) { if (new_parent == get_depended_from()) depended_from= NULL; @@ -2789,6 +2790,19 @@ void Item_field::fix_after_pullout(st_select_lex *new_parent, Item **ref) if (!need_change) return; + if (!merge) + { + /* + It is transformation without merge. + This field was "outer" for the inner SELECT where it was taken and + moved up. + "Outer" fields uses normal SELECT_LEX context of upper SELECTs for + name resolution, so we can switch everything to it safely. + */ + this->context= &new_parent->context; + return; + } + Name_resolution_context *ctx= new Name_resolution_context(); if (context->select_lex == new_parent) { @@ -8107,18 +8121,20 @@ bool Item_outer_ref::fix_fields(THD *thd, Item **reference) } -void Item_outer_ref::fix_after_pullout(st_select_lex *new_parent, Item **ref) +void Item_outer_ref::fix_after_pullout(st_select_lex *new_parent, + Item **ref, bool merge) { if (get_depended_from() == new_parent) { *ref= outer_ref; - (*ref)->fix_after_pullout(new_parent, ref); + (*ref)->fix_after_pullout(new_parent, ref, merge); } } -void Item_ref::fix_after_pullout(st_select_lex *new_parent, Item **refptr) +void Item_ref::fix_after_pullout(st_select_lex *new_parent, Item **refptr, + bool merge) { - (*ref)->fix_after_pullout(new_parent, ref); + (*ref)->fix_after_pullout(new_parent, ref, merge); if (get_depended_from() == new_parent) depended_from= NULL; } diff --git a/sql/item.h b/sql/item.h index d6b505b67b8..0470183faad 100644 --- a/sql/item.h +++ b/sql/item.h @@ -706,7 +706,9 @@ public: Fix after some tables has been pulled out. Basically re-calculate all attributes that are dependent on the tables. */ - virtual void fix_after_pullout(st_select_lex *new_parent, Item **ref) {}; + virtual void fix_after_pullout(st_select_lex *new_parent, Item **ref, + bool merge) + {}; /* This method should be used in case where we are sure that we do not need @@ -2256,7 +2258,7 @@ public: bool send(Protocol *protocol, String *str_arg); void reset_field(Field *f); bool fix_fields(THD *, Item **); - void fix_after_pullout(st_select_lex *new_parent, Item **ref); + void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge); void make_field(Send_field *tmp_field); int save_in_field(Field *field,bool no_conversions); void save_org_in_field(Field *field, fast_field_copier optimizer_data); @@ -3410,7 +3412,7 @@ public: bool send(Protocol *prot, String *tmp); void make_field(Send_field *field); bool fix_fields(THD *, Item **); - void fix_after_pullout(st_select_lex *new_parent, Item **ref); + void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge); int save_in_field(Field *field, bool no_conversions); void save_org_in_field(Field *field, fast_field_copier optimizer_data); fast_field_copier setup_fast_field_copier(Field *field) @@ -3664,9 +3666,9 @@ public: Item *it= ((Item *) item)->real_item(); return orig_item->eq(it, binary_cmp); } - void fix_after_pullout(st_select_lex *new_parent, Item **refptr) + void fix_after_pullout(st_select_lex *new_parent, Item **refptr, bool merge) { - orig_item->fix_after_pullout(new_parent, &orig_item); + orig_item->fix_after_pullout(new_parent, &orig_item, merge); } int save_in_field(Field *to, bool no_conversions); enum Item_result result_type () const { return orig_item->result_type(); } @@ -3924,7 +3926,7 @@ public: outer_ref->save_org_in_field(result_field, NULL); } bool fix_fields(THD *, Item **); - void fix_after_pullout(st_select_lex *new_parent, Item **ref); + void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge); table_map used_tables() const { return (*ref)->const_item() ? 0 : OUTER_REF_TABLE_BIT; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 0134f628c80..b82e5e7f9f0 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1442,10 +1442,11 @@ bool Item_in_optimizer::is_top_level_item() } -void Item_in_optimizer::fix_after_pullout(st_select_lex *new_parent, Item **ref) +void Item_in_optimizer::fix_after_pullout(st_select_lex *new_parent, + Item **ref, bool merge) { /* This will re-calculate attributes of our Item_in_subselect: */ - Item_bool_func::fix_after_pullout(new_parent, ref); + Item_bool_func::fix_after_pullout(new_parent, ref, merge); /* Then, re-calculate not_null_tables_cache: */ eval_not_null_tables(NULL); @@ -2288,10 +2289,11 @@ bool Item_func_between::count_sargable_conds(uchar *arg) } -void Item_func_between::fix_after_pullout(st_select_lex *new_parent, Item **ref) +void Item_func_between::fix_after_pullout(st_select_lex *new_parent, + Item **ref, bool merge) { /* This will re-calculate attributes of the arguments */ - Item_func_opt_neg::fix_after_pullout(new_parent, ref); + Item_func_opt_neg::fix_after_pullout(new_parent, ref, merge); /* Then, re-calculate not_null_tables_cache according to our special rules */ eval_not_null_tables(NULL); } @@ -2681,10 +2683,11 @@ Item_func_if::eval_not_null_tables(uchar *opt_arg) } -void Item_func_if::fix_after_pullout(st_select_lex *new_parent, Item **ref) +void Item_func_if::fix_after_pullout(st_select_lex *new_parent, + Item **ref, bool merge) { /* This will re-calculate attributes of the arguments */ - Item_func::fix_after_pullout(new_parent, ref); + Item_func::fix_after_pullout(new_parent, ref, merge); /* Then, re-calculate not_null_tables_cache according to our special rules */ eval_not_null_tables(NULL); } @@ -4010,10 +4013,11 @@ Item_func_in::eval_not_null_tables(uchar *opt_arg) } -void Item_func_in::fix_after_pullout(st_select_lex *new_parent, Item **ref) +void Item_func_in::fix_after_pullout(st_select_lex *new_parent, Item **ref, + bool merge) { /* This will re-calculate attributes of the arguments */ - Item_func_opt_neg::fix_after_pullout(new_parent, ref); + Item_func_opt_neg::fix_after_pullout(new_parent, ref, merge); /* Then, re-calculate not_null_tables_cache according to our special rules */ eval_not_null_tables(NULL); } @@ -4497,7 +4501,8 @@ Item_cond::eval_not_null_tables(uchar *opt_arg) } -void Item_cond::fix_after_pullout(st_select_lex *new_parent, Item **ref) +void Item_cond::fix_after_pullout(st_select_lex *new_parent, Item **ref, + bool merge) { List_iterator li(list); Item *item; @@ -4511,7 +4516,7 @@ void Item_cond::fix_after_pullout(st_select_lex *new_parent, Item **ref) while ((item=li++)) { table_map tmp_table_map; - item->fix_after_pullout(new_parent, li.ref()); + item->fix_after_pullout(new_parent, li.ref(), merge); item= *li.ref(); used_tables_cache|= item->used_tables(); const_item_cache&= item->const_item(); diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index ba0af32d76f..179ea10e5ef 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -272,7 +272,7 @@ public: virtual void get_cache_parameters(List ¶meters); bool is_top_level_item(); bool eval_not_null_tables(uchar *opt_arg); - void fix_after_pullout(st_select_lex *new_parent, Item **ref); + void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge); bool invisible_mode(); void reset_cache() { cache= NULL; } }; @@ -689,7 +689,7 @@ public: virtual void print(String *str, enum_query_type query_type); CHARSET_INFO *compare_collation() { return cmp_collation.collation; } bool eval_not_null_tables(uchar *opt_arg); - void fix_after_pullout(st_select_lex *new_parent, Item **ref); + void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge); bool count_sargable_conds(uchar *arg); }; @@ -791,7 +791,7 @@ public: uint decimal_precision() const; const char *func_name() const { return "if"; } bool eval_not_null_tables(uchar *opt_arg); - void fix_after_pullout(st_select_lex *new_parent, Item **ref); + void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge); private: void cache_type_info(Item *source); }; @@ -1337,7 +1337,7 @@ public: bool nulls_in_row(); CHARSET_INFO *compare_collation() { return cmp_collation.collation; } bool eval_not_null_tables(uchar *opt_arg); - void fix_after_pullout(st_select_lex *new_parent, Item **ref); + void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge); }; class cmp_item_row :public cmp_item @@ -1729,7 +1729,7 @@ public: list.concat(nlist); } bool fix_fields(THD *, Item **ref); - void fix_after_pullout(st_select_lex *new_parent, Item **ref); + void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge); enum Type type() const { return COND_ITEM; } List* argument_list() { return &list; } diff --git a/sql/item_func.cc b/sql/item_func.cc index 0ca8f700bfc..458db430222 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -265,7 +265,8 @@ Item_func::eval_not_null_tables(uchar *opt_arg) } -void Item_func::fix_after_pullout(st_select_lex *new_parent, Item **ref) +void Item_func::fix_after_pullout(st_select_lex *new_parent, Item **ref, + bool merge) { Item **arg,**arg_end; @@ -276,7 +277,7 @@ void Item_func::fix_after_pullout(st_select_lex *new_parent, Item **ref) { for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++) { - (*arg)->fix_after_pullout(new_parent, arg); + (*arg)->fix_after_pullout(new_parent, arg, merge); Item *item= *arg; used_tables_cache|= item->used_tables(); diff --git a/sql/item_func.h b/sql/item_func.h index 5db92b6f3fe..7dea193c99b 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -143,7 +143,7 @@ public: // Constructor used for Item_cond_and/or (see Item comment) Item_func(THD *thd, Item_func *item); bool fix_fields(THD *, Item **ref); - void fix_after_pullout(st_select_lex *new_parent, Item **ref); + void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge); void quick_fix_field(); table_map used_tables() const; table_map not_null_tables() const; diff --git a/sql/item_row.cc b/sql/item_row.cc index b38cffd1ad5..c07ea612850 100644 --- a/sql/item_row.cc +++ b/sql/item_row.cc @@ -184,14 +184,15 @@ void Item_row::update_used_tables() } -void Item_row::fix_after_pullout(st_select_lex *new_parent, Item **ref) +void Item_row::fix_after_pullout(st_select_lex *new_parent, Item **ref, + bool merge) { used_tables_cache= 0; const_item_cache= 1; not_null_tables_cache= 0; for (uint i= 0; i < arg_count; i++) { - items[i]->fix_after_pullout(new_parent, &items[i]); + items[i]->fix_after_pullout(new_parent, &items[i], merge); used_tables_cache|= items[i]->used_tables(); const_item_cache&= items[i]->const_item(); not_null_tables_cache|= items[i]->not_null_tables(); diff --git a/sql/item_row.h b/sql/item_row.h index 4d5c20711b5..ae9599baa57 100644 --- a/sql/item_row.h +++ b/sql/item_row.h @@ -65,7 +65,7 @@ public: return 0; }; bool fix_fields(THD *thd, Item **ref); - void fix_after_pullout(st_select_lex *new_parent, Item **ref); + void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge); void cleanup(); void split_sum_func(THD *thd, Item **ref_pointer_array, List &fields); table_map used_tables() const { return used_tables_cache; }; diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index a215092f30f..eb1e1a3d9b7 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -446,7 +446,8 @@ bool Item_subselect::mark_as_dependent(THD *thd, st_select_lex *select, OUTER_REF_TABLE_BIT. */ -void Item_subselect::fix_after_pullout(st_select_lex *new_parent, Item **ref) +void Item_subselect::fix_after_pullout(st_select_lex *new_parent, + Item **ref, bool merge) { recalc_used_tables(new_parent, TRUE); parent_select= new_parent; @@ -1110,7 +1111,8 @@ Item_singlerow_subselect::select_transformer(JOIN *join) /* as far as we moved content to upper level we have to fix dependences & Co */ - substitution->fix_after_pullout(select_lex->outer_select(), &substitution); + substitution->fix_after_pullout(select_lex->outer_select(), + &substitution, TRUE); } DBUG_RETURN(false); } @@ -2855,7 +2857,7 @@ bool Item_exists_subselect::exists2in_processor(uchar *opt_arg) goto out; } } - outer_exp->fix_after_pullout(unit->outer_select(), &outer_exp); + outer_exp->fix_after_pullout(unit->outer_select(), &outer_exp, FALSE); outer_exp->update_used_tables(); outer.push_back(outer_exp); } @@ -3228,10 +3230,11 @@ err: } -void Item_in_subselect::fix_after_pullout(st_select_lex *new_parent, Item **ref) +void Item_in_subselect::fix_after_pullout(st_select_lex *new_parent, + Item **ref, bool merge) { - left_expr->fix_after_pullout(new_parent, &left_expr); - Item_subselect::fix_after_pullout(new_parent, ref); + left_expr->fix_after_pullout(new_parent, &left_expr, merge); + Item_subselect::fix_after_pullout(new_parent, ref, merge); used_tables_cache |= left_expr->used_tables(); } diff --git a/sql/item_subselect.h b/sql/item_subselect.h index ad43215e437..769be7ee925 100644 --- a/sql/item_subselect.h +++ b/sql/item_subselect.h @@ -172,7 +172,7 @@ public: } bool fix_fields(THD *thd, Item **ref); bool mark_as_dependent(THD *thd, st_select_lex *select, Item *item); - void fix_after_pullout(st_select_lex *new_parent, Item **ref); + void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge); void recalc_used_tables(st_select_lex *new_parent, bool after_pullout); virtual bool exec(); /* @@ -608,7 +608,7 @@ public: virtual void print(String *str, enum_query_type query_type); bool fix_fields(THD *thd, Item **ref); void fix_length_and_dec(); - void fix_after_pullout(st_select_lex *new_parent, Item **ref); + void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge); bool const_item() const { return Item_subselect::const_item() && left_expr->const_item(); diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index 6bf122fac5a..3ed55c2b9c8 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -1794,7 +1794,8 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred) Walk through sj nest's WHERE and ON expressions and call item->fix_table_changes() for all items. */ - sj_nest->sj_on_expr->fix_after_pullout(parent_lex, &sj_nest->sj_on_expr); + sj_nest->sj_on_expr->fix_after_pullout(parent_lex, &sj_nest->sj_on_expr, + TRUE); fix_list_after_tbl_changes(parent_lex, &sj_nest->nested_join->join_list); @@ -1953,7 +1954,7 @@ static bool convert_subq_to_jtbm(JOIN *parent_join, DBUG_ASSERT(parent_join->table_count < MAX_TABLES); Item *conds= hash_sj_engine->semi_join_conds; - conds->fix_after_pullout(parent_lex, &conds); + conds->fix_after_pullout(parent_lex, &conds, TRUE); DBUG_EXECUTE("where", print_where(conds,"SJ-EXPR", QT_ORDINARY);); @@ -2005,7 +2006,7 @@ void fix_list_after_tbl_changes(SELECT_LEX *new_parent, List *tlist) while ((table= it++)) { if (table->on_expr) - table->on_expr->fix_after_pullout(new_parent, &table->on_expr); + table->on_expr->fix_after_pullout(new_parent, &table->on_expr, TRUE); if (table->nested_join) fix_list_after_tbl_changes(new_parent, &table->nested_join->join_list); } diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc index 4578bcec394..0aedf5084a9 100644 --- a/sql/sql_derived.cc +++ b/sql/sql_derived.cc @@ -466,7 +466,8 @@ bool mysql_derived_merge(THD *thd, LEX *lex, TABLE_LIST *derived) // Update used tables cache according to new table map if (derived->on_expr) { - derived->on_expr->fix_after_pullout(parent_lex, &derived->on_expr); + derived->on_expr->fix_after_pullout(parent_lex, &derived->on_expr, + TRUE); fix_list_after_tbl_changes(parent_lex, &derived->nested_join->join_list); } } @@ -636,7 +637,8 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived) SELECT_LEX_UNIT *unit= derived->get_unit(); DBUG_ENTER("mysql_derived_prepare"); bool res= FALSE; - DBUG_PRINT("enter", ("unit 0x%lx", (ulong) unit)); + DBUG_PRINT("enter", ("unit: %p table_list: %p Alias '%s'", + unit, derived, derived->alias)); // Skip already prepared views/DT if (!unit || unit->prepared || From d2ffafe00f7e4c2246bb0b45bd407ff179163c5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Thu, 9 Nov 2017 14:37:03 +0200 Subject: [PATCH 34/35] MDEV-14333 Mariabackup --apply-log-only crashes if incomplete transactions with update_undo logs are present trx_undo_free_prepared(): Relax the assertion for mariabackup --apply-log-only. --- .../suite/mariabackup/incremental_backup.result | 10 ++++++++-- .../suite/mariabackup/incremental_backup.test | 16 ++++++++++++---- storage/xtradb/trx/trx0undo.cc | 1 + 3 files changed, 21 insertions(+), 6 deletions(-) diff --git a/mysql-test/suite/mariabackup/incremental_backup.result b/mysql-test/suite/mariabackup/incremental_backup.result index eeedc751d83..20d8cefbefb 100644 --- a/mysql-test/suite/mariabackup/incremental_backup.result +++ b/mysql-test/suite/mariabackup/incremental_backup.result @@ -1,8 +1,14 @@ call mtr.add_suppression("InnoDB: New log files created"); -CREATE TABLE t(i INT) ENGINE INNODB; +CREATE TABLE t(i INT PRIMARY KEY) ENGINE INNODB; +BEGIN; +INSERT INTO t VALUES(2); +SET GLOBAL innodb_flush_log_at_trx_commit = 1; INSERT INTO t VALUES(1); # Create full backup , modify table, then create incremental/differential backup -INSERT INTO t VALUES(2); +BEGIN; +INSERT INTO t VALUES(0); +DELETE FROM t WHERE i=0; +COMMIT; SELECT * FROM t; i 1 diff --git a/mysql-test/suite/mariabackup/incremental_backup.test b/mysql-test/suite/mariabackup/incremental_backup.test index b92d7b323ac..93582f047a7 100644 --- a/mysql-test/suite/mariabackup/incremental_backup.test +++ b/mysql-test/suite/mariabackup/incremental_backup.test @@ -4,23 +4,31 @@ call mtr.add_suppression("InnoDB: New log files created"); let $basedir=$MYSQLTEST_VARDIR/tmp/backup; let $incremental_dir=$MYSQLTEST_VARDIR/tmp/backup_inc1; - -CREATE TABLE t(i INT) ENGINE INNODB; +CREATE TABLE t(i INT PRIMARY KEY) ENGINE INNODB; +BEGIN; +INSERT INTO t VALUES(2); +connect (con1,localhost,root,,); +SET GLOBAL innodb_flush_log_at_trx_commit = 1; INSERT INTO t VALUES(1); echo # Create full backup , modify table, then create incremental/differential backup; --disable_result_log exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$basedir; --enable_result_log -INSERT INTO t VALUES(2); +BEGIN; +INSERT INTO t VALUES(0); +DELETE FROM t WHERE i=0; +connection default; +COMMIT; SELECT * FROM t; exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$incremental_dir --incremental-basedir=$basedir; --disable_result_log echo # Prepare full backup, apply incremental one; exec $XTRABACKUP --prepare --apply-log-only --target-dir=$basedir; -exec $XTRABACKUP --prepare --target-dir=$basedir --incremental-dir=$incremental_dir ; +exec $XTRABACKUP --prepare --apply-log-only --target-dir=$basedir --incremental-dir=$incremental_dir ; +disconnect con1; echo # Restore and check results; let $targetdir=$basedir; -- source include/restart_and_restore.inc diff --git a/storage/xtradb/trx/trx0undo.cc b/storage/xtradb/trx/trx0undo.cc index 0cc3048e624..3259bcb70b1 100644 --- a/storage/xtradb/trx/trx0undo.cc +++ b/storage/xtradb/trx/trx0undo.cc @@ -2025,6 +2025,7 @@ trx_undo_free_prepared( /* lock_trx_release_locks() assigns trx->is_recovered=false */ ut_a(srv_read_only_mode + || srv_apply_log_only || srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO); break; default: From d40c23570ff1a9ba5aa317b85a32a4b27780b8ab Mon Sep 17 00:00:00 2001 From: Monty Date: Thu, 9 Nov 2017 14:57:40 +0200 Subject: [PATCH 35/35] Cleanup up after failed alter table in add_index_inplace_crash --- .../mysql-test/rocksdb/t/add_index_inplace_crash.test | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace_crash.test b/storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace_crash.test index 84fe0046e7b..d715eb7df7a 100644 --- a/storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace_crash.test +++ b/storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace_crash.test @@ -105,3 +105,13 @@ SHOW CREATE TABLE t1; SELECT COUNT(*) FROM t1; DROP TABLE t1; + +# Cleanup temporary #sql files. In the future server will remove these +# automatically but for now we need to do the delete explicit + +--disable_query_log +--disable_result_log +let $datadir=`select @@datadir`; +--remove_files_wildcard $datadir/test #sql* +--enable_result_log +--enable_query_log