From ebb8c9fb26f86cff8c0d81bd2415f415cef952bb Mon Sep 17 00:00:00 2001 From: Alexander Barkov Date: Thu, 12 Jan 2017 15:16:45 +0400 Subject: MDEV-11030 Assertion `precision > 0' failed in decimal_bin_size Fixing Item::decimal_precision() to return at least one digit. This fixes the problem reported in MDEV. Also, fixing Item_func_signed::fix_length_and_dec() to reserve space for at least one digit (plus one character for an optional sign). This is needed to have CONVERT(expr,SIGNED) and CONVERT(expr,UNSIGNED) create correct string fields when they appear in string context, e.g.: CREATE TABLE t1 AS SELECT CONCAT(CONVERT('',SIGNED)); --- mysql-test/r/cast.result | 73 +++++++++++++++++++++++++++++++++++++++++++++++- mysql-test/t/cast.test | 39 ++++++++++++++++++++++++++ sql/item.cc | 9 +++++- sql/item_func.h | 11 ++++++-- 4 files changed, 128 insertions(+), 4 deletions(-) diff --git a/mysql-test/r/cast.result b/mysql-test/r/cast.result index 4c9f257fdf2..ab784b5afc2 100644 --- a/mysql-test/r/cast.result +++ b/mysql-test/r/cast.result @@ -583,7 +583,7 @@ show create table t1; Table Create Table t1 CREATE TABLE `t1` ( `cast(1 as unsigned)` int(1) unsigned NOT NULL, - `cast(1 as signed)` int(1) NOT NULL, + `cast(1 as signed)` int(2) NOT NULL, `cast(1 as double(5,2))` double(5,2) DEFAULT NULL, `cast(1 as decimal(5,3))` decimal(5,3) NOT NULL, `cast("A" as binary)` varbinary(1) NOT NULL, @@ -819,3 +819,74 @@ utf8_bin select collation(cast("a" as char(10) binary ascii)); collation(cast("a" as char(10) binary ascii)) latin1_bin +# +# MDEV-11030 Assertion `precision > 0' failed in decimal_bin_size +# +SELECT * FROM (SELECT IFNULL(CONVERT(NULL, UNSIGNED), NULL)) sq; +IFNULL(CONVERT(NULL, UNSIGNED), NULL) +NULL +CREATE TABLE t1 AS SELECT IFNULL(CONVERT(NULL, UNSIGNED), NULL); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `IFNULL(CONVERT(NULL, UNSIGNED), NULL)` decimal(1,0) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT COALESCE(CONVERT(NULL, UNSIGNED), NULL); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `COALESCE(CONVERT(NULL, UNSIGNED), NULL)` decimal(1,0) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT CASE WHEN TRUE THEN CONVERT(NULL, UNSIGNED) ELSE NULL END; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `CASE WHEN TRUE THEN CONVERT(NULL, UNSIGNED) ELSE NULL END` decimal(1,0) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT IFNULL(CONVERT(NULL,SIGNED),CONVERT(NULL,UNSIGNED)) AS a; +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` decimal(1,0) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT +-1, +CONVERT(NULL,SIGNED), +CONCAT(CONVERT(NULL,SIGNED)), +1, +CONVERT(NULL,UNSIGNED), +CONCAT(CONVERT(NULL,UNSIGNED)); +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `-1` int(2) NOT NULL, + `CONVERT(NULL,SIGNED)` int(2) DEFAULT NULL, + `CONCAT(CONVERT(NULL,SIGNED))` varchar(2) DEFAULT NULL, + `1` int(1) NOT NULL, + `CONVERT(NULL,UNSIGNED)` int(1) unsigned DEFAULT NULL, + `CONCAT(CONVERT(NULL,UNSIGNED))` varchar(1) DEFAULT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1; +CREATE TABLE t1 AS SELECT +CONVERT('',SIGNED), +CONCAT(CONVERT('',SIGNED)), +CONVERT('',UNSIGNED), +CONCAT(CONVERT('',UNSIGNED)); +Warnings: +Warning 1292 Truncated incorrect INTEGER value: '' +Warning 1292 Truncated incorrect INTEGER value: '' +Warning 1292 Truncated incorrect INTEGER value: '' +Warning 1292 Truncated incorrect INTEGER value: '' +SHOW CREATE TABLE t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `CONVERT('',SIGNED)` int(2) NOT NULL, + `CONCAT(CONVERT('',SIGNED))` varchar(2) NOT NULL, + `CONVERT('',UNSIGNED)` int(1) unsigned NOT NULL, + `CONCAT(CONVERT('',UNSIGNED))` varchar(1) NOT NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +DROP TABLE t1; diff --git a/mysql-test/t/cast.test b/mysql-test/t/cast.test index 58f91571ebb..5316c12c857 100644 --- a/mysql-test/t/cast.test +++ b/mysql-test/t/cast.test @@ -472,3 +472,42 @@ select collation(cast("a" as char(10) ascii binary)); select collation(cast("a" as char(10) binary charset utf8)); select collation(cast("a" as char(10) binary ascii)); +--echo # +--echo # MDEV-11030 Assertion `precision > 0' failed in decimal_bin_size +--echo # + +SELECT * FROM (SELECT IFNULL(CONVERT(NULL, UNSIGNED), NULL)) sq; + +CREATE TABLE t1 AS SELECT IFNULL(CONVERT(NULL, UNSIGNED), NULL); +SHOW CREATE TABLE t1; +DROP TABLE t1; + +CREATE TABLE t1 AS SELECT COALESCE(CONVERT(NULL, UNSIGNED), NULL); +SHOW CREATE TABLE t1; +DROP TABLE t1; + +CREATE TABLE t1 AS SELECT CASE WHEN TRUE THEN CONVERT(NULL, UNSIGNED) ELSE NULL END; +SHOW CREATE TABLE t1; +DROP TABLE t1; + +CREATE TABLE t1 AS SELECT IFNULL(CONVERT(NULL,SIGNED),CONVERT(NULL,UNSIGNED)) AS a; +SHOW CREATE TABLE t1; +DROP TABLE t1; + +CREATE TABLE t1 AS SELECT + -1, + CONVERT(NULL,SIGNED), + CONCAT(CONVERT(NULL,SIGNED)), + 1, + CONVERT(NULL,UNSIGNED), + CONCAT(CONVERT(NULL,UNSIGNED)); +SHOW CREATE TABLE t1; +DROP TABLE t1; + +CREATE TABLE t1 AS SELECT + CONVERT('',SIGNED), + CONCAT(CONVERT('',SIGNED)), + CONVERT('',UNSIGNED), + CONCAT(CONVERT('',UNSIGNED)); +SHOW CREATE TABLE t1; +DROP TABLE t1; diff --git a/sql/item.cc b/sql/item.cc index 08599f1d486..015f5591c5d 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -533,7 +533,14 @@ uint Item::decimal_precision() const unsigned_flag); return MY_MIN(prec, DECIMAL_MAX_PRECISION); } - return MY_MIN(max_char_length(), DECIMAL_MAX_PRECISION); + uint res= max_char_length(); + /* + Return at least one decimal digit, even if Item::max_char_length() + returned 0. This is important to avoid attempts to create fields of types + INT(0) or DECIMAL(0,0) when converting NULL or empty strings to INT/DECIMAL: + CREATE TABLE t1 AS SELECT CONVERT(NULL,SIGNED) AS a; + */ + return res ? MY_MIN(res, DECIMAL_MAX_PRECISION) : 1; } diff --git a/sql/item_func.h b/sql/item_func.h index 4a55bd68453..56d7c190181 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -626,8 +626,15 @@ public: longlong val_int_from_str(int *error); void fix_length_and_dec() { - fix_char_length(MY_MIN(args[0]->max_char_length(), - MY_INT64_NUM_DECIMAL_DIGITS)); + uint32 char_length= MY_MIN(args[0]->max_char_length(), + MY_INT64_NUM_DECIMAL_DIGITS); + /* + args[0]->max_char_length() can return 0. + Reserve max_length to fit at least one character for one digit, + plus one character for the sign (if signed). + */ + set_if_bigger(char_length, 1 + (unsigned_flag ? 0 : 1)); + fix_char_length(char_length); } virtual void print(String *str, enum_query_type query_type); uint decimal_precision() const { return args[0]->decimal_precision(); } -- cgit v1.2.1 From 1282eb694c9fb18cac6bace643b4ce275a6a5689 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Sun, 11 Dec 2016 17:16:15 +0100 Subject: cleanup: make malloc_size_cb_func always defined --- mysys/my_malloc.c | 15 ++++++++------- sql/mysqld.cc | 5 ++--- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/mysys/my_malloc.c b/mysys/my_malloc.c index e533230106e..dc02d3896bd 100644 --- a/mysys/my_malloc.c +++ b/mysys/my_malloc.c @@ -48,7 +48,6 @@ static inline size_t malloc_size_and_flag(void *p, my_bool *is_thread_specific) #define MALLOC_FIX_POINTER_FOR_FREE(p) (((char*) (p)) - MALLOC_PREFIX_SIZE) #endif /* SAFEMALLOC */ -static MALLOC_SIZE_CB malloc_size_cb_func= NULL; /** Inform application that memory usage has changed @@ -59,17 +58,19 @@ static MALLOC_SIZE_CB malloc_size_cb_func= NULL; The type os size is long long, to be able to handle negative numbers to decrement the memory usage + + @return 0 - ok + 1 - failure, abort the allocation */ +static void dummy(long long size __attribute__((unused)), + my_bool is_thread_specific __attribute__((unused))) +{} -static void update_malloc_size(long long size, my_bool is_thread_specific) -{ - if (malloc_size_cb_func) - malloc_size_cb_func(size, is_thread_specific); -} +static MALLOC_SIZE_CB update_malloc_size= dummy; void set_malloc_size_cb(MALLOC_SIZE_CB func) { - malloc_size_cb_func= func; + update_malloc_size= func ? func : dummy; } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index adb1b273b80..96baaf25287 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -3989,7 +3989,7 @@ static void my_malloc_size_cb_func(long long size, my_bool is_thread_specific) { THD *thd= current_thd; - if (likely(is_thread_specific)) /* If thread specific memory */ + if (is_thread_specific) /* If thread specific memory */ { /* When thread specfic is set, both mysqld_server_initialized and thd @@ -4006,8 +4006,7 @@ static void my_malloc_size_cb_func(long long size, my_bool is_thread_specific) else if (likely(thd)) { DBUG_PRINT("info", ("global thd memory_used: %lld size: %lld", - (longlong) thd->status_var.global_memory_used, - size)); + (longlong) thd->status_var.global_memory_used, size)); thd->status_var.global_memory_used+= size; } else -- cgit v1.2.1 From ab3388c3c44caecbec9974f54a2f30dd06237eee Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 12 Dec 2016 01:00:45 +0100 Subject: bugfix: mutex order violation in embedded safe_mutex: Found wrong usage of mutex 'LOCK_thread_count' and 'LOCK_status' Mutex currently locked (in reverse order): LOCK_status sql/sql_class.h line 3873 LOCK_thread_count libmysqld/lib_sql.cc line 432 --- libmysqld/lib_sql.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index 63424af27f6..0dfb1a1ad9a 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -434,8 +434,8 @@ static void emb_free_embedded_thd(MYSQL *mysql) thread_count--; thd->store_globals(); thd->unlink(); - delete thd; mysql_mutex_unlock(&LOCK_thread_count); + delete thd; my_pthread_setspecific_ptr(THR_THD, 0); mysql->thd=0; } -- cgit v1.2.1 From 7e2f9d092dd1fb6b0fa1a8fdd5d1f3af68b56f45 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Mon, 12 Dec 2016 01:01:56 +0100 Subject: max_session_mem_used server variable --- mysql-test/r/mysqld--help.result | 5 + .../sys_vars/r/sysvars_server_embedded,32bit.rdiff | 168 ++++++++++---------- .../sys_vars/r/sysvars_server_embedded.result | 14 ++ .../r/sysvars_server_notembedded,32bit.rdiff | 176 ++++++++++----------- .../sys_vars/r/sysvars_server_notembedded.result | 14 ++ sql/mysqld.cc | 9 ++ sql/sql_class.cc | 6 +- sql/sql_class.h | 1 + sql/sys_vars.cc | 7 + 9 files changed, 226 insertions(+), 174 deletions(-) diff --git a/mysql-test/r/mysqld--help.result b/mysql-test/r/mysqld--help.result index 93027e2bba4..340fa21f0df 100644 --- a/mysql-test/r/mysqld--help.result +++ b/mysql-test/r/mysqld--help.result @@ -457,6 +457,10 @@ The following options may be given as the first argument: --max-seeks-for-key=# Limit assumed max number of seeks when looking up rows based on a key + --max-session-mem-used=# + Amount of memory a single user session is allowed to + allocate. This limits the value of the session variable + MEM_USED --max-sort-length=# The number of bytes to use when sorting BLOB or TEXT values (only the first max_sort_length bytes of each value are used; the rest are ignored) @@ -1266,6 +1270,7 @@ max-long-data-size 4194304 max-prepared-stmt-count 16382 max-relay-log-size 1073741824 max-seeks-for-key 18446744073709551615 +max-session-mem-used 9223372036854775807 max-sort-length 1024 max-sp-recursion-depth 0 max-statement-time 0 diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_embedded,32bit.rdiff b/mysql-test/suite/sys_vars/r/sysvars_server_embedded,32bit.rdiff index 13fa9b8e2b4..8a5a2d771b0 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_embedded,32bit.rdiff +++ b/mysql-test/suite/sys_vars/r/sysvars_server_embedded,32bit.rdiff @@ -1,5 +1,5 @@ ---- suite/sys_vars/r/sysvars_server_embedded.result 2016-03-23 01:02:33.000000000 +0100 -+++ suite/sys_vars/r/sysvars_server_embedded.reject 2016-03-23 01:09:44.000000000 +0100 +--- sysvars_server_embedded.result ++++ sysvars_server_embedded,32bit.result~ @@ -57,7 +57,7 @@ GLOBAL_VALUE_ORIGIN CONFIG DEFAULT_VALUE 1 @@ -476,7 +476,7 @@ VARIABLE_COMMENT Maximum stored procedure recursion depth NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 255 -@@ -2045,7 +2045,7 @@ +@@ -2059,7 +2059,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 32 VARIABLE_SCOPE SESSION @@ -485,7 +485,7 @@ VARIABLE_COMMENT Unused, will be removed. NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 4294967295 -@@ -2073,7 +2073,7 @@ +@@ -2087,7 +2087,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 4294967295 VARIABLE_SCOPE GLOBAL @@ -494,7 +494,7 @@ VARIABLE_COMMENT After this many write locks, allow some read locks to run in between NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 4294967295 -@@ -2087,7 +2087,7 @@ +@@ -2101,7 +2101,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 1024 VARIABLE_SCOPE GLOBAL @@ -503,7 +503,7 @@ VARIABLE_COMMENT Unused NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 1048576 -@@ -2101,7 +2101,7 @@ +@@ -2115,7 +2115,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 8 VARIABLE_SCOPE GLOBAL @@ -512,7 +512,7 @@ VARIABLE_COMMENT Unused NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 1024 -@@ -2115,7 +2115,7 @@ +@@ -2129,7 +2129,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 0 VARIABLE_SCOPE SESSION @@ -521,7 +521,7 @@ VARIABLE_COMMENT Don't write queries to slow log that examine fewer rows than that NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 -@@ -2129,7 +2129,7 @@ +@@ -2143,7 +2143,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 262144 VARIABLE_SCOPE SESSION @@ -530,7 +530,7 @@ VARIABLE_COMMENT Size of buffer to use when using MRR with range access NUMERIC_MIN_VALUE 8192 NUMERIC_MAX_VALUE 2147483647 -@@ -2143,10 +2143,10 @@ +@@ -2157,10 +2157,10 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 256 VARIABLE_SCOPE SESSION @@ -543,7 +543,7 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -2157,7 +2157,7 @@ +@@ -2171,7 +2171,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 1024 VARIABLE_SCOPE GLOBAL @@ -552,7 +552,7 @@ VARIABLE_COMMENT Block size to be used for MyISAM index pages NUMERIC_MIN_VALUE 1024 NUMERIC_MAX_VALUE 16384 -@@ -2171,7 +2171,7 @@ +@@ -2185,7 +2185,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 6 VARIABLE_SCOPE GLOBAL @@ -561,7 +561,7 @@ VARIABLE_COMMENT Default pointer size to be used for MyISAM tables NUMERIC_MIN_VALUE 2 NUMERIC_MAX_VALUE 7 -@@ -2181,9 +2181,9 @@ +@@ -2195,9 +2195,9 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME MYISAM_MAX_SORT_FILE_SIZE SESSION_VALUE NULL @@ -573,7 +573,7 @@ VARIABLE_SCOPE GLOBAL VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT Don't use the fast sort index method to created index if the temporary file would get bigger than this -@@ -2195,14 +2195,14 @@ +@@ -2209,14 +2209,14 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME MYISAM_MMAP_SIZE SESSION_VALUE NULL @@ -591,7 +591,7 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY YES -@@ -2227,10 +2227,10 @@ +@@ -2241,10 +2241,10 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 1 VARIABLE_SCOPE SESSION @@ -604,7 +604,7 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -2244,7 +2244,7 @@ +@@ -2258,7 +2258,7 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT The buffer that is allocated when sorting the index when doing a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE NUMERIC_MIN_VALUE 4096 @@ -613,7 +613,7 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -2297,7 +2297,7 @@ +@@ -2311,7 +2311,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 16384 VARIABLE_SCOPE SESSION @@ -622,7 +622,7 @@ VARIABLE_COMMENT Buffer length for TCP/IP and socket communication NUMERIC_MIN_VALUE 1024 NUMERIC_MAX_VALUE 1048576 -@@ -2311,7 +2311,7 @@ +@@ -2325,7 +2325,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 30 VARIABLE_SCOPE SESSION @@ -631,7 +631,7 @@ VARIABLE_COMMENT Number of seconds to wait for more data from a connection before aborting the read NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 31536000 -@@ -2325,7 +2325,7 @@ +@@ -2339,7 +2339,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 10 VARIABLE_SCOPE SESSION @@ -640,7 +640,7 @@ VARIABLE_COMMENT If a read on a communication port is interrupted, retry this many times before giving up NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 4294967295 -@@ -2339,7 +2339,7 @@ +@@ -2353,7 +2353,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 60 VARIABLE_SCOPE SESSION @@ -649,7 +649,7 @@ VARIABLE_COMMENT Number of seconds to wait for a block to be written to a connection before aborting the write NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 31536000 -@@ -2409,7 +2409,7 @@ +@@ -2423,7 +2423,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 1 VARIABLE_SCOPE SESSION @@ -658,7 +658,7 @@ VARIABLE_COMMENT Controls the heuristic(s) applied during query optimization to prune less-promising partial plans from the optimizer search space. Meaning: 0 - do not apply any heuristic, thus perform exhaustive search; 1 - prune plans based on number of retrieved rows NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 1 -@@ -2423,7 +2423,7 @@ +@@ -2437,7 +2437,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 62 VARIABLE_SCOPE SESSION @@ -667,7 +667,7 @@ VARIABLE_COMMENT Maximum depth of search performed by the query optimizer. Values larger than the number of relations in a query result in better query plans, but take longer to compile a query. Values smaller than the number of tables in a relation result in faster optimization, but may produce very bad query plans. If set to 0, the system will automatically pick a reasonable value; if set to 63, the optimizer will switch to the original find_best search. NOTE: The value 63 and its associated behaviour is deprecated NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 63 -@@ -2437,7 +2437,7 @@ +@@ -2451,7 +2451,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 100 VARIABLE_SCOPE SESSION @@ -676,7 +676,7 @@ VARIABLE_COMMENT Controls number of record samples to check condition selectivity NUMERIC_MIN_VALUE 10 NUMERIC_MAX_VALUE 4294967295 -@@ -2465,7 +2465,7 @@ +@@ -2479,7 +2479,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 1 VARIABLE_SCOPE SESSION @@ -685,7 +685,7 @@ VARIABLE_COMMENT Controls selectivity of which conditions the optimizer takes into account to calculate cardinality of a partial join when it searches for the best execution plan Meaning: 1 - use selectivity of index backed range conditions to calculate the cardinality of a partial join if the last joined table is accessed by full table scan or an index scan, 2 - use selectivity of index backed range conditions to calculate the cardinality of a partial join in any case, 3 - additionally always use selectivity of range conditions that are not backed by any index to calculate the cardinality of a partial join, 4 - use histograms to calculate selectivity of range conditions that are not backed by any index to calculate the cardinality of a partial join.5 - additionally use selectivity of certain non-range predicates calculated on record samples NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 5 -@@ -2493,7 +2493,7 @@ +@@ -2507,7 +2507,7 @@ GLOBAL_VALUE_ORIGIN CONFIG DEFAULT_VALUE -1 VARIABLE_SCOPE GLOBAL @@ -694,7 +694,7 @@ VARIABLE_COMMENT Maximum number of instrumented user@host accounts. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2507,7 +2507,7 @@ +@@ -2521,7 +2521,7 @@ GLOBAL_VALUE_ORIGIN CONFIG DEFAULT_VALUE -1 VARIABLE_SCOPE GLOBAL @@ -703,7 +703,7 @@ VARIABLE_COMMENT Size of the statement digest. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 200 -@@ -2521,7 +2521,7 @@ +@@ -2535,7 +2535,7 @@ GLOBAL_VALUE_ORIGIN CONFIG DEFAULT_VALUE -1 VARIABLE_SCOPE GLOBAL @@ -712,7 +712,7 @@ VARIABLE_COMMENT Number of rows in EVENTS_STAGES_HISTORY_LONG. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2535,7 +2535,7 @@ +@@ -2549,7 +2549,7 @@ GLOBAL_VALUE_ORIGIN CONFIG DEFAULT_VALUE -1 VARIABLE_SCOPE GLOBAL @@ -721,7 +721,7 @@ VARIABLE_COMMENT Number of rows per thread in EVENTS_STAGES_HISTORY. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1024 -@@ -2549,7 +2549,7 @@ +@@ -2563,7 +2563,7 @@ GLOBAL_VALUE_ORIGIN CONFIG DEFAULT_VALUE -1 VARIABLE_SCOPE GLOBAL @@ -730,7 +730,7 @@ VARIABLE_COMMENT Number of rows in EVENTS_STATEMENTS_HISTORY_LONG. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2563,7 +2563,7 @@ +@@ -2577,7 +2577,7 @@ GLOBAL_VALUE_ORIGIN CONFIG DEFAULT_VALUE -1 VARIABLE_SCOPE GLOBAL @@ -739,7 +739,7 @@ VARIABLE_COMMENT Number of rows per thread in EVENTS_STATEMENTS_HISTORY. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1024 -@@ -2577,7 +2577,7 @@ +@@ -2591,7 +2591,7 @@ GLOBAL_VALUE_ORIGIN CONFIG DEFAULT_VALUE -1 VARIABLE_SCOPE GLOBAL @@ -748,7 +748,7 @@ VARIABLE_COMMENT Number of rows in EVENTS_WAITS_HISTORY_LONG. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2591,7 +2591,7 @@ +@@ -2605,7 +2605,7 @@ GLOBAL_VALUE_ORIGIN CONFIG DEFAULT_VALUE -1 VARIABLE_SCOPE GLOBAL @@ -757,7 +757,7 @@ VARIABLE_COMMENT Number of rows per thread in EVENTS_WAITS_HISTORY. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1024 -@@ -2605,7 +2605,7 @@ +@@ -2619,7 +2619,7 @@ GLOBAL_VALUE_ORIGIN CONFIG DEFAULT_VALUE -1 VARIABLE_SCOPE GLOBAL @@ -766,7 +766,7 @@ VARIABLE_COMMENT Maximum number of instrumented hosts. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2619,7 +2619,7 @@ +@@ -2633,7 +2633,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 80 VARIABLE_SCOPE GLOBAL @@ -775,7 +775,7 @@ VARIABLE_COMMENT Maximum number of condition instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2633,7 +2633,7 @@ +@@ -2647,7 +2647,7 @@ GLOBAL_VALUE_ORIGIN CONFIG DEFAULT_VALUE -1 VARIABLE_SCOPE GLOBAL @@ -784,7 +784,7 @@ VARIABLE_COMMENT Maximum number of instrumented condition objects. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2647,7 +2647,7 @@ +@@ -2661,7 +2661,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 1024 VARIABLE_SCOPE GLOBAL @@ -793,7 +793,7 @@ VARIABLE_COMMENT Maximum length considered for digest text, when stored in performance_schema tables. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 1048576 -@@ -2661,7 +2661,7 @@ +@@ -2675,7 +2675,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 50 VARIABLE_SCOPE GLOBAL @@ -802,7 +802,7 @@ VARIABLE_COMMENT Maximum number of file instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2675,7 +2675,7 @@ +@@ -2689,7 +2689,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 32768 VARIABLE_SCOPE GLOBAL @@ -811,7 +811,7 @@ VARIABLE_COMMENT Maximum number of opened instrumented files. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 1048576 -@@ -2689,7 +2689,7 @@ +@@ -2703,7 +2703,7 @@ GLOBAL_VALUE_ORIGIN CONFIG DEFAULT_VALUE -1 VARIABLE_SCOPE GLOBAL @@ -820,7 +820,7 @@ VARIABLE_COMMENT Maximum number of instrumented files. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2703,7 +2703,7 @@ +@@ -2717,7 +2717,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 200 VARIABLE_SCOPE GLOBAL @@ -829,7 +829,7 @@ VARIABLE_COMMENT Maximum number of mutex instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2717,7 +2717,7 @@ +@@ -2731,7 +2731,7 @@ GLOBAL_VALUE_ORIGIN CONFIG DEFAULT_VALUE -1 VARIABLE_SCOPE GLOBAL @@ -838,7 +838,7 @@ VARIABLE_COMMENT Maximum number of instrumented MUTEX objects. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 104857600 -@@ -2731,7 +2731,7 @@ +@@ -2745,7 +2745,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 40 VARIABLE_SCOPE GLOBAL @@ -847,7 +847,7 @@ VARIABLE_COMMENT Maximum number of rwlock instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2745,7 +2745,7 @@ +@@ -2759,7 +2759,7 @@ GLOBAL_VALUE_ORIGIN CONFIG DEFAULT_VALUE -1 VARIABLE_SCOPE GLOBAL @@ -856,7 +856,7 @@ VARIABLE_COMMENT Maximum number of instrumented RWLOCK objects. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 104857600 -@@ -2759,7 +2759,7 @@ +@@ -2773,7 +2773,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 10 VARIABLE_SCOPE GLOBAL @@ -865,7 +865,7 @@ VARIABLE_COMMENT Maximum number of socket instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2773,7 +2773,7 @@ +@@ -2787,7 +2787,7 @@ GLOBAL_VALUE_ORIGIN CONFIG DEFAULT_VALUE -1 VARIABLE_SCOPE GLOBAL @@ -874,7 +874,7 @@ VARIABLE_COMMENT Maximum number of opened instrumented sockets. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2787,7 +2787,7 @@ +@@ -2801,7 +2801,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 150 VARIABLE_SCOPE GLOBAL @@ -883,7 +883,7 @@ VARIABLE_COMMENT Maximum number of stage instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2801,7 +2801,7 @@ +@@ -2815,7 +2815,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 178 VARIABLE_SCOPE GLOBAL @@ -892,7 +892,7 @@ VARIABLE_COMMENT Maximum number of statement instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2815,7 +2815,7 @@ +@@ -2829,7 +2829,7 @@ GLOBAL_VALUE_ORIGIN CONFIG DEFAULT_VALUE -1 VARIABLE_SCOPE GLOBAL @@ -901,7 +901,7 @@ VARIABLE_COMMENT Maximum number of opened instrumented tables. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2829,7 +2829,7 @@ +@@ -2843,7 +2843,7 @@ GLOBAL_VALUE_ORIGIN CONFIG DEFAULT_VALUE -1 VARIABLE_SCOPE GLOBAL @@ -910,7 +910,7 @@ VARIABLE_COMMENT Maximum number of instrumented tables. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2843,7 +2843,7 @@ +@@ -2857,7 +2857,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 50 VARIABLE_SCOPE GLOBAL @@ -919,7 +919,7 @@ VARIABLE_COMMENT Maximum number of thread instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2857,7 +2857,7 @@ +@@ -2871,7 +2871,7 @@ GLOBAL_VALUE_ORIGIN CONFIG DEFAULT_VALUE -1 VARIABLE_SCOPE GLOBAL @@ -928,7 +928,7 @@ VARIABLE_COMMENT Maximum number of instrumented threads. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2871,7 +2871,7 @@ +@@ -2885,7 +2885,7 @@ GLOBAL_VALUE_ORIGIN CONFIG DEFAULT_VALUE -1 VARIABLE_SCOPE GLOBAL @@ -937,7 +937,7 @@ VARIABLE_COMMENT Size of session attribute string buffer per thread. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2885,7 +2885,7 @@ +@@ -2899,7 +2899,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 100 VARIABLE_SCOPE GLOBAL @@ -946,7 +946,7 @@ VARIABLE_COMMENT Maximum number of rows in SETUP_ACTORS. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 1024 -@@ -2899,7 +2899,7 @@ +@@ -2913,7 +2913,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 100 VARIABLE_SCOPE GLOBAL @@ -955,7 +955,7 @@ VARIABLE_COMMENT Maximum number of rows in SETUP_OBJECTS. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 1048576 -@@ -2913,7 +2913,7 @@ +@@ -2927,7 +2927,7 @@ GLOBAL_VALUE_ORIGIN CONFIG DEFAULT_VALUE -1 VARIABLE_SCOPE GLOBAL @@ -964,7 +964,7 @@ VARIABLE_COMMENT Maximum number of instrumented users. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2983,7 +2983,7 @@ +@@ -2997,7 +2997,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 32768 VARIABLE_SCOPE SESSION @@ -973,7 +973,7 @@ VARIABLE_COMMENT The size of the buffer that is allocated when preloading indexes NUMERIC_MIN_VALUE 1024 NUMERIC_MAX_VALUE 1073741824 -@@ -3011,7 +3011,7 @@ +@@ -3025,7 +3025,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 15 VARIABLE_SCOPE SESSION @@ -982,7 +982,7 @@ VARIABLE_COMMENT Limit of query profiling memory NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 100 -@@ -3025,7 +3025,7 @@ +@@ -3039,7 +3039,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 5 VARIABLE_SCOPE SESSION @@ -991,7 +991,7 @@ VARIABLE_COMMENT Seconds between sending progress reports to the client for time-consuming statements. Set to 0 to disable progress reporting. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 -@@ -3081,10 +3081,10 @@ +@@ -3095,10 +3095,10 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 0 VARIABLE_SCOPE SESSION ONLY @@ -1004,7 +1004,7 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -3095,7 +3095,7 @@ +@@ -3109,7 +3109,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 16384 VARIABLE_SCOPE SESSION @@ -1013,7 +1013,7 @@ VARIABLE_COMMENT Allocation block size for query parsing and execution NUMERIC_MIN_VALUE 1024 NUMERIC_MAX_VALUE 4294967295 -@@ -3109,7 +3109,7 @@ +@@ -3123,7 +3123,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 1048576 VARIABLE_SCOPE GLOBAL @@ -1022,7 +1022,7 @@ VARIABLE_COMMENT Don't cache results that are bigger than this NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 -@@ -3123,7 +3123,7 @@ +@@ -3137,7 +3137,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 4096 VARIABLE_SCOPE GLOBAL @@ -1031,7 +1031,7 @@ VARIABLE_COMMENT The minimum size for blocks allocated by the query cache NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 -@@ -3140,7 +3140,7 @@ +@@ -3154,7 +3154,7 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT The memory allocated to store results from old queries NUMERIC_MIN_VALUE 0 @@ -1040,7 +1040,7 @@ NUMERIC_BLOCK_SIZE 1024 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -3193,7 +3193,7 @@ +@@ -3207,7 +3207,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 24576 VARIABLE_SCOPE SESSION @@ -1049,7 +1049,7 @@ VARIABLE_COMMENT Persistent buffer for query parsing and execution NUMERIC_MIN_VALUE 1024 NUMERIC_MAX_VALUE 4294967295 -@@ -3207,7 +3207,7 @@ +@@ -3221,7 +3221,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 4096 VARIABLE_SCOPE SESSION @@ -1058,7 +1058,7 @@ VARIABLE_COMMENT Allocation block size for storing ranges during optimization NUMERIC_MIN_VALUE 4096 NUMERIC_MAX_VALUE 4294967295 -@@ -3221,7 +3221,7 @@ +@@ -3235,7 +3235,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 131072 VARIABLE_SCOPE SESSION @@ -1067,7 +1067,7 @@ VARIABLE_COMMENT Each thread that does a sequential scan allocates a buffer of this size for each table it scans. If you do many sequential scans, you may want to increase this value NUMERIC_MIN_VALUE 8192 NUMERIC_MAX_VALUE 2147483647 -@@ -3249,7 +3249,7 @@ +@@ -3263,7 +3263,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 262144 VARIABLE_SCOPE SESSION @@ -1076,7 +1076,7 @@ VARIABLE_COMMENT When reading rows in sorted order after a sort, the rows are read through this buffer to avoid a disk seeks NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 2147483647 -@@ -3263,10 +3263,10 @@ +@@ -3277,10 +3277,10 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 8388608 VARIABLE_SCOPE SESSION @@ -1089,7 +1089,7 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -3305,7 +3305,7 @@ +@@ -3319,7 +3319,7 @@ GLOBAL_VALUE_ORIGIN CONFIG DEFAULT_VALUE 0 VARIABLE_SCOPE SESSION @@ -1098,7 +1098,7 @@ VARIABLE_COMMENT Uniquely identifies the server instance in the community of replication partners NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 -@@ -3403,7 +3403,7 @@ +@@ -3417,7 +3417,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 1073741824 VARIABLE_SCOPE GLOBAL @@ -1107,7 +1107,7 @@ VARIABLE_COMMENT The maximum packet length to sent successfully from the master to slave. NUMERIC_MIN_VALUE 1024 NUMERIC_MAX_VALUE 1073741824 -@@ -3417,7 +3417,7 @@ +@@ -3431,7 +3431,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 2 VARIABLE_SCOPE GLOBAL @@ -1116,7 +1116,7 @@ VARIABLE_COMMENT If creating the thread takes longer than this value (in seconds), the Slow_launch_threads counter will be incremented NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 31536000 -@@ -3476,7 +3476,7 @@ +@@ -3490,7 +3490,7 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT Each thread that needs to do a sort allocates a buffer of this size NUMERIC_MIN_VALUE 1024 @@ -1125,7 +1125,7 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -3753,7 +3753,7 @@ +@@ -3767,7 +3767,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 256 VARIABLE_SCOPE GLOBAL @@ -1134,7 +1134,7 @@ VARIABLE_COMMENT The soft upper limit for number of cached stored routines for one connection. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 524288 -@@ -3823,7 +3823,7 @@ +@@ -3837,7 +3837,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 400 VARIABLE_SCOPE GLOBAL @@ -1143,7 +1143,7 @@ VARIABLE_COMMENT The number of cached table definitions NUMERIC_MIN_VALUE 400 NUMERIC_MAX_VALUE 524288 -@@ -3837,7 +3837,7 @@ +@@ -3851,7 +3851,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 2000 VARIABLE_SCOPE GLOBAL @@ -1152,7 +1152,7 @@ VARIABLE_COMMENT The number of cached open tables NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 1048576 -@@ -3851,7 +3851,7 @@ +@@ -3865,7 +3865,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 0 VARIABLE_SCOPE GLOBAL @@ -1161,7 +1161,7 @@ VARIABLE_COMMENT How many threads we should keep in a cache for reuse NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 16384 -@@ -3865,7 +3865,7 @@ +@@ -3879,7 +3879,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 10 VARIABLE_SCOPE GLOBAL @@ -1170,7 +1170,7 @@ VARIABLE_COMMENT Permits the application to give the threads system a hint for the desired number of threads that should be run at the same time.This variable has no effect, and is deprecated. It will be removed in a future release. NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 512 -@@ -3980,7 +3980,7 @@ +@@ -3994,7 +3994,7 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT If an internal in-memory temporary table exceeds this size, MySQL will automatically convert it to an on-disk MyISAM or Aria table NUMERIC_MIN_VALUE 1024 @@ -1179,7 +1179,7 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -3991,7 +3991,7 @@ +@@ -4005,7 +4005,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 8192 VARIABLE_SCOPE SESSION @@ -1188,7 +1188,7 @@ VARIABLE_COMMENT Allocation block size for transactions to be stored in binary log NUMERIC_MIN_VALUE 1024 NUMERIC_MAX_VALUE 134217728 -@@ -4005,7 +4005,7 @@ +@@ -4019,7 +4019,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 4096 VARIABLE_SCOPE SESSION @@ -1197,7 +1197,7 @@ VARIABLE_COMMENT Persistent buffer for transactions to be stored in binary log NUMERIC_MIN_VALUE 1024 NUMERIC_MAX_VALUE 134217728 -@@ -4103,7 +4103,7 @@ +@@ -4117,7 +4117,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 28800 VARIABLE_SCOPE SESSION @@ -1206,7 +1206,7 @@ VARIABLE_COMMENT The number of seconds the server waits for activity on a connection before closing it NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 31536000 -@@ -4207,7 +4207,7 @@ +@@ -4221,7 +4221,7 @@ COMMAND_LINE_ARGUMENT OPTIONAL VARIABLE_NAME OPEN_FILES_LIMIT VARIABLE_SCOPE GLOBAL @@ -1215,7 +1215,7 @@ VARIABLE_COMMENT If this is not 0, then mysqld will use this value to reserve file descriptors to use with setrlimit(). If this value is 0 then mysqld will reserve max_connections*5 or max_connections + table_cache*2 (whichever is larger) number of file descriptors NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 -@@ -4220,7 +4220,7 @@ +@@ -4234,7 +4234,7 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT Sets the internal state of the RAND() generator for replication purposes NUMERIC_MIN_VALUE 0 @@ -1224,7 +1224,7 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -4230,7 +4230,7 @@ +@@ -4244,7 +4244,7 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT Sets the internal state of the RAND() generator for replication purposes NUMERIC_MIN_VALUE 0 @@ -1233,7 +1233,7 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -4315,7 +4315,7 @@ +@@ -4329,7 +4329,7 @@ VARIABLE_NAME LOG_TC_SIZE GLOBAL_VALUE_ORIGIN AUTO VARIABLE_SCOPE GLOBAL diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result index dfac2966558..7d728bc89dc 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result +++ b/mysql-test/suite/sys_vars/r/sysvars_server_embedded.result @@ -1997,6 +1997,20 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO COMMAND_LINE_ARGUMENT REQUIRED +VARIABLE_NAME MAX_SESSION_MEM_USED +SESSION_VALUE 9223372036854775807 +GLOBAL_VALUE 9223372036854775807 +GLOBAL_VALUE_ORIGIN COMPILE-TIME +DEFAULT_VALUE 9223372036854775807 +VARIABLE_SCOPE SESSION +VARIABLE_TYPE BIGINT UNSIGNED +VARIABLE_COMMENT Amount of memory a single user session is allowed to allocate. This limits the value of the session variable MEM_USED +NUMERIC_MIN_VALUE 8192 +NUMERIC_MAX_VALUE 18446744073709551615 +NUMERIC_BLOCK_SIZE 1 +ENUM_VALUE_LIST NULL +READ_ONLY NO +COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME MAX_SORT_LENGTH SESSION_VALUE 1024 GLOBAL_VALUE 1024 diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded,32bit.rdiff b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded,32bit.rdiff index 2246560d45a..918bee1e007 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded,32bit.rdiff +++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded,32bit.rdiff @@ -1,5 +1,5 @@ ---- suite/sys_vars/r/sysvars_server_notembedded.result 2016-03-22 21:25:49.000000000 +0100 -+++ suite/sys_vars/r/sysvars_server_notembedded.reject 2016-03-23 01:11:50.000000000 +0100 +--- sysvars_server_notembedded.result ++++ sysvars_server_notembedded,32bit.result~ @@ -57,7 +57,7 @@ GLOBAL_VALUE_ORIGIN CONFIG DEFAULT_VALUE 1 @@ -476,7 +476,7 @@ VARIABLE_COMMENT Maximum stored procedure recursion depth NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 255 -@@ -2241,7 +2241,7 @@ +@@ -2255,7 +2255,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 32 VARIABLE_SCOPE SESSION @@ -485,7 +485,7 @@ VARIABLE_COMMENT Unused, will be removed. NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 4294967295 -@@ -2269,7 +2269,7 @@ +@@ -2283,7 +2283,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 4294967295 VARIABLE_SCOPE GLOBAL @@ -494,7 +494,7 @@ VARIABLE_COMMENT After this many write locks, allow some read locks to run in between NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 4294967295 -@@ -2283,7 +2283,7 @@ +@@ -2297,7 +2297,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 1024 VARIABLE_SCOPE GLOBAL @@ -503,7 +503,7 @@ VARIABLE_COMMENT Unused NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 1048576 -@@ -2297,7 +2297,7 @@ +@@ -2311,7 +2311,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 8 VARIABLE_SCOPE GLOBAL @@ -512,7 +512,7 @@ VARIABLE_COMMENT Unused NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 1024 -@@ -2311,7 +2311,7 @@ +@@ -2325,7 +2325,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 0 VARIABLE_SCOPE SESSION @@ -521,7 +521,7 @@ VARIABLE_COMMENT Don't write queries to slow log that examine fewer rows than that NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 -@@ -2325,7 +2325,7 @@ +@@ -2339,7 +2339,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 262144 VARIABLE_SCOPE SESSION @@ -530,7 +530,7 @@ VARIABLE_COMMENT Size of buffer to use when using MRR with range access NUMERIC_MIN_VALUE 8192 NUMERIC_MAX_VALUE 2147483647 -@@ -2339,10 +2339,10 @@ +@@ -2353,10 +2353,10 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 256 VARIABLE_SCOPE SESSION @@ -543,7 +543,7 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -2353,7 +2353,7 @@ +@@ -2367,7 +2367,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 1024 VARIABLE_SCOPE GLOBAL @@ -552,7 +552,7 @@ VARIABLE_COMMENT Block size to be used for MyISAM index pages NUMERIC_MIN_VALUE 1024 NUMERIC_MAX_VALUE 16384 -@@ -2367,7 +2367,7 @@ +@@ -2381,7 +2381,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 6 VARIABLE_SCOPE GLOBAL @@ -561,7 +561,7 @@ VARIABLE_COMMENT Default pointer size to be used for MyISAM tables NUMERIC_MIN_VALUE 2 NUMERIC_MAX_VALUE 7 -@@ -2377,9 +2377,9 @@ +@@ -2391,9 +2391,9 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME MYISAM_MAX_SORT_FILE_SIZE SESSION_VALUE NULL @@ -573,7 +573,7 @@ VARIABLE_SCOPE GLOBAL VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT Don't use the fast sort index method to created index if the temporary file would get bigger than this -@@ -2391,14 +2391,14 @@ +@@ -2405,14 +2405,14 @@ COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME MYISAM_MMAP_SIZE SESSION_VALUE NULL @@ -591,7 +591,7 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY YES -@@ -2423,10 +2423,10 @@ +@@ -2437,10 +2437,10 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 1 VARIABLE_SCOPE SESSION @@ -604,7 +604,7 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -2440,7 +2440,7 @@ +@@ -2454,7 +2454,7 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT The buffer that is allocated when sorting the index when doing a REPAIR or when creating indexes with CREATE INDEX or ALTER TABLE NUMERIC_MIN_VALUE 4096 @@ -613,7 +613,7 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -2493,7 +2493,7 @@ +@@ -2507,7 +2507,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 16384 VARIABLE_SCOPE SESSION @@ -622,7 +622,7 @@ VARIABLE_COMMENT Buffer length for TCP/IP and socket communication NUMERIC_MIN_VALUE 1024 NUMERIC_MAX_VALUE 1048576 -@@ -2507,7 +2507,7 @@ +@@ -2521,7 +2521,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 30 VARIABLE_SCOPE SESSION @@ -631,7 +631,7 @@ VARIABLE_COMMENT Number of seconds to wait for more data from a connection before aborting the read NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 31536000 -@@ -2521,7 +2521,7 @@ +@@ -2535,7 +2535,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 10 VARIABLE_SCOPE SESSION @@ -640,7 +640,7 @@ VARIABLE_COMMENT If a read on a communication port is interrupted, retry this many times before giving up NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 4294967295 -@@ -2535,7 +2535,7 @@ +@@ -2549,7 +2549,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 60 VARIABLE_SCOPE SESSION @@ -649,7 +649,7 @@ VARIABLE_COMMENT Number of seconds to wait for a block to be written to a connection before aborting the write NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 31536000 -@@ -2605,7 +2605,7 @@ +@@ -2619,7 +2619,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 1 VARIABLE_SCOPE SESSION @@ -658,7 +658,7 @@ VARIABLE_COMMENT Controls the heuristic(s) applied during query optimization to prune less-promising partial plans from the optimizer search space. Meaning: 0 - do not apply any heuristic, thus perform exhaustive search; 1 - prune plans based on number of retrieved rows NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 1 -@@ -2619,7 +2619,7 @@ +@@ -2633,7 +2633,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 62 VARIABLE_SCOPE SESSION @@ -667,7 +667,7 @@ VARIABLE_COMMENT Maximum depth of search performed by the query optimizer. Values larger than the number of relations in a query result in better query plans, but take longer to compile a query. Values smaller than the number of tables in a relation result in faster optimization, but may produce very bad query plans. If set to 0, the system will automatically pick a reasonable value; if set to 63, the optimizer will switch to the original find_best search. NOTE: The value 63 and its associated behaviour is deprecated NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 63 -@@ -2633,7 +2633,7 @@ +@@ -2647,7 +2647,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 100 VARIABLE_SCOPE SESSION @@ -676,7 +676,7 @@ VARIABLE_COMMENT Controls number of record samples to check condition selectivity NUMERIC_MIN_VALUE 10 NUMERIC_MAX_VALUE 4294967295 -@@ -2661,7 +2661,7 @@ +@@ -2675,7 +2675,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 1 VARIABLE_SCOPE SESSION @@ -685,7 +685,7 @@ VARIABLE_COMMENT Controls selectivity of which conditions the optimizer takes into account to calculate cardinality of a partial join when it searches for the best execution plan Meaning: 1 - use selectivity of index backed range conditions to calculate the cardinality of a partial join if the last joined table is accessed by full table scan or an index scan, 2 - use selectivity of index backed range conditions to calculate the cardinality of a partial join in any case, 3 - additionally always use selectivity of range conditions that are not backed by any index to calculate the cardinality of a partial join, 4 - use histograms to calculate selectivity of range conditions that are not backed by any index to calculate the cardinality of a partial join.5 - additionally use selectivity of certain non-range predicates calculated on record samples NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 5 -@@ -2689,7 +2689,7 @@ +@@ -2703,7 +2703,7 @@ GLOBAL_VALUE_ORIGIN CONFIG DEFAULT_VALUE -1 VARIABLE_SCOPE GLOBAL @@ -694,7 +694,7 @@ VARIABLE_COMMENT Maximum number of instrumented user@host accounts. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2703,7 +2703,7 @@ +@@ -2717,7 +2717,7 @@ GLOBAL_VALUE_ORIGIN CONFIG DEFAULT_VALUE -1 VARIABLE_SCOPE GLOBAL @@ -703,7 +703,7 @@ VARIABLE_COMMENT Size of the statement digest. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 200 -@@ -2717,7 +2717,7 @@ +@@ -2731,7 +2731,7 @@ GLOBAL_VALUE_ORIGIN CONFIG DEFAULT_VALUE -1 VARIABLE_SCOPE GLOBAL @@ -712,7 +712,7 @@ VARIABLE_COMMENT Number of rows in EVENTS_STAGES_HISTORY_LONG. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2731,7 +2731,7 @@ +@@ -2745,7 +2745,7 @@ GLOBAL_VALUE_ORIGIN CONFIG DEFAULT_VALUE -1 VARIABLE_SCOPE GLOBAL @@ -721,7 +721,7 @@ VARIABLE_COMMENT Number of rows per thread in EVENTS_STAGES_HISTORY. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1024 -@@ -2745,7 +2745,7 @@ +@@ -2759,7 +2759,7 @@ GLOBAL_VALUE_ORIGIN CONFIG DEFAULT_VALUE -1 VARIABLE_SCOPE GLOBAL @@ -730,7 +730,7 @@ VARIABLE_COMMENT Number of rows in EVENTS_STATEMENTS_HISTORY_LONG. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2759,7 +2759,7 @@ +@@ -2773,7 +2773,7 @@ GLOBAL_VALUE_ORIGIN CONFIG DEFAULT_VALUE -1 VARIABLE_SCOPE GLOBAL @@ -739,7 +739,7 @@ VARIABLE_COMMENT Number of rows per thread in EVENTS_STATEMENTS_HISTORY. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1024 -@@ -2773,7 +2773,7 @@ +@@ -2787,7 +2787,7 @@ GLOBAL_VALUE_ORIGIN CONFIG DEFAULT_VALUE -1 VARIABLE_SCOPE GLOBAL @@ -748,7 +748,7 @@ VARIABLE_COMMENT Number of rows in EVENTS_WAITS_HISTORY_LONG. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2787,7 +2787,7 @@ +@@ -2801,7 +2801,7 @@ GLOBAL_VALUE_ORIGIN CONFIG DEFAULT_VALUE -1 VARIABLE_SCOPE GLOBAL @@ -757,7 +757,7 @@ VARIABLE_COMMENT Number of rows per thread in EVENTS_WAITS_HISTORY. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1024 -@@ -2801,7 +2801,7 @@ +@@ -2815,7 +2815,7 @@ GLOBAL_VALUE_ORIGIN CONFIG DEFAULT_VALUE -1 VARIABLE_SCOPE GLOBAL @@ -766,7 +766,7 @@ VARIABLE_COMMENT Maximum number of instrumented hosts. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2815,7 +2815,7 @@ +@@ -2829,7 +2829,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 80 VARIABLE_SCOPE GLOBAL @@ -775,7 +775,7 @@ VARIABLE_COMMENT Maximum number of condition instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2829,7 +2829,7 @@ +@@ -2843,7 +2843,7 @@ GLOBAL_VALUE_ORIGIN CONFIG DEFAULT_VALUE -1 VARIABLE_SCOPE GLOBAL @@ -784,7 +784,7 @@ VARIABLE_COMMENT Maximum number of instrumented condition objects. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2843,7 +2843,7 @@ +@@ -2857,7 +2857,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 1024 VARIABLE_SCOPE GLOBAL @@ -793,7 +793,7 @@ VARIABLE_COMMENT Maximum length considered for digest text, when stored in performance_schema tables. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 1048576 -@@ -2857,7 +2857,7 @@ +@@ -2871,7 +2871,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 50 VARIABLE_SCOPE GLOBAL @@ -802,7 +802,7 @@ VARIABLE_COMMENT Maximum number of file instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2871,7 +2871,7 @@ +@@ -2885,7 +2885,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 32768 VARIABLE_SCOPE GLOBAL @@ -811,7 +811,7 @@ VARIABLE_COMMENT Maximum number of opened instrumented files. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 1048576 -@@ -2885,7 +2885,7 @@ +@@ -2899,7 +2899,7 @@ GLOBAL_VALUE_ORIGIN CONFIG DEFAULT_VALUE -1 VARIABLE_SCOPE GLOBAL @@ -820,7 +820,7 @@ VARIABLE_COMMENT Maximum number of instrumented files. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2899,7 +2899,7 @@ +@@ -2913,7 +2913,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 200 VARIABLE_SCOPE GLOBAL @@ -829,7 +829,7 @@ VARIABLE_COMMENT Maximum number of mutex instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2913,7 +2913,7 @@ +@@ -2927,7 +2927,7 @@ GLOBAL_VALUE_ORIGIN CONFIG DEFAULT_VALUE -1 VARIABLE_SCOPE GLOBAL @@ -838,7 +838,7 @@ VARIABLE_COMMENT Maximum number of instrumented MUTEX objects. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 104857600 -@@ -2927,7 +2927,7 @@ +@@ -2941,7 +2941,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 40 VARIABLE_SCOPE GLOBAL @@ -847,7 +847,7 @@ VARIABLE_COMMENT Maximum number of rwlock instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2941,7 +2941,7 @@ +@@ -2955,7 +2955,7 @@ GLOBAL_VALUE_ORIGIN CONFIG DEFAULT_VALUE -1 VARIABLE_SCOPE GLOBAL @@ -856,7 +856,7 @@ VARIABLE_COMMENT Maximum number of instrumented RWLOCK objects. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 104857600 -@@ -2955,7 +2955,7 @@ +@@ -2969,7 +2969,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 10 VARIABLE_SCOPE GLOBAL @@ -865,7 +865,7 @@ VARIABLE_COMMENT Maximum number of socket instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2969,7 +2969,7 @@ +@@ -2983,7 +2983,7 @@ GLOBAL_VALUE_ORIGIN CONFIG DEFAULT_VALUE -1 VARIABLE_SCOPE GLOBAL @@ -874,7 +874,7 @@ VARIABLE_COMMENT Maximum number of opened instrumented sockets. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -2983,7 +2983,7 @@ +@@ -2997,7 +2997,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 150 VARIABLE_SCOPE GLOBAL @@ -883,7 +883,7 @@ VARIABLE_COMMENT Maximum number of stage instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -2997,7 +2997,7 @@ +@@ -3011,7 +3011,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 178 VARIABLE_SCOPE GLOBAL @@ -892,7 +892,7 @@ VARIABLE_COMMENT Maximum number of statement instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -3011,7 +3011,7 @@ +@@ -3025,7 +3025,7 @@ GLOBAL_VALUE_ORIGIN CONFIG DEFAULT_VALUE -1 VARIABLE_SCOPE GLOBAL @@ -901,7 +901,7 @@ VARIABLE_COMMENT Maximum number of opened instrumented tables. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -3025,7 +3025,7 @@ +@@ -3039,7 +3039,7 @@ GLOBAL_VALUE_ORIGIN CONFIG DEFAULT_VALUE -1 VARIABLE_SCOPE GLOBAL @@ -910,7 +910,7 @@ VARIABLE_COMMENT Maximum number of instrumented tables. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -3039,7 +3039,7 @@ +@@ -3053,7 +3053,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 50 VARIABLE_SCOPE GLOBAL @@ -919,7 +919,7 @@ VARIABLE_COMMENT Maximum number of thread instruments. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 256 -@@ -3053,7 +3053,7 @@ +@@ -3067,7 +3067,7 @@ GLOBAL_VALUE_ORIGIN CONFIG DEFAULT_VALUE -1 VARIABLE_SCOPE GLOBAL @@ -928,7 +928,7 @@ VARIABLE_COMMENT Maximum number of instrumented threads. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -3067,7 +3067,7 @@ +@@ -3081,7 +3081,7 @@ GLOBAL_VALUE_ORIGIN CONFIG DEFAULT_VALUE -1 VARIABLE_SCOPE GLOBAL @@ -937,7 +937,7 @@ VARIABLE_COMMENT Size of session attribute string buffer per thread. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -3081,7 +3081,7 @@ +@@ -3095,7 +3095,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 100 VARIABLE_SCOPE GLOBAL @@ -946,7 +946,7 @@ VARIABLE_COMMENT Maximum number of rows in SETUP_ACTORS. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 1024 -@@ -3095,7 +3095,7 @@ +@@ -3109,7 +3109,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 100 VARIABLE_SCOPE GLOBAL @@ -955,7 +955,7 @@ VARIABLE_COMMENT Maximum number of rows in SETUP_OBJECTS. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 1048576 -@@ -3109,7 +3109,7 @@ +@@ -3123,7 +3123,7 @@ GLOBAL_VALUE_ORIGIN CONFIG DEFAULT_VALUE -1 VARIABLE_SCOPE GLOBAL @@ -964,7 +964,7 @@ VARIABLE_COMMENT Maximum number of instrumented users. Use 0 to disable, -1 for automated sizing. NUMERIC_MIN_VALUE -1 NUMERIC_MAX_VALUE 1048576 -@@ -3179,7 +3179,7 @@ +@@ -3193,7 +3193,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 32768 VARIABLE_SCOPE SESSION @@ -973,7 +973,7 @@ VARIABLE_COMMENT The size of the buffer that is allocated when preloading indexes NUMERIC_MIN_VALUE 1024 NUMERIC_MAX_VALUE 1073741824 -@@ -3207,7 +3207,7 @@ +@@ -3221,7 +3221,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 15 VARIABLE_SCOPE SESSION @@ -982,7 +982,7 @@ VARIABLE_COMMENT Limit of query profiling memory NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 100 -@@ -3221,7 +3221,7 @@ +@@ -3235,7 +3235,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 5 VARIABLE_SCOPE SESSION @@ -991,7 +991,7 @@ VARIABLE_COMMENT Seconds between sending progress reports to the client for time-consuming statements. Set to 0 to disable progress reporting. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 -@@ -3277,10 +3277,10 @@ +@@ -3291,10 +3291,10 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 0 VARIABLE_SCOPE SESSION ONLY @@ -1004,7 +1004,7 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -3291,7 +3291,7 @@ +@@ -3305,7 +3305,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 16384 VARIABLE_SCOPE SESSION @@ -1013,7 +1013,7 @@ VARIABLE_COMMENT Allocation block size for query parsing and execution NUMERIC_MIN_VALUE 1024 NUMERIC_MAX_VALUE 4294967295 -@@ -3305,7 +3305,7 @@ +@@ -3319,7 +3319,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 1048576 VARIABLE_SCOPE GLOBAL @@ -1022,7 +1022,7 @@ VARIABLE_COMMENT Don't cache results that are bigger than this NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 -@@ -3319,7 +3319,7 @@ +@@ -3333,7 +3333,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 4096 VARIABLE_SCOPE GLOBAL @@ -1031,7 +1031,7 @@ VARIABLE_COMMENT The minimum size for blocks allocated by the query cache NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 -@@ -3336,7 +3336,7 @@ +@@ -3350,7 +3350,7 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT The memory allocated to store results from old queries NUMERIC_MIN_VALUE 0 @@ -1040,7 +1040,7 @@ NUMERIC_BLOCK_SIZE 1024 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -3389,7 +3389,7 @@ +@@ -3403,7 +3403,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 24576 VARIABLE_SCOPE SESSION @@ -1049,7 +1049,7 @@ VARIABLE_COMMENT Persistent buffer for query parsing and execution NUMERIC_MIN_VALUE 1024 NUMERIC_MAX_VALUE 4294967295 -@@ -3403,7 +3403,7 @@ +@@ -3417,7 +3417,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 4096 VARIABLE_SCOPE SESSION @@ -1058,7 +1058,7 @@ VARIABLE_COMMENT Allocation block size for storing ranges during optimization NUMERIC_MIN_VALUE 4096 NUMERIC_MAX_VALUE 4294967295 -@@ -3417,7 +3417,7 @@ +@@ -3431,7 +3431,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 131072 VARIABLE_SCOPE SESSION @@ -1067,7 +1067,7 @@ VARIABLE_COMMENT Each thread that does a sequential scan allocates a buffer of this size for each table it scans. If you do many sequential scans, you may want to increase this value NUMERIC_MIN_VALUE 8192 NUMERIC_MAX_VALUE 2147483647 -@@ -3445,7 +3445,7 @@ +@@ -3459,7 +3459,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 262144 VARIABLE_SCOPE SESSION @@ -1076,7 +1076,7 @@ VARIABLE_COMMENT When reading rows in sorted order after a sort, the rows are read through this buffer to avoid a disk seeks NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 2147483647 -@@ -3725,10 +3725,10 @@ +@@ -3739,10 +3739,10 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 8388608 VARIABLE_SCOPE SESSION @@ -1089,7 +1089,7 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -3767,7 +3767,7 @@ +@@ -3781,7 +3781,7 @@ GLOBAL_VALUE_ORIGIN CONFIG DEFAULT_VALUE 0 VARIABLE_SCOPE SESSION @@ -1098,7 +1098,7 @@ VARIABLE_COMMENT Uniquely identifies the server instance in the community of replication partners NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 -@@ -3893,7 +3893,7 @@ +@@ -3907,7 +3907,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 0 VARIABLE_SCOPE GLOBAL @@ -1107,7 +1107,7 @@ VARIABLE_COMMENT Maximum number of parallel threads to use on slave for events in a single replication domain. When using multiple domains, this can be used to limit a single domain from grabbing all threads and thus stalling other domains. The default of 0 means to allow a domain to grab as many threads as it wants, up to the value of slave_parallel_threads. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 16383 -@@ -3935,7 +3935,7 @@ +@@ -3949,7 +3949,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 1073741824 VARIABLE_SCOPE GLOBAL @@ -1116,7 +1116,7 @@ VARIABLE_COMMENT The maximum packet length to sent successfully from the master to slave. NUMERIC_MIN_VALUE 1024 NUMERIC_MAX_VALUE 1073741824 -@@ -3963,7 +3963,7 @@ +@@ -3977,7 +3977,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 131072 VARIABLE_SCOPE GLOBAL @@ -1125,7 +1125,7 @@ VARIABLE_COMMENT Limit on how much memory SQL threads should use per parallel replication thread when reading ahead in the relay log looking for opportunities for parallel replication. Only used when --slave-parallel-threads > 0. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 2147483647 -@@ -3991,7 +3991,7 @@ +@@ -4005,7 +4005,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 0 VARIABLE_SCOPE GLOBAL @@ -1134,7 +1134,7 @@ VARIABLE_COMMENT If non-zero, number of threads to spawn to apply in parallel events on the slave that were group-committed on the master or were logged with GTID in different replication domains. Note that these threads are in addition to the IO and SQL threads, which are always created by a replication slave NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 16383 -@@ -4047,7 +4047,7 @@ +@@ -4061,7 +4061,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 10 VARIABLE_SCOPE GLOBAL @@ -1143,7 +1143,7 @@ VARIABLE_COMMENT Number of times the slave SQL thread will retry a transaction in case it failed with a deadlock or elapsed lock wait timeout, before giving up and stopping NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 -@@ -4075,7 +4075,7 @@ +@@ -4089,7 +4089,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 2 VARIABLE_SCOPE GLOBAL @@ -1152,7 +1152,7 @@ VARIABLE_COMMENT If creating the thread takes longer than this value (in seconds), the Slow_launch_threads counter will be incremented NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 31536000 -@@ -4134,7 +4134,7 @@ +@@ -4148,7 +4148,7 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT Each thread that needs to do a sort allocates a buffer of this size NUMERIC_MIN_VALUE 1024 @@ -1161,7 +1161,7 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -4425,7 +4425,7 @@ +@@ -4439,7 +4439,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 256 VARIABLE_SCOPE GLOBAL @@ -1170,7 +1170,7 @@ VARIABLE_COMMENT The soft upper limit for number of cached stored routines for one connection. NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 524288 -@@ -4523,7 +4523,7 @@ +@@ -4537,7 +4537,7 @@ GLOBAL_VALUE_ORIGIN AUTO DEFAULT_VALUE 400 VARIABLE_SCOPE GLOBAL @@ -1179,7 +1179,7 @@ VARIABLE_COMMENT The number of cached table definitions NUMERIC_MIN_VALUE 400 NUMERIC_MAX_VALUE 524288 -@@ -4537,7 +4537,7 @@ +@@ -4551,7 +4551,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 2000 VARIABLE_SCOPE GLOBAL @@ -1188,7 +1188,7 @@ VARIABLE_COMMENT The number of cached open tables NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 1048576 -@@ -4551,7 +4551,7 @@ +@@ -4565,7 +4565,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 0 VARIABLE_SCOPE GLOBAL @@ -1197,7 +1197,7 @@ VARIABLE_COMMENT How many threads we should keep in a cache for reuse NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 16384 -@@ -4565,7 +4565,7 @@ +@@ -4579,7 +4579,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 10 VARIABLE_SCOPE GLOBAL @@ -1206,7 +1206,7 @@ VARIABLE_COMMENT Permits the application to give the threads system a hint for the desired number of threads that should be run at the same time.This variable has no effect, and is deprecated. It will be removed in a future release. NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 512 -@@ -4750,7 +4750,7 @@ +@@ -4764,7 +4764,7 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT If an internal in-memory temporary table exceeds this size, MySQL will automatically convert it to an on-disk MyISAM or Aria table NUMERIC_MIN_VALUE 1024 @@ -1215,7 +1215,7 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -4761,7 +4761,7 @@ +@@ -4775,7 +4775,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 8192 VARIABLE_SCOPE SESSION @@ -1224,7 +1224,7 @@ VARIABLE_COMMENT Allocation block size for transactions to be stored in binary log NUMERIC_MIN_VALUE 1024 NUMERIC_MAX_VALUE 134217728 -@@ -4775,7 +4775,7 @@ +@@ -4789,7 +4789,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 4096 VARIABLE_SCOPE SESSION @@ -1233,7 +1233,7 @@ VARIABLE_COMMENT Persistent buffer for transactions to be stored in binary log NUMERIC_MIN_VALUE 1024 NUMERIC_MAX_VALUE 134217728 -@@ -4873,7 +4873,7 @@ +@@ -4887,7 +4887,7 @@ GLOBAL_VALUE_ORIGIN COMPILE-TIME DEFAULT_VALUE 28800 VARIABLE_SCOPE SESSION @@ -1242,7 +1242,7 @@ VARIABLE_COMMENT The number of seconds the server waits for activity on a connection before closing it NUMERIC_MIN_VALUE 1 NUMERIC_MAX_VALUE 31536000 -@@ -4977,7 +4977,7 @@ +@@ -4991,7 +4991,7 @@ COMMAND_LINE_ARGUMENT OPTIONAL VARIABLE_NAME OPEN_FILES_LIMIT VARIABLE_SCOPE GLOBAL @@ -1251,7 +1251,7 @@ VARIABLE_COMMENT If this is not 0, then mysqld will use this value to reserve file descriptors to use with setrlimit(). If this value is 0 then mysqld will reserve max_connections*5 or max_connections + table_cache*2 (whichever is larger) number of file descriptors NUMERIC_MIN_VALUE 0 NUMERIC_MAX_VALUE 4294967295 -@@ -4990,7 +4990,7 @@ +@@ -5004,7 +5004,7 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT Sets the internal state of the RAND() generator for replication purposes NUMERIC_MIN_VALUE 0 @@ -1260,7 +1260,7 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -5000,7 +5000,7 @@ +@@ -5014,7 +5014,7 @@ VARIABLE_TYPE BIGINT UNSIGNED VARIABLE_COMMENT Sets the internal state of the RAND() generator for replication purposes NUMERIC_MIN_VALUE 0 @@ -1269,7 +1269,7 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO -@@ -5085,7 +5085,7 @@ +@@ -5099,7 +5099,7 @@ VARIABLE_NAME LOG_TC_SIZE GLOBAL_VALUE_ORIGIN AUTO VARIABLE_SCOPE GLOBAL diff --git a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result index 33d1f9722df..d6c4050545d 100644 --- a/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result +++ b/mysql-test/suite/sys_vars/r/sysvars_server_notembedded.result @@ -2193,6 +2193,20 @@ NUMERIC_BLOCK_SIZE 1 ENUM_VALUE_LIST NULL READ_ONLY NO COMMAND_LINE_ARGUMENT REQUIRED +VARIABLE_NAME MAX_SESSION_MEM_USED +SESSION_VALUE 9223372036854775807 +GLOBAL_VALUE 9223372036854775807 +GLOBAL_VALUE_ORIGIN COMPILE-TIME +DEFAULT_VALUE 9223372036854775807 +VARIABLE_SCOPE SESSION +VARIABLE_TYPE BIGINT UNSIGNED +VARIABLE_COMMENT Amount of memory a single user session is allowed to allocate. This limits the value of the session variable MEM_USED +NUMERIC_MIN_VALUE 8192 +NUMERIC_MAX_VALUE 18446744073709551615 +NUMERIC_BLOCK_SIZE 1 +ENUM_VALUE_LIST NULL +READ_ONLY NO +COMMAND_LINE_ARGUMENT REQUIRED VARIABLE_NAME MAX_SORT_LENGTH SESSION_VALUE 1024 GLOBAL_VALUE 1024 diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 96baaf25287..fcb6697fed6 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -4001,6 +4001,15 @@ static void my_malloc_size_cb_func(long long size, my_bool is_thread_specific) (longlong) thd->status_var.local_memory_used, size)); thd->status_var.local_memory_used+= size; + if (thd->status_var.local_memory_used > (int64)thd->variables.max_mem_used && + !thd->killed) + { + char buf[1024]; + thd->killed= KILL_QUERY; + my_snprintf(buf, sizeof(buf), "--max-thread-mem-used=%llu", + thd->variables.max_mem_used); + my_error(ER_OPTION_PREVENTS_STATEMENT, MYF(0), buf); + } DBUG_ASSERT((longlong) thd->status_var.local_memory_used >= 0); } else if (likely(thd)) diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 4143d2cc419..c9592df1b65 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -906,8 +906,8 @@ THD::THD(bool is_wsrep_applier) #endif { ulong tmp; + bzero(&variables, sizeof(variables)); - mdl_context.init(this); /* We set THR_THD to temporally point to this THD to register all the variables that allocates memory for this THD @@ -916,8 +916,11 @@ THD::THD(bool is_wsrep_applier) set_current_thd(this); status_var.local_memory_used= sizeof(THD); status_var.global_memory_used= 0; + variables.max_mem_used= global_system_variables.max_mem_used; main_da.init(); + mdl_context.init(this); + /* Pass nominal parameters to init_alloc_root only to ensure that the destructor works OK in case of an error. The main_mem_root @@ -964,7 +967,6 @@ THD::THD(bool is_wsrep_applier) connection_name.str= 0; connection_name.length= 0; - bzero(&variables, sizeof(variables)); file_id = 0; query_id= 0; query_name_consts= 0; diff --git a/sql/sql_class.h b/sql/sql_class.h index da885c3dbac..3058d81496c 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -540,6 +540,7 @@ typedef struct system_variables ulonglong sortbuff_size; ulonglong group_concat_max_len; ulonglong default_regex_flags; + ulonglong max_mem_used; /** Place holders to store Multi-source variables in sys_var.cc during diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index bb349e78724..641f8306f98 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -5401,3 +5401,10 @@ static Sys_var_ulong Sys_log_tc_size( DEFAULT(my_getpagesize() * 6), BLOCK_SIZE(my_getpagesize())); #endif + +static Sys_var_ulonglong Sys_max_thread_mem( + "max_session_mem_used", "Amount of memory a single user session " + "is allowed to allocate. This limits the value of the " + "session variable MEM_USED", SESSION_VAR(max_mem_used), + CMD_LINE(REQUIRED_ARG), VALID_RANGE(8192, ULONGLONG_MAX), + DEFAULT(LONGLONG_MAX), BLOCK_SIZE(1)); -- cgit v1.2.1 From 5dfab33c4ec54082daf034da99c4a796410fe4f3 Mon Sep 17 00:00:00 2001 From: Sergei Golubchik Date: Thu, 12 Jan 2017 00:33:21 +0100 Subject: MDEV-11551 Server crashes in Field::is_real_null sometimes table->s->stored_fields is less than table->s->null_fields --- mysql-test/r/trigger_null-8605.result | 10 ++++++++++ mysql-test/t/trigger_null-8605.test | 14 ++++++++++++++ sql/sql_trigger.cc | 2 +- 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/mysql-test/r/trigger_null-8605.result b/mysql-test/r/trigger_null-8605.result index b187fc19554..10315988708 100644 --- a/mysql-test/r/trigger_null-8605.result +++ b/mysql-test/r/trigger_null-8605.result @@ -354,3 +354,13 @@ show columns from t1; Field Type Null Key Default Extra a int(11) NO PRI NULL drop table t1; +create table t1 ( +pk int primary key, +i int, +v1 int as (i) virtual, +v2 int as (i) virtual +); +create trigger tr before update on t1 for each row set @a = 1; +insert into t1 (pk, i) values (null, null); +ERROR 23000: Column 'pk' cannot be null +drop table t1; diff --git a/mysql-test/t/trigger_null-8605.test b/mysql-test/t/trigger_null-8605.test index 748768a1849..34a57654b48 100644 --- a/mysql-test/t/trigger_null-8605.test +++ b/mysql-test/t/trigger_null-8605.test @@ -373,3 +373,17 @@ show columns from t1; insert into t1 (a) values (3); show columns from t1; drop table t1; + +# +# MDEV-11551 Server crashes in Field::is_real_null +# +create table t1 ( + pk int primary key, + i int, + v1 int as (i) virtual, + v2 int as (i) virtual +); +create trigger tr before update on t1 for each row set @a = 1; +--error ER_BAD_NULL_ERROR +insert into t1 (pk, i) values (null, null); +drop table t1; diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index 7a61279fc9c..7bfc1e950b5 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -1082,7 +1082,7 @@ bool Table_triggers_list::prepare_record_accessors(TABLE *table) && (table->s->stored_fields != table->s->null_fields)) { - int null_bytes= (table->s->stored_fields - table->s->null_fields + 7)/8; + int null_bytes= (table->s->fields - table->s->null_fields + 7)/8; if (!(extra_null_bitmap= (uchar*)alloc_root(&table->mem_root, null_bytes))) return 1; if (!(record0_field= (Field **)alloc_root(&table->mem_root, -- cgit v1.2.1 From 9b99d9bebd32b0280e7c7514c7fe65531316ad98 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Sat, 14 Jan 2017 17:52:33 +0200 Subject: MDEV-8139: Disable a randomly failing test until the code is fixed. --- mysql-test/suite/encryption/disabled.def | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/mysql-test/suite/encryption/disabled.def b/mysql-test/suite/encryption/disabled.def index 348e4c979ea..d92d3495cb8 100644 --- a/mysql-test/suite/encryption/disabled.def +++ b/mysql-test/suite/encryption/disabled.def @@ -10,4 +10,5 @@ # ############################################################################## -innodb_scrub_background : MDEV-8139 background scrubbing does not work reliably +innodb_scrub : MDEV-8139 scrubbing does not work reliably +innodb_scrub_background : MDEV-8139 scrubbing does not work reliably -- cgit v1.2.1 From a9d00db15559749e54fd9d55cf0ff90f83604e17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Sun, 15 Jan 2017 14:20:16 +0200 Subject: MDEV-11799 InnoDB can abort if the doublewrite buffer contains a bad and a good copy Clean up the InnoDB doublewrite buffer code. buf_dblwr_init_or_load_pages(): Do not add empty pages to the buffer. buf_dblwr_process(): Do consider changes to pages that are all zero. Do not abort when finding a corrupted copy of a page in the doublewrite buffer, because there could be multiple copies in the doublewrite buffer, and only one of them needs to be good. --- .../suite/innodb/r/group_commit_crash.result | 1 - .../r/group_commit_crash_no_optimize_thread.result | 1 - .../suite/innodb/r/innodb-alter-tempfile.result | 4 - .../suite/innodb/r/innodb_bug14147491.result | 1 - mysql-test/suite/innodb/r/xa_recovery.result | 2 +- mysql-test/suite/innodb/t/group_commit_crash.test | 2 - .../t/group_commit_crash_no_optimize_thread.test | 2 - .../suite/innodb/t/innodb-alter-tempfile.test | 7 - mysql-test/suite/innodb/t/innodb_bug14147491.test | 1 - mysql-test/suite/innodb/t/xa_recovery.test | 16 +- mysql-test/suite/rpl/r/rpl_gtid_crash.result | 1 - mysql-test/suite/rpl/t/rpl_gtid_crash.test | 5 - storage/innobase/buf/buf0dblwr.cc | 222 +++++++++------------ storage/xtradb/buf/buf0dblwr.cc | 221 +++++++++----------- 14 files changed, 191 insertions(+), 295 deletions(-) diff --git a/mysql-test/suite/innodb/r/group_commit_crash.result b/mysql-test/suite/innodb/r/group_commit_crash.result index 5d5dffab33e..005049df281 100644 --- a/mysql-test/suite/innodb/r/group_commit_crash.result +++ b/mysql-test/suite/innodb/r/group_commit_crash.result @@ -1,4 +1,3 @@ -call mtr.add_suppression("InnoDB: Warning: database page corruption or a failed"); CREATE TABLE t1(a CHAR(255), b CHAR(255), c CHAR(255), diff --git a/mysql-test/suite/innodb/r/group_commit_crash_no_optimize_thread.result b/mysql-test/suite/innodb/r/group_commit_crash_no_optimize_thread.result index 542ce9d496e..846500ad2b1 100644 --- a/mysql-test/suite/innodb/r/group_commit_crash_no_optimize_thread.result +++ b/mysql-test/suite/innodb/r/group_commit_crash_no_optimize_thread.result @@ -1,4 +1,3 @@ -call mtr.add_suppression("InnoDB: Warning: database page corruption or a failed"); CREATE TABLE t1(a CHAR(255), b CHAR(255), c CHAR(255), diff --git a/mysql-test/suite/innodb/r/innodb-alter-tempfile.result b/mysql-test/suite/innodb/r/innodb-alter-tempfile.result index 3cc973ca3a3..ce13ad0978b 100644 --- a/mysql-test/suite/innodb/r/innodb-alter-tempfile.result +++ b/mysql-test/suite/innodb/r/innodb-alter-tempfile.result @@ -4,10 +4,6 @@ # Temporary tablename will be unique. This makes sure that future # in-place ALTERs of the same table will not be blocked due to # temporary tablename. -call mtr.add_suppression("InnoDB: Warning: database page corruption or a failed -"); -call mtr.add_suppression("InnoDB: file read of space .* page .*"); -call mtr.add_suppression("InnoDB: Trying to recover it from the doublewrite buffer."); # Crash the server in ha_innobase::commit_inplace_alter_table() CREATE TABLE t1 (f1 INT NOT NULL, f2 INT NOT NULL) ENGINE=innodb; SET debug='d,innodb_alter_commit_crash_before_commit'; diff --git a/mysql-test/suite/innodb/r/innodb_bug14147491.result b/mysql-test/suite/innodb/r/innodb_bug14147491.result index bd3c388fae1..5ff6f652f9e 100644 --- a/mysql-test/suite/innodb/r/innodb_bug14147491.result +++ b/mysql-test/suite/innodb/r/innodb_bug14147491.result @@ -1,6 +1,5 @@ call mtr.add_suppression("InnoDB: Database page corruption on disk or a failed.*"); CALL mtr.add_suppression("InnoDB: Error: Unable to read tablespace .* page no .* into the buffer pool after 100 attempts"); -CALL mtr.add_suppression("InnoDB: Warning: database page corruption or a failed"); CALL mtr.add_suppression("InnoDB: Database page corruption on disk or a failed"); CALL mtr.add_suppression("InnoDB: Space .* file test/t1 read of page .*"); CALL mtr.add_suppression("InnoDB: You may have to recover from a backup."); diff --git a/mysql-test/suite/innodb/r/xa_recovery.result b/mysql-test/suite/innodb/r/xa_recovery.result index e65f702c488..f429808b8dd 100644 --- a/mysql-test/suite/innodb/r/xa_recovery.result +++ b/mysql-test/suite/innodb/r/xa_recovery.result @@ -1,4 +1,3 @@ -call mtr.add_suppression("InnoDB: Warning: database page corruption or a failed"); CREATE TABLE t1 (a INT) ENGINE=InnoDB; INSERT INTO t1 VALUES (1); XA START 'x'; @@ -6,6 +5,7 @@ UPDATE t1 set a=2; XA END 'x'; XA PREPARE 'x'; call mtr.add_suppression("Found 1 prepared XA transactions"); +# Kill the server SELECT * FROM t1 LOCK IN SHARE MODE; SET TRANSACTION ISOLATION LEVEL READ UNCOMMITTED; SELECT * FROM t1; diff --git a/mysql-test/suite/innodb/t/group_commit_crash.test b/mysql-test/suite/innodb/t/group_commit_crash.test index cad349819bd..7ad0d9d1e74 100644 --- a/mysql-test/suite/innodb/t/group_commit_crash.test +++ b/mysql-test/suite/innodb/t/group_commit_crash.test @@ -9,8 +9,6 @@ --source include/have_debug.inc --source include/have_log_bin.inc -call mtr.add_suppression("InnoDB: Warning: database page corruption or a failed"); - let $file_format_max=`SELECT @@innodb_file_format_max`; CREATE TABLE t1(a CHAR(255), b CHAR(255), diff --git a/mysql-test/suite/innodb/t/group_commit_crash_no_optimize_thread.test b/mysql-test/suite/innodb/t/group_commit_crash_no_optimize_thread.test index 8d1f460b64b..9dc2557e687 100644 --- a/mysql-test/suite/innodb/t/group_commit_crash_no_optimize_thread.test +++ b/mysql-test/suite/innodb/t/group_commit_crash_no_optimize_thread.test @@ -9,8 +9,6 @@ --source include/have_debug.inc --source include/have_log_bin.inc -call mtr.add_suppression("InnoDB: Warning: database page corruption or a failed"); - let $file_format_max=`SELECT @@innodb_file_format_max`; CREATE TABLE t1(a CHAR(255), b CHAR(255), diff --git a/mysql-test/suite/innodb/t/innodb-alter-tempfile.test b/mysql-test/suite/innodb/t/innodb-alter-tempfile.test index e1e736fc678..ec1ea35f1cf 100644 --- a/mysql-test/suite/innodb/t/innodb-alter-tempfile.test +++ b/mysql-test/suite/innodb/t/innodb-alter-tempfile.test @@ -20,13 +20,6 @@ --echo # in-place ALTERs of the same table will not be blocked due to --echo # temporary tablename. -# As we intentionally crash below, there could be partially written -# pages that are then recovered from the doublewrite buffer -call mtr.add_suppression("InnoDB: Warning: database page corruption or a failed -"); -call mtr.add_suppression("InnoDB: file read of space .* page .*"); -call mtr.add_suppression("InnoDB: Trying to recover it from the doublewrite buffer."); - let datadir= `select @@datadir`; --let $_server_id= `SELECT @@server_id` diff --git a/mysql-test/suite/innodb/t/innodb_bug14147491.test b/mysql-test/suite/innodb/t/innodb_bug14147491.test index 16e88826c85..d48fa074147 100644 --- a/mysql-test/suite/innodb/t/innodb_bug14147491.test +++ b/mysql-test/suite/innodb/t/innodb_bug14147491.test @@ -21,7 +21,6 @@ source include/have_debug.inc; source include/not_windows.inc; CALL mtr.add_suppression("InnoDB: Error: Unable to read tablespace .* page no .* into the buffer pool after 100 attempts"); -CALL mtr.add_suppression("InnoDB: Warning: database page corruption or a failed"); CALL mtr.add_suppression("InnoDB: Database page corruption on disk or a failed"); CALL mtr.add_suppression("InnoDB: Space .* file test/t1 read of page .*"); CALL mtr.add_suppression("InnoDB: You may have to recover from a backup."); diff --git a/mysql-test/suite/innodb/t/xa_recovery.test b/mysql-test/suite/innodb/t/xa_recovery.test index 32373d63d14..9f25e4d1f30 100644 --- a/mysql-test/suite/innodb/t/xa_recovery.test +++ b/mysql-test/suite/innodb/t/xa_recovery.test @@ -12,11 +12,6 @@ if (`select plugin_auth_version <= "5.6.24" from information_schema.plugins wher FLUSH TABLES; --enable_query_log -# -# We kill server belown with timeout 0 that is not fully safe -# -call mtr.add_suppression("InnoDB: Warning: database page corruption or a failed"); - CREATE TABLE t1 (a INT) ENGINE=InnoDB; INSERT INTO t1 VALUES (1); connect (con1,localhost,root); @@ -25,15 +20,8 @@ connection default; call mtr.add_suppression("Found 1 prepared XA transactions"); -# Kill and restart the server. --- exec echo "wait" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --- shutdown_server 0 --- source include/wait_until_disconnected.inc - --- exec echo "restart" > $MYSQLTEST_VARDIR/tmp/mysqld.1.expect --- enable_reconnect --- source include/wait_until_connected_again.inc --- disable_reconnect +--source include/kill_mysqld.inc +--source include/start_mysqld.inc disconnect con1; connect (con1,localhost,root); diff --git a/mysql-test/suite/rpl/r/rpl_gtid_crash.result b/mysql-test/suite/rpl/r/rpl_gtid_crash.result index 0c2249f2dce..5f67901b7f5 100644 --- a/mysql-test/suite/rpl/r/rpl_gtid_crash.result +++ b/mysql-test/suite/rpl/r/rpl_gtid_crash.result @@ -3,7 +3,6 @@ include/rpl_init.inc [topology=1->2] call mtr.add_suppression("Checking table:"); call mtr.add_suppression("client is using or hasn't closed the table properly"); call mtr.add_suppression("Table .* is marked as crashed and should be repaired"); -call mtr.add_suppression("InnoDB: Warning: database page corruption or a failed"); flush tables; ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; CREATE TABLE t1 (a INT PRIMARY KEY, b INT) ENGINE=InnoDB; diff --git a/mysql-test/suite/rpl/t/rpl_gtid_crash.test b/mysql-test/suite/rpl/t/rpl_gtid_crash.test index df3ba9a3420..b81cbd38cd3 100644 --- a/mysql-test/suite/rpl/t/rpl_gtid_crash.test +++ b/mysql-test/suite/rpl/t/rpl_gtid_crash.test @@ -12,11 +12,6 @@ call mtr.add_suppression("Checking table:"); call mtr.add_suppression("client is using or hasn't closed the table properly"); call mtr.add_suppression("Table .* is marked as crashed and should be repaired"); -# We have seen this warning a couple of times in Buildbot. Since we crash the -# server deliberately, it seems possible that we could in rare cases crash in -# the middle of a page write. The page is recovered from the doublewrite -# buffer ("[Note] InnoDB: Recovered the page from the doublewrite buffer."). -call mtr.add_suppression("InnoDB: Warning: database page corruption or a failed"); flush tables; ALTER TABLE mysql.gtid_slave_pos ENGINE=InnoDB; diff --git a/storage/innobase/buf/buf0dblwr.cc b/storage/innobase/buf/buf0dblwr.cc index 1cf856a731f..0b42e38a655 100644 --- a/storage/innobase/buf/buf0dblwr.cc +++ b/storage/innobase/buf/buf0dblwr.cc @@ -455,8 +455,11 @@ buf_dblwr_init_or_load_pages( os_file_write(path, file, page, source_page_no * UNIV_PAGE_SIZE, UNIV_PAGE_SIZE); - } else if (load_corrupt_pages) { - + } else if (load_corrupt_pages + && !buf_page_is_zeroes(page, FIL_PAGE_DATA)) { + /* Each valid page header must contain some + nonzero bytes, such as FIL_PAGE_OFFSET + or FIL_PAGE_LSN. */ recv_dblwr.add(page); } @@ -492,8 +495,6 @@ buf_dblwr_process() for (std::list::iterator i = recv_dblwr.pages.begin(); i != recv_dblwr.pages.end(); ++i, ++page_no_dblwr ) { - bool is_compressed = false; - page = *i; page_no = mach_read_from_4(page + FIL_PAGE_OFFSET); space_id = mach_read_from_4(page + FIL_PAGE_SPACE_ID); @@ -501,139 +502,104 @@ buf_dblwr_process() if (!fil_tablespace_exists_in_mem(space_id)) { /* Maybe we have dropped the single-table tablespace and this page once belonged to it: do nothing */ + continue; + } - } else if (!fil_check_adress_in_tablespace(space_id, - page_no)) { + if (!fil_check_adress_in_tablespace(space_id, page_no)) { ib_logf(IB_LOG_LEVEL_WARN, - "A page in the doublewrite buffer is not " - "within space bounds; space id %lu " - "page number %lu, page %lu in " - "doublewrite buf.", - (ulong) space_id, (ulong) page_no, - page_no_dblwr); + "A copy of page " ULINTPF ":" ULINTPF + " in the doublewrite buffer slot " ULINTPF + " is not within space bounds", + space_id, page_no, page_no_dblwr); + continue; + } + + ulint zip_size = fil_space_get_zip_size(space_id); + ut_ad(!buf_page_is_zeroes(page, zip_size)); + + /* Read in the actual page from the file */ + fil_io(OS_FILE_READ, + true, + space_id, + zip_size, + page_no, + 0, + zip_size ? zip_size : UNIV_PAGE_SIZE, + read_buf, + NULL, + 0); + + const bool is_all_zero = buf_page_is_zeroes( + read_buf, zip_size); + + if (is_all_zero) { + /* We will check if the copy in the + doublewrite buffer is valid. If not, we will + ignore this page (there should be redo log + records to initialize it). */ } else { - ulint zip_size = fil_space_get_zip_size(space_id); - - /* Read in the actual page from the file */ - fil_io(OS_FILE_READ, - true, - space_id, - zip_size, - page_no, - 0, - zip_size ? zip_size : UNIV_PAGE_SIZE, - read_buf, - NULL, - 0); - - /* Is page compressed ? */ - is_compressed = fil_page_is_compressed_encrypted(read_buf) | - fil_page_is_compressed(read_buf); - - /* If page was compressed, decompress it before we - check checksum. */ - if (is_compressed) { - fil_decompress_page(NULL, read_buf, UNIV_PAGE_SIZE, NULL, true); + if (fil_page_is_compressed_encrypted(read_buf) || + fil_page_is_compressed(read_buf)) { + /* Decompress the page before + validating the checksum. */ + fil_decompress_page( + NULL, read_buf, UNIV_PAGE_SIZE, + NULL, true); } - if (fil_space_verify_crypt_checksum(read_buf, zip_size)) { - /* page is encrypted and checksum is OK */ - } else if (buf_page_is_corrupted(true, read_buf, zip_size)) { - - fprintf(stderr, - "InnoDB: Warning: database page" - " corruption or a failed\n" - "InnoDB: file read of" - " space %lu page %lu.\n" - "InnoDB: Trying to recover it from" - " the doublewrite buffer.\n", - (ulong) space_id, (ulong) page_no); - - /* Is page compressed ? */ - is_compressed = fil_page_is_compressed_encrypted(page) | - fil_page_is_compressed(page); - - /* If page was compressed, decompress it before we - check checksum. */ - if (is_compressed) { - fil_decompress_page(NULL, page, UNIV_PAGE_SIZE, NULL, true); - } + if (fil_space_verify_crypt_checksum( + read_buf, zip_size) + || !buf_page_is_corrupted( + true, read_buf, zip_size)) { + /* The page is good; there is no need + to consult the doublewrite buffer. */ + continue; + } - if (fil_space_verify_crypt_checksum(page, zip_size)) { - /* the doublewrite buffer page is encrypted and OK */ - } else if (buf_page_is_corrupted(true, - page, - zip_size)) { - fprintf(stderr, - "InnoDB: Dump of the page:\n"); - buf_page_print( - read_buf, zip_size, - BUF_PAGE_PRINT_NO_CRASH); - fprintf(stderr, - "InnoDB: Dump of" - " corresponding page" - " in doublewrite buffer:\n"); - buf_page_print( - page, zip_size, - BUF_PAGE_PRINT_NO_CRASH); - - fprintf(stderr, - "InnoDB: Also the page in the" - " doublewrite buffer" - " is corrupt.\n" - "InnoDB: Cannot continue" - " operation.\n" - "InnoDB: You can try to" - " recover the database" - " with the my.cnf\n" - "InnoDB: option:\n" - "InnoDB:" - " innodb_force_recovery=6\n"); - ut_error; - } + /* We intentionally skip this message for + is_all_zero pages. */ + ib_logf(IB_LOG_LEVEL_INFO, + "Trying to recover page " ULINTPF ":" ULINTPF + " from the doublewrite buffer.", + space_id, page_no); + } - /* Write the good page from the - doublewrite buffer to the intended - position */ - - fil_io(OS_FILE_WRITE, - true, - space_id, - zip_size, - page_no, - 0, - zip_size ? zip_size : UNIV_PAGE_SIZE, - page, - NULL, - 0); - - ib_logf(IB_LOG_LEVEL_INFO, - "Recovered the page from" - " the doublewrite buffer."); - - } else if (buf_page_is_zeroes(read_buf, zip_size)) { - - if (!buf_page_is_zeroes(page, zip_size) - && !buf_page_is_corrupted(true, page, - zip_size)) { - - /* Database page contained only - zeroes, while a valid copy is - available in dblwr buffer. */ - - fil_io(OS_FILE_WRITE, - true, - space_id, - zip_size, - page_no, - 0, - zip_size ? zip_size : UNIV_PAGE_SIZE, - page, - NULL, - 0); - } + /* Next, validate the doublewrite page. */ + if (fil_page_is_compressed_encrypted(page) || + fil_page_is_compressed(page)) { + /* Decompress the page before + validating the checksum. */ + fil_decompress_page( + NULL, page, UNIV_PAGE_SIZE, NULL, true); + } + + if (!fil_space_verify_crypt_checksum(page, zip_size) + && buf_page_is_corrupted(true, page, zip_size)) { + if (!is_all_zero) { + ib_logf(IB_LOG_LEVEL_WARN, + "A doublewrite copy of page " + ULINTPF ":" ULINTPF " is corrupted.", + space_id, page_no); } + /* Theoretically we could have another good + copy for this page in the doublewrite + buffer. If not, we will report a fatal error + for a corrupted page somewhere else if that + page was truly needed. */ + continue; } + + /* Write the good page from the doublewrite buffer to + the intended position. */ + + fil_io(OS_FILE_WRITE, true, space_id, zip_size, page_no, 0, + zip_size ? zip_size : UNIV_PAGE_SIZE, + page, NULL, 0); + + ib_logf(IB_LOG_LEVEL_INFO, + "Recovered page " ULINTPF ":" ULINTPF " from" + " the doublewrite buffer.", + space_id, page_no); } ut_free(unaligned_read_buf); diff --git a/storage/xtradb/buf/buf0dblwr.cc b/storage/xtradb/buf/buf0dblwr.cc index 7f6b6caee9d..9c7eea6410a 100644 --- a/storage/xtradb/buf/buf0dblwr.cc +++ b/storage/xtradb/buf/buf0dblwr.cc @@ -455,8 +455,11 @@ buf_dblwr_init_or_load_pages( os_file_write(path, file, page, source_page_no * UNIV_PAGE_SIZE, UNIV_PAGE_SIZE); - } else if (load_corrupt_pages) { - + } else if (load_corrupt_pages + && !buf_page_is_zeroes(page, FIL_PAGE_DATA)) { + /* Each valid page header must contain some + nonzero bytes, such as FIL_PAGE_OFFSET + or FIL_PAGE_LSN. */ recv_dblwr.add(page); } @@ -492,8 +495,6 @@ buf_dblwr_process() for (std::list::iterator i = recv_dblwr.pages.begin(); i != recv_dblwr.pages.end(); ++i, ++page_no_dblwr ) { - bool is_compressed = false; - page = *i; page_no = mach_read_from_4(page + FIL_PAGE_OFFSET); space_id = mach_read_from_4(page + FIL_PAGE_SPACE_ID); @@ -501,138 +502,104 @@ buf_dblwr_process() if (!fil_tablespace_exists_in_mem(space_id)) { /* Maybe we have dropped the single-table tablespace and this page once belonged to it: do nothing */ + continue; + } - } else if (!fil_check_adress_in_tablespace(space_id, - page_no)) { + if (!fil_check_adress_in_tablespace(space_id, page_no)) { ib_logf(IB_LOG_LEVEL_WARN, - "A page in the doublewrite buffer is not " - "within space bounds; space id %lu " - "page number %lu, page %lu in " - "doublewrite buf.", - (ulong) space_id, (ulong) page_no, - page_no_dblwr); + "A copy of page " ULINTPF ":" ULINTPF + " in the doublewrite buffer slot " ULINTPF + " is not within space bounds", + space_id, page_no, page_no_dblwr); + continue; + } + + ulint zip_size = fil_space_get_zip_size(space_id); + ut_ad(!buf_page_is_zeroes(page, zip_size)); + + /* Read in the actual page from the file */ + fil_io(OS_FILE_READ, + true, + space_id, + zip_size, + page_no, + 0, + zip_size ? zip_size : UNIV_PAGE_SIZE, + read_buf, + NULL, + 0); + + const bool is_all_zero = buf_page_is_zeroes( + read_buf, zip_size); + + if (is_all_zero) { + /* We will check if the copy in the + doublewrite buffer is valid. If not, we will + ignore this page (there should be redo log + records to initialize it). */ } else { - ulint zip_size = fil_space_get_zip_size(space_id); - - /* Read in the actual page from the file */ - fil_io(OS_FILE_READ, - true, - space_id, - zip_size, - page_no, - 0, - zip_size ? zip_size : UNIV_PAGE_SIZE, - read_buf, - NULL, - 0); - - /* Is page compressed ? */ - is_compressed = fil_page_is_compressed_encrypted(read_buf) | - fil_page_is_compressed(read_buf); - - /* If page was compressed, decompress it before we - check checksum. */ - if (is_compressed) { - fil_decompress_page(NULL, read_buf, UNIV_PAGE_SIZE, NULL, true); + if (fil_page_is_compressed_encrypted(read_buf) || + fil_page_is_compressed(read_buf)) { + /* Decompress the page before + validating the checksum. */ + fil_decompress_page( + NULL, read_buf, UNIV_PAGE_SIZE, + NULL, true); } - if (fil_space_verify_crypt_checksum(read_buf, zip_size)) { - /* page is encrypted and checksum is OK */ - } else if (buf_page_is_corrupted(true, read_buf, zip_size)) { - - fprintf(stderr, - "InnoDB: Database page" - " corruption or a failed\n" - "InnoDB: file read of" - " space %lu page %lu.\n" - "InnoDB: Trying to recover it from" - " the doublewrite buffer.\n", - (ulong) space_id, (ulong) page_no); - - /* Is page compressed ? */ - is_compressed = fil_page_is_compressed_encrypted(page) | - fil_page_is_compressed(page); - - /* If page was compressed, decompress it before we - check checksum. */ - if (is_compressed) { - fil_decompress_page(NULL, page, UNIV_PAGE_SIZE, NULL, true); - } + if (fil_space_verify_crypt_checksum( + read_buf, zip_size) + || !buf_page_is_corrupted( + true, read_buf, zip_size)) { + /* The page is good; there is no need + to consult the doublewrite buffer. */ + continue; + } - if (fil_space_verify_crypt_checksum(page, zip_size)) { - /* the doublewrite buffer page is encrypted and OK */ - } else if (buf_page_is_corrupted(true, - page, - zip_size)) { - fprintf(stderr, - "InnoDB: Dump of the page:\n"); - buf_page_print( - read_buf, zip_size, - BUF_PAGE_PRINT_NO_CRASH); - fprintf(stderr, - "InnoDB: Dump of" - " corresponding page" - " in doublewrite buffer:\n"); - buf_page_print( - page, zip_size, - BUF_PAGE_PRINT_NO_CRASH); - - fprintf(stderr, - "InnoDB: Also the page in the" - " doublewrite buffer" - " is corrupt.\n" - "InnoDB: Cannot continue" - " operation.\n" - "InnoDB: You can try to" - " recover the database" - " with the my.cnf\n" - "InnoDB: option:\n" - "InnoDB:" - " innodb_force_recovery=6\n"); - ut_error; - } + /* We intentionally skip this message for + is_all_zero pages. */ + ib_logf(IB_LOG_LEVEL_INFO, + "Trying to recover page " ULINTPF ":" ULINTPF + " from the doublewrite buffer.", + space_id, page_no); + } - /* Write the good page from the - doublewrite buffer to the intended - position */ - - fil_io(OS_FILE_WRITE, - true, - space_id, - zip_size, - page_no, - 0, - zip_size ? zip_size : UNIV_PAGE_SIZE, - page, - NULL, - 0); - - ib_logf(IB_LOG_LEVEL_INFO, - "Recovered the page from" - " the doublewrite buffer."); - - } else if (buf_page_is_zeroes(read_buf, zip_size)) { - - if (!buf_page_is_zeroes(page, zip_size) - && !buf_page_is_corrupted(true, page, - zip_size)) { - - /* Database page contained only - zeroes, while a valid copy is - available in dblwr buffer. */ - - fil_io(OS_FILE_WRITE, - true, - space_id, - zip_size, - page_no, 0, - zip_size ? zip_size : UNIV_PAGE_SIZE, - page, - NULL, - 0); - } + /* Next, validate the doublewrite page. */ + if (fil_page_is_compressed_encrypted(page) || + fil_page_is_compressed(page)) { + /* Decompress the page before + validating the checksum. */ + fil_decompress_page( + NULL, page, UNIV_PAGE_SIZE, NULL, true); + } + + if (!fil_space_verify_crypt_checksum(page, zip_size) + && buf_page_is_corrupted(true, page, zip_size)) { + if (!is_all_zero) { + ib_logf(IB_LOG_LEVEL_WARN, + "A doublewrite copy of page " + ULINTPF ":" ULINTPF " is corrupted.", + space_id, page_no); } + /* Theoretically we could have another good + copy for this page in the doublewrite + buffer. If not, we will report a fatal error + for a corrupted page somewhere else if that + page was truly needed. */ + continue; } + + /* Write the good page from the doublewrite buffer to + the intended position. */ + + fil_io(OS_FILE_WRITE, true, space_id, zip_size, page_no, 0, + zip_size ? zip_size : UNIV_PAGE_SIZE, + page, NULL, 0); + + ib_logf(IB_LOG_LEVEL_INFO, + "Recovered page " ULINTPF ":" ULINTPF " from" + " the doublewrite buffer.", + space_id, page_no); } ut_free(unaligned_read_buf); -- cgit v1.2.1 From ab1e6fefd869242d962cb91a006f37bb9ad534a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Sat, 14 Jan 2017 00:13:16 +0200 Subject: MDEV-11623 MariaDB 10.1 fails to start datadir created with MariaDB 10.0/MySQL 5.6 using innodb-page-size!=16K The storage format of FSP_SPACE_FLAGS was accidentally broken already in MariaDB 10.1.0. This fix is bringing the format in line with other MySQL and MariaDB release series. Please refer to the comments that were added to fsp0fsp.h for details. This is an INCOMPATIBLE CHANGE that affects users of page_compression and non-default innodb_page_size. Upgrading to this release will correct the flags in the data files. If you want to downgrade to earlier MariaDB 10.1.x, please refer to the test innodb.101_compatibility how to reset the FSP_SPACE_FLAGS in the files. NOTE: MariaDB 10.1.0 to 10.1.20 can misinterpret uncompressed data files with innodb_page_size=4k or 64k as compressed innodb_page_size=16k files, and then probably fail when trying to access the pages. See the comments in the function fsp_flags_convert_from_101() for detailed analysis. Move PAGE_COMPRESSION to FSP_SPACE_FLAGS bit position 16. In this way, compressed innodb_page_size=16k tablespaces will not be mistaken for uncompressed ones by MariaDB 10.1.0 to 10.1.20. Derive PAGE_COMPRESSION_LEVEL, ATOMIC_WRITES and DATA_DIR from the dict_table_t::flags when the table is available, in fil_space_for_table_exists_in_mem() or fil_open_single_table_tablespace(). During crash recovery, fil_load_single_table_tablespace() will use innodb_compression_level for the PAGE_COMPRESSION_LEVEL. FSP_FLAGS_MEM_MASK: A bitmap of the memory-only fil_space_t::flags that are not to be written to FSP_SPACE_FLAGS. Currently, these will include PAGE_COMPRESSION_LEVEL, ATOMIC_WRITES and DATA_DIR. Introduce the macro FSP_FLAGS_PAGE_SSIZE(). We only support one innodb_page_size for the whole instance. When creating a dummy tablespace for the redo log, use fil_space_t::flags=0. The flags are never written to the redo log files. Remove many FSP_FLAGS_SET_ macros. dict_tf_verify_flags(): Remove. This is basically only duplicating the logic of dict_tf_to_fsp_flags(), used in a debug assertion. fil_space_t::mark: Remove. This flag was not used for anything. fil_space_for_table_exists_in_mem(): Remove the unnecessary parameter mark_space, and add a parameter for table flags. Check that fil_space_t::flags match the table flags, and adjust the (memory-only) flags based on the table flags. fil_node_open_file(): Remove some redundant or unreachable conditions, do not use stderr for output, and avoid unnecessary server aborts. fil_user_tablespace_restore_page(): Convert the flags, so that the correct page_size will be used when restoring a page from the doublewrite buffer. fil_space_get_page_compressed(), fsp_flags_is_page_compressed(): Remove. It suffices to have fil_space_is_page_compressed(). FSP_FLAGS_WIDTH_DATA_DIR, FSP_FLAGS_WIDTH_PAGE_COMPRESSION_LEVEL, FSP_FLAGS_WIDTH_ATOMIC_WRITES: Remove, because these flags do not exist in the FSP_SPACE_FLAGS but only in memory. fsp_flags_try_adjust(): New function, to adjust the FSP_SPACE_FLAGS in page 0. Called by fil_open_single_table_tablespace(), fil_space_for_table_exists_in_mem(), innobase_start_or_create_for_mysql() except if --innodb-read-only is active. fsp_flags_is_valid(ulint): Reimplement from the scratch, with accurate comments. Do not display any details of detected inconsistencies, because the output could be confusing when dealing with MariaDB 10.1.x data files. fsp_flags_convert_from_101(ulint): Convert flags from buggy MariaDB 10.1.x format, or return ULINT_UNDEFINED if the flags cannot be in MariaDB 10.1.x format. fsp_flags_match(): Check the flags when probing files. Implemented based on fsp_flags_is_valid() and fsp_flags_convert_from_101(). dict_check_tablespaces_and_store_max_id(): Do not access the page after committing the mini-transaction. IMPORT TABLESPACE fixes: AbstractCallback::init(): Convert the flags. FetchIndexRootPages::operator(): Check that the tablespace flags match the table flags. Do not attempt to convert tablespace flags to table flags, because the conversion would necessarily be lossy. PageConverter::update_header(): Write back the correct flags. This takes care of the flags in IMPORT TABLESPACE. --- mysql-test/suite/innodb/include/ibd_convert.pl | 25 ++ mysql-test/suite/innodb/r/101_compatibility.result | 48 +++ mysql-test/suite/innodb/r/doublewrite.result | 2 + .../suite/innodb/r/innodb-wl5522-debug-zip.result | 5 +- mysql-test/suite/innodb/t/101_compatibility.test | 101 +++++ mysql-test/suite/innodb/t/doublewrite.test | 42 +- .../suite/innodb/t/innodb-wl5522-debug-zip.test | 3 +- storage/innobase/buf/buf0dblwr.cc | 15 + storage/innobase/dict/dict0load.cc | 20 +- storage/innobase/fil/fil0fil.cc | 396 +++++++++---------- storage/innobase/fsp/fsp0fsp.cc | 3 +- storage/innobase/include/dict0dict.ic | 40 +- storage/innobase/include/dict0pagecompress.h | 13 +- storage/innobase/include/dict0pagecompress.ic | 88 +---- storage/innobase/include/fil0fil.h | 41 +- storage/innobase/include/fil0pagecompress.h | 13 +- storage/innobase/include/fsp0fsp.h | 430 +++++++++++++++----- storage/innobase/include/fsp0fsp.ic | 153 +------- storage/innobase/include/fsp0pagecompress.h | 11 +- storage/innobase/include/fsp0pagecompress.ic | 28 +- storage/innobase/row/row0import.cc | 94 ++--- storage/innobase/row/row0mysql.cc | 11 +- storage/innobase/srv/srv0start.cc | 18 +- storage/xtradb/buf/buf0dblwr.cc | 15 + storage/xtradb/dict/dict0load.cc | 20 +- storage/xtradb/fil/fil0fil.cc | 395 +++++++++---------- storage/xtradb/fsp/fsp0fsp.cc | 3 +- storage/xtradb/include/dict0dict.ic | 40 +- storage/xtradb/include/dict0pagecompress.h | 13 +- storage/xtradb/include/dict0pagecompress.ic | 88 +---- storage/xtradb/include/fil0fil.h | 41 +- storage/xtradb/include/fil0pagecompress.h | 13 +- storage/xtradb/include/fsp0fsp.h | 437 ++++++++++++++++----- storage/xtradb/include/fsp0fsp.ic | 153 +------- storage/xtradb/include/fsp0pagecompress.h | 11 +- storage/xtradb/include/fsp0pagecompress.ic | 28 +- storage/xtradb/row/row0import.cc | 94 ++--- storage/xtradb/row/row0mysql.cc | 11 +- storage/xtradb/srv/srv0start.cc | 18 +- 39 files changed, 1483 insertions(+), 1497 deletions(-) create mode 100644 mysql-test/suite/innodb/include/ibd_convert.pl create mode 100644 mysql-test/suite/innodb/r/101_compatibility.result create mode 100644 mysql-test/suite/innodb/t/101_compatibility.test diff --git a/mysql-test/suite/innodb/include/ibd_convert.pl b/mysql-test/suite/innodb/include/ibd_convert.pl new file mode 100644 index 00000000000..aba742ac649 --- /dev/null +++ b/mysql-test/suite/innodb/include/ibd_convert.pl @@ -0,0 +1,25 @@ +#!/usr/bin/perl +# Convert tablespace flags to the format understood by MariaDB 10.1.0..10.1.20, +# with the assumption that the flags were correct. + +sub convert_to_mariadb_101 +{ + my ($file, $page_size) = @_; + open(FILE, "+<", $file) or die "Unable to open $file\n"; + sysread(FILE, $_, $page_size)==$page_size||die "Unable to read $file\n"; + sysseek(FILE, 0, 0)||die "Unable to seek $file\n"; + + # FIL_PAGE_DATA + FSP_SPACE_FLAGS = 38 + 16 = 54 bytes from the start + my($flags) = unpack "x[54]N"; + my $badflags = ($flags & 0x3f); + my $compression_level=6; + $badflags |= 1<<6|$compression_level<<7 if ($flags & 1 << 16); + $badflags |= ($flags & 15 << 6) << 7; # PAGE_SSIZE + + substr ($_, 54, 4) = pack("N", $badflags); + # Replace the innodb_checksum_algorithm=none checksum + substr ($_, 0, 4) = pack("N", 0xdeadbeef); + substr ($_, $page_size - 8, 4) = pack("N", 0xdeadbeef); + syswrite(FILE, $_, $page_size)==$page_size||die "Unable to write $file\n"; + close(FILE); +} diff --git a/mysql-test/suite/innodb/r/101_compatibility.result b/mysql-test/suite/innodb/r/101_compatibility.result new file mode 100644 index 00000000000..f9cc8c288ca --- /dev/null +++ b/mysql-test/suite/innodb/r/101_compatibility.result @@ -0,0 +1,48 @@ +# +# MDEV-11623 MariaDB 10.1 fails to start datadir created with +# MariaDB 10.0/MySQL 5.6 using innodb-page-size!=16K +# +call mtr.add_suppression("InnoDB: adjusting FSP_SPACE_FLAGS of tablespace"); +SET GLOBAL innodb_file_per_table=1; +SET GLOBAL innodb_file_format=Barracuda; +CREATE TABLE tr(a INT)ENGINE=InnoDB ROW_FORMAT=REDUNDANT; +CREATE TABLE tc(a INT)ENGINE=InnoDB ROW_FORMAT=COMPACT; +CREATE TABLE td(a INT)ENGINE=InnoDB ROW_FORMAT=DYNAMIC; +CREATE TABLE tz(a INT)ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1; +CREATE TABLE tdd(a INT) ENGINE=InnoDB, DATA DIRECTORY='MYSQL_TMP_DIR'; +CREATE TABLE tp(a INT) ENGINE=InnoDB page_compressed=1; +CREATE TABLE ti(a INT) ENGINE=InnoDB; +FLUSH TABLES ti FOR EXPORT; +backup: ti +UNLOCK TABLES; +ALTER TABLE ti DISCARD TABLESPACE; +restore: ti .ibd and .cfg files +ALTER TABLE ti IMPORT TABLESPACE; +BEGIN; +INSERT INTO tr VALUES(1); +INSERT INTO tc VALUES(1); +INSERT INTO td VALUES(1); +INSERT INTO tz VALUES(1); +INSERT INTO tdd VALUES(1); +INSERT INTO tp VALUES(1); +INSERT INTO ti VALUES(1); +# Kill the server +CHECK TABLE tr,tc,td,tz,tdd,tp,ti; +Table Op Msg_type Msg_text +test.tr check status OK +test.tc check status OK +test.td check status OK +test.tz check status OK +test.tdd check status OK +test.tp check status OK +test.ti check status OK +CHECK TABLE tr,tc,td,tz,tdd,tp,ti; +Table Op Msg_type Msg_text +test.tr check status OK +test.tc check status OK +test.td check status OK +test.tz check status OK +test.tdd check status OK +test.tp check status OK +test.ti check status OK +DROP TABLE tr,tc,td,tz,tdd,tp,ti; diff --git a/mysql-test/suite/innodb/r/doublewrite.result b/mysql-test/suite/innodb/r/doublewrite.result index aa96a5f2d93..6b913f49972 100644 --- a/mysql-test/suite/innodb/r/doublewrite.result +++ b/mysql-test/suite/innodb/r/doublewrite.result @@ -39,6 +39,8 @@ set global innodb_buf_flush_list_now = 1; # Kill the server # Make the first page (page_no=0) of the user tablespace # full of zeroes. +# +# MDEV-11623: Use old FSP_SPACE_FLAGS in the doublewrite buffer. check table t1; Table Op Msg_type Msg_text test.t1 check status OK diff --git a/mysql-test/suite/innodb/r/innodb-wl5522-debug-zip.result b/mysql-test/suite/innodb/r/innodb-wl5522-debug-zip.result index 6231a875804..58721a8732a 100644 --- a/mysql-test/suite/innodb/r/innodb-wl5522-debug-zip.result +++ b/mysql-test/suite/innodb/r/innodb-wl5522-debug-zip.result @@ -1,4 +1,5 @@ -call mtr.add_suppression("InnoDB: Page for tablespace .* "); +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; @@ -565,7 +566,7 @@ ERROR HY000: Tablespace has been discarded for table 't1' 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 +ERROR HY000: Internal error: Cannot reset LSNs in table '"test_wl5522"."t1"' : Data structure corruption SET SESSION debug_dbug="-d,fsp_flags_is_valid_failure"; DROP TABLE test_wl5522.t1; unlink: t1.ibd diff --git a/mysql-test/suite/innodb/t/101_compatibility.test b/mysql-test/suite/innodb/t/101_compatibility.test new file mode 100644 index 00000000000..125a559c1cb --- /dev/null +++ b/mysql-test/suite/innodb/t/101_compatibility.test @@ -0,0 +1,101 @@ +--source include/have_innodb.inc +--source include/not_embedded.inc + +-- echo # +-- echo # MDEV-11623 MariaDB 10.1 fails to start datadir created with +-- echo # MariaDB 10.0/MySQL 5.6 using innodb-page-size!=16K +-- echo # + +# This is actually testing the opposite: starting the fixed 10.1 with +# buggy 10.1 files (by manually converting the flags in the files). + +call mtr.add_suppression("InnoDB: adjusting FSP_SPACE_FLAGS of tablespace"); +SET GLOBAL innodb_file_per_table=1; +SET GLOBAL innodb_file_format=Barracuda; +let INNODB_PAGE_SIZE=`select @@innodb_page_size`; +let MYSQLD_DATADIR=`select @@datadir`; + +CREATE TABLE tr(a INT)ENGINE=InnoDB ROW_FORMAT=REDUNDANT; +CREATE TABLE tc(a INT)ENGINE=InnoDB ROW_FORMAT=COMPACT; +CREATE TABLE td(a INT)ENGINE=InnoDB ROW_FORMAT=DYNAMIC; +--disable_warnings +CREATE TABLE tz(a INT)ENGINE=InnoDB ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1; +--enable_warnings + +--replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR +EVAL CREATE TABLE tdd(a INT) ENGINE=InnoDB, DATA DIRECTORY='$MYSQL_TMP_DIR'; + +CREATE TABLE tp(a INT) ENGINE=InnoDB page_compressed=1; +CREATE TABLE ti(a INT) ENGINE=InnoDB; +FLUSH TABLES ti FOR EXPORT; +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_backup_tablespaces("test", "ti"); +EOF +UNLOCK TABLES; +ALTER TABLE ti DISCARD TABLESPACE; +perl; +do "$ENV{MTR_SUITE_DIR}/include/innodb-util.pl"; +ib_discard_tablespaces("test", "ti"); +ib_restore_tablespaces("test", "ti"); +do "$ENV{MTR_SUITE_DIR}/include/ibd_convert.pl"; +my $ps = $ENV{INNODB_PAGE_SIZE}; +my $dd = $ENV{MYSQLD_DATADIR}; +convert_to_mariadb_101("$dd/test/ti.ibd", $ps); +EOF + +ALTER TABLE ti IMPORT TABLESPACE; + +BEGIN; +INSERT INTO tr VALUES(1); +INSERT INTO tc VALUES(1); +INSERT INTO td VALUES(1); +INSERT INTO tz VALUES(1); +INSERT INTO tdd VALUES(1); +INSERT INTO tp VALUES(1); +INSERT INTO ti VALUES(1); + +--source include/kill_mysqld.inc + +perl; +do "$ENV{MTR_SUITE_DIR}/include/ibd_convert.pl"; +my $ps = $ENV{INNODB_PAGE_SIZE}; +my $dd = $ENV{MYSQLD_DATADIR}; + +convert_to_mariadb_101("$dd/ibdata1", $ps); +convert_to_mariadb_101("$dd/test/tr.ibd", $ps); +convert_to_mariadb_101("$dd/test/tc.ibd", $ps); +convert_to_mariadb_101("$dd/test/td.ibd", $ps); +convert_to_mariadb_101("$dd/test/tz.ibd", 1024) if $ps<32768; +convert_to_mariadb_101("$dd/test/tp.ibd", $ps); +convert_to_mariadb_101("$dd/test/ti.ibd", $ps); +convert_to_mariadb_101("$ENV{MYSQL_TMP_DIR}/test/tdd.ibd", $ps); +EOF + +--source include/start_mysqld.inc +CHECK TABLE tr,tc,td,tz,tdd,tp,ti; +--source include/shutdown_mysqld.inc + +perl; +do "$ENV{MTR_SUITE_DIR}/include/ibd_convert.pl"; +my $ps = $ENV{INNODB_PAGE_SIZE}; +my $dd = $ENV{MYSQLD_DATADIR}; + +convert_to_mariadb_101("$dd/ibdata1", $ps); +convert_to_mariadb_101("$dd/test/tr.ibd", $ps); +convert_to_mariadb_101("$dd/test/tc.ibd", $ps); +convert_to_mariadb_101("$dd/test/td.ibd", $ps); +convert_to_mariadb_101("$dd/test/tz.ibd", 1024) if $ps<32768; +convert_to_mariadb_101("$dd/test/tp.ibd", $ps); +convert_to_mariadb_101("$dd/test/ti.ibd", $ps); +convert_to_mariadb_101("$ENV{MYSQL_TMP_DIR}/test/tdd.ibd", $ps); +EOF + +--let $restart_parameters=--innodb-read-only +--source include/start_mysqld.inc +CHECK TABLE tr,tc,td,tz,tdd,tp,ti; +--source include/shutdown_mysqld.inc + +--let $restart_parameters= +--source include/start_mysqld.inc +DROP TABLE tr,tc,td,tz,tdd,tp,ti; diff --git a/mysql-test/suite/innodb/t/doublewrite.test b/mysql-test/suite/innodb/t/doublewrite.test index 56cc88f5590..245b4e1a676 100644 --- a/mysql-test/suite/innodb/t/doublewrite.test +++ b/mysql-test/suite/innodb/t/doublewrite.test @@ -17,7 +17,7 @@ call mtr.add_suppression("space header page consists of zero bytes.*test.t1"); call mtr.add_suppression("checksum mismatch in tablespace.*test.t1"); call mtr.add_suppression("Current page size .* != page size on page"); call mtr.add_suppression("innodb-page-size mismatch in tablespace.*test.t1"); -call mtr.add_suppression("Database page corruption"); +call mtr.add_suppression("Trying to recover page.*from the doublewrite buffer"); --enable_query_log let INNODB_PAGE_SIZE=`select @@innodb_page_size`; @@ -65,14 +65,48 @@ set global innodb_buf_flush_list_now = 1; --echo # Make the first page (page_no=0) of the user tablespace --echo # full of zeroes. +--echo # +--echo # MDEV-11623: Use old FSP_SPACE_FLAGS in the doublewrite buffer. + perl; use IO::Handle; my $fname= "$ENV{'MYSQLD_DATADIR'}test/t1.ibd"; +my $page_size = $ENV{INNODB_PAGE_SIZE}; +my $page; open(FILE, "+<", $fname) or die; -FILE->autoflush(1); -binmode FILE; -print FILE chr(0) x ($ENV{'INNODB_PAGE_SIZE'}); +sysread(FILE, $page, $page_size)==$page_size||die "Unable to read $file\n"; +sysseek(FILE, 0, 0)||die "Unable to seek $file\n"; +die unless syswrite(FILE, chr(0) x $page_size, $page_size) == $page_size; close FILE; + +open(FILE, "+<", "$ENV{MYSQLD_DATADIR}ibdata1")||die "cannot open ibdata1\n"; +sysseek(FILE, 6 * $page_size - 190, 0)||die "Unable to seek ibdata1\n"; +sysread(FILE, $_, 12) == 12||die "Unable to read TRX_SYS\n"; +my($magic,$d1,$d2)=unpack "NNN"; +die "magic=$magic, $d1, $d2\n" unless $magic == 536853855 && $d2 >= $d1 + 64; +sysseek(FILE, $d1 * $page_size, 0)||die "Unable to seek ibdata1\n"; +# Find the page in the doublewrite buffer +for (my $d = $d1; $d < $d2 + 64; $d++) +{ + sysread(FILE, $_, $page_size)==$page_size||die "Cannot read doublewrite\n"; + next unless $_ eq $page; + sysseek(FILE, $d * $page_size, 0)||die "Unable to seek ibdata1\n"; + # Write buggy MariaDB 10.1.x FSP_SPACE_FLAGS to the doublewrite buffer + my($flags) = unpack "x[54]N"; + my $badflags = ($flags & 0x3f); + my $compression_level=6; + $badflags |= 1<<6|$compression_level<<7 if ($flags & 1 << 16); + $badflags |= ($flags & 15 << 6) << 7; # PAGE_SSIZE + + substr ($_, 54, 4) = pack("N", $badflags); + # Replace the innodb_checksum_algorithm=none checksum + substr ($_, 0, 4) = pack("N", 0xdeadbeef); + substr ($_, $page_size - 8, 4) = pack("N", 0xdeadbeef); + syswrite(FILE, $_, $page_size)==$page_size||die "Unable to write $file\n"; + close(FILE); + exit 0; +} +die "Did not find the page in the doublewrite buffer ($d1,$d2)\n"; EOF --source include/start_mysqld.inc diff --git a/mysql-test/suite/innodb/t/innodb-wl5522-debug-zip.test b/mysql-test/suite/innodb/t/innodb-wl5522-debug-zip.test index bc3edbb2643..0bfe67c06bc 100644 --- a/mysql-test/suite/innodb/t/innodb-wl5522-debug-zip.test +++ b/mysql-test/suite/innodb/t/innodb-wl5522-debug-zip.test @@ -17,7 +17,8 @@ # allow test to run only when innodb-page-size=16 --source include/have_innodb_16k.inc -call mtr.add_suppression("InnoDB: Page for tablespace .* "); +call mtr.add_suppression("InnoDB: Page for tablespace "); +call mtr.add_suppression("InnoDB: Invalid FSP_SPACE_FLAGS=0x"); FLUSH TABLES; let MYSQLD_DATADIR =`SELECT @@datadir`; diff --git a/storage/innobase/buf/buf0dblwr.cc b/storage/innobase/buf/buf0dblwr.cc index 0b42e38a655..e49185f6a1f 100644 --- a/storage/innobase/buf/buf0dblwr.cc +++ b/storage/innobase/buf/buf0dblwr.cc @@ -589,6 +589,21 @@ buf_dblwr_process() continue; } + if (page_no == 0) { + /* Check the FSP_SPACE_FLAGS. */ + ulint flags = fsp_header_get_flags(page); + if (!fsp_flags_is_valid(flags) + && fsp_flags_convert_from_101(flags) + == ULINT_UNDEFINED) { + ib_logf(IB_LOG_LEVEL_WARN, + "Ignoring a doublewrite copy of page " + ULINTPF ":0 due to invalid flags 0x%x", + space_id, int(flags)); + continue; + } + /* The flags on the page should be converted later. */ + } + /* Write the good page from the doublewrite buffer to the intended position. */ diff --git a/storage/innobase/dict/dict0load.cc b/storage/innobase/dict/dict0load.cc index 0ab25ee1eac..0f9f4f153f5 100644 --- a/storage/innobase/dict/dict0load.cc +++ b/storage/innobase/dict/dict0load.cc @@ -1052,8 +1052,6 @@ loop: btr_pcur_store_position(&pcur, &mtr); - mtr_commit(&mtr); - /* For tables created with old versions of InnoDB, SYS_TABLES.MIX_LEN may contain garbage. Such tables would always be in ROW_FORMAT=REDUNDANT. Pretend that @@ -1087,16 +1085,19 @@ loop: if (space_id == 0) { /* The system tablespace always exists. */ ut_ad(!discarded); - goto next_tablespace; + mem_free(name); + goto loop; } + mtr_commit(&mtr); + switch (dict_check) { case DICT_CHECK_ALL_LOADED: /* All tablespaces should have been found in fil_load_single_table_tablespaces(). */ if (fil_space_for_table_exists_in_mem( - space_id, name, TRUE, !(is_temp || discarded), - false, NULL, 0) + space_id, name, !(is_temp || discarded), + false, NULL, 0, flags) && !(is_temp || discarded)) { /* If user changes the path of .ibd files in *.isl files before doing crash recovery , @@ -1128,8 +1129,8 @@ loop: /* Some tablespaces may have been opened in trx_resurrect_table_locks(). */ if (fil_space_for_table_exists_in_mem( - space_id, name, FALSE, FALSE, - false, NULL, 0)) { + space_id, name, false, + false, NULL, 0, flags)) { break; } /* fall through */ @@ -1191,7 +1192,6 @@ loop: max_space_id = space_id; } -next_tablespace: mem_free(name); mtr_start(&mtr); @@ -2382,8 +2382,8 @@ err_exit: table->ibd_file_missing = TRUE; } else if (!fil_space_for_table_exists_in_mem( - table->space, name, FALSE, FALSE, true, heap, - table->id)) { + table->space, name, false, true, heap, + table->id, table->flags)) { if (DICT_TF2_FLAG_IS_SET(table, DICT_TF2_TEMPORARY)) { /* Do not bother to retry opening temporary tables. */ diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc index 1e8b2be6f01..fe6a2922b35 100644 --- a/storage/innobase/fil/fil0fil.cc +++ b/storage/innobase/fil/fil0fil.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2016, Oracle and/or its affiliates. -Copyright (c) 2013, 2016, MariaDB Corporation. +Copyright (c) 2013, 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 @@ -596,10 +596,7 @@ fil_node_open_file( ibool success; byte* buf2; byte* page; - ulint space_id; - ulint flags=0; ulint page_size; - ulint atomic_writes=0; ut_ad(mutex_own(&(system->mutex))); ut_a(node->n_pending == 0); @@ -621,8 +618,6 @@ fil_node_open_file( /* The following call prints an error message */ os_file_get_last_error(true); - ut_print_timestamp(stderr); - ib_logf(IB_LOG_LEVEL_WARN, "InnoDB: Error: cannot " "open %s\n. InnoDB: Have you deleted .ibd " "files under a running mysqld server?\n", @@ -648,17 +643,13 @@ fil_node_open_file( ut_a(fil_is_user_tablespace_id(space->id)); if (size_bytes < FIL_IBD_FILE_INITIAL_SIZE * UNIV_PAGE_SIZE) { - fprintf(stderr, - "InnoDB: Error: the size of single-table" - " tablespace file %s\n" - "InnoDB: is only " UINT64PF "," - " should be at least %lu!\n", - node->name, - size_bytes, - (ulong) (FIL_IBD_FILE_INITIAL_SIZE - * UNIV_PAGE_SIZE)); - - ut_a(0); + ib_logf(IB_LOG_LEVEL_ERROR, + "The size of the file %s is only " UINT64PF + " bytes, should be at least " ULINTPF, + node->name, size_bytes, + FIL_IBD_FILE_INITIAL_SIZE * UNIV_PAGE_SIZE); + os_file_close(node->handle); + return(false); } /* Read the first page of the tablespace */ @@ -671,78 +662,34 @@ fil_node_open_file( success = os_file_read(node->handle, page, 0, UNIV_PAGE_SIZE); srv_stats.page0_read.add(1); - space_id = fsp_header_get_space_id(page); - flags = fsp_header_get_flags(page); - - page_size = fsp_flags_get_page_size(flags); - atomic_writes = fsp_flags_get_atomic_writes(flags); - + const ulint space_id = fsp_header_get_space_id(page); + ulint flags = fsp_header_get_flags(page); ut_free(buf2); - - /* Close the file now that we have read the space id from it */ - os_file_close(node->handle); - if (UNIV_UNLIKELY(space_id != space->id)) { - fprintf(stderr, - "InnoDB: Error: tablespace id is %lu" - " in the data dictionary\n" - "InnoDB: but in file %s it is %lu!\n", - space->id, node->name, space_id); - - ut_error; - } - - if (UNIV_UNLIKELY(space_id == ULINT_UNDEFINED - || space_id == 0)) { - fprintf(stderr, - "InnoDB: Error: tablespace id %lu" - " in file %s is not sensible\n", - (ulong) space_id, node->name); - - ut_error; - } - - if (UNIV_UNLIKELY(fsp_flags_get_page_size(space->flags) - != page_size)) { - fprintf(stderr, - "InnoDB: Error: tablespace file %s" - " has page size 0x%lx\n" - "InnoDB: but the data dictionary" - " expects page size 0x%lx!\n", - node->name, flags, - fsp_flags_get_page_size(space->flags)); + if (!fsp_flags_is_valid(flags)) { + ulint cflags = fsp_flags_convert_from_101(flags); + if (cflags == ULINT_UNDEFINED) { + ib_logf(IB_LOG_LEVEL_ERROR, + "Expected tablespace flags 0x%x" + " but found 0x%x in the file %s", + int(space->flags), int(flags), + node->name); + return(false); + } - ut_error; + flags = cflags; } - if (UNIV_UNLIKELY(space->flags != flags)) { - ulint sflags = (space->flags & ~FSP_FLAGS_MASK_DATA_DIR); - ulint fflags = (flags & ~FSP_FLAGS_MASK_DATA_DIR_ORACLE); - - /* DATA_DIR option is on different place on MariaDB - compared to MySQL. If this is the difference. Fix - it. */ - - if (sflags == fflags) { - fprintf(stderr, - "InnoDB: Warning: Table flags 0x%lx" - " in the data dictionary but in file %s are 0x%lx!\n" - " Temporally corrected because DATA_DIR option to 0x%lx.\n", - space->flags, node->name, flags, space->flags); - - flags = space->flags; - } + page_size = fsp_flags_get_page_size(flags); - if (!dict_tf_verify_flags(space->flags, flags)) { - fprintf(stderr, - "InnoDB: Error: table flags are 0x%lx" - " in the data dictionary\n" - "InnoDB: but the flags in file %s are 0x%lx!\n", - space->flags, node->name, flags); - ut_error; - } + if (UNIV_UNLIKELY(space_id != space->id)) { + ib_logf(IB_LOG_LEVEL_ERROR, + "tablespace id is " ULINTPF " in the data dictionary" + " but in file %s it is " ULINTPF "!\n", + space->id, node->name, space_id); + return(false); } if (size_bytes >= (1024*1024)) { @@ -764,7 +711,7 @@ add_size: space->size += node->size; } - atomic_writes = fsp_flags_get_atomic_writes(space->flags); + ulint atomic_writes = fsp_flags_get_atomic_writes(space->flags); /* printf("Opening file %s\n", node->name); */ @@ -1534,7 +1481,6 @@ fil_space_create( fil_system->tablespace_version++; space->tablespace_version = fil_system->tablespace_version; - space->mark = FALSE; if (purpose == FIL_TABLESPACE && !recv_recovery_on && id > fil_system->max_assigned_id) { @@ -2273,27 +2219,21 @@ fil_write_flushed_lsn_to_data_files( return(DB_SUCCESS); } -/*******************************************************************//** -Checks the consistency of the first data page of a tablespace +/** Check the consistency of the first data page of a tablespace at database startup. +@param[in] page page frame +@param[in] space_id tablespace identifier +@param[in] flags tablespace flags @retval NULL on success, or if innodb_force_recovery is set @return pointer to an error message string */ static MY_ATTRIBUTE((warn_unused_result)) const char* -fil_check_first_page( -/*=================*/ - const page_t* page) /*!< in: data page */ +fil_check_first_page(const page_t* page, ulint space_id, ulint flags) { - ulint space_id; - ulint flags; - if (srv_force_recovery >= SRV_FORCE_IGNORE_CORRUPT) { return(NULL); } - space_id = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_ID + page); - flags = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + page); - if (UNIV_PAGE_SIZE != fsp_flags_get_page_size(flags)) { fprintf(stderr, "InnoDB: Error: Current page size %lu != " @@ -2342,7 +2282,7 @@ fil_read_first_page( ibool one_read_already, /*!< in: TRUE if min and max parameters below already contain sensible data */ - ulint* flags, /*!< out: tablespace flags */ + ulint* flags, /*!< out: FSP_SPACE_FLAGS */ ulint* space_id, /*!< out: tablespace ID */ #ifdef UNIV_LOG_ARCHIVE ulint* min_arch_log_no, /*!< out: min of archived @@ -2378,12 +2318,22 @@ fil_read_first_page( *flags and *space_id as they were read from the first file and do not validate the first page. */ if (!one_read_already) { - *flags = fsp_header_get_flags(page); *space_id = fsp_header_get_space_id(page); - } + *flags = fsp_header_get_flags(page); - if (!one_read_already) { - check_msg = fil_check_first_page(page); + if (!fsp_flags_is_valid(*flags)) { + ulint cflags = fsp_flags_convert_from_101(*flags); + if (cflags == ULINT_UNDEFINED) { + ib_logf(IB_LOG_LEVEL_ERROR, + "Invalid flags 0x%x in tablespace %u", + unsigned(*flags), unsigned(*space_id)); + return "invalid tablespace flags"; + } else { + *flags = cflags; + } + } + + check_msg = fil_check_first_page(page, *space_id, *flags); } flushed_lsn = mach_read_from_8(page + @@ -2577,6 +2527,7 @@ fil_op_write_log( ulint len; log_ptr = mlog_open(mtr, 11 + 2 + 1); + ut_ad(fsp_flags_is_valid(flags)); if (!log_ptr) { /* Logging in mtr is switched off during crash recovery: @@ -3783,7 +3734,7 @@ fil_create_new_single_table_tablespace( ibool success; /* TRUE if a table is created with CREATE TEMPORARY TABLE */ bool is_temp = !!(flags2 & DICT_TF2_TEMPORARY); - bool has_data_dir = FSP_FLAGS_HAS_DATA_DIR(flags); + bool has_data_dir = FSP_FLAGS_HAS_DATA_DIR(flags) != 0; ulint atomic_writes = FSP_FLAGS_GET_ATOMIC_WRITES(flags); fil_space_crypt_t *crypt_data = NULL; @@ -3791,7 +3742,7 @@ fil_create_new_single_table_tablespace( ut_ad(!srv_read_only_mode); ut_a(space_id < SRV_LOG_SPACE_FIRST_ID); ut_a(size >= FIL_IBD_FILE_INITIAL_SIZE); - ut_a(fsp_flags_is_valid(flags)); + ut_a(fsp_flags_is_valid(flags & ~FSP_FLAGS_MEM_MASK)); if (is_temp) { /* Temporary table filepath */ @@ -3884,12 +3835,9 @@ fil_create_new_single_table_tablespace( memset(page, '\0', UNIV_PAGE_SIZE); - /* Add the UNIV_PAGE_SIZE to the table flags and write them to the - tablespace header. */ - flags = fsp_flags_set_page_size(flags, UNIV_PAGE_SIZE); + flags |= FSP_FLAGS_PAGE_SSIZE(); fsp_header_init_fields(page, space_id, flags); mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, space_id); - ut_ad(fsp_flags_is_valid(flags)); if (!(fsp_flags_is_compressed(flags))) { buf_flush_init_for_writing(page, NULL, 0); @@ -3968,7 +3916,8 @@ fil_create_new_single_table_tablespace( fil_op_write_log(flags ? MLOG_FILE_CREATE2 : MLOG_FILE_CREATE, - space_id, mlog_file_flag, flags, + space_id, mlog_file_flag, + flags & ~FSP_FLAGS_MEM_MASK, tablename, NULL, &mtr); mtr_commit(&mtr); @@ -4032,6 +3981,39 @@ fil_report_bad_tablespace( (ulong) expected_id, (ulong) expected_flags); } +/** Try to adjust FSP_SPACE_FLAGS if they differ from the expectations. +(Typically when upgrading from MariaDB 10.1.0..10.1.20.) +@param[in] space_id tablespace ID +@param[in] flags desired tablespace flags */ +UNIV_INTERN +void +fsp_flags_try_adjust(ulint space_id, ulint flags) +{ + ut_ad(!srv_read_only_mode); + ut_ad(fsp_flags_is_valid(flags)); + + mtr_t mtr; + mtr_start(&mtr); + if (buf_block_t* b = buf_page_get( + space_id, fsp_flags_get_zip_size(flags), 0, RW_X_LATCH, + &mtr)) { + ulint f = fsp_header_get_flags(b->frame); + /* Suppress the message if only the DATA_DIR flag to differs. */ + if ((f ^ flags) & ~(1U << FSP_FLAGS_POS_RESERVED)) { + ib_logf(IB_LOG_LEVEL_WARN, + "adjusting FSP_SPACE_FLAGS of tablespace " + ULINTPF " from 0x%x to 0x%x", + space_id, int(f), int(flags)); + } + if (f != flags) { + mlog_write_ulint(FSP_HEADER_OFFSET + + FSP_SPACE_FLAGS + b->frame, + flags, MLOG_4BYTES, &mtr); + } + } + mtr_commit(&mtr); +} + /********************************************************************//** Tries to open a single-table tablespace and optionally checks that the space id in it is correct. If this does not succeed, print an error message @@ -4061,7 +4043,7 @@ fil_open_single_table_tablespace( bool validate, /*!< in: Do we validate tablespace? */ bool fix_dict, /*!< in: Can we fix the dictionary? */ ulint id, /*!< in: space id */ - ulint flags, /*!< in: tablespace flags */ + ulint flags, /*!< in: expected FSP_SPACE_FLAGS */ const char* tablename, /*!< in: table name in the databasename/tablename format */ const char* path_in, /*!< in: tablespace filepath */ @@ -4086,20 +4068,13 @@ fil_open_single_table_tablespace( /* Table flags can be ULINT_UNDEFINED if dict_tf_to_fsp_flags_failure is set. */ - if (flags != ULINT_UNDEFINED) { - if (!fsp_flags_is_valid(flags)) { - return(DB_CORRUPTION); - } - } else { + if (flags == ULINT_UNDEFINED) { return(DB_CORRUPTION); } + ut_ad(fsp_flags_is_valid(flags & ~FSP_FLAGS_MEM_MASK)); atomic_writes = fsp_flags_get_atomic_writes(flags); - /* If the tablespace was relocated, we do not - compare the DATA_DIR flag */ - ulint mod_flags = flags & ~FSP_FLAGS_MASK_DATA_DIR; - memset(&def, 0, sizeof(def)); memset(&dict, 0, sizeof(dict)); memset(&remote, 0, sizeof(remote)); @@ -4180,31 +4155,17 @@ fil_open_single_table_tablespace( &space_arch_log_no, &space_arch_log_no, #endif /* UNIV_LOG_ARCHIVE */ &def.lsn, &def.lsn, &def.crypt_data); - def.valid = !def.check_msg; if (table) { table->crypt_data = def.crypt_data; table->page_0_read = true; } - /* Validate this single-table-tablespace with SYS_TABLES, - but do not compare the DATA_DIR flag, in case the - tablespace was relocated. */ - - ulint newf = def.flags; - if (newf != mod_flags) { - if (FSP_FLAGS_HAS_DATA_DIR(newf)) { - newf = (newf & ~FSP_FLAGS_MASK_DATA_DIR); - } else if(FSP_FLAGS_HAS_DATA_DIR_ORACLE(newf)) { - newf = (newf & ~FSP_FLAGS_MASK_DATA_DIR_ORACLE); - } - } - - if (def.valid && def.id == id - && newf == mod_flags) { + def.valid = !def.check_msg && def.id == id + && fsp_flags_match(flags, def.flags); + if (def.valid) { valid_tablespaces_found++; } else { - def.valid = false; /* Do not use this tablespace. */ fil_report_bad_tablespace( def.filepath, def.check_msg, def.id, @@ -4220,30 +4181,18 @@ fil_open_single_table_tablespace( &remote.arch_log_no, &remote.arch_log_no, #endif /* UNIV_LOG_ARCHIVE */ &remote.lsn, &remote.lsn, &remote.crypt_data); - remote.valid = !remote.check_msg; if (table) { table->crypt_data = remote.crypt_data; table->page_0_read = true; } - /* Validate this single-table-tablespace with SYS_TABLES, - but do not compare the DATA_DIR flag, in case the - tablespace was relocated. */ - ulint newf = remote.flags; - if (newf != mod_flags) { - if (FSP_FLAGS_HAS_DATA_DIR(newf)) { - newf = (newf & ~FSP_FLAGS_MASK_DATA_DIR); - } else if(FSP_FLAGS_HAS_DATA_DIR_ORACLE(newf)) { - newf = (newf & ~FSP_FLAGS_MASK_DATA_DIR_ORACLE); - } - } - - if (remote.valid && remote.id == id - && newf == mod_flags) { + /* Validate this single-table-tablespace with SYS_TABLES. */ + remote.valid = !remote.check_msg && remote.id == id + && fsp_flags_match(flags, remote.flags); + if (remote.valid) { valid_tablespaces_found++; } else { - remote.valid = false; /* Do not use this linked tablespace. */ fil_report_bad_tablespace( remote.filepath, remote.check_msg, remote.id, @@ -4260,30 +4209,19 @@ fil_open_single_table_tablespace( &dict.arch_log_no, &dict.arch_log_no, #endif /* UNIV_LOG_ARCHIVE */ &dict.lsn, &dict.lsn, &dict.crypt_data); - dict.valid = !dict.check_msg; if (table) { table->crypt_data = dict.crypt_data; table->page_0_read = true; } - /* Validate this single-table-tablespace with SYS_TABLES, - but do not compare the DATA_DIR flag, in case the - tablespace was relocated. */ - ulint newf = dict.flags; - if (newf != mod_flags) { - if (FSP_FLAGS_HAS_DATA_DIR(newf)) { - newf = (newf & ~FSP_FLAGS_MASK_DATA_DIR); - } else if(FSP_FLAGS_HAS_DATA_DIR_ORACLE(newf)) { - newf = (newf & ~FSP_FLAGS_MASK_DATA_DIR_ORACLE); - } - } + /* Validate this single-table-tablespace with SYS_TABLES. */ + dict.valid = !dict.check_msg && dict.id == id + && fsp_flags_match(flags, dict.flags); - if (dict.valid && dict.id == id - && newf == mod_flags) { + if (dict.valid) { valid_tablespaces_found++; } else { - dict.valid = false; /* Do not use this tablespace. */ fil_report_bad_tablespace( dict.filepath, dict.check_msg, dict.id, @@ -4481,6 +4419,10 @@ cleanup_and_exit: mem_free(def.filepath); + if (err == DB_SUCCESS && !srv_read_only_mode) { + fsp_flags_try_adjust(id, flags & ~FSP_FLAGS_MEM_MASK); + } + return(err); } #endif /* !UNIV_HOTBACKUP */ @@ -4662,7 +4604,23 @@ fil_user_tablespace_restore_page( goto out; } - flags = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + page); + flags = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + page); + + if (!fsp_flags_is_valid(flags)) { + ulint cflags = fsp_flags_convert_from_101(flags); + if (cflags == ULINT_UNDEFINED) { + ib_logf(IB_LOG_LEVEL_WARN, + "Ignoring a doublewrite copy of page " + ULINTPF ":" ULINTPF + " due to invalid flags 0x%x", + fsp->id, page_no, int(flags)); + err = false; + goto out; + } + flags = cflags; + /* The flags on the page should be converted later. */ + } + zip_size = fsp_flags_get_zip_size(flags); page_size = fsp_flags_get_page_size(flags); @@ -5051,6 +5009,16 @@ will_not_choose: } mutex_exit(&fil_system->mutex); #endif /* UNIV_HOTBACKUP */ + /* Adjust the memory-based flags that would normally be set by + dict_tf_to_fsp_flags(). In recovery, we have no data dictionary. */ + if (FSP_FLAGS_HAS_PAGE_COMPRESSION(fsp->flags)) { + fsp->flags |= page_zip_level + << FSP_FLAGS_MEM_COMPRESSION_LEVEL; + } + remote.flags |= 1U << FSP_FLAGS_MEM_DATA_DIR; + /* We will leave atomic_writes at ATOMIC_WRITES_DEFAULT. + That will be adjusted in fil_space_for_table_exists_in_mem(). */ + ibool file_space_create_success = fil_space_create( tablename, fsp->id, fsp->flags, FIL_TABLESPACE, fsp->crypt_data, false); @@ -5342,13 +5310,12 @@ fil_report_missing_tablespace( name, space_id); } -/*******************************************************************//** -Returns TRUE if a matching tablespace exists in the InnoDB tablespace memory +/** Check if a matching tablespace exists in the InnoDB tablespace memory cache. Note that if we have not done a crash recovery at the database startup, there may be many tablespaces which are not yet in the memory cache. -@return TRUE if a matching tablespace exists in the memory cache */ +@return whether a matching tablespace exists in the memory cache */ UNIV_INTERN -ibool +bool fil_space_for_table_exists_in_mem( /*==============================*/ ulint id, /*!< in: space id */ @@ -5356,13 +5323,7 @@ fil_space_for_table_exists_in_mem( fil_space_create(). Either the standard 'dbname/tablename' format or table->dir_path_of_temp_table */ - ibool mark_space, /*!< in: in crash recovery, at database - startup we mark all spaces which have - an associated table in the InnoDB - data dictionary, so that - we can print a warning about orphaned - tablespaces */ - ibool print_error_if_does_not_exist, + bool print_error_if_does_not_exist, /*!< in: print detailed error information to the .err log if a matching tablespace is not found from @@ -5370,12 +5331,13 @@ fil_space_for_table_exists_in_mem( bool adjust_space, /*!< in: whether to adjust space id when find table space mismatch */ mem_heap_t* heap, /*!< in: heap memory */ - table_id_t table_id) /*!< in: table id */ + table_id_t table_id, /*!< in: table id */ + ulint table_flags) /*!< in: table flags */ { fil_space_t* fnamespace; fil_space_t* space; - ut_ad(fil_system); + const ulint expected_flags = dict_tf_to_fsp_flags(table_flags); mutex_enter(&fil_system->mutex); @@ -5387,42 +5349,31 @@ fil_space_for_table_exists_in_mem( directory path from the datadir to the file */ fnamespace = fil_space_get_by_name(name); - if (space && space == fnamespace) { - /* Found */ - - if (mark_space) { - space->mark = TRUE; - } - - mutex_exit(&fil_system->mutex); - - return(TRUE); - } - - /* Info from "fnamespace" comes from the ibd file itself, it can - be different from data obtained from System tables since it is - not transactional. If adjust_space is set, and the mismatching - space are between a user table and its temp table, we shall - adjust the ibd file name according to system table info */ - if (adjust_space - && space != NULL - && row_is_mysql_tmp_table_name(space->name) - && !row_is_mysql_tmp_table_name(name)) { + bool valid = space && !((space->flags ^ expected_flags) + & ~FSP_FLAGS_MEM_MASK); + if (!space) { + } else if (!valid || space == fnamespace) { + /* Found with the same file name, or got a flag mismatch. */ + goto func_exit; + } else if (adjust_space + && row_is_mysql_tmp_table_name(space->name) + && !row_is_mysql_tmp_table_name(name)) { + /* Info from fnamespace comes from the ibd file + itself, it can be different from data obtained from + System tables since renaming files is not + transactional. We shall adjust the ibd file name + according to system table info. */ mutex_exit(&fil_system->mutex); DBUG_EXECUTE_IF("ib_crash_before_adjust_fil_space", DBUG_SUICIDE();); - if (fnamespace) { - char* tmp_name; + char* tmp_name = dict_mem_create_temporary_tablename( + heap, name, table_id); - tmp_name = dict_mem_create_temporary_tablename( - heap, name, table_id); - - fil_rename_tablespace(fnamespace->name, fnamespace->id, - tmp_name, NULL); - } + fil_rename_tablespace(fnamespace->name, fnamespace->id, + tmp_name, NULL); DBUG_EXECUTE_IF("ib_crash_after_adjust_one_fil_space", DBUG_SUICIDE();); @@ -5435,16 +5386,12 @@ fil_space_for_table_exists_in_mem( mutex_enter(&fil_system->mutex); fnamespace = fil_space_get_by_name(name); ut_ad(space == fnamespace); - mutex_exit(&fil_system->mutex); - - return(TRUE); + goto func_exit; } if (!print_error_if_does_not_exist) { - - mutex_exit(&fil_system->mutex); - - return(FALSE); + valid = false; + goto func_exit; } if (space == NULL) { @@ -5471,10 +5418,8 @@ error_exit: fputs("InnoDB: Please refer to\n" "InnoDB: " REFMAN "innodb-troubleshooting-datadict.html\n" "InnoDB: for how to resolve the issue.\n", stderr); - - mutex_exit(&fil_system->mutex); - - return(FALSE); + valid = false; + goto func_exit; } if (0 != strcmp(space->name, name)) { @@ -5501,9 +5446,19 @@ error_exit: goto error_exit; } +func_exit: + if (valid) { + /* Adjust the flags that are in FSP_FLAGS_MEM_MASK. + FSP_SPACE_FLAGS will not be written back here. */ + space->flags = expected_flags; + } mutex_exit(&fil_system->mutex); - return(FALSE); + if (valid && !srv_read_only_mode) { + fsp_flags_try_adjust(id, expected_flags & ~FSP_FLAGS_MEM_MASK); + } + + return(valid); } /*******************************************************************//** @@ -7331,9 +7286,8 @@ fil_space_get_crypt_data( byte *page = static_cast(ut_align(buf, UNIV_PAGE_SIZE)); fil_read(true, space_id, 0, 0, 0, UNIV_PAGE_SIZE, page, NULL, NULL); - ulint flags = fsp_header_get_flags(page); ulint offset = fsp_header_get_crypt_offset( - fsp_flags_get_zip_size(flags), NULL); + fsp_header_get_zip_size(page), NULL); space->crypt_data = fil_space_read_crypt_data(space_id, page, offset); ut_free(buf); diff --git a/storage/innobase/fsp/fsp0fsp.cc b/storage/innobase/fsp/fsp0fsp.cc index 87aa5f7db5c..a71d9f95ac2 100644 --- a/storage/innobase/fsp/fsp0fsp.cc +++ b/storage/innobase/fsp/fsp0fsp.cc @@ -660,6 +660,7 @@ fsp_header_init_fields( ulint space_id, /*!< in: space id */ ulint flags) /*!< in: tablespace flags (FSP_SPACE_FLAGS) */ { + flags &= ~FSP_FLAGS_MEM_MASK; ut_a(fsp_flags_is_valid(flags)); mach_write_to_4(FSP_HEADER_OFFSET + FSP_SPACE_ID + page, @@ -710,7 +711,7 @@ fsp_header_init( mlog_write_ulint(header + FSP_SIZE, size, MLOG_4BYTES, mtr); mlog_write_ulint(header + FSP_FREE_LIMIT, 0, MLOG_4BYTES, mtr); - mlog_write_ulint(header + FSP_SPACE_FLAGS, flags, + mlog_write_ulint(header + FSP_SPACE_FLAGS, flags & ~FSP_FLAGS_MEM_MASK, MLOG_4BYTES, mtr); mlog_write_ulint(header + FSP_FRAG_N_USED, 0, MLOG_4BYTES, mtr); diff --git a/storage/innobase/include/dict0dict.ic b/storage/innobase/include/dict0dict.ic index 3d2f0dff0da..800065ddaa1 100644 --- a/storage/innobase/include/dict0dict.ic +++ b/storage/innobase/include/dict0dict.ic @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates -Copyright (c) 2013, 2016, MariaDB Corporation +Copyright (c) 2013, 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 @@ -914,10 +914,13 @@ dict_tf_to_fsp_flags( ulint table_flags) /*!< in: dict_table_t::flags */ { ulint fsp_flags; - ulint page_compression = DICT_TF_GET_PAGE_COMPRESSION(table_flags); - ulint page_compression_level = DICT_TF_GET_PAGE_COMPRESSION_LEVEL(table_flags); + ulint page_compression_level = DICT_TF_GET_PAGE_COMPRESSION_LEVEL( + table_flags); ulint atomic_writes = DICT_TF_GET_ATOMIC_WRITES(table_flags); + ut_ad((DICT_TF_GET_PAGE_COMPRESSION(table_flags) == 0) + == (page_compression_level == 0)); + DBUG_EXECUTE_IF("dict_tf_to_fsp_flags_failure", return(ULINT_UNDEFINED);); @@ -925,30 +928,23 @@ dict_tf_to_fsp_flags( fsp_flags = DICT_TF_HAS_ATOMIC_BLOBS(table_flags) ? 1 : 0; /* ZIP_SSIZE and ATOMIC_BLOBS are at the same position. */ - fsp_flags |= table_flags & DICT_TF_MASK_ZIP_SSIZE; - fsp_flags |= table_flags & DICT_TF_MASK_ATOMIC_BLOBS; - - /* In addition, tablespace flags also contain the page size. */ - fsp_flags |= fsp_flags_set_page_size(fsp_flags, UNIV_PAGE_SIZE); + fsp_flags |= table_flags + & (DICT_TF_MASK_ZIP_SSIZE | DICT_TF_MASK_ATOMIC_BLOBS); - /* The DATA_DIR flag is in a different position in fsp_flag */ - fsp_flags |= DICT_TF_HAS_DATA_DIR(table_flags) - ? FSP_FLAGS_MASK_DATA_DIR : 0; + fsp_flags |= FSP_FLAGS_PAGE_SSIZE(); - /* In addition, tablespace flags also contain if the page - compression is used for this table. */ - fsp_flags |= FSP_FLAGS_SET_PAGE_COMPRESSION(fsp_flags, page_compression); + if (page_compression_level) { + fsp_flags |= FSP_FLAGS_MASK_PAGE_COMPRESSION; + } - /* In addition, tablespace flags also contain page compression level - if page compression is used for this table. */ - fsp_flags |= FSP_FLAGS_SET_PAGE_COMPRESSION_LEVEL(fsp_flags, page_compression_level); + ut_a(fsp_flags_is_valid(fsp_flags)); - /* In addition, tablespace flags also contain flag if atomic writes - is used for this table */ - fsp_flags |= FSP_FLAGS_SET_ATOMIC_WRITES(fsp_flags, atomic_writes); + if (DICT_TF_HAS_DATA_DIR(table_flags)) { + fsp_flags |= 1U << FSP_FLAGS_MEM_DATA_DIR; + } - ut_a(fsp_flags_is_valid(fsp_flags)); - ut_a(dict_tf_verify_flags(table_flags, fsp_flags)); + fsp_flags |= atomic_writes << FSP_FLAGS_MEM_ATOMIC_WRITES; + fsp_flags |= page_compression_level << FSP_FLAGS_MEM_COMPRESSION_LEVEL; return(fsp_flags); } diff --git a/storage/innobase/include/dict0pagecompress.h b/storage/innobase/include/dict0pagecompress.h index 19a2a6c52f3..6503c86ffa2 100644 --- a/storage/innobase/include/dict0pagecompress.h +++ b/storage/innobase/include/dict0pagecompress.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (C) 2013 SkySQL Ab. All Rights Reserved. +Copyright (C) 2013, 2017, MariaDB Corporation. All Rights Reserved. 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 @@ -56,17 +56,6 @@ dict_table_page_compression_level( const dict_table_t* table) /*!< in: table */ __attribute__((const)); -/********************************************************************//** -Verify that dictionary flags match tablespace flags -@return true if flags match, false if not */ -UNIV_INLINE -ibool -dict_tf_verify_flags( -/*=================*/ - ulint table_flags, /*!< in: dict_table_t::flags */ - ulint fsp_flags) /*!< in: fil_space_t::flags */ - __attribute__((const)); - /********************************************************************//** Extract the atomic writes flag from table flags. @return true if atomic writes are used, false if not used */ diff --git a/storage/innobase/include/dict0pagecompress.ic b/storage/innobase/include/dict0pagecompress.ic index 811976434a8..13c2b46c51c 100644 --- a/storage/innobase/include/dict0pagecompress.ic +++ b/storage/innobase/include/dict0pagecompress.ic @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (C) 2013 SkySQL Ab. All Rights Reserved. +Copyright (C) 2013, 2017, MariaDB Corporation. All Rights Reserved. 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 @@ -24,92 +24,6 @@ page compression and atomic writes information to dictionary. Created 11/12/2013 Jan Lindström jan.lindstrom@skysql.com ***********************************************************************/ -/********************************************************************//** -Verify that dictionary flags match tablespace flags -@return true if flags match, false if not */ -UNIV_INLINE -ibool -dict_tf_verify_flags( -/*=================*/ - ulint table_flags, /*!< in: dict_table_t::flags */ - ulint fsp_flags) /*!< in: fil_space_t::flags */ -{ - ulint table_unused = DICT_TF_GET_UNUSED(table_flags); - ulint compact = DICT_TF_GET_COMPACT(table_flags); - ulint ssize = DICT_TF_GET_ZIP_SSIZE(table_flags); - ulint atomic_blobs = DICT_TF_HAS_ATOMIC_BLOBS(table_flags); - ulint data_dir = DICT_TF_HAS_DATA_DIR(table_flags); - ulint page_compression = DICT_TF_GET_PAGE_COMPRESSION(table_flags); - ulint page_compression_level = DICT_TF_GET_PAGE_COMPRESSION_LEVEL(table_flags); - ulint atomic_writes = DICT_TF_GET_ATOMIC_WRITES(table_flags); - ulint post_antelope = FSP_FLAGS_GET_POST_ANTELOPE(fsp_flags); - ulint zip_ssize = FSP_FLAGS_GET_ZIP_SSIZE(fsp_flags); - ulint fsp_atomic_blobs = FSP_FLAGS_HAS_ATOMIC_BLOBS(fsp_flags); - ulint page_ssize = FSP_FLAGS_GET_PAGE_SSIZE(fsp_flags); - ulint fsp_unused = FSP_FLAGS_GET_UNUSED(fsp_flags); - ulint fsp_page_compression = FSP_FLAGS_GET_PAGE_COMPRESSION(fsp_flags); - ulint fsp_page_compression_level = FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL(fsp_flags); - ulint fsp_atomic_writes = FSP_FLAGS_GET_ATOMIC_WRITES(fsp_flags); - - DBUG_EXECUTE_IF("dict_tf_verify_flags_failure", - return(ULINT_UNDEFINED);); - - ut_a(!table_unused); - ut_a(!fsp_unused); - ut_a(page_ssize == 0 || page_ssize != 0); /* silence compiler */ - ut_a(compact == 0 || compact == 1); /* silence compiler */ - ut_a(data_dir == 0 || data_dir == 1); /* silence compiler */ - ut_a(post_antelope == 0 || post_antelope == 1); /* silence compiler */ - - if (ssize != zip_ssize) { - fprintf(stderr, - "InnoDB: Error: table flags has zip_ssize %ld" - " in the data dictionary\n" - "InnoDB: but the flags in file has zip_ssize %ld\n", - ssize, zip_ssize); - return (FALSE); - } - if (atomic_blobs != fsp_atomic_blobs) { - fprintf(stderr, - "InnoDB: Error: table flags has atomic_blobs %ld" - " in the data dictionary\n" - "InnoDB: but the flags in file has atomic_blobs %ld\n", - atomic_blobs, fsp_atomic_blobs); - - return (FALSE); - } - if (page_compression != fsp_page_compression) { - fprintf(stderr, - "InnoDB: Error: table flags has page_compression %ld" - " in the data dictionary\n" - "InnoDB: but the flags in file ahas page_compression %ld\n", - page_compression, fsp_page_compression); - - return (FALSE); - } - if (page_compression_level != fsp_page_compression_level) { - fprintf(stderr, - "InnoDB: Error: table flags has page_compression_level %ld" - " in the data dictionary\n" - "InnoDB: but the flags in file has page_compression_level %ld\n", - page_compression_level, fsp_page_compression_level); - - return (FALSE); - } - - if (atomic_writes != fsp_atomic_writes) { - fprintf(stderr, - "InnoDB: Error: table flags has atomic writes %ld" - " in the data dictionary\n" - "InnoDB: but the flags in file has atomic_writes %ld\n", - atomic_writes, fsp_atomic_writes); - - return (FALSE); - } - - return(TRUE); -} - /********************************************************************//** Extract the page compression level from dict_table_t::flags. These flags are in memory, so assert that they are valid. diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h index cc67d918d5f..525a68bf5e6 100644 --- a/storage/innobase/include/fil0fil.h +++ b/storage/innobase/include/fil0fil.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2016, Oracle and/or its affiliates. -Copyright (c) 2013, 2016, MariaDB Corporation. +Copyright (c) 2013, 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 @@ -44,7 +44,6 @@ Created 10/25/1995 Heikki Tuuri // Forward declaration struct trx_t; -struct fil_space_t; typedef std::list space_name_list_t; @@ -271,10 +270,6 @@ struct fil_space_t { an insert buffer merge request for a page because it actually was for the previous incarnation of the space */ - ibool mark; /*!< this is set to TRUE at database startup if - the space corresponds to a table in the InnoDB - data dictionary; so we can print a warning of - orphaned tablespaces */ ibool stop_ios;/*!< TRUE if we want to rename the .ibd file of tablespace and want to stop temporarily posting of new i/o @@ -303,7 +298,8 @@ struct fil_space_t { /*!< recovered tablespace size in pages; 0 if no size change was read from the redo log, or if the size change was implemented */ - ulint flags; /*!< tablespace flags; see + ulint flags; /*!< FSP_SPACE_FLAGS and FSP_FLAGS_MEM_ flags; + see fsp0fsp.h, fsp_flags_is_valid(), fsp_flags_get_zip_size() */ ulint n_reserved_extents; @@ -455,6 +451,7 @@ fil_node_create( ibool is_raw) /*!< in: TRUE if a raw device or a raw disk partition */ MY_ATTRIBUTE((nonnull, warn_unused_result)); + #ifdef UNIV_LOG_ARCHIVE /****************************************************************//** Drops files from the start of a file space, so that its size is cut by @@ -618,7 +615,7 @@ fil_read_first_page( ibool one_read_already, /*!< in: TRUE if min and max parameters below already contain sensible data */ - ulint* flags, /*!< out: tablespace flags */ + ulint* flags, /*!< out: FSP_SPACE_FLAGS */ ulint* space_id, /*!< out: tablespace ID */ #ifdef UNIV_LOG_ARCHIVE ulint* min_arch_log_no, /*!< out: min of archived @@ -836,6 +833,14 @@ fil_create_new_single_table_tablespace( ulint key_id) /*!< in: encryption key_id */ __attribute__((nonnull, warn_unused_result)); #ifndef UNIV_HOTBACKUP +/** Try to adjust FSP_SPACE_FLAGS if they differ from the expectations. +(Typically when upgrading from MariaDB 10.1.0..10.1.20.) +@param[in] space_id tablespace ID +@param[in] flags desired tablespace flags */ +UNIV_INTERN +void +fsp_flags_try_adjust(ulint space_id, ulint flags); + /********************************************************************//** Tries to open a single-table tablespace and optionally checks the space id is right in it. If does not succeed, prints an error message to the .err log. This @@ -864,7 +869,7 @@ fil_open_single_table_tablespace( bool validate, /*!< in: Do we validate tablespace? */ bool fix_dict, /*!< in: Can we fix the dictionary? */ ulint id, /*!< in: space id */ - ulint flags, /*!< in: tablespace flags */ + ulint flags, /*!< in: expected FSP_SPACE_FLAGS */ const char* tablename, /*!< in: table name in the databasename/tablename format */ const char* filepath, /*!< in: tablespace filepath */ @@ -905,25 +910,18 @@ fil_tablespace_exists_in_mem( /*=========================*/ ulint id); /*!< in: space id */ #ifndef UNIV_HOTBACKUP -/*******************************************************************//** -Returns TRUE if a matching tablespace exists in the InnoDB tablespace memory +/** Check if a matching tablespace exists in the InnoDB tablespace memory cache. Note that if we have not done a crash recovery at the database startup, there may be many tablespaces which are not yet in the memory cache. -@return TRUE if a matching tablespace exists in the memory cache */ +@return whether a matching tablespace exists in the memory cache */ UNIV_INTERN -ibool +bool fil_space_for_table_exists_in_mem( /*==============================*/ ulint id, /*!< in: space id */ const char* name, /*!< in: table name in the standard 'databasename/tablename' format */ - ibool mark_space, /*!< in: in crash recovery, at database - startup we mark all spaces which have - an associated table in the InnoDB - data dictionary, so that - we can print a warning about orphaned - tablespaces */ - ibool print_error_if_does_not_exist, + bool print_error_if_does_not_exist, /*!< in: print detailed error information to the .err log if a matching tablespace is not found from @@ -931,7 +929,8 @@ fil_space_for_table_exists_in_mem( bool adjust_space, /*!< in: whether to adjust space id when find table space mismatch */ mem_heap_t* heap, /*!< in: heap memory */ - table_id_t table_id); /*!< in: table id */ + table_id_t table_id, /*!< in: table id */ + ulint table_flags); /*!< in: table flags */ #else /* !UNIV_HOTBACKUP */ /********************************************************************//** Extends all tablespaces to the size stored in the space header. During the diff --git a/storage/innobase/include/fil0pagecompress.h b/storage/innobase/include/fil0pagecompress.h index 10db59fb218..1fe5cb66bf6 100644 --- a/storage/innobase/include/fil0pagecompress.h +++ b/storage/innobase/include/fil0pagecompress.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (C) 2013, 2016 MariaDB Corporation. All Rights Reserved. +Copyright (C) 2013, 2017 MariaDB Corporation. All Rights Reserved. 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 @@ -44,20 +44,11 @@ Returns the page compression flag of the space, or false if the space is not compressed. The tablespace must be cached in the memory cache. @return true if page compressed, false if not or space not found */ UNIV_INLINE -ibool +bool fil_space_is_page_compressed( /*=========================*/ ulint id); /*!< in: space id */ /*******************************************************************//** -Returns the page compression flag of the space, or false if the space -is not compressed. The tablespace must be cached in the memory cache. -@return true if page compressed, false if not or space not found */ -UNIV_INTERN -ibool -fil_space_get_page_compressed( -/*=========================*/ - fil_space_t* space); /*!< in: space id */ -/*******************************************************************//** Returns the atomic writes flag of the space, or false if the space is not using atomic writes. The tablespace must be cached in the memory cache. @return atomic write table option value */ diff --git a/storage/innobase/include/fsp0fsp.h b/storage/innobase/include/fsp0fsp.h index abcd5721a47..24fe382b344 100644 --- a/storage/innobase/include/fsp0fsp.h +++ b/storage/innobase/include/fsp0fsp.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2013, 2016, MariaDB Corporation. All Rights Reserved. +Copyright (c) 2013, 2017, MariaDB Corporation. All Rights Reserved. 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 @@ -52,28 +52,67 @@ to the two Barracuda row formats COMPRESSED and DYNAMIC. */ #define FSP_FLAGS_WIDTH_ATOMIC_BLOBS 1 /** Number of flag bits used to indicate the tablespace page size */ #define FSP_FLAGS_WIDTH_PAGE_SSIZE 4 -/** Width of the DATA_DIR flag. This flag indicates that the tablespace -is found in a remote location, not the default data directory. */ -#define FSP_FLAGS_WIDTH_DATA_DIR 1 -/** Number of flag bits used to indicate the page compression and compression level */ -#define FSP_FLAGS_WIDTH_PAGE_COMPRESSION 1 -#define FSP_FLAGS_WIDTH_PAGE_COMPRESSION_LEVEL 4 +/** Number of reserved bits */ +#define FSP_FLAGS_WIDTH_RESERVED 6 +/** Number of flag bits used to indicate the page compression */ +#define FSP_FLAGS_WIDTH_PAGE_COMPRESSION 1 -/** Number of flag bits used to indicate atomic writes for this tablespace */ -#define FSP_FLAGS_WIDTH_ATOMIC_WRITES 2 - -/** Width of all the currently known tablespace flags */ +/** Width of all the currently known persistent tablespace flags */ #define FSP_FLAGS_WIDTH (FSP_FLAGS_WIDTH_POST_ANTELOPE \ + FSP_FLAGS_WIDTH_ZIP_SSIZE \ + FSP_FLAGS_WIDTH_ATOMIC_BLOBS \ + FSP_FLAGS_WIDTH_PAGE_SSIZE \ - + FSP_FLAGS_WIDTH_DATA_DIR \ - + FSP_FLAGS_WIDTH_PAGE_COMPRESSION \ - + FSP_FLAGS_WIDTH_PAGE_COMPRESSION_LEVEL \ - + FSP_FLAGS_WIDTH_ATOMIC_WRITES ) - -/** A mask of all the known/used bits in tablespace flags */ -#define FSP_FLAGS_MASK (~(~0 << FSP_FLAGS_WIDTH)) + + FSP_FLAGS_WIDTH_RESERVED \ + + FSP_FLAGS_WIDTH_PAGE_COMPRESSION) + +/** A mask of all the known/used bits in FSP_SPACE_FLAGS */ +#define FSP_FLAGS_MASK (~(~0U << FSP_FLAGS_WIDTH)) + +/* FSP_SPACE_FLAGS position and name in MySQL 5.6/MariaDB 10.0 or older +and MariaDB 10.1.20 or older MariaDB 10.1 and in MariaDB 10.1.21 +or newer. +MySQL 5.6 MariaDB 10.1.x MariaDB 10.1.21 +==================================================================== +Below flags in same offset +==================================================================== +0: POST_ANTELOPE 0:POST_ANTELOPE 0: POST_ANTELOPE +1..4: ZIP_SSIZE(0..5) 1..4:ZIP_SSIZE(0..5) 1..4: ZIP_SSIZE(0..5) +(NOTE: bit 4 is always 0) +5: ATOMIC_BLOBS 5:ATOMIC_BLOBS 5: ATOMIC_BLOBS +===================================================================== +Below note the order difference: +===================================================================== +6..9: PAGE_SSIZE(3..7) 6: COMPRESSION 6..9: PAGE_SSIZE(3..7) +10: DATA_DIR 7..10: COMP_LEVEL(0..9) 10: RESERVED (5.6 DATA_DIR) +===================================================================== +The flags below were in incorrect position in MariaDB 10.1, +or have been introduced in MySQL 5.7 or 8.0: +===================================================================== +11: UNUSED 11..12:ATOMIC_WRITES 11: RESERVED (5.7 SHARED) + 12: RESERVED (5.7 TEMPORARY) + 13..15:PAGE_SSIZE(3..7) 13: RESERVED (5.7 ENCRYPTION) + 14: RESERVED (8.0 SDI) + 15: RESERVED + 16: PAGE_SSIZE_msb(0) 16: COMPRESSION + 17: DATA_DIR 17: UNUSED + 18: UNUSED +===================================================================== +The flags below only exist in fil_space_t::flags, not in FSP_SPACE_FLAGS: +===================================================================== + 25: DATA_DIR + 26..27: ATOMIC_WRITES + 28..31: COMPRESSION_LEVEL +*/ + +/** A mask of the memory-only flags in fil_space_t::flags */ +#define FSP_FLAGS_MEM_MASK (~0U << FSP_FLAGS_MEM_DATA_DIR) + +/** Zero relative shift position of the DATA_DIR flag */ +#define FSP_FLAGS_MEM_DATA_DIR 25 +/** Zero relative shift position of the ATOMIC_WRITES field */ +#define FSP_FLAGS_MEM_ATOMIC_WRITES 26 +/** Zero relative shift position of the COMPRESSION_LEVEL field */ +#define FSP_FLAGS_MEM_COMPRESSION_LEVEL 28 /** Zero relative shift position of the POST_ANTELOPE field */ #define FSP_FLAGS_POS_POST_ANTELOPE 0 @@ -83,29 +122,16 @@ is found in a remote location, not the default data directory. */ /** Zero relative shift position of the ATOMIC_BLOBS field */ #define FSP_FLAGS_POS_ATOMIC_BLOBS (FSP_FLAGS_POS_ZIP_SSIZE \ + FSP_FLAGS_WIDTH_ZIP_SSIZE) -/** Note that these need to be before the page size to be compatible with -dictionary */ -/** Zero relative shift position of the PAGE_COMPRESSION field */ -#define FSP_FLAGS_POS_PAGE_COMPRESSION (FSP_FLAGS_POS_ATOMIC_BLOBS \ - + FSP_FLAGS_WIDTH_ATOMIC_BLOBS) -/** Zero relative shift position of the PAGE_COMPRESSION_LEVEL field */ -#define FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL (FSP_FLAGS_POS_PAGE_COMPRESSION \ - + FSP_FLAGS_WIDTH_PAGE_COMPRESSION) -/** Zero relative shift position of the ATOMIC_WRITES field */ -#define FSP_FLAGS_POS_ATOMIC_WRITES (FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL \ - + FSP_FLAGS_WIDTH_PAGE_COMPRESSION_LEVEL) -/** Zero relative shift position of the PAGE_SSIZE field */ -#define FSP_FLAGS_POS_PAGE_SSIZE (FSP_FLAGS_POS_ATOMIC_WRITES \ - + FSP_FLAGS_WIDTH_ATOMIC_WRITES) -/** Zero relative shift position of the start of the UNUSED bits */ -#define FSP_FLAGS_POS_DATA_DIR (FSP_FLAGS_POS_PAGE_SSIZE \ - + FSP_FLAGS_WIDTH_PAGE_SSIZE) -#define FSP_FLAGS_POS_DATA_DIR_ORACLE (FSP_FLAGS_POS_ATOMIC_BLOBS \ - + FSP_FLAGS_WIDTH_ATOMIC_BLOBS \ +/** Zero relative shift position of the start of the PAGE_SSIZE bits */ +#define FSP_FLAGS_POS_PAGE_SSIZE (FSP_FLAGS_POS_ATOMIC_BLOBS \ + + FSP_FLAGS_WIDTH_ATOMIC_BLOBS) +/** Zero relative shift position of the start of the RESERVED bits +these are only used in MySQL 5.7 and used for compatibility. */ +#define FSP_FLAGS_POS_RESERVED (FSP_FLAGS_POS_PAGE_SSIZE \ + FSP_FLAGS_WIDTH_PAGE_SSIZE) -/** Zero relative shift position of the start of the UNUSED bits */ -#define FSP_FLAGS_POS_UNUSED (FSP_FLAGS_POS_DATA_DIR \ - + FSP_FLAGS_WIDTH_DATA_DIR) +/** Zero relative shift position of the PAGE_COMPRESSION field */ +#define FSP_FLAGS_POS_PAGE_COMPRESSION (FSP_FLAGS_POS_RESERVED \ + + FSP_FLAGS_WIDTH_RESERVED) /** Bit mask of the POST_ANTELOPE field */ #define FSP_FLAGS_MASK_POST_ANTELOPE \ @@ -123,26 +149,23 @@ dictionary */ #define FSP_FLAGS_MASK_PAGE_SSIZE \ ((~(~0U << FSP_FLAGS_WIDTH_PAGE_SSIZE)) \ << FSP_FLAGS_POS_PAGE_SSIZE) -/** Bit mask of the DATA_DIR field */ -#define FSP_FLAGS_MASK_DATA_DIR \ - ((~(~0U << FSP_FLAGS_WIDTH_DATA_DIR)) \ - << FSP_FLAGS_POS_DATA_DIR) -/** Bit mask of the DATA_DIR field */ -#define FSP_FLAGS_MASK_DATA_DIR_ORACLE \ - ((~(~0U << FSP_FLAGS_WIDTH_DATA_DIR)) \ - << FSP_FLAGS_POS_DATA_DIR_ORACLE) +/** Bit mask of the RESERVED1 field */ +#define FSP_FLAGS_MASK_RESERVED \ + ((~(~0U << FSP_FLAGS_WIDTH_RESERVED)) \ + << FSP_FLAGS_POS_RESERVED) /** Bit mask of the PAGE_COMPRESSION field */ -#define FSP_FLAGS_MASK_PAGE_COMPRESSION \ +#define FSP_FLAGS_MASK_PAGE_COMPRESSION \ ((~(~0U << FSP_FLAGS_WIDTH_PAGE_COMPRESSION)) \ << FSP_FLAGS_POS_PAGE_COMPRESSION) -/** Bit mask of the PAGE_COMPRESSION_LEVEL field */ -#define FSP_FLAGS_MASK_PAGE_COMPRESSION_LEVEL \ - ((~(~0U << FSP_FLAGS_WIDTH_PAGE_COMPRESSION_LEVEL)) \ - << FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL) -/** Bit mask of the ATOMIC_WRITES field */ -#define FSP_FLAGS_MASK_ATOMIC_WRITES \ - ((~(~0U << FSP_FLAGS_WIDTH_ATOMIC_WRITES)) \ - << FSP_FLAGS_POS_ATOMIC_WRITES) + +/** Bit mask of the in-memory ATOMIC_WRITES field */ +#define FSP_FLAGS_MASK_MEM_ATOMIC_WRITES \ + (3U << FSP_FLAGS_MEM_ATOMIC_WRITES) + +/** Bit mask of the in-memory COMPRESSION_LEVEL field */ +#define FSP_FLAGS_MASK_MEM_COMPRESSION_LEVEL \ + (15U << FSP_FLAGS_MEM_COMPRESSION_LEVEL) + /** Return the value of the POST_ANTELOPE field */ #define FSP_FLAGS_GET_POST_ANTELOPE(flags) \ ((flags & FSP_FLAGS_MASK_POST_ANTELOPE) \ @@ -159,49 +182,78 @@ dictionary */ #define FSP_FLAGS_GET_PAGE_SSIZE(flags) \ ((flags & FSP_FLAGS_MASK_PAGE_SSIZE) \ >> FSP_FLAGS_POS_PAGE_SSIZE) -/** Return the value of the DATA_DIR field */ -#define FSP_FLAGS_HAS_DATA_DIR(flags) \ - ((flags & FSP_FLAGS_MASK_DATA_DIR) \ - >> FSP_FLAGS_POS_DATA_DIR) -#define FSP_FLAGS_HAS_DATA_DIR_ORACLE(flags) \ - ((flags & FSP_FLAGS_MASK_DATA_DIR_ORACLE) \ - >> FSP_FLAGS_POS_DATA_DIR_ORACLE) +/** @return the RESERVED flags */ +#define FSP_FLAGS_GET_RESERVED(flags) \ + ((flags & FSP_FLAGS_MASK_RESERVED) \ + >> FSP_FLAGS_POS_RESERVED) +/** @return the PAGE_COMPRESSION flag */ +#define FSP_FLAGS_HAS_PAGE_COMPRESSION(flags) \ + ((flags & FSP_FLAGS_MASK_PAGE_COMPRESSION) \ + >> FSP_FLAGS_POS_PAGE_COMPRESSION) + /** Return the contents of the UNUSED bits */ #define FSP_FLAGS_GET_UNUSED(flags) \ (flags >> FSP_FLAGS_POS_UNUSED) -/** Return the value of the PAGE_COMPRESSION field */ -#define FSP_FLAGS_GET_PAGE_COMPRESSION(flags) \ - ((flags & FSP_FLAGS_MASK_PAGE_COMPRESSION) \ - >> FSP_FLAGS_POS_PAGE_COMPRESSION) -/** Return the value of the PAGE_COMPRESSION_LEVEL field */ +/** @return the PAGE_SSIZE flags for the current innodb_page_size */ +#define FSP_FLAGS_PAGE_SSIZE() \ + ((UNIV_PAGE_SIZE == UNIV_PAGE_SIZE_ORIG) ? \ + 0 : (UNIV_PAGE_SIZE_SHIFT - UNIV_ZIP_SIZE_SHIFT_MIN + 1) \ + << FSP_FLAGS_POS_PAGE_SSIZE) + +/** @return the value of the DATA_DIR field */ +#define FSP_FLAGS_HAS_DATA_DIR(flags) \ + (flags & 1U << FSP_FLAGS_MEM_DATA_DIR) +/** @return the COMPRESSION_LEVEL field */ #define FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL(flags) \ - ((flags & FSP_FLAGS_MASK_PAGE_COMPRESSION_LEVEL) \ - >> FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL) -/** Return the value of the ATOMIC_WRITES field */ + ((flags & FSP_FLAGS_MASK_MEM_COMPRESSION_LEVEL) \ + >> FSP_FLAGS_MEM_COMPRESSION_LEVEL) +/** @return the ATOMIC_WRITES field */ #define FSP_FLAGS_GET_ATOMIC_WRITES(flags) \ - ((flags & FSP_FLAGS_MASK_ATOMIC_WRITES) \ - >> FSP_FLAGS_POS_ATOMIC_WRITES) - -/** Set a PAGE_SSIZE into the correct bits in a given -tablespace flags. */ -#define FSP_FLAGS_SET_PAGE_SSIZE(flags, ssize) \ - (flags | (ssize << FSP_FLAGS_POS_PAGE_SSIZE)) + ((flags & FSP_FLAGS_MASK_MEM_ATOMIC_WRITES) \ + >> FSP_FLAGS_MEM_ATOMIC_WRITES) -/** Set a PAGE_COMPRESSION into the correct bits in a given -tablespace flags. */ -#define FSP_FLAGS_SET_PAGE_COMPRESSION(flags, compression) \ - (flags | (compression << FSP_FLAGS_POS_PAGE_COMPRESSION)) +/* Compatibility macros for MariaDB 10.1.20 or older 10.1 see +table above. */ +/** Zero relative shift position of the PAGE_COMPRESSION field */ +#define FSP_FLAGS_POS_PAGE_COMPRESSION_MARIADB101 \ + (FSP_FLAGS_POS_ATOMIC_BLOBS \ + + FSP_FLAGS_WIDTH_ATOMIC_BLOBS) +/** Zero relative shift position of the PAGE_COMPRESSION_LEVEL field */ +#define FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL_MARIADB101 \ + (FSP_FLAGS_POS_PAGE_COMPRESSION_MARIADB101 + 1) +/** Zero relative shift position of the ATOMIC_WRITES field */ +#define FSP_FLAGS_POS_ATOMIC_WRITES_MARIADB101 \ + (FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL_MARIADB101 + 4) +/** Zero relative shift position of the PAGE_SSIZE field */ +#define FSP_FLAGS_POS_PAGE_SSIZE_MARIADB101 \ + (FSP_FLAGS_POS_ATOMIC_WRITES_MARIADB101 + 2) -/** Set a PAGE_COMPRESSION_LEVEL into the correct bits in a given -tablespace flags. */ -#define FSP_FLAGS_SET_PAGE_COMPRESSION_LEVEL(flags, level) \ - (flags | (level << FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL)) +/** Bit mask of the PAGE_COMPRESSION field */ +#define FSP_FLAGS_MASK_PAGE_COMPRESSION_MARIADB101 \ + (1U << FSP_FLAGS_POS_PAGE_COMPRESSION_MARIADB101) +/** Bit mask of the PAGE_COMPRESSION_LEVEL field */ +#define FSP_FLAGS_MASK_PAGE_COMPRESSION_LEVEL_MARIADB101 \ + (15U << FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL_MARIADB101) +/** Bit mask of the ATOMIC_WRITES field */ +#define FSP_FLAGS_MASK_ATOMIC_WRITES_MARIADB101 \ + (3U << FSP_FLAGS_POS_ATOMIC_WRITES_MARIADB101) +/** Bit mask of the PAGE_SSIZE field */ +#define FSP_FLAGS_MASK_PAGE_SSIZE_MARIADB101 \ + (15U << FSP_FLAGS_POS_PAGE_SSIZE_MARIADB101) -/** Set a ATOMIC_WRITES into the correct bits in a given -tablespace flags. */ -#define FSP_FLAGS_SET_ATOMIC_WRITES(flags, atomics) \ - (flags | (atomics << FSP_FLAGS_POS_ATOMIC_WRITES)) +/** Return the value of the PAGE_COMPRESSION field */ +#define FSP_FLAGS_GET_PAGE_COMPRESSION_MARIADB101(flags) \ + ((flags & FSP_FLAGS_MASK_PAGE_COMPRESSION_MARIADB101) \ + >> FSP_FLAGS_POS_PAGE_COMPRESSION_MARIADB101) +/** Return the value of the PAGE_COMPRESSION_LEVEL field */ +#define FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL_MARIADB101(flags) \ + ((flags & FSP_FLAGS_MASK_PAGE_COMPRESSION_LEVEL_MARIADB101) \ + >> FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL_MARIADB101) +/** Return the value of the PAGE_SSIZE field */ +#define FSP_FLAGS_GET_PAGE_SSIZE_MARIADB101(flags) \ + ((flags & FSP_FLAGS_MASK_PAGE_SSIZE_MARIADB101) \ + >> FSP_FLAGS_POS_PAGE_SSIZE_MARIADB101) /* @} */ @@ -735,19 +787,193 @@ fseg_print( mtr_t* mtr); /*!< in/out: mini-transaction */ #endif /* UNIV_BTR_PRINT */ -/********************************************************************//** -Validate and return the tablespace flags, which are stored in the -tablespace header at offset FSP_SPACE_FLAGS. They should be 0 for -ROW_FORMAT=COMPACT and ROW_FORMAT=REDUNDANT. The newer row formats, -COMPRESSED and DYNAMIC, use a file format > Antelope so they should -have a file format number plus the DICT_TF_COMPACT bit set. -@return true if check ok */ +/** Validate the tablespace flags, which are stored in the +tablespace header at offset FSP_SPACE_FLAGS. +@param[in] flags the contents of FSP_SPACE_FLAGS +@return whether the flags are correct (not in the buggy 10.1) format */ +MY_ATTRIBUTE((warn_unused_result, const)) UNIV_INLINE bool -fsp_flags_is_valid( -/*===============*/ - ulint flags) /*!< in: tablespace flags */ - MY_ATTRIBUTE((warn_unused_result, const)); +fsp_flags_is_valid(ulint flags) +{ + DBUG_EXECUTE_IF("fsp_flags_is_valid_failure", + return(false);); + if (flags == 0) { + return(true); + } + if (flags & ~FSP_FLAGS_MASK) { + return(false); + } + if ((flags & (FSP_FLAGS_MASK_POST_ANTELOPE | FSP_FLAGS_MASK_ATOMIC_BLOBS)) + == FSP_FLAGS_MASK_ATOMIC_BLOBS) { + /* If the "atomic blobs" flag (indicating + ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED) flag + is set, then the "post Antelope" (ROW_FORMAT!=REDUNDANT) flag + must also be set. */ + return(false); + } + /* Bits 10..14 should be 0b0000d where d is the DATA_DIR flag + of MySQL 5.6 and MariaDB 10.0, which we ignore. + In the buggy FSP_SPACE_FLAGS written by MariaDB 10.1.0 to 10.1.20, + bits 10..14 would be nonzero 0bsssaa where sss is + nonzero PAGE_SSIZE (3, 4, 6, or 7) + and aa is ATOMIC_WRITES (not 0b11). */ + if (FSP_FLAGS_GET_RESERVED(flags) & ~1) { + return(false); + } + + const ulint ssize = FSP_FLAGS_GET_PAGE_SSIZE(flags); + if (ssize == 1 || ssize == 2 || ssize == 5 || ssize & 8) { + /* the page_size is not between 4k and 64k; + 16k should be encoded as 0, not 5 */ + return(false); + } + const ulint zssize = FSP_FLAGS_GET_ZIP_SSIZE(flags); + if (zssize == 0) { + /* not ROW_FORMAT=COMPRESSED */ + } else if (zssize > (ssize ? ssize : 5)) { + /* invalid KEY_BLOCK_SIZE */ + return(false); + } else if (~flags & (FSP_FLAGS_MASK_POST_ANTELOPE + | FSP_FLAGS_MASK_ATOMIC_BLOBS)) { + /* both these flags should be set for + ROW_FORMAT=COMPRESSED */ + return(false); + } + + return(true); +} + +/** Convert FSP_SPACE_FLAGS from the buggy MariaDB 10.1.0..10.1.20 format. +@param[in] flags the contents of FSP_SPACE_FLAGS +@return the flags corrected from the buggy MariaDB 10.1 format +@retval ULINT_UNDEFINED if the flags are not in the buggy 10.1 format */ +MY_ATTRIBUTE((warn_unused_result, const)) +UNIV_INLINE +ulint +fsp_flags_convert_from_101(ulint flags) +{ + DBUG_EXECUTE_IF("fsp_flags_is_valid_failure", + return(ULINT_UNDEFINED);); + if (flags == 0) { + return(flags); + } + + if (flags >> 18) { + /* The most significant FSP_SPACE_FLAGS bit that was ever set + by MariaDB 10.1.0 to 10.1.20 was bit 17 (misplaced DATA_DIR flag). + The flags must be less than 1<<18 in order to be valid. */ + return(ULINT_UNDEFINED); + } + + if ((flags & (FSP_FLAGS_MASK_POST_ANTELOPE | FSP_FLAGS_MASK_ATOMIC_BLOBS)) + == FSP_FLAGS_MASK_ATOMIC_BLOBS) { + /* If the "atomic blobs" flag (indicating + ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED) flag + is set, then the "post Antelope" (ROW_FORMAT!=REDUNDANT) flag + must also be set. */ + return(ULINT_UNDEFINED); + } + + /* Bits 6..10 denote compression in MariaDB 10.1.0 to 10.1.20. + They must be either 0b00000 or 0b00011 through 0b10011. + In correct versions, these bits would be + 0bd0sss where d is the DATA_DIR flag (garbage bit) and + sss is the PAGE_SSIZE (3, 4, 6, or 7). + + NOTE: MariaDB 10.1.0 to 10.1.20 can misinterpret + uncompressed data files with innodb_page_size=4k or 64k as + compressed innodb_page_size=16k files. Below is an exhaustive + state space analysis. + + -0by1zzz: impossible (the bit 4 must be clean; see above) + -0b101xx: DATA_DIR, innodb_page_size>4k: invalid (COMPRESSION_LEVEL>9) + +0bx0011: innodb_page_size=4k: + !!! Misinterpreted as COMPRESSION_LEVEL=9 or 1, COMPRESSION=1. + -0bx0010: impossible, because sss must be 0b011 or 0b1xx + -0bx0001: impossible, because sss must be 0b011 or 0b1xx + -0b10000: DATA_DIR, innodb_page_size=16: + invalid (COMPRESSION_LEVEL=8 but COMPRESSION=0) + +0b00111: no DATA_DIR, innodb_page_size=64k: + !!! Misinterpreted as COMPRESSION_LEVEL=3, COMPRESSION=1. + -0b00101: impossible, because sss must be 0 for 16k, not 0b101 + -0b001x0: no DATA_DIR, innodb_page_size=32k or 8k: + invalid (COMPRESSION_LEVEL=3 but COMPRESSION=0) + +0b00000: innodb_page_size=16k (looks like COMPRESSION=0) + ??? Could actually be compressed; see PAGE_SSIZE below */ + const ulint level = FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL_MARIADB101( + flags); + if (FSP_FLAGS_GET_PAGE_COMPRESSION_MARIADB101(flags) != (level != 0) + || level > 9) { + /* The compression flags are not in the buggy MariaDB + 10.1 format. */ + return(ULINT_UNDEFINED); + } + if (!(~flags & FSP_FLAGS_MASK_ATOMIC_WRITES_MARIADB101)) { + /* The ATOMIC_WRITES flags cannot be 0b11. + (The bits 11..12 should actually never be 0b11, + because in MySQL they would be SHARED|TEMPORARY.) */ + return(ULINT_UNDEFINED); + } + + /* Bits 13..16 are the wrong position for PAGE_SSIZE, and they + should contain one of the values 3,4,6,7, that is, be of the form + 0b0011 or 0b01xx (except 0b0110). + In correct versions, these bits should be 0bc0se + where c is the MariaDB COMPRESSED flag + and e is the MySQL 5.7 ENCRYPTION flag + and s is the MySQL 8.0 SDI flag. MariaDB can only support s=0, e=0. + + Compressed innodb_page_size=16k tables with correct FSP_SPACE_FLAGS + will be properly rejected by older MariaDB 10.1.x because they + would read as PAGE_SSIZE>=8 which is not valid. */ + + const ulint ssize = FSP_FLAGS_GET_PAGE_SSIZE_MARIADB101(flags); + if (ssize == 1 || ssize == 2 || ssize == 5 || ssize & 8) { + /* the page_size is not between 4k and 64k; + 16k should be encoded as 0, not 5 */ + return(ULINT_UNDEFINED); + } + const ulint zssize = FSP_FLAGS_GET_ZIP_SSIZE(flags); + if (zssize == 0) { + /* not ROW_FORMAT=COMPRESSED */ + } else if (zssize > (ssize ? ssize : 5)) { + /* invalid KEY_BLOCK_SIZE */ + return(ULINT_UNDEFINED); + } else if (~flags & (FSP_FLAGS_MASK_POST_ANTELOPE + | FSP_FLAGS_MASK_ATOMIC_BLOBS)) { + /* both these flags should be set for + ROW_FORMAT=COMPRESSED */ + return(ULINT_UNDEFINED); + } + + flags = ((flags & 0x3f) | ssize << FSP_FLAGS_POS_PAGE_SSIZE + | FSP_FLAGS_GET_PAGE_COMPRESSION_MARIADB101(flags) + << FSP_FLAGS_POS_PAGE_COMPRESSION); + ut_ad(fsp_flags_is_valid(flags)); + return(flags); +} + +/** Compare tablespace flags. +@param[in] expected expected flags from dict_tf_to_fsp_flags() +@param[in] actual flags read from FSP_SPACE_FLAGS +@return whether the flags match */ +MY_ATTRIBUTE((warn_unused_result)) +UNIV_INLINE +bool +fsp_flags_match(ulint expected, ulint actual) +{ + expected &= ~FSP_FLAGS_MEM_MASK; + ut_ad(fsp_flags_is_valid(expected)); + + if (actual == expected) { + return(true); + } + + actual = fsp_flags_convert_from_101(actual); + return(actual == expected); +} + /********************************************************************//** Determine if the tablespace is compressed from dict_table_t::flags. @return TRUE if compressed, FALSE if not compressed */ diff --git a/storage/innobase/include/fsp0fsp.ic b/storage/innobase/include/fsp0fsp.ic index 9f09a9d53e1..59c732b7a29 100644 --- a/storage/innobase/include/fsp0fsp.ic +++ b/storage/innobase/include/fsp0fsp.ic @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2012, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2013, SkySQL Ab. All Rights Reserved. +Copyright (c) 2013, 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 @@ -46,107 +46,6 @@ fsp_descr_page( return((page_no & (zip_size - 1)) == FSP_XDES_OFFSET); } -/********************************************************************//** -Validate and return the tablespace flags, which are stored in the -tablespace header at offset FSP_SPACE_FLAGS. They should be 0 for -ROW_FORMAT=COMPACT and ROW_FORMAT=REDUNDANT. The newer row formats, -COMPRESSED and DYNAMIC, use a file format > Antelope so they should -have a file format number plus the DICT_TF_COMPACT bit set. -@return true if check ok */ -UNIV_INLINE -bool -fsp_flags_is_valid( -/*===============*/ - ulint flags) /*!< in: tablespace flags */ -{ - ulint post_antelope = FSP_FLAGS_GET_POST_ANTELOPE(flags); - ulint zip_ssize = FSP_FLAGS_GET_ZIP_SSIZE(flags); - ulint atomic_blobs = FSP_FLAGS_HAS_ATOMIC_BLOBS(flags); - ulint page_ssize = FSP_FLAGS_GET_PAGE_SSIZE(flags); - ulint unused = FSP_FLAGS_GET_UNUSED(flags); - ulint page_compression = FSP_FLAGS_GET_PAGE_COMPRESSION(flags); - ulint page_compression_level = FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL(flags); - ulint atomic_writes = FSP_FLAGS_GET_ATOMIC_WRITES(flags); - - DBUG_EXECUTE_IF("fsp_flags_is_valid_failure", return(false);); - - /* fsp_flags is zero unless atomic_blobs is set. */ - /* Make sure there are no bits that we do not know about. */ - if (unused != 0 || flags == 1) { - fprintf(stderr, "InnoDB: Error: Tablespace flags %lu corrupted unused %lu\n", - flags, unused); - return(false); - } else if (post_antelope) { - /* The Antelope row formats REDUNDANT and COMPACT did - not use tablespace flags, so this flag and the entire - 4-byte field is zero for Antelope row formats. */ - - if (!atomic_blobs) { - fprintf(stderr, "InnoDB: Error: Tablespace flags %lu corrupted atomic_blobs %lu\n", - flags, atomic_blobs); - return(false); - } - } - - if (!atomic_blobs) { - /* Barracuda row formats COMPRESSED and DYNAMIC build on - the page structure introduced for the COMPACT row format - by allowing long fields to be broken into prefix and - externally stored parts. */ - - if (post_antelope || zip_ssize != 0) { - fprintf(stderr, "InnoDB: Error: Tablespace flags %lu corrupted zip_ssize %lu atomic_blobs %lu\n", - flags, zip_ssize, atomic_blobs); - return(false); - } - - } else if (!post_antelope || zip_ssize > PAGE_ZIP_SSIZE_MAX) { - fprintf(stderr, "InnoDB: Error: Tablespace flags %lu corrupted zip_ssize %lu max %d\n", - flags, zip_ssize, PAGE_ZIP_SSIZE_MAX); - return(false); - } else if (page_ssize > UNIV_PAGE_SSIZE_MAX) { - - /* The page size field can be used for any row type, or it may - be zero for an original 16k page size. - Validate the page shift size is within allowed range. */ - - fprintf(stderr, "InnoDB: Error: Tablespace flags %lu corrupted page_ssize %lu max %lu\n", - flags, page_ssize, UNIV_PAGE_SSIZE_MAX); - return(false); - - } else if (UNIV_PAGE_SIZE != UNIV_PAGE_SIZE_ORIG && !page_ssize) { - fprintf(stderr, "InnoDB: Error: Tablespace flags %lu corrupted page_ssize %lu max %lu:%d\n", - flags, page_ssize, UNIV_PAGE_SIZE, UNIV_PAGE_SIZE_ORIG); - return(false); - } - - /* Page compression level requires page compression and atomic blobs - to be set */ - if (page_compression_level || page_compression) { - if (!page_compression || !atomic_blobs) { - fprintf(stderr, "InnoDB: Error: Tablespace flags %lu corrupted page_compression %lu\n" - "InnoDB: Error: page_compression_level %lu atomic_blobs %lu\n", - flags, page_compression, page_compression_level, atomic_blobs); - return(false); - } - } - - if (atomic_writes > ATOMIC_WRITES_OFF) { - fprintf(stderr, "InnoDB: Error: Tablespace flags %lu corrupted atomic_writes %lu\n", - flags, atomic_writes); - return (false); - } - -#if UNIV_FORMAT_MAX != UNIV_FORMAT_B -# error "UNIV_FORMAT_MAX != UNIV_FORMAT_B, Add more validations." -#endif - - /* The DATA_DIR field can be used for any row type so there is - nothing here to validate. */ - - return(true); -} - /********************************************************************//** Determine if the tablespace is compressed from dict_table_t::flags. @return TRUE if compressed, FALSE if not compressed */ @@ -191,10 +90,10 @@ UNIV_INLINE ulint fsp_flags_get_page_size( /*====================*/ - ulint flags) /*!< in: tablespace flags */ + ulint flags) /*!< in: tablespace flags */ { - ulint page_size = 0; - ulint ssize = FSP_FLAGS_GET_PAGE_SSIZE(flags); + ulint page_size = 0; + ulint ssize = FSP_FLAGS_GET_PAGE_SSIZE(flags); /* Convert from a 'log2 minus 9' to a page size in bytes. */ if (UNIV_UNLIKELY(ssize)) { @@ -211,50 +110,6 @@ fsp_flags_get_page_size( } #ifndef UNIV_INNOCHECKSUM - -/********************************************************************//** -Add the page size to the tablespace flags. -@return tablespace flags after page size is added */ -UNIV_INLINE -ulint -fsp_flags_set_page_size( -/*====================*/ - ulint flags, /*!< in: tablespace flags */ - ulint page_size) /*!< in: page size in bytes */ -{ - ulint ssize = 0; - ulint shift; - - /* Page size should be > UNIV_PAGE_SIZE_MIN */ - ut_ad(page_size >= UNIV_PAGE_SIZE_MIN); - ut_ad(page_size <= UNIV_PAGE_SIZE_MAX); - - if (page_size == UNIV_PAGE_SIZE_ORIG) { - ut_ad(0 == FSP_FLAGS_GET_PAGE_SSIZE(flags)); - return(flags); - } - - for (shift = UNIV_PAGE_SIZE_SHIFT_MAX; - shift >= UNIV_PAGE_SIZE_SHIFT_MIN; - shift--) { - ulint mask = (1 << shift); - if (page_size & mask) { - ut_ad(!(page_size & ~mask)); - ssize = shift - UNIV_ZIP_SIZE_SHIFT_MIN + 1; - break; - } - } - - ut_ad(ssize); - ut_ad(ssize <= UNIV_PAGE_SSIZE_MAX); - - flags = FSP_FLAGS_SET_PAGE_SSIZE(flags, ssize); - - ut_ad(fsp_flags_is_valid(flags)); - - return(flags); -} - /********************************************************************//** Calculates the descriptor index within a descriptor page. @return descriptor index */ diff --git a/storage/innobase/include/fsp0pagecompress.h b/storage/innobase/include/fsp0pagecompress.h index 5f943ee2b83..c623d11c326 100644 --- a/storage/innobase/include/fsp0pagecompress.h +++ b/storage/innobase/include/fsp0pagecompress.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (C) 2013, 2015, MariaDB Corporation. All Rights Reserved. +Copyright (C) 2013, 2017, MariaDB Corporation. All Rights Reserved. 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 @@ -47,15 +47,6 @@ fsp_header_get_compression_level( /*=============================*/ const page_t* page); /*!< in: first page of a tablespace */ -/********************************************************************//** -Determine if the tablespace is page compressed from dict_table_t::flags. -@return TRUE if page compressed, FALSE if not compressed */ -UNIV_INLINE -ibool -fsp_flags_is_page_compressed( -/*=========================*/ - ulint flags); /*!< in: tablespace flags */ - /********************************************************************//** Extract the page compression level from tablespace flags. A tablespace has only one physical page compression level diff --git a/storage/innobase/include/fsp0pagecompress.ic b/storage/innobase/include/fsp0pagecompress.ic index e879aa2c16e..48163277feb 100644 --- a/storage/innobase/include/fsp0pagecompress.ic +++ b/storage/innobase/include/fsp0pagecompress.ic @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (C) 2013, 2015, MariaDB Corporation. All Rights Reserved. +Copyright (C) 2013, 2017, MariaDB Corporation. All Rights Reserved. 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 @@ -25,18 +25,6 @@ Created 11/12/2013 Jan Lindström jan.lindstrom@mariadb.com ***********************************************************************/ -/********************************************************************//** -Determine if the tablespace is page compressed from dict_table_t::flags. -@return TRUE if page compressed, FALSE if not page compressed */ -UNIV_INLINE -ibool -fsp_flags_is_page_compressed( -/*=========================*/ - ulint flags) /*!< in: tablespace flags */ -{ - return(FSP_FLAGS_GET_PAGE_COMPRESSION(flags)); -} - /********************************************************************//** Determine the tablespace is page compression level from dict_table_t::flags. @return page compression level or 0 if not compressed*/ @@ -125,21 +113,15 @@ Extract the page compression from space. @return true if space is page compressed, false if space is not found or space is not page compressed. */ UNIV_INLINE -ibool +bool fil_space_is_page_compressed( /*=========================*/ ulint id) /*!< in: space id */ { - ulint flags; - - flags = fil_space_get_flags(id); - - if (flags && flags != ULINT_UNDEFINED) { - - return(fsp_flags_is_page_compressed(flags)); - } + ulint flags = fil_space_get_flags(id); - return(0); + return(flags != ULINT_UNDEFINED + && FSP_FLAGS_HAS_PAGE_COMPRESSION(flags)); } #endif /* UNIV_INNOCHECKSUM */ diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc index 3a47e3fc6aa..f54c9d589c2 100644 --- a/storage/innobase/row/row0import.cc +++ b/storage/innobase/row/row0import.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2015, 2016, MariaDB Corporation. +Copyright (c) 2015, 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 @@ -371,8 +371,7 @@ public: m_space(ULINT_UNDEFINED), m_xdes(), m_xdes_page_no(ULINT_UNDEFINED), - m_space_flags(ULINT_UNDEFINED), - m_table_flags(ULINT_UNDEFINED) UNIV_NOTHROW { } + m_space_flags(ULINT_UNDEFINED) UNIV_NOTHROW { } /** Free any extent descriptor instance */ @@ -535,10 +534,6 @@ protected: /** Flags value read from the header page */ ulint m_space_flags; - - /** Derived from m_space_flags and row format type, the row format - type is determined from the page header. */ - ulint m_table_flags; }; /** Determine the page size to use for traversing the tablespace @@ -553,6 +548,19 @@ AbstractCallback::init( const page_t* page = block->frame; m_space_flags = fsp_header_get_flags(page); + if (!fsp_flags_is_valid(m_space_flags)) { + ulint cflags = fsp_flags_convert_from_101(m_space_flags); + if (cflags == ULINT_UNDEFINED) { + ib_logf(IB_LOG_LEVEL_ERROR, + "Invalid FSP_SPACE_FLAGS=0x%x", + int(m_space_flags)); + return(DB_CORRUPTION); + } + m_space_flags = cflags; + } + + /* Clear the DATA_DIR flag, which is basically garbage. */ + m_space_flags &= ~(1U << FSP_FLAGS_POS_RESERVED); /* Since we don't know whether it is a compressed table or not, the data is always read into the block->frame. */ @@ -640,46 +648,6 @@ struct FetchIndexRootPages : public AbstractCallback { return(m_space); } - /** - Check if the .ibd file row format is the same as the table's. - @param ibd_table_flags - determined from space and page. - @return DB_SUCCESS or error code. */ - dberr_t check_row_format(ulint ibd_table_flags) UNIV_NOTHROW - { - dberr_t err; - rec_format_t ibd_rec_format; - rec_format_t table_rec_format; - - if (!dict_tf_is_valid(ibd_table_flags)) { - - ib_errf(m_trx->mysql_thd, IB_LOG_LEVEL_ERROR, - ER_TABLE_SCHEMA_MISMATCH, - ".ibd file has invlad table flags: %lx", - ibd_table_flags); - - return(DB_CORRUPTION); - } - - ibd_rec_format = dict_tf_get_rec_format(ibd_table_flags); - table_rec_format = dict_tf_get_rec_format(m_table->flags); - - if (table_rec_format != ibd_rec_format) { - - ib_errf(m_trx->mysql_thd, IB_LOG_LEVEL_ERROR, - ER_TABLE_SCHEMA_MISMATCH, - "Table has %s row format, .ibd " - "file has %s row format.", - dict_tf_to_row_format_string(m_table->flags), - dict_tf_to_row_format_string(ibd_table_flags)); - - err = DB_CORRUPTION; - } else { - err = DB_SUCCESS; - } - - return(err); - } - /** Called for each block as it is read from the file. @param offset - physical offset in the file @@ -743,12 +711,17 @@ FetchIndexRootPages::operator() ( m_indexes.push_back(Index(id, page_no)); if (m_indexes.size() == 1) { - - m_table_flags = dict_sys_tables_type_to_tf( - m_space_flags, - page_is_comp(page) ? DICT_N_COLS_COMPACT : 0); - - err = check_row_format(m_table_flags); + /* Check that the tablespace flags match the table flags. */ + ulint expected = dict_tf_to_fsp_flags(m_table->flags); + if (!fsp_flags_match(expected, m_space_flags)) { + ib_errf(m_trx->mysql_thd, IB_LOG_LEVEL_ERROR, + ER_TABLE_SCHEMA_MISMATCH, + "Expected FSP_SPACE_FLAGS=0x%x, .ibd " + "file contains 0x%x.", + unsigned(expected), + unsigned(m_space_flags)); + return(DB_CORRUPTION); + } } } @@ -1965,21 +1938,14 @@ PageConverter::update_header( "- ignored"); } - ulint space_flags = fsp_header_get_flags(get_frame(block)); - - if (!fsp_flags_is_valid(space_flags)) { - - ib_logf(IB_LOG_LEVEL_ERROR, - "Unsupported tablespace format %lu", - (ulong) space_flags); - - return(DB_UNSUPPORTED); - } - mach_write_to_8( get_frame(block) + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, m_current_lsn); + /* Write back the adjusted flags. */ + mach_write_to_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + + get_frame(block), m_space_flags); + /* Write space_id to the tablespace header, page 0. */ mach_write_to_4( get_frame(block) + FSP_HEADER_OFFSET + FSP_SPACE_ID, diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index 1c02590933f..0e539f53641 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -4335,6 +4335,7 @@ row_drop_table_for_mysql( switch (err) { ibool is_temp; + ulint table_flags; case DB_SUCCESS: /* Clone the name, in case it has been allocated @@ -4343,6 +4344,7 @@ row_drop_table_for_mysql( space_id = table->space; ibd_file_missing = table->ibd_file_missing; + table_flags = table->flags; is_temp = DICT_TF2_FLAG_IS_SET(table, DICT_TF2_TEMPORARY); /* If there is a temp path then the temp flag is set. @@ -4358,9 +4360,9 @@ row_drop_table_for_mysql( } /* We do not allow temporary tables with a remote path. */ - ut_a(!(is_temp && DICT_TF_HAS_DATA_DIR(table->flags))); + ut_a(!(is_temp && DICT_TF_HAS_DATA_DIR(table_flags))); - if (space_id && DICT_TF_HAS_DATA_DIR(table->flags)) { + if (space_id && DICT_TF_HAS_DATA_DIR(table_flags)) { dict_get_and_save_data_dir_path(table, true); ut_a(table->data_dir_path); @@ -4426,8 +4428,9 @@ row_drop_table_for_mysql( if (err == DB_SUCCESS && space_id > TRX_SYS_SPACE) { if (!is_temp && !fil_space_for_table_exists_in_mem( - space_id, tablename, FALSE, - print_msg, false, NULL, 0)) { + space_id, tablename, + print_msg, false, NULL, 0, + table_flags)) { /* This might happen if we are dropping a discarded tablespace */ err = DB_SUCCESS; diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc index 40154c11ce1..2fec8b7bc2f 100644 --- a/storage/innobase/srv/srv0start.cc +++ b/storage/innobase/srv/srv0start.cc @@ -673,8 +673,7 @@ create_log_files( sprintf(logfilename + dirnamelen, "ib_logfile%u", INIT_LOG_FILE0); fil_space_create( - logfilename, SRV_LOG_SPACE_FIRST_ID, - fsp_flags_set_page_size(0, UNIV_PAGE_SIZE), + logfilename, SRV_LOG_SPACE_FIRST_ID, 0, FIL_LOG, NULL /* no encryption yet */, true /* this is create */); @@ -1159,7 +1158,7 @@ check_first_page: crypt_data = fil_space_create_crypt_data(FIL_SPACE_ENCRYPTION_DEFAULT, FIL_DEFAULT_ENCRYPTION_KEY); } - flags = fsp_flags_set_page_size(0, UNIV_PAGE_SIZE); + flags = FSP_FLAGS_PAGE_SSIZE(); fil_space_create(name, 0, flags, FIL_TABLESPACE, crypt_data, (*create_new_db) == true); @@ -1307,7 +1306,7 @@ srv_undo_tablespace_open( fil_set_max_space_id_if_bigger(space); /* Set the compressed page size to 0 (non-compressed) */ - flags = fsp_flags_set_page_size(0, UNIV_PAGE_SIZE); + flags = FSP_FLAGS_PAGE_SSIZE(); fil_space_create(name, space, flags, FIL_TABLESPACE, NULL /* no encryption */, true /* create */); @@ -2296,9 +2295,7 @@ innobase_start_or_create_for_mysql(void) sprintf(logfilename + dirnamelen, "ib_logfile%u", 0); fil_space_create(logfilename, - SRV_LOG_SPACE_FIRST_ID, - fsp_flags_set_page_size(0, UNIV_PAGE_SIZE), - FIL_LOG, + SRV_LOG_SPACE_FIRST_ID, 0, FIL_LOG, NULL /* no encryption yet */, true /* create */); @@ -2714,6 +2711,13 @@ files_checked: } if (!srv_read_only_mode) { + const ulint flags = FSP_FLAGS_PAGE_SSIZE(); + for (ulint id = 0; id <= srv_undo_tablespaces; id++) { + if (fil_space_get(id)) { + fsp_flags_try_adjust(id, flags); + } + } + /* Create the thread which watches the timeouts for lock waits */ thread_handles[2 + SRV_MAX_N_IO_THREADS] = os_thread_create( diff --git a/storage/xtradb/buf/buf0dblwr.cc b/storage/xtradb/buf/buf0dblwr.cc index 9c7eea6410a..68bb83e4903 100644 --- a/storage/xtradb/buf/buf0dblwr.cc +++ b/storage/xtradb/buf/buf0dblwr.cc @@ -589,6 +589,21 @@ buf_dblwr_process() continue; } + if (page_no == 0) { + /* Check the FSP_SPACE_FLAGS. */ + ulint flags = fsp_header_get_flags(page); + if (!fsp_flags_is_valid(flags) + && fsp_flags_convert_from_101(flags) + == ULINT_UNDEFINED) { + ib_logf(IB_LOG_LEVEL_WARN, + "Ignoring a doublewrite copy of page " + ULINTPF ":0 due to invalid flags 0x%x", + space_id, int(flags)); + continue; + } + /* The flags on the page should be converted later. */ + } + /* Write the good page from the doublewrite buffer to the intended position. */ diff --git a/storage/xtradb/dict/dict0load.cc b/storage/xtradb/dict/dict0load.cc index 39a6ae993c8..776bb873c5c 100644 --- a/storage/xtradb/dict/dict0load.cc +++ b/storage/xtradb/dict/dict0load.cc @@ -1052,8 +1052,6 @@ loop: btr_pcur_store_position(&pcur, &mtr); - mtr_commit(&mtr); - /* For tables created with old versions of InnoDB, SYS_TABLES.MIX_LEN may contain garbage. Such tables would always be in ROW_FORMAT=REDUNDANT. Pretend that @@ -1087,16 +1085,19 @@ loop: if (space_id == 0) { /* The system tablespace always exists. */ ut_ad(!discarded); - goto next_tablespace; + mem_free(name); + goto loop; } + mtr_commit(&mtr); + switch (dict_check) { case DICT_CHECK_ALL_LOADED: /* All tablespaces should have been found in fil_load_single_table_tablespaces(). */ if (fil_space_for_table_exists_in_mem( - space_id, name, TRUE, !(is_temp || discarded), - false, NULL, 0) + space_id, name, !(is_temp || discarded), + false, NULL, 0, flags) && !(is_temp || discarded)) { /* If user changes the path of .ibd files in *.isl files before doing crash recovery , @@ -1128,8 +1129,8 @@ loop: /* Some tablespaces may have been opened in trx_resurrect_table_locks(). */ if (fil_space_for_table_exists_in_mem( - space_id, name, FALSE, FALSE, - false, NULL, 0)) { + space_id, name, false, + false, NULL, 0, flags)) { break; } /* fall through */ @@ -1191,7 +1192,6 @@ loop: max_space_id = space_id; } -next_tablespace: mem_free(name); mtr_start(&mtr); @@ -2383,8 +2383,8 @@ err_exit: table->ibd_file_missing = TRUE; } else if (!fil_space_for_table_exists_in_mem( - table->space, name, FALSE, FALSE, true, heap, - table->id)) { + table->space, name, false, true, heap, + table->id, table->flags)) { if (DICT_TF2_FLAG_IS_SET(table, DICT_TF2_TEMPORARY)) { /* Do not bother to retry opening temporary tables. */ diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc index 133960ae8b4..f4301d47028 100644 --- a/storage/xtradb/fil/fil0fil.cc +++ b/storage/xtradb/fil/fil0fil.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2013, 2016, MariaDB Corporation. All Rights Reserved. +Copyright (c) 2013, 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 @@ -601,10 +601,7 @@ fil_node_open_file( ibool success; byte* buf2; byte* page; - ulint space_id; - ulint flags=0; ulint page_size; - ulint atomic_writes=0; ut_ad(mutex_own(&(system->mutex))); ut_a(node->n_pending == 0); @@ -626,8 +623,6 @@ fil_node_open_file( /* The following call prints an error message */ os_file_get_last_error(true); - ut_print_timestamp(stderr); - ib_logf(IB_LOG_LEVEL_WARN, "InnoDB: Error: cannot " "open %s\n. InnoDB: Have you deleted .ibd " "files under a running mysqld server?\n", @@ -653,17 +648,13 @@ fil_node_open_file( ut_a(fil_is_user_tablespace_id(space->id)); if (size_bytes < FIL_IBD_FILE_INITIAL_SIZE * UNIV_PAGE_SIZE) { - fprintf(stderr, - "InnoDB: Error: the size of single-table" - " tablespace file %s\n" - "InnoDB: is only " UINT64PF "," - " should be at least %lu!\n", - node->name, - size_bytes, - (ulong) (FIL_IBD_FILE_INITIAL_SIZE - * UNIV_PAGE_SIZE)); - - ut_a(0); + ib_logf(IB_LOG_LEVEL_ERROR, + "The size of the file %s is only " UINT64PF + " bytes, should be at least " ULINTPF, + node->name, size_bytes, + FIL_IBD_FILE_INITIAL_SIZE * UNIV_PAGE_SIZE); + os_file_close(node->handle); + return(false); } /* Read the first page of the tablespace */ @@ -676,77 +667,34 @@ fil_node_open_file( success = os_file_read(node->handle, page, 0, UNIV_PAGE_SIZE); srv_stats.page0_read.add(1); - space_id = fsp_header_get_space_id(page); - flags = fsp_header_get_flags(page); - - page_size = fsp_flags_get_page_size(flags); - atomic_writes = fsp_flags_get_atomic_writes(flags); + const ulint space_id = fsp_header_get_space_id(page); + ulint flags = fsp_header_get_flags(page); ut_free(buf2); - - /* Close the file now that we have read the space id from it */ - os_file_close(node->handle); - if (UNIV_UNLIKELY(space_id != space->id)) { - fprintf(stderr, - "InnoDB: Error: tablespace id is %lu" - " in the data dictionary\n" - "InnoDB: but in file %s it is %lu!\n", - space->id, node->name, space_id); - - ut_error; - } - - if (UNIV_UNLIKELY(space_id == ULINT_UNDEFINED - || space_id == 0)) { - fprintf(stderr, - "InnoDB: Error: tablespace id %lu" - " in file %s is not sensible\n", - (ulong) space_id, node->name); - - ut_error; - } - - if (UNIV_UNLIKELY(fsp_flags_get_page_size(space->flags) - != page_size)) { - fprintf(stderr, - "InnoDB: Error: tablespace file %s" - " has page size 0x%lx\n" - "InnoDB: but the data dictionary" - " expects page size 0x%lx!\n", - node->name, flags, - fsp_flags_get_page_size(space->flags)); + if (!fsp_flags_is_valid(flags)) { + ulint cflags = fsp_flags_convert_from_101(flags); + if (cflags == ULINT_UNDEFINED) { + ib_logf(IB_LOG_LEVEL_ERROR, + "Expected tablespace flags 0x%x" + " but found 0x%x in the file %s", + int(space->flags), int(flags), + node->name); + return(false); + } - ut_error; + flags = cflags; } - if (UNIV_UNLIKELY(space->flags != flags)) { - ulint sflags = (space->flags & ~FSP_FLAGS_MASK_DATA_DIR); - ulint fflags = (flags & ~FSP_FLAGS_MASK_DATA_DIR_ORACLE); - - /* DATA_DIR option is on different place on MariaDB - compared to MySQL. If this is the difference. Fix - it. */ - - if (sflags == fflags) { - fprintf(stderr, - "InnoDB: Warning: Table flags 0x%lx" - " in the data dictionary but in file %s are 0x%lx!\n" - " Temporally corrected because DATA_DIR option to 0x%lx.\n", - space->flags, node->name, flags, space->flags); - - flags = space->flags; - } + page_size = fsp_flags_get_page_size(flags); - if (!dict_tf_verify_flags(space->flags, flags)) { - fprintf(stderr, - "InnoDB: Error: table flags are 0x%lx" - " in the data dictionary\n" - "InnoDB: but the flags in file %s are 0x%lx!\n", - space->flags, node->name, flags); - ut_error; - } + if (UNIV_UNLIKELY(space_id != space->id)) { + ib_logf(IB_LOG_LEVEL_ERROR, + "tablespace id is " ULINTPF " in the data dictionary" + " but in file %s it is " ULINTPF "!\n", + space->id, node->name, space_id); + return(false); } if (size_bytes >= (1024*1024)) { @@ -768,7 +716,7 @@ add_size: space->size += node->size; } - atomic_writes = fsp_flags_get_atomic_writes(space->flags); + ulint atomic_writes = fsp_flags_get_atomic_writes(space->flags); /* printf("Opening file %s\n", node->name); */ @@ -1572,7 +1520,6 @@ fil_space_create( fil_system->tablespace_version++; space->tablespace_version = fil_system->tablespace_version; - space->mark = FALSE; if (purpose == FIL_TABLESPACE && !recv_recovery_on && id > fil_system->max_assigned_id) { @@ -2324,27 +2271,21 @@ fil_write_flushed_lsn_to_data_files( return(DB_SUCCESS); } -/*******************************************************************//** -Checks the consistency of the first data page of a tablespace +/** Check the consistency of the first data page of a tablespace at database startup. +@param[in] page page frame +@param[in] space_id tablespace identifier +@param[in] flags tablespace flags @retval NULL on success, or if innodb_force_recovery is set @return pointer to an error message string */ static MY_ATTRIBUTE((warn_unused_result)) const char* -fil_check_first_page( -/*=================*/ - const page_t* page) /*!< in: data page */ +fil_check_first_page(const page_t* page, ulint space_id, ulint flags) { - ulint space_id; - ulint flags; - if (srv_force_recovery >= SRV_FORCE_IGNORE_CORRUPT) { return(NULL); } - space_id = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_ID + page); - flags = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + page); - if (UNIV_PAGE_SIZE != fsp_flags_get_page_size(flags)) { fprintf(stderr, "InnoDB: Error: Current page size %lu != " @@ -2393,7 +2334,7 @@ fil_read_first_page( ibool one_read_already, /*!< in: TRUE if min and max parameters below already contain sensible data */ - ulint* flags, /*!< out: tablespace flags */ + ulint* flags, /*!< out: FSP_SPACE_FLAGS */ ulint* space_id, /*!< out: tablespace ID */ lsn_t* min_flushed_lsn, /*!< out: min of flushed lsn values in data files */ @@ -2423,12 +2364,22 @@ fil_read_first_page( *flags and *space_id as they were read from the first file and do not validate the first page. */ if (!one_read_already) { - *flags = fsp_header_get_flags(page); *space_id = fsp_header_get_space_id(page); - } + *flags = fsp_header_get_flags(page); - if (!one_read_already) { - check_msg = fil_check_first_page(page); + if (!fsp_flags_is_valid(*flags)) { + ulint cflags = fsp_flags_convert_from_101(*flags); + if (cflags == ULINT_UNDEFINED) { + ib_logf(IB_LOG_LEVEL_ERROR, + "Invalid flags 0x%x in tablespace %u", + unsigned(*flags), unsigned(*space_id)); + return "invalid tablespace flags"; + } else { + *flags = cflags; + } + } + + check_msg = fil_check_first_page(page, *space_id, *flags); } flushed_lsn = mach_read_from_8(page + @@ -2612,6 +2563,7 @@ fil_op_write_log( ulint len; log_ptr = mlog_open(mtr, 11 + 2 + 1); + ut_ad(fsp_flags_is_valid(flags)); if (!log_ptr) { /* Logging in mtr is switched off during crash recovery: @@ -3823,7 +3775,7 @@ fil_create_new_single_table_tablespace( ibool success; /* TRUE if a table is created with CREATE TEMPORARY TABLE */ bool is_temp = !!(flags2 & DICT_TF2_TEMPORARY); - bool has_data_dir = FSP_FLAGS_HAS_DATA_DIR(flags); + bool has_data_dir = FSP_FLAGS_HAS_DATA_DIR(flags) != 0; ulint atomic_writes = FSP_FLAGS_GET_ATOMIC_WRITES(flags); fil_space_crypt_t *crypt_data = NULL; @@ -3831,7 +3783,7 @@ fil_create_new_single_table_tablespace( ut_ad(!srv_read_only_mode); ut_a(space_id < SRV_LOG_SPACE_FIRST_ID); ut_a(size >= FIL_IBD_FILE_INITIAL_SIZE); - ut_a(fsp_flags_is_valid(flags)); + ut_a(fsp_flags_is_valid(flags & ~FSP_FLAGS_MEM_MASK)); if (is_temp) { /* Temporary table filepath */ @@ -3924,12 +3876,9 @@ fil_create_new_single_table_tablespace( memset(page, '\0', UNIV_PAGE_SIZE); - /* Add the UNIV_PAGE_SIZE to the table flags and write them to the - tablespace header. */ - flags = fsp_flags_set_page_size(flags, UNIV_PAGE_SIZE); + flags |= FSP_FLAGS_PAGE_SSIZE(); fsp_header_init_fields(page, space_id, flags); mach_write_to_4(page + FIL_PAGE_ARCH_LOG_NO_OR_SPACE_ID, space_id); - ut_ad(fsp_flags_is_valid(flags)); if (!(fsp_flags_is_compressed(flags))) { buf_flush_init_for_writing(page, NULL, 0); @@ -4008,7 +3957,8 @@ fil_create_new_single_table_tablespace( fil_op_write_log(flags ? MLOG_FILE_CREATE2 : MLOG_FILE_CREATE, - space_id, mlog_file_flag, flags, + space_id, mlog_file_flag, + flags & ~FSP_FLAGS_MEM_MASK, tablename, NULL, &mtr); mtr_commit(&mtr); @@ -4072,6 +4022,39 @@ fil_report_bad_tablespace( (ulong) expected_id, (ulong) expected_flags); } +/** Try to adjust FSP_SPACE_FLAGS if they differ from the expectations. +(Typically when upgrading from MariaDB 10.1.0..10.1.20.) +@param[in] space_id tablespace ID +@param[in] flags desired tablespace flags */ +UNIV_INTERN +void +fsp_flags_try_adjust(ulint space_id, ulint flags) +{ + ut_ad(!srv_read_only_mode); + ut_ad(fsp_flags_is_valid(flags)); + + mtr_t mtr; + mtr_start(&mtr); + if (buf_block_t* b = buf_page_get( + space_id, fsp_flags_get_zip_size(flags), 0, RW_X_LATCH, + &mtr)) { + ulint f = fsp_header_get_flags(b->frame); + /* Suppress the message if only the DATA_DIR flag to differs. */ + if ((f ^ flags) & ~(1U << FSP_FLAGS_POS_RESERVED)) { + ib_logf(IB_LOG_LEVEL_WARN, + "adjusting FSP_SPACE_FLAGS of tablespace " + ULINTPF " from 0x%x to 0x%x", + space_id, int(f), int(flags)); + } + if (f != flags) { + mlog_write_ulint(FSP_HEADER_OFFSET + + FSP_SPACE_FLAGS + b->frame, + flags, MLOG_4BYTES, &mtr); + } + } + mtr_commit(&mtr); +} + /********************************************************************//** Tries to open a single-table tablespace and optionally checks that the space id in it is correct. If this does not succeed, print an error message @@ -4101,7 +4084,7 @@ fil_open_single_table_tablespace( bool validate, /*!< in: Do we validate tablespace? */ bool fix_dict, /*!< in: Can we fix the dictionary? */ ulint id, /*!< in: space id */ - ulint flags, /*!< in: tablespace flags */ + ulint flags, /*!< in: expected FSP_SPACE_FLAGS */ const char* tablename, /*!< in: table name in the databasename/tablename format */ const char* path_in, /*!< in: tablespace filepath */ @@ -4126,20 +4109,13 @@ fil_open_single_table_tablespace( /* Table flags can be ULINT_UNDEFINED if dict_tf_to_fsp_flags_failure is set. */ - if (flags != ULINT_UNDEFINED) { - if (!fsp_flags_is_valid(flags)) { - return(DB_CORRUPTION); - } - } else { + if (flags == ULINT_UNDEFINED) { return(DB_CORRUPTION); } + ut_ad(fsp_flags_is_valid(flags & ~FSP_FLAGS_MEM_MASK)); atomic_writes = fsp_flags_get_atomic_writes(flags); - /* If the tablespace was relocated, we do not - compare the DATA_DIR flag */ - ulint mod_flags = flags & ~FSP_FLAGS_MASK_DATA_DIR; - memset(&def, 0, sizeof(def)); memset(&dict, 0, sizeof(dict)); memset(&remote, 0, sizeof(remote)); @@ -4217,31 +4193,17 @@ fil_open_single_table_tablespace( def.check_msg = fil_read_first_page( def.file, FALSE, &def.flags, &def.id, &def.lsn, &def.lsn, &def.crypt_data); - def.valid = !def.check_msg; if (table) { table->crypt_data = def.crypt_data; table->page_0_read = true; } - /* Validate this single-table-tablespace with SYS_TABLES, - but do not compare the DATA_DIR flag, in case the - tablespace was relocated. */ - - ulint newf = def.flags; - if (newf != mod_flags) { - if (FSP_FLAGS_HAS_DATA_DIR(newf)) { - newf = (newf & ~FSP_FLAGS_MASK_DATA_DIR); - } else if(FSP_FLAGS_HAS_DATA_DIR_ORACLE(newf)) { - newf = (newf & ~FSP_FLAGS_MASK_DATA_DIR_ORACLE); - } - } - - if (def.valid && def.id == id - && newf == mod_flags) { + def.valid = !def.check_msg && def.id == id + && fsp_flags_match(flags, def.flags); + if (def.valid) { valid_tablespaces_found++; } else { - def.valid = false; /* Do not use this tablespace. */ fil_report_bad_tablespace( def.filepath, def.check_msg, def.id, @@ -4254,30 +4216,18 @@ fil_open_single_table_tablespace( remote.check_msg = fil_read_first_page( remote.file, FALSE, &remote.flags, &remote.id, &remote.lsn, &remote.lsn, &remote.crypt_data); - remote.valid = !remote.check_msg; if (table) { table->crypt_data = remote.crypt_data; table->page_0_read = true; } - /* Validate this single-table-tablespace with SYS_TABLES, - but do not compare the DATA_DIR flag, in case the - tablespace was relocated. */ - ulint newf = remote.flags; - if (newf != mod_flags) { - if (FSP_FLAGS_HAS_DATA_DIR(newf)) { - newf = (newf & ~FSP_FLAGS_MASK_DATA_DIR); - } else if(FSP_FLAGS_HAS_DATA_DIR_ORACLE(newf)) { - newf = (newf & ~FSP_FLAGS_MASK_DATA_DIR_ORACLE); - } - } - - if (remote.valid && remote.id == id - && newf == mod_flags) { + /* Validate this single-table-tablespace with SYS_TABLES. */ + remote.valid = !remote.check_msg && remote.id == id + && fsp_flags_match(flags, remote.flags); + if (remote.valid) { valid_tablespaces_found++; } else { - remote.valid = false; /* Do not use this linked tablespace. */ fil_report_bad_tablespace( remote.filepath, remote.check_msg, remote.id, @@ -4291,30 +4241,19 @@ fil_open_single_table_tablespace( dict.check_msg = fil_read_first_page( dict.file, FALSE, &dict.flags, &dict.id, &dict.lsn, &dict.lsn, &dict.crypt_data); - dict.valid = !dict.check_msg; if (table) { table->crypt_data = dict.crypt_data; table->page_0_read = true; } - /* Validate this single-table-tablespace with SYS_TABLES, - but do not compare the DATA_DIR flag, in case the - tablespace was relocated. */ - ulint newf = dict.flags; - if (newf != mod_flags) { - if (FSP_FLAGS_HAS_DATA_DIR(newf)) { - newf = (newf & ~FSP_FLAGS_MASK_DATA_DIR); - } else if(FSP_FLAGS_HAS_DATA_DIR_ORACLE(newf)) { - newf = (newf & ~FSP_FLAGS_MASK_DATA_DIR_ORACLE); - } - } + /* Validate this single-table-tablespace with SYS_TABLES. */ + dict.valid = !dict.check_msg && dict.id == id + && fsp_flags_match(flags, dict.flags); - if (dict.valid && dict.id == id - && newf == mod_flags) { + if (dict.valid) { valid_tablespaces_found++; } else { - dict.valid = false; /* Do not use this tablespace. */ fil_report_bad_tablespace( dict.filepath, dict.check_msg, dict.id, @@ -4512,6 +4451,10 @@ cleanup_and_exit: mem_free(def.filepath); + if (err == DB_SUCCESS && !srv_read_only_mode) { + fsp_flags_try_adjust(id, flags & ~FSP_FLAGS_MEM_MASK); + } + return(err); } #endif /* !UNIV_HOTBACKUP */ @@ -4693,7 +4636,23 @@ fil_user_tablespace_restore_page( goto out; } - flags = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + page); + flags = mach_read_from_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + page); + + if (!fsp_flags_is_valid(flags)) { + ulint cflags = fsp_flags_convert_from_101(flags); + if (cflags == ULINT_UNDEFINED) { + ib_logf(IB_LOG_LEVEL_WARN, + "Ignoring a doublewrite copy of page " + ULINTPF ":" ULINTPF + " due to invalid flags 0x%x", + fsp->id, page_no, int(flags)); + err = false; + goto out; + } + flags = cflags; + /* The flags on the page should be converted later. */ + } + zip_size = fsp_flags_get_zip_size(flags); page_size = fsp_flags_get_page_size(flags); @@ -5071,6 +5030,16 @@ will_not_choose: } mutex_exit(&fil_system->mutex); #endif /* UNIV_HOTBACKUP */ + /* Adjust the memory-based flags that would normally be set by + dict_tf_to_fsp_flags(). In recovery, we have no data dictionary. */ + if (FSP_FLAGS_HAS_PAGE_COMPRESSION(fsp->flags)) { + fsp->flags |= page_zip_level + << FSP_FLAGS_MEM_COMPRESSION_LEVEL; + } + remote.flags |= 1U << FSP_FLAGS_MEM_DATA_DIR; + /* We will leave atomic_writes at ATOMIC_WRITES_DEFAULT. + That will be adjusted in fil_space_for_table_exists_in_mem(). */ + ibool file_space_create_success = fil_space_create( tablename, fsp->id, fsp->flags, FIL_TABLESPACE, fsp->crypt_data, false); @@ -5380,13 +5349,12 @@ fil_report_missing_tablespace( name, space_id); } -/*******************************************************************//** -Returns TRUE if a matching tablespace exists in the InnoDB tablespace memory +/** Check if a matching tablespace exists in the InnoDB tablespace memory cache. Note that if we have not done a crash recovery at the database startup, there may be many tablespaces which are not yet in the memory cache. -@return TRUE if a matching tablespace exists in the memory cache */ +@return whether a matching tablespace exists in the memory cache */ UNIV_INTERN -ibool +bool fil_space_for_table_exists_in_mem( /*==============================*/ ulint id, /*!< in: space id */ @@ -5394,13 +5362,7 @@ fil_space_for_table_exists_in_mem( fil_space_create(). Either the standard 'dbname/tablename' format or table->dir_path_of_temp_table */ - ibool mark_space, /*!< in: in crash recovery, at database - startup we mark all spaces which have - an associated table in the InnoDB - data dictionary, so that - we can print a warning about orphaned - tablespaces */ - ibool print_error_if_does_not_exist, + bool print_error_if_does_not_exist, /*!< in: print detailed error information to the .err log if a matching tablespace is not found from @@ -5408,12 +5370,13 @@ fil_space_for_table_exists_in_mem( bool adjust_space, /*!< in: whether to adjust space id when find table space mismatch */ mem_heap_t* heap, /*!< in: heap memory */ - table_id_t table_id) /*!< in: table id */ + table_id_t table_id, /*!< in: table id */ + ulint table_flags) /*!< in: table flags */ { fil_space_t* fnamespace; fil_space_t* space; - ut_ad(fil_system); + const ulint expected_flags = dict_tf_to_fsp_flags(table_flags); mutex_enter(&fil_system->mutex); @@ -5425,42 +5388,31 @@ fil_space_for_table_exists_in_mem( directory path from the datadir to the file */ fnamespace = fil_space_get_by_name(name); - if (space && space == fnamespace) { - /* Found */ - - if (mark_space) { - space->mark = TRUE; - } - - mutex_exit(&fil_system->mutex); - - return(TRUE); - } - - /* Info from "fnamespace" comes from the ibd file itself, it can - be different from data obtained from System tables since it is - not transactional. If adjust_space is set, and the mismatching - space are between a user table and its temp table, we shall - adjust the ibd file name according to system table info */ - if (adjust_space - && space != NULL - && row_is_mysql_tmp_table_name(space->name) - && !row_is_mysql_tmp_table_name(name)) { + bool valid = space && !((space->flags ^ expected_flags) + & ~FSP_FLAGS_MEM_MASK); + if (!space) { + } else if (!valid || space == fnamespace) { + /* Found with the same file name, or got a flag mismatch. */ + goto func_exit; + } else if (adjust_space + && row_is_mysql_tmp_table_name(space->name) + && !row_is_mysql_tmp_table_name(name)) { + /* Info from fnamespace comes from the ibd file + itself, it can be different from data obtained from + System tables since renaming files is not + transactional. We shall adjust the ibd file name + according to system table info. */ mutex_exit(&fil_system->mutex); DBUG_EXECUTE_IF("ib_crash_before_adjust_fil_space", DBUG_SUICIDE();); - if (fnamespace) { - char* tmp_name; + char* tmp_name = dict_mem_create_temporary_tablename( + heap, name, table_id); - tmp_name = dict_mem_create_temporary_tablename( - heap, name, table_id); - - fil_rename_tablespace(fnamespace->name, fnamespace->id, - tmp_name, NULL); - } + fil_rename_tablespace(fnamespace->name, fnamespace->id, + tmp_name, NULL); DBUG_EXECUTE_IF("ib_crash_after_adjust_one_fil_space", DBUG_SUICIDE();); @@ -5473,16 +5425,12 @@ fil_space_for_table_exists_in_mem( mutex_enter(&fil_system->mutex); fnamespace = fil_space_get_by_name(name); ut_ad(space == fnamespace); - mutex_exit(&fil_system->mutex); - - return(TRUE); + goto func_exit; } if (!print_error_if_does_not_exist) { - - mutex_exit(&fil_system->mutex); - - return(FALSE); + valid = false; + goto func_exit; } if (space == NULL) { @@ -5509,10 +5457,8 @@ error_exit: fputs("InnoDB: Please refer to\n" "InnoDB: " REFMAN "innodb-troubleshooting-datadict.html\n" "InnoDB: for how to resolve the issue.\n", stderr); - - mutex_exit(&fil_system->mutex); - - return(FALSE); + valid = false; + goto func_exit; } if (0 != strcmp(space->name, name)) { @@ -5539,9 +5485,19 @@ error_exit: goto error_exit; } +func_exit: + if (valid) { + /* Adjust the flags that are in FSP_FLAGS_MEM_MASK. + FSP_SPACE_FLAGS will not be written back here. */ + space->flags = expected_flags; + } mutex_exit(&fil_system->mutex); - return(FALSE); + if (valid && !srv_read_only_mode) { + fsp_flags_try_adjust(id, expected_flags & ~FSP_FLAGS_MEM_MASK); + } + + return(valid); } /*******************************************************************//** @@ -7444,9 +7400,8 @@ fil_space_get_crypt_data( byte *page = static_cast(ut_align(buf, UNIV_PAGE_SIZE)); fil_read(true, space_id, 0, 0, 0, UNIV_PAGE_SIZE, page, NULL, NULL); - ulint flags = fsp_header_get_flags(page); ulint offset = fsp_header_get_crypt_offset( - fsp_flags_get_zip_size(flags), NULL); + fsp_header_get_zip_size(page), NULL); space->crypt_data = fil_space_read_crypt_data(space_id, page, offset); ut_free(buf); diff --git a/storage/xtradb/fsp/fsp0fsp.cc b/storage/xtradb/fsp/fsp0fsp.cc index 4acfd134c1f..c32fddaabbe 100644 --- a/storage/xtradb/fsp/fsp0fsp.cc +++ b/storage/xtradb/fsp/fsp0fsp.cc @@ -663,6 +663,7 @@ fsp_header_init_fields( ulint space_id, /*!< in: space id */ ulint flags) /*!< in: tablespace flags (FSP_SPACE_FLAGS) */ { + flags &= ~FSP_FLAGS_MEM_MASK; ut_a(fsp_flags_is_valid(flags)); mach_write_to_4(FSP_HEADER_OFFSET + FSP_SPACE_ID + page, @@ -713,7 +714,7 @@ fsp_header_init( mlog_write_ulint(header + FSP_SIZE, size, MLOG_4BYTES, mtr); mlog_write_ulint(header + FSP_FREE_LIMIT, 0, MLOG_4BYTES, mtr); - mlog_write_ulint(header + FSP_SPACE_FLAGS, flags, + mlog_write_ulint(header + FSP_SPACE_FLAGS, flags & ~FSP_FLAGS_MEM_MASK, MLOG_4BYTES, mtr); mlog_write_ulint(header + FSP_FRAG_N_USED, 0, MLOG_4BYTES, mtr); diff --git a/storage/xtradb/include/dict0dict.ic b/storage/xtradb/include/dict0dict.ic index d9d40b809d1..2b63ddea51d 100644 --- a/storage/xtradb/include/dict0dict.ic +++ b/storage/xtradb/include/dict0dict.ic @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2013, 2016, MariaDB +Copyright (c) 2013, 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 @@ -918,10 +918,13 @@ dict_tf_to_fsp_flags( ulint table_flags) /*!< in: dict_table_t::flags */ { ulint fsp_flags; - ulint page_compression = DICT_TF_GET_PAGE_COMPRESSION(table_flags); - ulint page_compression_level = DICT_TF_GET_PAGE_COMPRESSION_LEVEL(table_flags); + ulint page_compression_level = DICT_TF_GET_PAGE_COMPRESSION_LEVEL( + table_flags); ulint atomic_writes = DICT_TF_GET_ATOMIC_WRITES(table_flags); + ut_ad((DICT_TF_GET_PAGE_COMPRESSION(table_flags) == 0) + == (page_compression_level == 0)); + DBUG_EXECUTE_IF("dict_tf_to_fsp_flags_failure", return(ULINT_UNDEFINED);); @@ -929,30 +932,23 @@ dict_tf_to_fsp_flags( fsp_flags = DICT_TF_HAS_ATOMIC_BLOBS(table_flags) ? 1 : 0; /* ZIP_SSIZE and ATOMIC_BLOBS are at the same position. */ - fsp_flags |= table_flags & DICT_TF_MASK_ZIP_SSIZE; - fsp_flags |= table_flags & DICT_TF_MASK_ATOMIC_BLOBS; - - /* In addition, tablespace flags also contain the page size. */ - fsp_flags |= fsp_flags_set_page_size(fsp_flags, UNIV_PAGE_SIZE); + fsp_flags |= table_flags + & (DICT_TF_MASK_ZIP_SSIZE | DICT_TF_MASK_ATOMIC_BLOBS); - /* The DATA_DIR flag is in a different position in fsp_flag */ - fsp_flags |= DICT_TF_HAS_DATA_DIR(table_flags) - ? FSP_FLAGS_MASK_DATA_DIR : 0; + fsp_flags |= FSP_FLAGS_PAGE_SSIZE(); - /* In addition, tablespace flags also contain if the page - compression is used for this table. */ - fsp_flags |= FSP_FLAGS_SET_PAGE_COMPRESSION(fsp_flags, page_compression); + if (page_compression_level) { + fsp_flags |= FSP_FLAGS_MASK_PAGE_COMPRESSION; + } - /* In addition, tablespace flags also contain page compression level - if page compression is used for this table. */ - fsp_flags |= FSP_FLAGS_SET_PAGE_COMPRESSION_LEVEL(fsp_flags, page_compression_level); + ut_a(fsp_flags_is_valid(fsp_flags)); - /* In addition, tablespace flags also contain flag if atomic writes - is used for this table */ - fsp_flags |= FSP_FLAGS_SET_ATOMIC_WRITES(fsp_flags, atomic_writes); + if (DICT_TF_HAS_DATA_DIR(table_flags)) { + fsp_flags |= 1U << FSP_FLAGS_MEM_DATA_DIR; + } - ut_a(fsp_flags_is_valid(fsp_flags)); - ut_a(dict_tf_verify_flags(table_flags, fsp_flags)); + fsp_flags |= atomic_writes << FSP_FLAGS_MEM_ATOMIC_WRITES; + fsp_flags |= page_compression_level << FSP_FLAGS_MEM_COMPRESSION_LEVEL; return(fsp_flags); } diff --git a/storage/xtradb/include/dict0pagecompress.h b/storage/xtradb/include/dict0pagecompress.h index 19a2a6c52f3..6503c86ffa2 100644 --- a/storage/xtradb/include/dict0pagecompress.h +++ b/storage/xtradb/include/dict0pagecompress.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (C) 2013 SkySQL Ab. All Rights Reserved. +Copyright (C) 2013, 2017, MariaDB Corporation. All Rights Reserved. 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 @@ -56,17 +56,6 @@ dict_table_page_compression_level( const dict_table_t* table) /*!< in: table */ __attribute__((const)); -/********************************************************************//** -Verify that dictionary flags match tablespace flags -@return true if flags match, false if not */ -UNIV_INLINE -ibool -dict_tf_verify_flags( -/*=================*/ - ulint table_flags, /*!< in: dict_table_t::flags */ - ulint fsp_flags) /*!< in: fil_space_t::flags */ - __attribute__((const)); - /********************************************************************//** Extract the atomic writes flag from table flags. @return true if atomic writes are used, false if not used */ diff --git a/storage/xtradb/include/dict0pagecompress.ic b/storage/xtradb/include/dict0pagecompress.ic index 811976434a8..13c2b46c51c 100644 --- a/storage/xtradb/include/dict0pagecompress.ic +++ b/storage/xtradb/include/dict0pagecompress.ic @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (C) 2013 SkySQL Ab. All Rights Reserved. +Copyright (C) 2013, 2017, MariaDB Corporation. All Rights Reserved. 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 @@ -24,92 +24,6 @@ page compression and atomic writes information to dictionary. Created 11/12/2013 Jan Lindström jan.lindstrom@skysql.com ***********************************************************************/ -/********************************************************************//** -Verify that dictionary flags match tablespace flags -@return true if flags match, false if not */ -UNIV_INLINE -ibool -dict_tf_verify_flags( -/*=================*/ - ulint table_flags, /*!< in: dict_table_t::flags */ - ulint fsp_flags) /*!< in: fil_space_t::flags */ -{ - ulint table_unused = DICT_TF_GET_UNUSED(table_flags); - ulint compact = DICT_TF_GET_COMPACT(table_flags); - ulint ssize = DICT_TF_GET_ZIP_SSIZE(table_flags); - ulint atomic_blobs = DICT_TF_HAS_ATOMIC_BLOBS(table_flags); - ulint data_dir = DICT_TF_HAS_DATA_DIR(table_flags); - ulint page_compression = DICT_TF_GET_PAGE_COMPRESSION(table_flags); - ulint page_compression_level = DICT_TF_GET_PAGE_COMPRESSION_LEVEL(table_flags); - ulint atomic_writes = DICT_TF_GET_ATOMIC_WRITES(table_flags); - ulint post_antelope = FSP_FLAGS_GET_POST_ANTELOPE(fsp_flags); - ulint zip_ssize = FSP_FLAGS_GET_ZIP_SSIZE(fsp_flags); - ulint fsp_atomic_blobs = FSP_FLAGS_HAS_ATOMIC_BLOBS(fsp_flags); - ulint page_ssize = FSP_FLAGS_GET_PAGE_SSIZE(fsp_flags); - ulint fsp_unused = FSP_FLAGS_GET_UNUSED(fsp_flags); - ulint fsp_page_compression = FSP_FLAGS_GET_PAGE_COMPRESSION(fsp_flags); - ulint fsp_page_compression_level = FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL(fsp_flags); - ulint fsp_atomic_writes = FSP_FLAGS_GET_ATOMIC_WRITES(fsp_flags); - - DBUG_EXECUTE_IF("dict_tf_verify_flags_failure", - return(ULINT_UNDEFINED);); - - ut_a(!table_unused); - ut_a(!fsp_unused); - ut_a(page_ssize == 0 || page_ssize != 0); /* silence compiler */ - ut_a(compact == 0 || compact == 1); /* silence compiler */ - ut_a(data_dir == 0 || data_dir == 1); /* silence compiler */ - ut_a(post_antelope == 0 || post_antelope == 1); /* silence compiler */ - - if (ssize != zip_ssize) { - fprintf(stderr, - "InnoDB: Error: table flags has zip_ssize %ld" - " in the data dictionary\n" - "InnoDB: but the flags in file has zip_ssize %ld\n", - ssize, zip_ssize); - return (FALSE); - } - if (atomic_blobs != fsp_atomic_blobs) { - fprintf(stderr, - "InnoDB: Error: table flags has atomic_blobs %ld" - " in the data dictionary\n" - "InnoDB: but the flags in file has atomic_blobs %ld\n", - atomic_blobs, fsp_atomic_blobs); - - return (FALSE); - } - if (page_compression != fsp_page_compression) { - fprintf(stderr, - "InnoDB: Error: table flags has page_compression %ld" - " in the data dictionary\n" - "InnoDB: but the flags in file ahas page_compression %ld\n", - page_compression, fsp_page_compression); - - return (FALSE); - } - if (page_compression_level != fsp_page_compression_level) { - fprintf(stderr, - "InnoDB: Error: table flags has page_compression_level %ld" - " in the data dictionary\n" - "InnoDB: but the flags in file has page_compression_level %ld\n", - page_compression_level, fsp_page_compression_level); - - return (FALSE); - } - - if (atomic_writes != fsp_atomic_writes) { - fprintf(stderr, - "InnoDB: Error: table flags has atomic writes %ld" - " in the data dictionary\n" - "InnoDB: but the flags in file has atomic_writes %ld\n", - atomic_writes, fsp_atomic_writes); - - return (FALSE); - } - - return(TRUE); -} - /********************************************************************//** Extract the page compression level from dict_table_t::flags. These flags are in memory, so assert that they are valid. diff --git a/storage/xtradb/include/fil0fil.h b/storage/xtradb/include/fil0fil.h index 38cc09bced3..41e38794ea9 100644 --- a/storage/xtradb/include/fil0fil.h +++ b/storage/xtradb/include/fil0fil.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2013, 2016, MariaDB Corporation. +Copyright (c) 2013, 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 @@ -45,7 +45,6 @@ Created 10/25/1995 Heikki Tuuri // Forward declaration struct trx_t; -struct fil_space_t; typedef std::list space_name_list_t; @@ -264,10 +263,6 @@ struct fil_space_t { an insert buffer merge request for a page because it actually was for the previous incarnation of the space */ - ibool mark; /*!< this is set to TRUE at database startup if - the space corresponds to a table in the InnoDB - data dictionary; so we can print a warning of - orphaned tablespaces */ ibool stop_ios;/*!< TRUE if we want to rename the .ibd file of tablespace and want to stop temporarily posting of new i/o @@ -296,7 +291,8 @@ struct fil_space_t { /*!< recovered tablespace size in pages; 0 if no size change was read from the redo log, or if the size change was implemented */ - ulint flags; /*!< tablespace flags; see + ulint flags; /*!< FSP_SPACE_FLAGS and FSP_FLAGS_MEM_ flags; + see fsp0fsp.h, fsp_flags_is_valid(), fsp_flags_get_zip_size() */ ulint n_reserved_extents; @@ -449,6 +445,7 @@ fil_node_create( ibool is_raw) /*!< in: TRUE if a raw device or a raw disk partition */ MY_ATTRIBUTE((nonnull, warn_unused_result)); + #ifdef UNIV_LOG_ARCHIVE /****************************************************************//** Drops files from the start of a file space, so that its size is cut by @@ -620,7 +617,7 @@ fil_read_first_page( ibool one_read_already, /*!< in: TRUE if min and max parameters below already contain sensible data */ - ulint* flags, /*!< out: tablespace flags */ + ulint* flags, /*!< out: FSP_SPACE_FLAGS */ ulint* space_id, /*!< out: tablespace ID */ lsn_t* min_flushed_lsn, /*!< out: min of flushed lsn values in data files */ @@ -832,6 +829,14 @@ fil_create_new_single_table_tablespace( ulint key_id) /*!< in: encryption key_id */ __attribute__((nonnull, warn_unused_result)); #ifndef UNIV_HOTBACKUP +/** Try to adjust FSP_SPACE_FLAGS if they differ from the expectations. +(Typically when upgrading from MariaDB 10.1.0..10.1.20.) +@param[in] space_id tablespace ID +@param[in] flags desired tablespace flags */ +UNIV_INTERN +void +fsp_flags_try_adjust(ulint space_id, ulint flags); + /********************************************************************//** Tries to open a single-table tablespace and optionally checks the space id is right in it. If does not succeed, prints an error message to the .err log. This @@ -860,7 +865,7 @@ fil_open_single_table_tablespace( bool validate, /*!< in: Do we validate tablespace? */ bool fix_dict, /*!< in: Can we fix the dictionary? */ ulint id, /*!< in: space id */ - ulint flags, /*!< in: tablespace flags */ + ulint flags, /*!< in: expected FSP_SPACE_FLAGS */ const char* tablename, /*!< in: table name in the databasename/tablename format */ const char* filepath, /*!< in: tablespace filepath */ @@ -901,25 +906,18 @@ fil_tablespace_exists_in_mem( /*=========================*/ ulint id); /*!< in: space id */ #ifndef UNIV_HOTBACKUP -/*******************************************************************//** -Returns TRUE if a matching tablespace exists in the InnoDB tablespace memory +/** Check if a matching tablespace exists in the InnoDB tablespace memory cache. Note that if we have not done a crash recovery at the database startup, there may be many tablespaces which are not yet in the memory cache. -@return TRUE if a matching tablespace exists in the memory cache */ +@return whether a matching tablespace exists in the memory cache */ UNIV_INTERN -ibool +bool fil_space_for_table_exists_in_mem( /*==============================*/ ulint id, /*!< in: space id */ const char* name, /*!< in: table name in the standard 'databasename/tablename' format */ - ibool mark_space, /*!< in: in crash recovery, at database - startup we mark all spaces which have - an associated table in the InnoDB - data dictionary, so that - we can print a warning about orphaned - tablespaces */ - ibool print_error_if_does_not_exist, + bool print_error_if_does_not_exist, /*!< in: print detailed error information to the .err log if a matching tablespace is not found from @@ -927,7 +925,8 @@ fil_space_for_table_exists_in_mem( bool adjust_space, /*!< in: whether to adjust space id when find table space mismatch */ mem_heap_t* heap, /*!< in: heap memory */ - table_id_t table_id); /*!< in: table id */ + table_id_t table_id, /*!< in: table id */ + ulint table_flags); /*!< in: table flags */ #else /* !UNIV_HOTBACKUP */ /********************************************************************//** Extends all tablespaces to the size stored in the space header. During the diff --git a/storage/xtradb/include/fil0pagecompress.h b/storage/xtradb/include/fil0pagecompress.h index 10db59fb218..1fe5cb66bf6 100644 --- a/storage/xtradb/include/fil0pagecompress.h +++ b/storage/xtradb/include/fil0pagecompress.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (C) 2013, 2016 MariaDB Corporation. All Rights Reserved. +Copyright (C) 2013, 2017 MariaDB Corporation. All Rights Reserved. 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 @@ -44,20 +44,11 @@ Returns the page compression flag of the space, or false if the space is not compressed. The tablespace must be cached in the memory cache. @return true if page compressed, false if not or space not found */ UNIV_INLINE -ibool +bool fil_space_is_page_compressed( /*=========================*/ ulint id); /*!< in: space id */ /*******************************************************************//** -Returns the page compression flag of the space, or false if the space -is not compressed. The tablespace must be cached in the memory cache. -@return true if page compressed, false if not or space not found */ -UNIV_INTERN -ibool -fil_space_get_page_compressed( -/*=========================*/ - fil_space_t* space); /*!< in: space id */ -/*******************************************************************//** Returns the atomic writes flag of the space, or false if the space is not using atomic writes. The tablespace must be cached in the memory cache. @return atomic write table option value */ diff --git a/storage/xtradb/include/fsp0fsp.h b/storage/xtradb/include/fsp0fsp.h index 551a8c9ef97..93f98eb0b0b 100644 --- a/storage/xtradb/include/fsp0fsp.h +++ b/storage/xtradb/include/fsp0fsp.h @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2013, 2016, MariaDB Corporation. All Rights Reserved. +Copyright (c) 2013, 2017, MariaDB Corporation. All Rights Reserved. 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,28 +51,67 @@ to the two Barracuda row formats COMPRESSED and DYNAMIC. */ #define FSP_FLAGS_WIDTH_ATOMIC_BLOBS 1 /** Number of flag bits used to indicate the tablespace page size */ #define FSP_FLAGS_WIDTH_PAGE_SSIZE 4 -/** Width of the DATA_DIR flag. This flag indicates that the tablespace -is found in a remote location, not the default data directory. */ -#define FSP_FLAGS_WIDTH_DATA_DIR 1 -/** Number of flag bits used to indicate the page compression and compression level */ -#define FSP_FLAGS_WIDTH_PAGE_COMPRESSION 1 -#define FSP_FLAGS_WIDTH_PAGE_COMPRESSION_LEVEL 4 +/** Number of reserved bits */ +#define FSP_FLAGS_WIDTH_RESERVED 6 +/** Number of flag bits used to indicate the page compression */ +#define FSP_FLAGS_WIDTH_PAGE_COMPRESSION 1 -/** Number of flag bits used to indicate atomic writes for this tablespace */ -#define FSP_FLAGS_WIDTH_ATOMIC_WRITES 2 - -/** Width of all the currently known tablespace flags */ +/** Width of all the currently known persistent tablespace flags */ #define FSP_FLAGS_WIDTH (FSP_FLAGS_WIDTH_POST_ANTELOPE \ + FSP_FLAGS_WIDTH_ZIP_SSIZE \ + FSP_FLAGS_WIDTH_ATOMIC_BLOBS \ + FSP_FLAGS_WIDTH_PAGE_SSIZE \ - + FSP_FLAGS_WIDTH_DATA_DIR \ - + FSP_FLAGS_WIDTH_PAGE_COMPRESSION \ - + FSP_FLAGS_WIDTH_PAGE_COMPRESSION_LEVEL \ - + FSP_FLAGS_WIDTH_ATOMIC_WRITES ) - -/** A mask of all the known/used bits in tablespace flags */ -#define FSP_FLAGS_MASK (~(~0 << FSP_FLAGS_WIDTH)) + + FSP_FLAGS_WIDTH_RESERVED \ + + FSP_FLAGS_WIDTH_PAGE_COMPRESSION) + +/** A mask of all the known/used bits in FSP_SPACE_FLAGS */ +#define FSP_FLAGS_MASK (~(~0U << FSP_FLAGS_WIDTH)) + +/* FSP_SPACE_FLAGS position and name in MySQL 5.6/MariaDB 10.0 or older +and MariaDB 10.1.20 or older MariaDB 10.1 and in MariaDB 10.1.21 +or newer. +MySQL 5.6 MariaDB 10.1.x MariaDB 10.1.21 +==================================================================== +Below flags in same offset +==================================================================== +0: POST_ANTELOPE 0:POST_ANTELOPE 0: POST_ANTELOPE +1..4: ZIP_SSIZE(0..5) 1..4:ZIP_SSIZE(0..5) 1..4: ZIP_SSIZE(0..5) +(NOTE: bit 4 is always 0) +5: ATOMIC_BLOBS 5:ATOMIC_BLOBS 5: ATOMIC_BLOBS +===================================================================== +Below note the order difference: +===================================================================== +6..9: PAGE_SSIZE(3..7) 6: COMPRESSION 6..9: PAGE_SSIZE(3..7) +10: DATA_DIR 7..10: COMP_LEVEL(0..9) 10: RESERVED (5.6 DATA_DIR) +===================================================================== +The flags below were in incorrect position in MariaDB 10.1, +or have been introduced in MySQL 5.7 or 8.0: +===================================================================== +11: UNUSED 11..12:ATOMIC_WRITES 11: RESERVED (5.7 SHARED) + 12: RESERVED (5.7 TEMPORARY) + 13..15:PAGE_SSIZE(3..7) 13: RESERVED (5.7 ENCRYPTION) + 14: RESERVED (8.0 SDI) + 15: RESERVED + 16: PAGE_SSIZE_msb(0) 16: COMPRESSION + 17: DATA_DIR 17: UNUSED + 18: UNUSED +===================================================================== +The flags below only exist in fil_space_t::flags, not in FSP_SPACE_FLAGS: +===================================================================== + 25: DATA_DIR + 26..27: ATOMIC_WRITES + 28..31: COMPRESSION_LEVEL +*/ + +/** A mask of the memory-only flags in fil_space_t::flags */ +#define FSP_FLAGS_MEM_MASK (~0U << FSP_FLAGS_MEM_DATA_DIR) + +/** Zero relative shift position of the DATA_DIR flag */ +#define FSP_FLAGS_MEM_DATA_DIR 25 +/** Zero relative shift position of the ATOMIC_WRITES field */ +#define FSP_FLAGS_MEM_ATOMIC_WRITES 26 +/** Zero relative shift position of the COMPRESSION_LEVEL field */ +#define FSP_FLAGS_MEM_COMPRESSION_LEVEL 28 /** Zero relative shift position of the POST_ANTELOPE field */ #define FSP_FLAGS_POS_POST_ANTELOPE 0 @@ -82,29 +121,16 @@ is found in a remote location, not the default data directory. */ /** Zero relative shift position of the ATOMIC_BLOBS field */ #define FSP_FLAGS_POS_ATOMIC_BLOBS (FSP_FLAGS_POS_ZIP_SSIZE \ + FSP_FLAGS_WIDTH_ZIP_SSIZE) -/** Note that these need to be before the page size to be compatible with -dictionary */ -/** Zero relative shift position of the PAGE_COMPRESSION field */ -#define FSP_FLAGS_POS_PAGE_COMPRESSION (FSP_FLAGS_POS_ATOMIC_BLOBS \ - + FSP_FLAGS_WIDTH_ATOMIC_BLOBS) -/** Zero relative shift position of the PAGE_COMPRESSION_LEVEL field */ -#define FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL (FSP_FLAGS_POS_PAGE_COMPRESSION \ - + FSP_FLAGS_WIDTH_PAGE_COMPRESSION) -/** Zero relative shift position of the ATOMIC_WRITES field */ -#define FSP_FLAGS_POS_ATOMIC_WRITES (FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL \ - + FSP_FLAGS_WIDTH_PAGE_COMPRESSION_LEVEL) -/** Zero relative shift position of the PAGE_SSIZE field */ -#define FSP_FLAGS_POS_PAGE_SSIZE (FSP_FLAGS_POS_ATOMIC_WRITES \ - + FSP_FLAGS_WIDTH_ATOMIC_WRITES) -/** Zero relative shift position of the start of the DATA DIR bits */ -#define FSP_FLAGS_POS_DATA_DIR (FSP_FLAGS_POS_PAGE_SSIZE \ - + FSP_FLAGS_WIDTH_PAGE_SSIZE) -#define FSP_FLAGS_POS_DATA_DIR_ORACLE (FSP_FLAGS_POS_ATOMIC_BLOBS \ - + FSP_FLAGS_WIDTH_ATOMIC_BLOBS \ +/** Zero relative shift position of the start of the PAGE_SSIZE bits */ +#define FSP_FLAGS_POS_PAGE_SSIZE (FSP_FLAGS_POS_ATOMIC_BLOBS \ + + FSP_FLAGS_WIDTH_ATOMIC_BLOBS) +/** Zero relative shift position of the start of the RESERVED bits +these are only used in MySQL 5.7 and used for compatibility. */ +#define FSP_FLAGS_POS_RESERVED (FSP_FLAGS_POS_PAGE_SSIZE \ + FSP_FLAGS_WIDTH_PAGE_SSIZE) -/** Zero relative shift position of the start of the UNUSED bits */ -#define FSP_FLAGS_POS_UNUSED (FSP_FLAGS_POS_DATA_DIR\ - + FSP_FLAGS_WIDTH_DATA_DIR) +/** Zero relative shift position of the PAGE_COMPRESSION field */ +#define FSP_FLAGS_POS_PAGE_COMPRESSION (FSP_FLAGS_POS_RESERVED \ + + FSP_FLAGS_WIDTH_RESERVED) /** Bit mask of the POST_ANTELOPE field */ #define FSP_FLAGS_MASK_POST_ANTELOPE \ @@ -122,26 +148,23 @@ dictionary */ #define FSP_FLAGS_MASK_PAGE_SSIZE \ ((~(~0U << FSP_FLAGS_WIDTH_PAGE_SSIZE)) \ << FSP_FLAGS_POS_PAGE_SSIZE) -/** Bit mask of the DATA_DIR field */ -#define FSP_FLAGS_MASK_DATA_DIR \ - ((~(~0U << FSP_FLAGS_WIDTH_DATA_DIR)) \ - << FSP_FLAGS_POS_DATA_DIR) -/** Bit mask of the DATA_DIR field */ -#define FSP_FLAGS_MASK_DATA_DIR_ORACLE \ - ((~(~0U << FSP_FLAGS_WIDTH_DATA_DIR)) \ - << FSP_FLAGS_POS_DATA_DIR_ORACLE) +/** Bit mask of the RESERVED1 field */ +#define FSP_FLAGS_MASK_RESERVED \ + ((~(~0U << FSP_FLAGS_WIDTH_RESERVED)) \ + << FSP_FLAGS_POS_RESERVED) /** Bit mask of the PAGE_COMPRESSION field */ -#define FSP_FLAGS_MASK_PAGE_COMPRESSION \ +#define FSP_FLAGS_MASK_PAGE_COMPRESSION \ ((~(~0U << FSP_FLAGS_WIDTH_PAGE_COMPRESSION)) \ << FSP_FLAGS_POS_PAGE_COMPRESSION) -/** Bit mask of the PAGE_COMPRESSION_LEVEL field */ -#define FSP_FLAGS_MASK_PAGE_COMPRESSION_LEVEL \ - ((~(~0U << FSP_FLAGS_WIDTH_PAGE_COMPRESSION_LEVEL)) \ - << FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL) -/** Bit mask of the ATOMIC_WRITES field */ -#define FSP_FLAGS_MASK_ATOMIC_WRITES \ - ((~(~0U << FSP_FLAGS_WIDTH_ATOMIC_WRITES)) \ - << FSP_FLAGS_POS_ATOMIC_WRITES) + +/** Bit mask of the in-memory ATOMIC_WRITES field */ +#define FSP_FLAGS_MASK_MEM_ATOMIC_WRITES \ + (3U << FSP_FLAGS_MEM_ATOMIC_WRITES) + +/** Bit mask of the in-memory COMPRESSION_LEVEL field */ +#define FSP_FLAGS_MASK_MEM_COMPRESSION_LEVEL \ + (15U << FSP_FLAGS_MEM_COMPRESSION_LEVEL) + /** Return the value of the POST_ANTELOPE field */ #define FSP_FLAGS_GET_POST_ANTELOPE(flags) \ ((flags & FSP_FLAGS_MASK_POST_ANTELOPE) \ @@ -158,48 +181,78 @@ dictionary */ #define FSP_FLAGS_GET_PAGE_SSIZE(flags) \ ((flags & FSP_FLAGS_MASK_PAGE_SSIZE) \ >> FSP_FLAGS_POS_PAGE_SSIZE) -/** Return the value of the DATA_DIR field */ -#define FSP_FLAGS_HAS_DATA_DIR(flags) \ - ((flags & FSP_FLAGS_MASK_DATA_DIR) \ - >> FSP_FLAGS_POS_DATA_DIR) -#define FSP_FLAGS_HAS_DATA_DIR_ORACLE(flags) \ - ((flags & FSP_FLAGS_MASK_DATA_DIR_ORACLE) \ - >> FSP_FLAGS_POS_DATA_DIR_ORACLE) +/** @return the RESERVED flags */ +#define FSP_FLAGS_GET_RESERVED(flags) \ + ((flags & FSP_FLAGS_MASK_RESERVED) \ + >> FSP_FLAGS_POS_RESERVED) +/** @return the PAGE_COMPRESSION flag */ +#define FSP_FLAGS_HAS_PAGE_COMPRESSION(flags) \ + ((flags & FSP_FLAGS_MASK_PAGE_COMPRESSION) \ + >> FSP_FLAGS_POS_PAGE_COMPRESSION) + /** Return the contents of the UNUSED bits */ #define FSP_FLAGS_GET_UNUSED(flags) \ (flags >> FSP_FLAGS_POS_UNUSED) + +/** @return the PAGE_SSIZE flags for the current innodb_page_size */ +#define FSP_FLAGS_PAGE_SSIZE() \ + ((UNIV_PAGE_SIZE == UNIV_PAGE_SIZE_ORIG) ? \ + 0 : (UNIV_PAGE_SIZE_SHIFT - UNIV_ZIP_SIZE_SHIFT_MIN + 1) \ + << FSP_FLAGS_POS_PAGE_SSIZE) + +/** @return the value of the DATA_DIR field */ +#define FSP_FLAGS_HAS_DATA_DIR(flags) \ + (flags & 1U << FSP_FLAGS_MEM_DATA_DIR) +/** @return the COMPRESSION_LEVEL field */ +#define FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL(flags) \ + ((flags & FSP_FLAGS_MASK_MEM_COMPRESSION_LEVEL) \ + >> FSP_FLAGS_MEM_COMPRESSION_LEVEL) +/** @return the ATOMIC_WRITES field */ +#define FSP_FLAGS_GET_ATOMIC_WRITES(flags) \ + ((flags & FSP_FLAGS_MASK_MEM_ATOMIC_WRITES) \ + >> FSP_FLAGS_MEM_ATOMIC_WRITES) + +/* Compatibility macros for MariaDB 10.1.20 or older 10.1 see +table above. */ +/** Zero relative shift position of the PAGE_COMPRESSION field */ +#define FSP_FLAGS_POS_PAGE_COMPRESSION_MARIADB101 \ + (FSP_FLAGS_POS_ATOMIC_BLOBS \ + + FSP_FLAGS_WIDTH_ATOMIC_BLOBS) +/** Zero relative shift position of the PAGE_COMPRESSION_LEVEL field */ +#define FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL_MARIADB101 \ + (FSP_FLAGS_POS_PAGE_COMPRESSION_MARIADB101 + 1) +/** Zero relative shift position of the ATOMIC_WRITES field */ +#define FSP_FLAGS_POS_ATOMIC_WRITES_MARIADB101 \ + (FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL_MARIADB101 + 4) +/** Zero relative shift position of the PAGE_SSIZE field */ +#define FSP_FLAGS_POS_PAGE_SSIZE_MARIADB101 \ + (FSP_FLAGS_POS_ATOMIC_WRITES_MARIADB101 + 2) + +/** Bit mask of the PAGE_COMPRESSION field */ +#define FSP_FLAGS_MASK_PAGE_COMPRESSION_MARIADB101 \ + (1U << FSP_FLAGS_POS_PAGE_COMPRESSION_MARIADB101) +/** Bit mask of the PAGE_COMPRESSION_LEVEL field */ +#define FSP_FLAGS_MASK_PAGE_COMPRESSION_LEVEL_MARIADB101 \ + (15U << FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL_MARIADB101) +/** Bit mask of the ATOMIC_WRITES field */ +#define FSP_FLAGS_MASK_ATOMIC_WRITES_MARIADB101 \ + (3U << FSP_FLAGS_POS_ATOMIC_WRITES_MARIADB101) +/** Bit mask of the PAGE_SSIZE field */ +#define FSP_FLAGS_MASK_PAGE_SSIZE_MARIADB101 \ + (15U << FSP_FLAGS_POS_PAGE_SSIZE_MARIADB101) + /** Return the value of the PAGE_COMPRESSION field */ -#define FSP_FLAGS_GET_PAGE_COMPRESSION(flags) \ - ((flags & FSP_FLAGS_MASK_PAGE_COMPRESSION) \ - >> FSP_FLAGS_POS_PAGE_COMPRESSION) +#define FSP_FLAGS_GET_PAGE_COMPRESSION_MARIADB101(flags) \ + ((flags & FSP_FLAGS_MASK_PAGE_COMPRESSION_MARIADB101) \ + >> FSP_FLAGS_POS_PAGE_COMPRESSION_MARIADB101) /** Return the value of the PAGE_COMPRESSION_LEVEL field */ -#define FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL(flags) \ - ((flags & FSP_FLAGS_MASK_PAGE_COMPRESSION_LEVEL) \ - >> FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL) -/** Return the value of the ATOMIC_WRITES field */ -#define FSP_FLAGS_GET_ATOMIC_WRITES(flags) \ - ((flags & FSP_FLAGS_MASK_ATOMIC_WRITES) \ - >> FSP_FLAGS_POS_ATOMIC_WRITES) - -/** Set a PAGE_SSIZE into the correct bits in a given -tablespace flags. */ -#define FSP_FLAGS_SET_PAGE_SSIZE(flags, ssize) \ - (flags | (ssize << FSP_FLAGS_POS_PAGE_SSIZE)) - -/** Set a PAGE_COMPRESSION into the correct bits in a given -tablespace flags. */ -#define FSP_FLAGS_SET_PAGE_COMPRESSION(flags, compression) \ - (flags | (compression << FSP_FLAGS_POS_PAGE_COMPRESSION)) - -/** Set a PAGE_COMPRESSION_LEVEL into the correct bits in a given -tablespace flags. */ -#define FSP_FLAGS_SET_PAGE_COMPRESSION_LEVEL(flags, level) \ - (flags | (level << FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL)) - -/** Set a ATOMIC_WRITES into the correct bits in a given -tablespace flags. */ -#define FSP_FLAGS_SET_ATOMIC_WRITES(flags, atomics) \ - (flags | (atomics << FSP_FLAGS_POS_ATOMIC_WRITES)) +#define FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL_MARIADB101(flags) \ + ((flags & FSP_FLAGS_MASK_PAGE_COMPRESSION_LEVEL_MARIADB101) \ + >> FSP_FLAGS_POS_PAGE_COMPRESSION_LEVEL_MARIADB101) +/** Return the value of the PAGE_SSIZE field */ +#define FSP_FLAGS_GET_PAGE_SSIZE_MARIADB101(flags) \ + ((flags & FSP_FLAGS_MASK_PAGE_SSIZE_MARIADB101) \ + >> FSP_FLAGS_POS_PAGE_SSIZE_MARIADB101) /* @} */ @@ -733,19 +786,193 @@ fseg_print( mtr_t* mtr); /*!< in/out: mini-transaction */ #endif /* UNIV_BTR_PRINT */ -/********************************************************************//** -Validate and return the tablespace flags, which are stored in the -tablespace header at offset FSP_SPACE_FLAGS. They should be 0 for -ROW_FORMAT=COMPACT and ROW_FORMAT=REDUNDANT. The newer row formats, -COMPRESSED and DYNAMIC, use a file format > Antelope so they should -have a file format number plus the DICT_TF_COMPACT bit set. -@return true if check ok */ +/** Validate the tablespace flags, which are stored in the +tablespace header at offset FSP_SPACE_FLAGS. +@param[in] flags the contents of FSP_SPACE_FLAGS +@return whether the flags are correct (not in the buggy 10.1) format */ +MY_ATTRIBUTE((warn_unused_result, const)) UNIV_INLINE bool -fsp_flags_is_valid( -/*===============*/ - ulint flags) /*!< in: tablespace flags */ - MY_ATTRIBUTE((warn_unused_result, const)); +fsp_flags_is_valid(ulint flags) +{ + DBUG_EXECUTE_IF("fsp_flags_is_valid_failure", + return(false);); + if (flags == 0) { + return(true); + } + if (flags & ~FSP_FLAGS_MASK) { + return(false); + } + if ((flags & (FSP_FLAGS_MASK_POST_ANTELOPE | FSP_FLAGS_MASK_ATOMIC_BLOBS)) + == FSP_FLAGS_MASK_ATOMIC_BLOBS) { + /* If the "atomic blobs" flag (indicating + ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED) flag + is set, then the "post Antelope" (ROW_FORMAT!=REDUNDANT) flag + must also be set. */ + return(false); + } + /* Bits 10..14 should be 0b0000d where d is the DATA_DIR flag + of MySQL 5.6 and MariaDB 10.0, which we ignore. + In the buggy FSP_SPACE_FLAGS written by MariaDB 10.1.0 to 10.1.20, + bits 10..14 would be nonzero 0bsssaa where sss is + nonzero PAGE_SSIZE (3, 4, 6, or 7) + and aa is ATOMIC_WRITES (not 0b11). */ + if (FSP_FLAGS_GET_RESERVED(flags) & ~1) { + return(false); + } + + const ulint ssize = FSP_FLAGS_GET_PAGE_SSIZE(flags); + if (ssize == 1 || ssize == 2 || ssize == 5 || ssize & 8) { + /* the page_size is not between 4k and 64k; + 16k should be encoded as 0, not 5 */ + return(false); + } + const ulint zssize = FSP_FLAGS_GET_ZIP_SSIZE(flags); + if (zssize == 0) { + /* not ROW_FORMAT=COMPRESSED */ + } else if (zssize > (ssize ? ssize : 5)) { + /* invalid KEY_BLOCK_SIZE */ + return(false); + } else if (~flags & (FSP_FLAGS_MASK_POST_ANTELOPE + | FSP_FLAGS_MASK_ATOMIC_BLOBS)) { + /* both these flags should be set for + ROW_FORMAT=COMPRESSED */ + return(false); + } + + return(true); +} + +/** Convert FSP_SPACE_FLAGS from the buggy MariaDB 10.1.0..10.1.20 format. +@param[in] flags the contents of FSP_SPACE_FLAGS +@return the flags corrected from the buggy MariaDB 10.1 format +@retval ULINT_UNDEFINED if the flags are not in the buggy 10.1 format */ +MY_ATTRIBUTE((warn_unused_result, const)) +UNIV_INLINE +ulint +fsp_flags_convert_from_101(ulint flags) +{ + DBUG_EXECUTE_IF("fsp_flags_is_valid_failure", + return(ULINT_UNDEFINED);); + if (flags == 0) { + return(flags); + } + + if (flags >> 18) { + /* The most significant FSP_SPACE_FLAGS bit that was ever set + by MariaDB 10.1.0 to 10.1.20 was bit 17 (misplaced DATA_DIR flag). + The flags must be less than 1<<18 in order to be valid. */ + return(ULINT_UNDEFINED); + } + + if ((flags & (FSP_FLAGS_MASK_POST_ANTELOPE | FSP_FLAGS_MASK_ATOMIC_BLOBS)) + == FSP_FLAGS_MASK_ATOMIC_BLOBS) { + /* If the "atomic blobs" flag (indicating + ROW_FORMAT=DYNAMIC or ROW_FORMAT=COMPRESSED) flag + is set, then the "post Antelope" (ROW_FORMAT!=REDUNDANT) flag + must also be set. */ + return(ULINT_UNDEFINED); + } + + /* Bits 6..10 denote compression in MariaDB 10.1.0 to 10.1.20. + They must be either 0b00000 or 0b00011 through 0b10011. + In correct versions, these bits would be + 0bd0sss where d is the DATA_DIR flag (garbage bit) and + sss is the PAGE_SSIZE (3, 4, 6, or 7). + + NOTE: MariaDB 10.1.0 to 10.1.20 can misinterpret + uncompressed data files with innodb_page_size=4k or 64k as + compressed innodb_page_size=16k files. Below is an exhaustive + state space analysis. + + -0by1zzz: impossible (the bit 4 must be clean; see above) + -0b101xx: DATA_DIR, innodb_page_size>4k: invalid (COMPRESSION_LEVEL>9) + +0bx0011: innodb_page_size=4k: + !!! Misinterpreted as COMPRESSION_LEVEL=9 or 1, COMPRESSION=1. + -0bx0010: impossible, because sss must be 0b011 or 0b1xx + -0bx0001: impossible, because sss must be 0b011 or 0b1xx + -0b10000: DATA_DIR, innodb_page_size=16: + invalid (COMPRESSION_LEVEL=8 but COMPRESSION=0) + +0b00111: no DATA_DIR, innodb_page_size=64k: + !!! Misinterpreted as COMPRESSION_LEVEL=3, COMPRESSION=1. + -0b00101: impossible, because sss must be 0 for 16k, not 0b101 + -0b001x0: no DATA_DIR, innodb_page_size=32k or 8k: + invalid (COMPRESSION_LEVEL=3 but COMPRESSION=0) + +0b00000: innodb_page_size=16k (looks like COMPRESSION=0) + ??? Could actually be compressed; see PAGE_SSIZE below */ + const ulint level = FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL_MARIADB101( + flags); + if (FSP_FLAGS_GET_PAGE_COMPRESSION_MARIADB101(flags) != (level != 0) + || level > 9) { + /* The compression flags are not in the buggy MariaDB + 10.1 format. */ + return(ULINT_UNDEFINED); + } + if (!(~flags & FSP_FLAGS_MASK_ATOMIC_WRITES_MARIADB101)) { + /* The ATOMIC_WRITES flags cannot be 0b11. + (The bits 11..12 should actually never be 0b11, + because in MySQL they would be SHARED|TEMPORARY.) */ + return(ULINT_UNDEFINED); + } + + /* Bits 13..16 are the wrong position for PAGE_SSIZE, and they + should contain one of the values 3,4,6,7, that is, be of the form + 0b0011 or 0b01xx (except 0b0110). + In correct versions, these bits should be 0bc0se + where c is the MariaDB COMPRESSED flag + and e is the MySQL 5.7 ENCRYPTION flag + and s is the MySQL 8.0 SDI flag. MariaDB can only support s=0, e=0. + + Compressed innodb_page_size=16k tables with correct FSP_SPACE_FLAGS + will be properly rejected by older MariaDB 10.1.x because they + would read as PAGE_SSIZE>=8 which is not valid. */ + + const ulint ssize = FSP_FLAGS_GET_PAGE_SSIZE_MARIADB101(flags); + if (ssize == 1 || ssize == 2 || ssize == 5 || ssize & 8) { + /* the page_size is not between 4k and 64k; + 16k should be encoded as 0, not 5 */ + return(ULINT_UNDEFINED); + } + const ulint zssize = FSP_FLAGS_GET_ZIP_SSIZE(flags); + if (zssize == 0) { + /* not ROW_FORMAT=COMPRESSED */ + } else if (zssize > (ssize ? ssize : 5)) { + /* invalid KEY_BLOCK_SIZE */ + return(ULINT_UNDEFINED); + } else if (~flags & (FSP_FLAGS_MASK_POST_ANTELOPE + | FSP_FLAGS_MASK_ATOMIC_BLOBS)) { + /* both these flags should be set for + ROW_FORMAT=COMPRESSED */ + return(ULINT_UNDEFINED); + } + + flags = ((flags & 0x3f) | ssize << FSP_FLAGS_POS_PAGE_SSIZE + | FSP_FLAGS_GET_PAGE_COMPRESSION_MARIADB101(flags) + << FSP_FLAGS_POS_PAGE_COMPRESSION); + ut_ad(fsp_flags_is_valid(flags)); + return(flags); +} + +/** Compare tablespace flags. +@param[in] expected expected flags from dict_tf_to_fsp_flags() +@param[in] actual flags read from FSP_SPACE_FLAGS +@return whether the flags match */ +MY_ATTRIBUTE((warn_unused_result)) +UNIV_INLINE +bool +fsp_flags_match(ulint expected, ulint actual) +{ + expected &= ~FSP_FLAGS_MEM_MASK; + ut_ad(fsp_flags_is_valid(expected)); + + if (actual == expected) { + return(true); + } + + actual = fsp_flags_convert_from_101(actual); + return(actual == expected); +} + /********************************************************************//** Determine if the tablespace is compressed from dict_table_t::flags. @return TRUE if compressed, FALSE if not compressed */ diff --git a/storage/xtradb/include/fsp0fsp.ic b/storage/xtradb/include/fsp0fsp.ic index ddcb87b0e57..ee4cb1f32c7 100644 --- a/storage/xtradb/include/fsp0fsp.ic +++ b/storage/xtradb/include/fsp0fsp.ic @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 1995, 2012, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2013, SkySQL Ab. All Rights Reserved. +Copyright (c) 2013, 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 @@ -46,107 +46,6 @@ fsp_descr_page( return((page_no & (zip_size - 1)) == FSP_XDES_OFFSET); } -/********************************************************************//** -Validate and return the tablespace flags, which are stored in the -tablespace header at offset FSP_SPACE_FLAGS. They should be 0 for -ROW_FORMAT=COMPACT and ROW_FORMAT=REDUNDANT. The newer row formats, -COMPRESSED and DYNAMIC, use a file format > Antelope so they should -have a file format number plus the DICT_TF_COMPACT bit set. -@return true if check ok */ -UNIV_INLINE -bool -fsp_flags_is_valid( -/*===============*/ - ulint flags) /*!< in: tablespace flags */ -{ - ulint post_antelope = FSP_FLAGS_GET_POST_ANTELOPE(flags); - ulint zip_ssize = FSP_FLAGS_GET_ZIP_SSIZE(flags); - ulint atomic_blobs = FSP_FLAGS_HAS_ATOMIC_BLOBS(flags); - ulint page_ssize = FSP_FLAGS_GET_PAGE_SSIZE(flags); - ulint unused = FSP_FLAGS_GET_UNUSED(flags); - ulint page_compression = FSP_FLAGS_GET_PAGE_COMPRESSION(flags); - ulint page_compression_level = FSP_FLAGS_GET_PAGE_COMPRESSION_LEVEL(flags); - ulint atomic_writes = FSP_FLAGS_GET_ATOMIC_WRITES(flags); - - DBUG_EXECUTE_IF("fsp_flags_is_valid_failure", return(false);); - - /* fsp_flags is zero unless atomic_blobs is set. */ - /* Make sure there are no bits that we do not know about. */ - if (unused != 0 || flags == 1) { - fprintf(stderr, "InnoDB: Error: Tablespace flags %lu corrupted unused %lu\n", - flags, unused); - return(false); - } else if (post_antelope) { - /* The Antelope row formats REDUNDANT and COMPACT did - not use tablespace flags, so this flag and the entire - 4-byte field is zero for Antelope row formats. */ - - if (!atomic_blobs) { - fprintf(stderr, "InnoDB: Error: Tablespace flags %lu corrupted atomic_blobs %lu\n", - flags, atomic_blobs); - return(false); - } - } - - if (!atomic_blobs) { - /* Barracuda row formats COMPRESSED and DYNAMIC build on - the page structure introduced for the COMPACT row format - by allowing long fields to be broken into prefix and - externally stored parts. */ - - if (post_antelope || zip_ssize != 0) { - fprintf(stderr, "InnoDB: Error: Tablespace flags %lu corrupted zip_ssize %lu atomic_blobs %lu\n", - flags, zip_ssize, atomic_blobs); - return(false); - } - - } else if (!post_antelope || zip_ssize > PAGE_ZIP_SSIZE_MAX) { - fprintf(stderr, "InnoDB: Error: Tablespace flags %lu corrupted zip_ssize %lu max %d\n", - flags, zip_ssize, PAGE_ZIP_SSIZE_MAX); - return(false); - } else if (page_ssize > UNIV_PAGE_SSIZE_MAX) { - - /* The page size field can be used for any row type, or it may - be zero for an original 16k page size. - Validate the page shift size is within allowed range. */ - - fprintf(stderr, "InnoDB: Error: Tablespace flags %lu corrupted page_ssize %lu max %lu\n", - flags, page_ssize, UNIV_PAGE_SSIZE_MAX); - return(false); - - } else if (UNIV_PAGE_SIZE != UNIV_PAGE_SIZE_ORIG && !page_ssize) { - fprintf(stderr, "InnoDB: Error: Tablespace flags %lu corrupted page_ssize %lu max %lu:%d\n", - flags, page_ssize, UNIV_PAGE_SIZE, UNIV_PAGE_SIZE_ORIG); - return(false); - } - -#if UNIV_FORMAT_MAX != UNIV_FORMAT_B -# error "UNIV_FORMAT_MAX != UNIV_FORMAT_B, Add more validations." -#endif - - /* Page compression level requires page compression and atomic blobs - to be set */ - if (page_compression_level || page_compression) { - if (!page_compression || !atomic_blobs) { - fprintf(stderr, "InnoDB: Error: Tablespace flags %lu corrupted page_compression %lu\n" - "InnoDB: Error: page_compression_level %lu atomic_blobs %lu\n", - flags, page_compression, page_compression_level, atomic_blobs); - return(false); - } - } - - if (atomic_writes > ATOMIC_WRITES_OFF) { - fprintf(stderr, "InnoDB: Error: Tablespace flags %lu corrupted atomic_writes %lu\n", - flags, atomic_writes); - return (false); - } - - /* The DATA_DIR field can be used for any row type so there is - nothing here to validate. */ - - return(true); -} - /********************************************************************//** Determine if the tablespace is compressed from dict_table_t::flags. @return TRUE if compressed, FALSE if not compressed */ @@ -191,10 +90,10 @@ UNIV_INLINE ulint fsp_flags_get_page_size( /*====================*/ - ulint flags) /*!< in: tablespace flags */ + ulint flags) /*!< in: tablespace flags */ { - ulint page_size = 0; - ulint ssize = FSP_FLAGS_GET_PAGE_SSIZE(flags); + ulint page_size = 0; + ulint ssize = FSP_FLAGS_GET_PAGE_SSIZE(flags); /* Convert from a 'log2 minus 9' to a page size in bytes. */ if (UNIV_UNLIKELY(ssize)) { @@ -211,50 +110,6 @@ fsp_flags_get_page_size( } #ifndef UNIV_INNOCHECKSUM - -/********************************************************************//** -Add the page size to the tablespace flags. -@return tablespace flags after page size is added */ -UNIV_INLINE -ulint -fsp_flags_set_page_size( -/*====================*/ - ulint flags, /*!< in: tablespace flags */ - ulint page_size) /*!< in: page size in bytes */ -{ - ulint ssize = 0; - ulint shift; - - /* Page size should be > UNIV_PAGE_SIZE_MIN */ - ut_ad(page_size >= UNIV_PAGE_SIZE_MIN); - ut_ad(page_size <= UNIV_PAGE_SIZE_MAX); - - if (page_size == UNIV_PAGE_SIZE_ORIG) { - ut_ad(0 == FSP_FLAGS_GET_PAGE_SSIZE(flags)); - return(flags); - } - - for (shift = UNIV_PAGE_SIZE_SHIFT_MAX; - shift >= UNIV_PAGE_SIZE_SHIFT_MIN; - shift--) { - ulint mask = (1 << shift); - if (page_size & mask) { - ut_ad(!(page_size & ~mask)); - ssize = shift - UNIV_ZIP_SIZE_SHIFT_MIN + 1; - break; - } - } - - ut_ad(ssize); - ut_ad(ssize <= UNIV_PAGE_SSIZE_MAX); - - flags = FSP_FLAGS_SET_PAGE_SSIZE(flags, ssize); - - ut_ad(fsp_flags_is_valid(flags)); - - return(flags); -} - /********************************************************************//** Calculates the descriptor index within a descriptor page. @return descriptor index */ diff --git a/storage/xtradb/include/fsp0pagecompress.h b/storage/xtradb/include/fsp0pagecompress.h index 5f943ee2b83..c623d11c326 100644 --- a/storage/xtradb/include/fsp0pagecompress.h +++ b/storage/xtradb/include/fsp0pagecompress.h @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (C) 2013, 2015, MariaDB Corporation. All Rights Reserved. +Copyright (C) 2013, 2017, MariaDB Corporation. All Rights Reserved. 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 @@ -47,15 +47,6 @@ fsp_header_get_compression_level( /*=============================*/ const page_t* page); /*!< in: first page of a tablespace */ -/********************************************************************//** -Determine if the tablespace is page compressed from dict_table_t::flags. -@return TRUE if page compressed, FALSE if not compressed */ -UNIV_INLINE -ibool -fsp_flags_is_page_compressed( -/*=========================*/ - ulint flags); /*!< in: tablespace flags */ - /********************************************************************//** Extract the page compression level from tablespace flags. A tablespace has only one physical page compression level diff --git a/storage/xtradb/include/fsp0pagecompress.ic b/storage/xtradb/include/fsp0pagecompress.ic index e879aa2c16e..48163277feb 100644 --- a/storage/xtradb/include/fsp0pagecompress.ic +++ b/storage/xtradb/include/fsp0pagecompress.ic @@ -1,6 +1,6 @@ /***************************************************************************** -Copyright (C) 2013, 2015, MariaDB Corporation. All Rights Reserved. +Copyright (C) 2013, 2017, MariaDB Corporation. All Rights Reserved. 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 @@ -25,18 +25,6 @@ Created 11/12/2013 Jan Lindström jan.lindstrom@mariadb.com ***********************************************************************/ -/********************************************************************//** -Determine if the tablespace is page compressed from dict_table_t::flags. -@return TRUE if page compressed, FALSE if not page compressed */ -UNIV_INLINE -ibool -fsp_flags_is_page_compressed( -/*=========================*/ - ulint flags) /*!< in: tablespace flags */ -{ - return(FSP_FLAGS_GET_PAGE_COMPRESSION(flags)); -} - /********************************************************************//** Determine the tablespace is page compression level from dict_table_t::flags. @return page compression level or 0 if not compressed*/ @@ -125,21 +113,15 @@ Extract the page compression from space. @return true if space is page compressed, false if space is not found or space is not page compressed. */ UNIV_INLINE -ibool +bool fil_space_is_page_compressed( /*=========================*/ ulint id) /*!< in: space id */ { - ulint flags; - - flags = fil_space_get_flags(id); - - if (flags && flags != ULINT_UNDEFINED) { - - return(fsp_flags_is_page_compressed(flags)); - } + ulint flags = fil_space_get_flags(id); - return(0); + return(flags != ULINT_UNDEFINED + && FSP_FLAGS_HAS_PAGE_COMPRESSION(flags)); } #endif /* UNIV_INNOCHECKSUM */ diff --git a/storage/xtradb/row/row0import.cc b/storage/xtradb/row/row0import.cc index d45ce907304..6170eb66195 100644 --- a/storage/xtradb/row/row0import.cc +++ b/storage/xtradb/row/row0import.cc @@ -1,7 +1,7 @@ /***************************************************************************** Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved. -Copyright (c) 2016, MariaDB Corporation. +Copyright (c) 2015, 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 @@ -371,8 +371,7 @@ public: m_space(ULINT_UNDEFINED), m_xdes(), m_xdes_page_no(ULINT_UNDEFINED), - m_space_flags(ULINT_UNDEFINED), - m_table_flags(ULINT_UNDEFINED) UNIV_NOTHROW { } + m_space_flags(ULINT_UNDEFINED) UNIV_NOTHROW { } /** Free any extent descriptor instance */ @@ -535,10 +534,6 @@ protected: /** Flags value read from the header page */ ulint m_space_flags; - - /** Derived from m_space_flags and row format type, the row format - type is determined from the page header. */ - ulint m_table_flags; }; /** Determine the page size to use for traversing the tablespace @@ -553,6 +548,19 @@ AbstractCallback::init( const page_t* page = block->frame; m_space_flags = fsp_header_get_flags(page); + if (!fsp_flags_is_valid(m_space_flags)) { + ulint cflags = fsp_flags_convert_from_101(m_space_flags); + if (cflags == ULINT_UNDEFINED) { + ib_logf(IB_LOG_LEVEL_ERROR, + "Invalid FSP_SPACE_FLAGS=0x%x", + int(m_space_flags)); + return(DB_CORRUPTION); + } + m_space_flags = cflags; + } + + /* Clear the DATA_DIR flag, which is basically garbage. */ + m_space_flags &= ~(1U << FSP_FLAGS_POS_RESERVED); /* Since we don't know whether it is a compressed table or not, the data is always read into the block->frame. */ @@ -640,46 +648,6 @@ struct FetchIndexRootPages : public AbstractCallback { return(m_space); } - /** - Check if the .ibd file row format is the same as the table's. - @param ibd_table_flags - determined from space and page. - @return DB_SUCCESS or error code. */ - dberr_t check_row_format(ulint ibd_table_flags) UNIV_NOTHROW - { - dberr_t err; - rec_format_t ibd_rec_format; - rec_format_t table_rec_format; - - if (!dict_tf_is_valid(ibd_table_flags)) { - - ib_errf(m_trx->mysql_thd, IB_LOG_LEVEL_ERROR, - ER_TABLE_SCHEMA_MISMATCH, - ".ibd file has invlad table flags: %lx", - ibd_table_flags); - - return(DB_CORRUPTION); - } - - ibd_rec_format = dict_tf_get_rec_format(ibd_table_flags); - table_rec_format = dict_tf_get_rec_format(m_table->flags); - - if (table_rec_format != ibd_rec_format) { - - ib_errf(m_trx->mysql_thd, IB_LOG_LEVEL_ERROR, - ER_TABLE_SCHEMA_MISMATCH, - "Table has %s row format, .ibd " - "file has %s row format.", - dict_tf_to_row_format_string(m_table->flags), - dict_tf_to_row_format_string(ibd_table_flags)); - - err = DB_CORRUPTION; - } else { - err = DB_SUCCESS; - } - - return(err); - } - /** Called for each block as it is read from the file. @param offset - physical offset in the file @@ -743,12 +711,17 @@ FetchIndexRootPages::operator() ( m_indexes.push_back(Index(id, page_no)); if (m_indexes.size() == 1) { - - m_table_flags = dict_sys_tables_type_to_tf( - m_space_flags, - page_is_comp(page) ? DICT_N_COLS_COMPACT : 0); - - err = check_row_format(m_table_flags); + /* Check that the tablespace flags match the table flags. */ + ulint expected = dict_tf_to_fsp_flags(m_table->flags); + if (!fsp_flags_match(expected, m_space_flags)) { + ib_errf(m_trx->mysql_thd, IB_LOG_LEVEL_ERROR, + ER_TABLE_SCHEMA_MISMATCH, + "Expected FSP_SPACE_FLAGS=0x%x, .ibd " + "file contains 0x%x.", + unsigned(expected), + unsigned(m_space_flags)); + return(DB_CORRUPTION); + } } } @@ -1968,21 +1941,14 @@ PageConverter::update_header( "- ignored"); } - ulint space_flags = fsp_header_get_flags(get_frame(block)); - - if (!fsp_flags_is_valid(space_flags)) { - - ib_logf(IB_LOG_LEVEL_ERROR, - "Unsupported tablespace format %lu", - (ulong) space_flags); - - return(DB_UNSUPPORTED); - } - mach_write_to_8( get_frame(block) + FIL_PAGE_FILE_FLUSH_LSN_OR_KEY_VERSION, m_current_lsn); + /* Write back the adjusted flags. */ + mach_write_to_4(FSP_HEADER_OFFSET + FSP_SPACE_FLAGS + + get_frame(block), m_space_flags); + /* Write space_id to the tablespace header, page 0. */ mach_write_to_4( get_frame(block) + FSP_HEADER_OFFSET + FSP_SPACE_ID, diff --git a/storage/xtradb/row/row0mysql.cc b/storage/xtradb/row/row0mysql.cc index aff7b758249..c81b10b93f1 100644 --- a/storage/xtradb/row/row0mysql.cc +++ b/storage/xtradb/row/row0mysql.cc @@ -4362,6 +4362,7 @@ row_drop_table_for_mysql( switch (err) { ibool is_temp; + ulint table_flags; case DB_SUCCESS: /* Clone the name, in case it has been allocated @@ -4370,6 +4371,7 @@ row_drop_table_for_mysql( space_id = table->space; ibd_file_missing = table->ibd_file_missing; + table_flags = table->flags; is_temp = DICT_TF2_FLAG_IS_SET(table, DICT_TF2_TEMPORARY); /* If there is a temp path then the temp flag is set. @@ -4385,9 +4387,9 @@ row_drop_table_for_mysql( } /* We do not allow temporary tables with a remote path. */ - ut_a(!(is_temp && DICT_TF_HAS_DATA_DIR(table->flags))); + ut_a(!(is_temp && DICT_TF_HAS_DATA_DIR(table_flags))); - if (space_id && DICT_TF_HAS_DATA_DIR(table->flags)) { + if (space_id && DICT_TF_HAS_DATA_DIR(table_flags)) { dict_get_and_save_data_dir_path(table, true); ut_a(table->data_dir_path); @@ -4453,8 +4455,9 @@ row_drop_table_for_mysql( if (err == DB_SUCCESS && space_id > TRX_SYS_SPACE) { if (!is_temp && !fil_space_for_table_exists_in_mem( - space_id, tablename, FALSE, - print_msg, false, NULL, 0)) { + space_id, tablename, + print_msg, false, NULL, 0, + table_flags)) { /* This might happen if we are dropping a discarded tablespace */ err = DB_SUCCESS; diff --git a/storage/xtradb/srv/srv0start.cc b/storage/xtradb/srv/srv0start.cc index 77cdfe1affb..b933171e683 100644 --- a/storage/xtradb/srv/srv0start.cc +++ b/storage/xtradb/srv/srv0start.cc @@ -703,8 +703,7 @@ create_log_files( sprintf(logfilename + dirnamelen, "ib_logfile%u", INIT_LOG_FILE0); fil_space_create( - logfilename, SRV_LOG_SPACE_FIRST_ID, - fsp_flags_set_page_size(0, UNIV_PAGE_SIZE), + logfilename, SRV_LOG_SPACE_FIRST_ID, 0, FIL_LOG, NULL /* no encryption yet */, true /* this is create */); @@ -1193,7 +1192,7 @@ check_first_page: crypt_data = fil_space_create_crypt_data(FIL_SPACE_ENCRYPTION_DEFAULT, FIL_DEFAULT_ENCRYPTION_KEY); } - flags = fsp_flags_set_page_size(0, UNIV_PAGE_SIZE); + flags = FSP_FLAGS_PAGE_SSIZE(); fil_space_create(name, 0, flags, FIL_TABLESPACE, crypt_data, (*create_new_db) == true); @@ -1341,7 +1340,7 @@ srv_undo_tablespace_open( fil_set_max_space_id_if_bigger(space); /* Set the compressed page size to 0 (non-compressed) */ - flags = fsp_flags_set_page_size(0, UNIV_PAGE_SIZE); + flags = FSP_FLAGS_PAGE_SSIZE(); fil_space_create(name, space, flags, FIL_TABLESPACE, NULL /* no encryption */, true /* create */); @@ -2374,9 +2373,7 @@ innobase_start_or_create_for_mysql(void) sprintf(logfilename + dirnamelen, "ib_logfile%u", 0); fil_space_create(logfilename, - SRV_LOG_SPACE_FIRST_ID, - fsp_flags_set_page_size(0, UNIV_PAGE_SIZE), - FIL_LOG, + SRV_LOG_SPACE_FIRST_ID, 0, FIL_LOG, NULL /* no encryption yet */, true /* create */); @@ -2771,6 +2768,13 @@ files_checked: } if (!srv_read_only_mode) { + const ulint flags = FSP_FLAGS_PAGE_SSIZE(); + for (ulint id = 0; id <= srv_undo_tablespaces; id++) { + if (fil_space_get(id)) { + fsp_flags_try_adjust(id, flags); + } + } + /* Create the thread which watches the timeouts for lock waits */ thread_handles[2 + SRV_MAX_N_IO_THREADS] = os_thread_create( -- cgit v1.2.1 From 34c89d01d285f4e08de2bbb940e30cabffdf1548 Mon Sep 17 00:00:00 2001 From: Elena Stepanova Date: Mon, 16 Jan 2017 01:27:26 +0200 Subject: Updated list of unstable tests for 10.1.21 --- mysql-test/unstable-tests | 144 ++++++++++++++++++++++++++++------------------ 1 file changed, 89 insertions(+), 55 deletions(-) diff --git a/mysql-test/unstable-tests b/mysql-test/unstable-tests index 7b5c2756f11..42985e1d66d 100644 --- a/mysql-test/unstable-tests +++ b/mysql-test/unstable-tests @@ -23,66 +23,83 @@ # ############################################################################## -main.alter_table : Modified in 10.1.19 -main.analyze_stmt_slow_query_log : MDEV-7558 - wrong result -main.create : Modified in 10.1.20 +main.alter_table : Modified in 10.1.21 +main.alter_table_trans : MDEV-11805 - timeout +main.analyze_stmt_slow_query_log : Modified in 10.1.21 +main.cast : Modified in 10.1.21 +main.create : Modified in 10.1.21 main.create_delayed : MDEV-10605 - failed with timeout main.create_drop_binlog : Uses binlog_start_pos.inc modified in 10.1.20 -main.create_or_replace : Modified in 10.1.19 +main.ctype_ucs : Modified in 10.1.21 +main.ctype_ucs2_def : Modified in 10.1.21 +main.ctype_ucs2_query_cache : Modified in 10.1.21 +main.ctype_utf16 : Modified in 10.1.21 +main.ctype_utf16_def : Modified in 10.1.21 main.ctype_utf16le : MDEV-10675: timeout or extra warnings +main.ctype_utf32 : Modified in 10.1.21 main.ctype_utf8 : Modified in 10.1.20 main.ctype_utf8mb4 : Modified in 10.1.20 main.default : Modified in 10.1.20 main.derived : Modified in 10.1.20 main.derived_view : Modified in 10.1.20 -main.drop : Modified in 10.1.19 main.events_restart : MDEV-11221: assertion failure +main.events_slowlog : Added in 10.1.21 main.fulltext_charsets : Added in 10.1.20 -main.func_time : Modified in 10.1.20 +main.func_time : Modified in 10.1.21 main.group_by : Modified in 10.1.20 main.group_by_innodb : Modified in 10.1.20 main.host_cache_size_functionality : MDEV-10606 - sporadic failure on shutdown main.index_intersect_innodb : MDEV-10643 - failed with timeout -main.index_merge_innodb : MDEV-7142 - Wrong execution plan -main.information_schema : Modified in 10.1.19 +main.index_merge_innodb : MDEV-7142 - Wrong execution plan, also modified in 10.1.21 +main.information_schema_part : Modified in 10.1.21 main.innodb_mysql_lock : MDEV-7861 - sporadic lock detection failure +main.join_cache : Modified in 10.1.21 main.kill_processlist-6619 : MDEV-10793 - wrong result in processlist -main.loaddata : Modified in 10.1.20 +main.loaddata : Modified in 10.1.21 +main.log_slow : Modified in 10.1.21 main.lowercase_fs_on : Uses search_pattern_in_file.inc modified in 10.1.20 main.mdev-504 : MDEV-10607 - sporadic "can't connect" main.mdev375 : MDEV-10607 - sporadic "can't connect" main.merge : MDEV-10607 - sporadic "can't connect" -main.mysql : Modified in 10.1.19 -main.mysql_not_windows : Modified in 10.1.19 main.mysqlbinlog : Uses binlog_start_pos.inc modified in 10.1.20 main.mysqldump-max : Uses binlog_start_pos.inc modified in 10.1.20 -main.mysqldump-nl : Added in 10.1.19 -main.mysqltest : MDEV-9269 - fails on Alpha; also modified in 10.1.19 +main.mysqlslap : MDEV-11801 - timeout +main.mysqltest : MDEV-9269 - fails on Alpha main.named_pipe : Uses search_pattern_in_file.inc modified in 10.1.20 -main.null : Modified in 10.1.19 +main.order_by : Modified in 10.1.21 main.order_by_optimizer_innodb : MDEV-10683 - wrong execution plan main.parser : Modified in 10.1.20 -main.pool_of_threads : MDEV-10100 - sporadic error on detecting max connections +main.pool_of_threads : Modified in 10.1.21 main.ps : MDEV-11017 - sporadic wrong Prepared_stmt_count main.selectivity : Modified in 10.1.20 -main.selectivity_innodb : Modified in 10.1.19 main.show_explain : MDEV-10674 - sporadic failure -main.sp : Modified in 10.1.20 +main.signal_demo3 : MDEV-11720 - Thread stack overrun on labrador +main.sp : Modified in 10.1.21 +main.sp-prelocking : Modified in 10.1.21 main.sp-security : MDEV-10607 - sporadic "can't connect" main.stat_tables_par_innodb : MDEV-10515 - sporadic wrong results main.statistics : Modified in 10.1.20 main.status : MDEV-8510 - sporadic wrong result -main.subselect : Modified in 10.1.20 +main.subselect : Modified in 10.1.21 +main.subselect2 : Modified in 10.1.21 +main.subselect4 : Modified in 10.1.21 main.subselect_innodb : MDEV-10614 - sporadic wrong results +main.subselect_no_exists_to_in : Uses subselect.test modified in 10.1.21 +main.subselect_no_mat : Uses subselect.test modified in 10.1.21 +main.subselect_no_opts : Uses subselect.test modified in 10.1.21 +main.subselect_no_scache : Uses subselect.test modified in 10.1.21 +main.subselect_no_semijoin : Uses subselect.test modified in 10.1.21 +main.trigger_null-8605 : Modified in 10.1.21 main.type_datetime_hires : MDEV-10687 - timeout main.type_decimal : Modified in 10.1.20 -main.view : Uses search_pattern_in_file.inc modified in 10.1.20 +main.union : Modified in 10.1.21 +main.view : Modified in 10.1.21 main.wait_timeout_not_windows : Uses search_pattern_in_file.inc modified in 10.1.20 #---------------------------------------------------------------- archive.archive-big : MDEV-10615 - table is marked as crashed -archive.discover : MDEV-10510 - table is marked as crashed +archive.discover : MDEV-10510 - table is marked as crashed; modified in 10.1.21 #---------------------------------------------------------------- @@ -101,6 +118,8 @@ binlog_encryption.* : Added in 10.1.20 #---------------------------------------------------------------- +connect.jdbc : Modified in 10.1.21 +connect.jdbc_new : Modified in 10.1.21 connect.tbl : MDEV-9844, MDEV-10179 - sporadic crashes, valgrind warnings, wrong results #---------------------------------------------------------------- @@ -115,27 +134,28 @@ encryption.filekeys_nofile : Uses search_pattern_in_file.inc mo encryption.filekeys_syntax : Uses search_pattern_in_file.inc modified in 10.1.20 encryption.filekeys_tooshort : Uses search_pattern_in_file.inc modified in 10.1.20 encryption.filekeys_unencfile : Uses search_pattern_in_file.inc modified in 10.1.20 -encryption.innodb-bad-key-change : uses keys2.txt modified in 10.1.19 -encryption.innodb-bad-key-change2 : uses keys2.txt modified in 10.1.19 -encryption.innodb-bad-key-change3 : Uses search_pattern_in_file.inc modified in 10.1.20 -encryption.innodb-bad-key-change4 : uses keys2.txt modified in 10.1.19 -encryption.innodb-bad-key-change5 : uses keys2.txt modified in 10.1.19 -encryption.innodb-bad-key-shutdown : MDEV-9105 - valgrind warnings, assertion failures, and uses keys2.txt modified in 10.1.19 -encryption.innodb-discard-import : Uses search_pattern_in_file.inc modified in 10.1.20 -encryption.innodb_encryption_discard_import : MDEV-11218 - wrong result, also uses search_pattern_in_file.inc modified in 10.1.20 +encryption.innodb-bad-key-change3 : Modified in 10.1.21 +encryption.innodb-bad-key-shutdown : MDEV-9105 - valgrind warnings, assertion failures +encryption.innodb-discard-import : Modified in 10.1.21 +encryption.innodb-discard-import-change : Modified in 10.1.21 +encryption.innodb_encryption_discard_import : MDEV-11218 - wrong result, also modified in 10.1.21 encryption.innodb_encryption_filekeys : MDEV-9962 - timeouts +encryption.innodb_encryption-page-compression : MDEV-11420 - Trying to access missing tablespace encryption.innodb_encryption_row_compressed : Uses search_pattern_in_file.inc modified in 10.1.20 encryption.innodb_first_page : MDEV-10689 - crashes -encryption.innodb-log-encrypt : Uses search_pattern_in_file.inc modified in 10.1.20 -encryption.innodb_lotoftables : MDEV-11531 - InnoDB error -encryption.innodb-missing-key : Added in 10.1.19 +encryption.innodb-log-encrypt : Modified in 10.1.21 +encryption.innodb_lotoftables : MDEV-11531 - InnoDB error, also modified in 10.1.21 +encryption.innodb-missing-key : MDEV-9359 - assertion failure encryption.innodb_onlinealter_encryption : MDEV-10099 - wrong results; also uses search_pattern_in_file.inc modified in 10.1.20 encryption.innodb-page_encryption : MDEV-10641 - mutex problem -encryption.innodb_page_encryption_key_change : uses keys2.txt modified in 10.1.19 +encryption.innodb_scrub : MDEV-8139, also was modified in 10.1.21 +encryption.innodb_scrub_background : MDEV_8139, also was modified in 10.1.21 +encryption.innodb_scrub_compressed : MDEV-8139; also was modified and re-enabled in 10.1.21 #---------------------------------------------------------------- -extra/binlog_tests.database : Modified in 10.1.19 (merge) +engines/iuds.* : Not maintained in timely manner +engines/funcs.* : Not maintained in timely manner #---------------------------------------------------------------- @@ -147,51 +167,57 @@ federated.federated_transactions : MDEV-10617, MDEV-10417 - Wrong checksum, time #---------------------------------------------------------------- funcs_1.processlist_val_no_prot : MDEV-11223 - Wrong result + +funcs_2.innodb_charset : Modified in 10.1.21 funcs_2.memory_charset : MDEV-10290 - Timeout funcs_2.myisam_charset : MDEV-11535 - Timeout #---------------------------------------------------------------- -galera.* : Added to default suites in 10.1.19 - -galera.galera_var_dirty_reads : Modified in 10.1.20 +galera.galera_var_cluster_address : Modified in 10.1.21 +galera.galera_var_dirty_reads : Modified in 10.1.21 +galera.MW-284 : Modified in 10.1.21 galera.rpl_row_annotate : Uses binlog_start_pos.inc modified in 10.1.20 +galera_split_brain : Modified in 10.1.21 -galera_3nodes.* : Added to default suites in 10.1.19, MDEV-11490 +galera_3nodes.* : MDEV-11490 - Warnings not suppressed #---------------------------------------------------------------- +innodb.101_compatibility : Added in 10.1.21 innodb.binlog_consistent : MDEV-10618 - Server fails to start; also uses binlog_start_pos.inc modified in 10.1.20 +innodb.doublewrite : Added in 10.1.21 innodb.group_commit_binlog_pos : Uses binlog_start_pos.inc modified in 10.1.20 innodb.group_commit_binlog_pos_no_optimize_thread : Uses binlog_start_pos.inc modified in 10.1.20 +innodb.group_commit_crash : Modified in 10.1.21 +innodb.group_commit_crash_no_optimize_thread : Modified in 10.1.21 innodb.innodb-alter-table : MDEV-10619 - Testcase timeout -innodb.innodb-bug-14068765 : MDEV-9105 - valgrind warnings, assertion failures, also uses innodb-util.pl added in 10.1.19 -innodb.innodb-bug-14084530 : MDEV-9105 - valgrind warnings, assertion failures, also uses innodb-util.pl added in 10.1.19 +innodb.innodb-bug-14068765 : MDEV-9105 - valgrind warnings, assertion failures +innodb.innodb-bug-14084530 : MDEV-9105 - valgrind warnings, assertion failures +innodb.innodb_bug14147491 : MDEV-11808, also modified in 10.1.21 +innodb.innodb_bug14676111 : MDEV-11802 - wrong result innodb.innodb_bug30423 : MDEV-7311 - Wrong number of rows in the plan -innodb.innodb-change-buffer-recovery : Uses search_pattern_in_file.inc modified in 10.1.20 +innodb.innodb-change-buffer-recovery : Modified in 10.1.21 innodb.innodb_defragment_fill_factor : Modified in 10.1.20 innodb.innodb-lock-schedule-algorithm : Modified in 10.1.20 innodb.innodb-page_compression_zip : MDEV-10641 - mutex problem innodb.innodb_stats : MDEV-10682 - wrong result innodb.innodb_sys_semaphore_waits : MDEV-10331 - wrong result -innodb.innodb-wl5522 : MDEV-9105 - valgrind warnings, assertion failures, also uses innodb-util.pl added in 10.1.19 -innodb.innodb-wl5522-1 : MDEV-9105 - valgrind warnings, assertion failures, also uses innodb-util.pl added in 10.1.19 -innodb.innodb-wl5522-debug : Modified in 10.1.19 -innodb.innodb-wl5522-debug-zip : Modified in 10.1.20 -innodb.innodb-wl5522-zip : MDEV-9105 - valgrind warnings, assertion failures, also uses innodb-util.pl added in 10.1.19 +innodb.innodb-wl5522 : MDEV-9105 - valgrind warnings, assertion failures +innodb.innodb-wl5522-1 : MDEV-9105 - valgrind warnings, assertion failures +innodb.innodb-wl5522-debug-zip : Modified in 10.1.21 +innodb.log_data_file_size : Added in 10.1.21 innodb.table_index_statistics : Added in 10.1.20 innodb.trigger : Modified in 10.1.20 -innodb.xa_recovery : Modified in 10.1.19 +innodb.xa_recovery : Modified in 10.1.21 #---------------------------------------------------------------- innodb_fts.create : Added in 10.1.20 -innodb_fts.innodb_fts_misc : MDEV-11233 - Crash on CREATE FULLTEXT INDEX #---------------------------------------------------------------- maria.collations : Added in 10.1.20 -maria.encrypt-wrong-key : uses keys2.txt modified in 10.1.19 maria.maria-connect : Uses binlog_start_pos.inc modified in 10.1.20 #---------------------------------------------------------------- @@ -225,24 +251,26 @@ perfschema.func_file_io : MDEV-5708 - fails for s390x perfschema.func_mutex : MDEV-5708 - fails for s390x perfschema.setup_actors : MDEV-10679 - rare crash perfschema.socket_summary_by_event_name_func : MDEV-10622 - Socket summary tables do not match +perfschema.stage_mdl_global : MDEV-11803 - wrong result on slow builders perfschema.threads_mysql : MDEV-10677 - sporadic wrong result #---------------------------------------------------------------- +plugins.cracklib_password_check : MDEV-11650 - valgrind warnings plugins.feedback_plugin_send : MDEV-7932 - ssl failed for url plugins.server_audit : MDEV-9562 - crashes on sol10-sparc plugins.thread_pool_server_audit : MDEV-9562 - crashes on sol10-sparc - +plugins.two_password_validations : MDEV-11650 - valgrind warnings #---------------------------------------------------------------- roles.role_case_sensitive-10744 : Added in 10.1.20 roles.create_and_drop_role : Modified in 10.1.20 -roles.create_and_grant_role : MDEV-11533 - Extra grant in output #---------------------------------------------------------------- rpl.last_insert_id : MDEV-10625 - warnings in error log +rpl.rpl_alter_extra_persistent : Added in 10.1.21 rpl.rpl_auto_increment : MDEV-10417 - Fails on Mips rpl.rpl_auto_increment_bug45679 : MDEV-10417 - Fails on Mips rpl.rpl_auto_increment_update_failure : MDEV-10625 - warnings in error log @@ -252,7 +280,6 @@ rpl.rpl_checksum_cache : MDEV-10626 - Testcase timeout rpl.rpl_circular_for_4_hosts : MDEV-10627 - Testcase timeout rpl.rpl_ddl : MDEV-10417 - Fails on Mips rpl.rpl_domain_id_filter_restart : MDEV-10684 - Wrong result -rpl.rpl_drop_db : Modified in 10.1.19 rpl.rpl_gtid_basic : MDEV-10681 - server startup problem rpl.rpl_gtid_crash : MDEV-9501 - Warning: failed registering on master rpl.rpl_gtid_errorlog : Uses search_pattern_in_file.inc modified in 10.1.20 @@ -260,6 +287,7 @@ rpl.rpl_gtid_master_promote : MDEV-10628 - Timeout in sync_with_master rpl.rpl_gtid_mdev9033 : MDEV-10680 - warnings rpl.rpl_gtid_stop_start : MDEV-10629 - Crash on shutdown rpl.rpl_gtid_until : MDEV-10625 - warnings in error log +rpl.rpl_heartbeat_basic : MDEV-11668 - wrong result rpl.rpl_innodb_bug30888 : MDEV-10417 - Fails on Mips rpl.rpl_insert : MDEV-9329 - Fails on Ubuntu/s390x rpl.rpl_insert_delayed : MDEV-9329 - Fails on Ubuntu/s390x @@ -278,17 +306,21 @@ rpl.rpl_password_boundaries : MDEV-11534 - Slave IO warnings rpl.rpl_row_drop_create_temp_table : MDEV-10626 - Testcase timeout rpl.rpl_row_flsh_tbls : Uses binlog_start_pos.inc modified in 10.1.20 rpl.rpl_row_log_innodb : MDEV-10688 - Wrong result +rpl.rpl_row_mysqlbinlog : Modified in 10.1.21 rpl.rpl_row_sp001 : MDEV-9329 - Fails on Ubuntu/s390x rpl.rpl_semi_sync : MDEV-11220 - Wrong result +rpl.rpl_semi_sync_event_after_sync : MDEV-11806 - warnings rpl.rpl_semi_sync_uninstall_plugin : MDEV-7140 - Wrong plugin status +rpl.rpl_semi_sync_wait_point : MDEV-11807 - timeout in wait condition rpl.rpl_show_slave_hosts : MDEV-10681 - server startup problem rpl.rpl_skip_replication : MDEV-9268 - Fails with timeout in sync_slave_with_master on Alpha rpl.rpl_slave_grp_exec : MDEV-10514 - Unexpected deadlock +rpl.rpl_special_charset : Modified in 10.1.21 rpl.rpl_stm_flsh_tbls : Uses binlog_start_pos.inc modified in 10.1.20 rpl.rpl_stop_slave_error : Uses search_pattern_in_file.inc modified in 10.1.20 rpl.rpl_sync : MDEV-10633 - Database page corruption rpl.rpl_temporary_error2 : MDEV-10634 - Wrong number of retries -rpl.sec_behind_master-5114 : MDEV-8518 - Wrong value of Seconds_Behind_Master +rpl.sec_behind_master-5114 : Modified in 10.1.21 #---------------------------------------------------------------- @@ -301,9 +333,11 @@ spider/bg.ha_part : MDEV-9329 - Fails on Ubuntu/s390x spider/bg.spider_fixes : MDEV-7098, MDEV-9329 - Mutex problem, failures on s390x spider/bg.vp_fixes : MDEV-9329 - Fails on Ubuntu/s390x +spider/handler.* : MDEV-10987, MDEV-10990 - Tests have not been maintained + #---------------------------------------------------------------- -sphinx.* : MDEV-10985, MDEV-10986 - Tests have not been maintained +sphinx.* : MDEV-10986 - Tests have not been maintained #---------------------------------------------------------------- @@ -325,6 +359,7 @@ sys_vars.replicate_ignore_db_basic : Modified in 10.1.20 sys_vars.replicate_ignore_table_basic : Modified in 10.1.20 sys_vars.replicate_wild_do_table_basic : Modified in 10.1.20 sys_vars.replicate_wild_ignore_table_basic : Modified in 10.1.20 +sys_vars.rpl_init_slave_func : MDEV-10149 - wrong results sys_vars.sysvars_innodb : MDEV-6958 - error-prone rdiffs sys_vars.sysvars_server_embedded : MDEV-6958 - error-prone rdiffs sys_vars.table_open_cache_instances_basic : Modified in 10.1.20 @@ -339,6 +374,7 @@ tokudb.table_index_statistics : Added in 10.1.20 tokudb_bugs.checkpoint_lock : MDEV-10637 - Wrong processlist output tokudb_bugs.checkpoint_lock_3 : MDEV-10637 - Wrong processlist output +tokudb_bugs.xa : MDEV-11804 - Lock wait timeout tokudb_rpl.rpl_parallel_optimistic : Added in 10.1.20 tokudb_rpl.rpl_tokudb_rfr_partition_table : Added in 10.1.20 @@ -355,9 +391,7 @@ vcol.vcol_keys_innodb : MDEV-10639 - Testcase timeout #---------------------------------------------------------------- wsrep.binlog_format : MDEV-11532 - WSREP has not yet prepared node -wsrep.mdev_10186 : Modified in 10.1.19 #---------------------------------------------------------------- -wsrep_info.* : suite.pm modified in 10.1.19 wsrep_info.plugin : MDEV-11530 - Warnings; also modified in 10.1.20 -- cgit v1.2.1 From 3a91dec1243773627d08965e7e258571a7844deb Mon Sep 17 00:00:00 2001 From: Elena Stepanova Date: Mon, 16 Jan 2017 02:36:31 +0200 Subject: 101_compatibility test fails on CentOS 5 Apparently, in older versions of Perl unpack does not have a logic for using $_ as a default value for the second argument. Fixed by specifying it explicitly --- mysql-test/suite/innodb/include/ibd_convert.pl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mysql-test/suite/innodb/include/ibd_convert.pl b/mysql-test/suite/innodb/include/ibd_convert.pl index aba742ac649..32eef96fd23 100644 --- a/mysql-test/suite/innodb/include/ibd_convert.pl +++ b/mysql-test/suite/innodb/include/ibd_convert.pl @@ -10,7 +10,7 @@ sub convert_to_mariadb_101 sysseek(FILE, 0, 0)||die "Unable to seek $file\n"; # FIL_PAGE_DATA + FSP_SPACE_FLAGS = 38 + 16 = 54 bytes from the start - my($flags) = unpack "x[54]N"; + my($flags) = unpack "x[54]N", $_; my $badflags = ($flags & 0x3f); my $compression_level=6; $badflags |= 1<<6|$compression_level<<7 if ($flags & 1 << 16); -- cgit v1.2.1 From 7e3f3deb41a875778a540718abd8f90278e4cb67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 16 Jan 2017 09:15:56 +0200 Subject: MDEV-11623 follow-up: Adjust tests. innodb.doublewrite: Similar to what was done to innodb.101_compatibility, add an explicit $_ parameter to the Perl unpack function. Also, fix some diagnostic messages in the Perl code. innodb.innodb-wl5522-debug: Adjust for the changed error codes and messages on fault injection. --- mysql-test/suite/innodb/r/innodb-wl5522-debug.result | 3 ++- mysql-test/suite/innodb/t/doublewrite.test | 10 +++++----- mysql-test/suite/innodb/t/innodb-wl5522-debug.test | 1 + 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/mysql-test/suite/innodb/r/innodb-wl5522-debug.result b/mysql-test/suite/innodb/r/innodb-wl5522-debug.result index ee8bd22c58f..031f382401f 100644 --- a/mysql-test/suite/innodb/r/innodb-wl5522-debug.result +++ b/mysql-test/suite/innodb/r/innodb-wl5522-debug.result @@ -1,4 +1,5 @@ call mtr.add_suppression("InnoDB: Page for tablespace .* "); +call mtr.add_suppression("InnoDB: Invalid FSP_SPACE_FLAGS="); FLUSH TABLES; SET GLOBAL innodb_file_per_table = 1; SELECT @@innodb_file_per_table; @@ -912,7 +913,7 @@ ERROR HY000: Tablespace has been discarded for table 't1' 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 +ERROR HY000: Internal error: Cannot reset LSNs in table '"test_wl5522"."t1"' : Data structure corruption SET SESSION debug_dbug="-d,fsp_flags_is_valid_failure"; DROP TABLE test_wl5522.t1; unlink: t1.ibd diff --git a/mysql-test/suite/innodb/t/doublewrite.test b/mysql-test/suite/innodb/t/doublewrite.test index 245b4e1a676..6e0a4a70200 100644 --- a/mysql-test/suite/innodb/t/doublewrite.test +++ b/mysql-test/suite/innodb/t/doublewrite.test @@ -74,15 +74,15 @@ my $fname= "$ENV{'MYSQLD_DATADIR'}test/t1.ibd"; my $page_size = $ENV{INNODB_PAGE_SIZE}; my $page; open(FILE, "+<", $fname) or die; -sysread(FILE, $page, $page_size)==$page_size||die "Unable to read $file\n"; -sysseek(FILE, 0, 0)||die "Unable to seek $file\n"; +sysread(FILE, $page, $page_size)==$page_size||die "Unable to read $name\n"; +sysseek(FILE, 0, 0)||die "Unable to seek $fname\n"; die unless syswrite(FILE, chr(0) x $page_size, $page_size) == $page_size; close FILE; open(FILE, "+<", "$ENV{MYSQLD_DATADIR}ibdata1")||die "cannot open ibdata1\n"; sysseek(FILE, 6 * $page_size - 190, 0)||die "Unable to seek ibdata1\n"; sysread(FILE, $_, 12) == 12||die "Unable to read TRX_SYS\n"; -my($magic,$d1,$d2)=unpack "NNN"; +my($magic,$d1,$d2)=unpack "NNN", $_; die "magic=$magic, $d1, $d2\n" unless $magic == 536853855 && $d2 >= $d1 + 64; sysseek(FILE, $d1 * $page_size, 0)||die "Unable to seek ibdata1\n"; # Find the page in the doublewrite buffer @@ -92,7 +92,7 @@ for (my $d = $d1; $d < $d2 + 64; $d++) next unless $_ eq $page; sysseek(FILE, $d * $page_size, 0)||die "Unable to seek ibdata1\n"; # Write buggy MariaDB 10.1.x FSP_SPACE_FLAGS to the doublewrite buffer - my($flags) = unpack "x[54]N"; + my($flags) = unpack "x[54]N", $_; my $badflags = ($flags & 0x3f); my $compression_level=6; $badflags |= 1<<6|$compression_level<<7 if ($flags & 1 << 16); @@ -102,7 +102,7 @@ for (my $d = $d1; $d < $d2 + 64; $d++) # Replace the innodb_checksum_algorithm=none checksum substr ($_, 0, 4) = pack("N", 0xdeadbeef); substr ($_, $page_size - 8, 4) = pack("N", 0xdeadbeef); - syswrite(FILE, $_, $page_size)==$page_size||die "Unable to write $file\n"; + syswrite(FILE, $_, $page_size)==$page_size||die; close(FILE); exit 0; } diff --git a/mysql-test/suite/innodb/t/innodb-wl5522-debug.test b/mysql-test/suite/innodb/t/innodb-wl5522-debug.test index e8a037ab2f1..6c94f408ae9 100644 --- a/mysql-test/suite/innodb/t/innodb-wl5522-debug.test +++ b/mysql-test/suite/innodb/t/innodb-wl5522-debug.test @@ -16,6 +16,7 @@ -- source include/have_innodb.inc call mtr.add_suppression("InnoDB: Page for tablespace .* "); +call mtr.add_suppression("InnoDB: Invalid FSP_SPACE_FLAGS="); FLUSH TABLES; let MYSQLD_DATADIR =`SELECT @@datadir`; -- cgit v1.2.1 From 03497129371fe2c16d847b7e83a5eeecab9c34a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marko=20M=C3=A4kel=C3=A4?= Date: Mon, 16 Jan 2017 18:26:14 +0200 Subject: MDEV-11623 follow-up: Adjust one more test. The function fsp_flags_try_adjust(), which is called on startup, is incrementing the Innodb_pages0_read counts for every affected file. Adjust the result of encryption.innodb_lotoftables accordingly. --- .../suite/encryption/r/innodb_lotoftables.result | 28 +++++++++++----------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/mysql-test/suite/encryption/r/innodb_lotoftables.result b/mysql-test/suite/encryption/r/innodb_lotoftables.result index b7cfdd2db9d..418ab175a01 100644 --- a/mysql-test/suite/encryption/r/innodb_lotoftables.result +++ b/mysql-test/suite/encryption/r/innodb_lotoftables.result @@ -12,13 +12,13 @@ create database innodb_encrypted_1; use innodb_encrypted_1; show status like 'innodb_pages0_read%'; Variable_name Value -Innodb_pages0_read 1 +Innodb_pages0_read 3 set autocommit=0; set autocommit=1; commit work; show status like 'innodb_pages0_read%'; Variable_name Value -Innodb_pages0_read 1 +Innodb_pages0_read 3 # should be 100 SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE NAME LIKE 'innodb_encrypted%'; COUNT(*) @@ -88,47 +88,47 @@ Innodb_pages0_read 3 # Restart Success! show status like 'innodb_pages0_read%'; Variable_name Value -Innodb_pages0_read 1 +Innodb_pages0_read 303 show status like 'innodb_pages0_read%'; Variable_name Value -Innodb_pages0_read 1 +Innodb_pages0_read 303 use test; show status like 'innodb_pages0_read%'; Variable_name Value -Innodb_pages0_read 1 +Innodb_pages0_read 303 use innodb_encrypted_1; show status like 'innodb_pages0_read%'; Variable_name Value -Innodb_pages0_read 1 +Innodb_pages0_read 303 use innodb_encrypted_2; show status like 'innodb_pages0_read%'; Variable_name Value -Innodb_pages0_read 1 +Innodb_pages0_read 303 use innodb_encrypted_3; show status like 'innodb_pages0_read%'; Variable_name Value -Innodb_pages0_read 1 +Innodb_pages0_read 303 use innodb_encrypted_1; show status like 'innodb_pages0_read%'; Variable_name Value -Innodb_pages0_read 1 +Innodb_pages0_read 303 show status like 'innodb_pages0_read%'; Variable_name Value -Innodb_pages0_read 101 +Innodb_pages0_read 303 use innodb_encrypted_2; show status like 'innodb_pages0_read%'; Variable_name Value -Innodb_pages0_read 101 +Innodb_pages0_read 303 show status like 'innodb_pages0_read%'; Variable_name Value -Innodb_pages0_read 201 +Innodb_pages0_read 303 use innodb_encrypted_3; show status like 'innodb_pages0_read%'; Variable_name Value -Innodb_pages0_read 201 +Innodb_pages0_read 303 show status like 'innodb_pages0_read%'; Variable_name Value -Innodb_pages0_read 301 +Innodb_pages0_read 303 SELECT COUNT(*) FROM INFORMATION_SCHEMA.INNODB_TABLESPACES_ENCRYPTION WHERE MIN_KEY_VERSION = 0 AND NAME LIKE 'innodb_encrypted%'; COUNT(*) 100 -- cgit v1.2.1