summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMonty <monty@mariadb.org>2017-11-09 23:21:41 +0200
committerMonty <monty@mariadb.org>2017-11-09 23:21:41 +0200
commit0bb0d52221af99c46d17486382806caa6dd7338e (patch)
tree92b2ddfceaf8df5be6d47774b25fd3006ac5bb35
parent7dbff2c513aeec3b3f3d0fa4952ae97deba22282 (diff)
parentd40c23570ff1a9ba5aa317b85a32a4b27780b8ab (diff)
downloadmariadb-git-0bb0d52221af99c46d17486382806caa6dd7338e.tar.gz
Merge remote-tracking branch 'origin/10.2' into bb-10.2-ext
Conflicts: mysql-test/r/cte_recursive.result mysql-test/r/derived_cond_pushdown.result mysql-test/t/cte_recursive.test mysql-test/t/derived_cond_pushdown.test sql/datadict.cc sql/handler.cc
-rw-r--r--client/mysql.cc2
-rw-r--r--extra/mariabackup/backup_copy.cc35
-rw-r--r--extra/mariabackup/xtrabackup.cc2
-rw-r--r--mysql-test/include/check-testcase.test2
-rw-r--r--mysql-test/r/cte_nonrecursive.result68
-rw-r--r--mysql-test/r/cte_recursive.result22
-rw-r--r--mysql-test/r/delimiter_command_case_sensitivity.result2
-rw-r--r--mysql-test/r/derived_cond_pushdown.result41
-rw-r--r--mysql-test/r/func_misc.result14
-rw-r--r--mysql-test/r/subselect_exists2in.result37
-rw-r--r--mysql-test/r/type_bit.result24
-rw-r--r--mysql-test/r/type_date.result11
-rw-r--r--mysql-test/r/type_time.result14
-rw-r--r--mysql-test/suite/mariabackup/data_directory.result13
-rw-r--r--mysql-test/suite/mariabackup/data_directory.test23
-rw-r--r--mysql-test/suite/mariabackup/incremental_backup.result13
-rw-r--r--mysql-test/suite/mariabackup/incremental_backup.test13
-rw-r--r--mysql-test/suite/mariabackup/partition_datadir.opt1
-rw-r--r--mysql-test/suite/mariabackup/partition_datadir.result22
-rw-r--r--mysql-test/suite/mariabackup/partition_datadir.test24
-rw-r--r--mysql-test/suite/plugins/r/server_audit.result9
-rw-r--r--mysql-test/suite/plugins/r/thread_pool_server_audit.result9
-rw-r--r--mysql-test/suite/plugins/t/server_audit.test5
-rw-r--r--mysql-test/suite/plugins/t/thread_pool_server_audit.test5
-rw-r--r--mysql-test/suite/sys_vars/r/innodb_buffer_pool_dump_now_basic.result7
-rw-r--r--mysql-test/suite/sys_vars/r/innodb_buffer_pool_dump_pct_basic.result6
-rw-r--r--mysql-test/suite/sys_vars/r/innodb_buffer_pool_load_now_basic.result6
-rw-r--r--mysql-test/suite/sys_vars/t/innodb_buffer_pool_dump_now_basic.test31
-rw-r--r--mysql-test/suite/sys_vars/t/innodb_buffer_pool_dump_pct_basic.test12
-rw-r--r--mysql-test/suite/sys_vars/t/innodb_buffer_pool_load_now_basic.opt1
-rw-r--r--mysql-test/suite/sys_vars/t/innodb_buffer_pool_load_now_basic.test46
-rw-r--r--mysql-test/t/cte_nonrecursive.test47
-rw-r--r--mysql-test/t/cte_recursive.test20
-rw-r--r--mysql-test/t/delimiter_case_mdev_10728.sql3
-rw-r--r--mysql-test/t/delimiter_command_case_sensitivity.test4
-rw-r--r--mysql-test/t/derived_cond_pushdown.test18
-rw-r--r--mysql-test/t/func_misc.test17
-rw-r--r--mysql-test/t/show_check.test4
-rw-r--r--mysql-test/t/subselect_exists2in.test40
-rw-r--r--mysql-test/t/type_bit.test19
-rw-r--r--mysql-test/t/type_date.test9
-rw-r--r--mysql-test/t/type_time.test11
-rw-r--r--mysql-test/t/view.test1
-rw-r--r--plugin/server_audit/server_audit.c41
-rw-r--r--sql/datadict.cc20
-rw-r--r--sql/handler.cc7
-rw-r--r--sql/item.cc25
-rw-r--r--sql/item.h25
-rw-r--r--sql/item_cmpfunc.cc25
-rw-r--r--sql/item_cmpfunc.h10
-rw-r--r--sql/item_func.cc5
-rw-r--r--sql/item_func.h9
-rw-r--r--sql/item_inetfunc.cc7
-rw-r--r--sql/item_inetfunc.h6
-rw-r--r--sql/item_row.cc5
-rw-r--r--sql/item_row.h2
-rw-r--r--sql/item_strfunc.h6
-rw-r--r--sql/item_subselect.cc15
-rw-r--r--sql/item_subselect.h4
-rw-r--r--sql/item_sum.cc12
-rw-r--r--sql/item_sum.h1
-rw-r--r--sql/opt_subselect.cc9
-rw-r--r--sql/sql_cte.cc22
-rw-r--r--sql/sql_derived.cc6
-rw-r--r--storage/innobase/buf/buf0buf.cc67
-rw-r--r--storage/innobase/buf/buf0flu.cc24
-rw-r--r--storage/innobase/buf/buf0lru.cc271
-rw-r--r--storage/innobase/dict/dict0dict.cc2
-rw-r--r--storage/innobase/fil/fil0fil.cc54
-rw-r--r--storage/innobase/handler/ha_innodb.cc5
-rw-r--r--storage/innobase/ibuf/ibuf0ibuf.cc30
-rw-r--r--storage/innobase/include/buf0buf.h1
-rw-r--r--storage/innobase/include/buf0lru.h18
-rw-r--r--storage/innobase/include/buf0types.h11
-rw-r--r--storage/innobase/include/fil0fil.h15
-rw-r--r--storage/innobase/row/row0import.cc27
-rw-r--r--storage/innobase/row/row0mysql.cc11
-rw-r--r--storage/innobase/row/row0quiesce.cc4
-rw-r--r--storage/innobase/srv/srv0start.cc9
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/r/read_only_tx.result14
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace_crash.test10
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/disabled.def2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/read_only_tx-master.opt2
-rw-r--r--storage/rocksdb/mysql-test/rocksdb/t/read_only_tx.test8
-rw-r--r--storage/xtradb/buf/buf0buf.cc58
-rw-r--r--storage/xtradb/buf/buf0lru.cc297
-rw-r--r--storage/xtradb/dict/dict0dict.cc2
-rw-r--r--storage/xtradb/fil/fil0fil.cc24
-rw-r--r--storage/xtradb/handler/ha_innodb.cc7
-rw-r--r--storage/xtradb/ibuf/ibuf0ibuf.cc16
-rw-r--r--storage/xtradb/include/buf0buf.h1
-rw-r--r--storage/xtradb/include/buf0lru.h18
-rw-r--r--storage/xtradb/include/buf0types.h11
-rw-r--r--storage/xtradb/include/fil0fil.h15
-rw-r--r--storage/xtradb/lock/lock0lock.cc2
-rw-r--r--storage/xtradb/os/os0file.cc29
-rw-r--r--storage/xtradb/row/row0import.cc27
-rw-r--r--storage/xtradb/row/row0mysql.cc12
-rw-r--r--storage/xtradb/row/row0quiesce.cc4
-rw-r--r--storage/xtradb/trx/trx0undo.cc1
100 files changed, 1187 insertions, 897 deletions
diff --git a/client/mysql.cc b/client/mysql.cc
index 5fe940eeca7..50114ee8b65 100644
--- a/client/mysql.cc
+++ b/client/mysql.cc
@@ -1094,7 +1094,7 @@ inline bool is_delimiter_command(char *name, ulong len)
only name(first DELIMITER_NAME_LEN bytes) is checked.
*/
return (len >= DELIMITER_NAME_LEN &&
- !my_strnncoll(charset_info, (uchar*) name, DELIMITER_NAME_LEN,
+ !my_strnncoll(&my_charset_latin1, (uchar*) name, DELIMITER_NAME_LEN,
(uchar *) DELIMITER_NAME, DELIMITER_NAME_LEN));
}
diff --git a/extra/mariabackup/backup_copy.cc b/extra/mariabackup/backup_copy.cc
index bc37f347532..0b501970efa 100644
--- a/extra/mariabackup/backup_copy.cc
+++ b/extra/mariabackup/backup_copy.cc
@@ -46,6 +46,7 @@ Place, Suite 330, Boston, MA 02111-1307 USA
#include <ut0mem.h>
#include <srv0start.h>
#include <fil0fil.h>
+#include <trx0sys.h>
#include <set>
#include <string>
#include <mysqld.h>
@@ -1680,26 +1681,30 @@ copy_back()
ut_crc32_init();
/* copy undo tablespaces */
- if (srv_undo_tablespaces > 0) {
- dst_dir = (srv_undo_dir && *srv_undo_dir)
- ? srv_undo_dir : mysql_data_home;
- ds_data = ds_create(dst_dir, DS_TYPE_LOCAL);
+ dst_dir = (srv_undo_dir && *srv_undo_dir)
+ ? srv_undo_dir : mysql_data_home;
- for (ulong i = 1; i <= srv_undo_tablespaces; i++) {
- char filename[20];
- sprintf(filename, "undo%03lu", i);
- if (!(ret = copy_or_move_file(filename, filename,
- dst_dir, 1))) {
- goto cleanup;
- }
- }
+ ds_data = ds_create(dst_dir, DS_TYPE_LOCAL);
- ds_destroy(ds_data);
- ds_data = NULL;
+ for (uint i = 1; i <= TRX_SYS_MAX_UNDO_SPACES; i++) {
+ char filename[20];
+ sprintf(filename, "undo%03u", i);
+ if (!file_exists(filename)) {
+ break;
+ }
+ if (!(ret = copy_or_move_file(filename, filename,
+ dst_dir, 1))) {
+ goto cleanup;
+ }
}
+ ds_destroy(ds_data);
+ ds_data = NULL;
+
+ /* copy redo logs */
+
dst_dir = (srv_log_group_home_dir && *srv_log_group_home_dir)
? srv_log_group_home_dir : mysql_data_home;
@@ -1825,7 +1830,7 @@ copy_back()
}
}
- /* copy buufer pool dump */
+ /* copy buffer pool dump */
if (innobase_buffer_pool_filename) {
const char *src_name;
diff --git a/extra/mariabackup/xtrabackup.cc b/extra/mariabackup/xtrabackup.cc
index a6bc4dab552..de32b5b864f 100644
--- a/extra/mariabackup/xtrabackup.cc
+++ b/extra/mariabackup/xtrabackup.cc
@@ -2838,7 +2838,7 @@ static dberr_t enumerate_ibd_files(process_single_tablespace_func_t callback)
/* We found a symlink or a file */
if (strlen(fileinfo.name) > 4) {
bool is_isl= false;
- if (ends_with(fileinfo.name, ".ibd") || ((is_isl = ends_with(fileinfo.name, ".ibd"))))
+ if (ends_with(fileinfo.name, ".ibd") || ((is_isl = ends_with(fileinfo.name, ".isl"))))
(*callback)(dbinfo.name, fileinfo.name, is_isl);
}
}
diff --git a/mysql-test/include/check-testcase.test b/mysql-test/include/check-testcase.test
index 3b2c2a46590..a282201857e 100644
--- a/mysql-test/include/check-testcase.test
+++ b/mysql-test/include/check-testcase.test
@@ -82,6 +82,8 @@ call mtr.check_testcase();
let $datadir=`select @@datadir`;
list_files $datadir mysql_upgrade_info;
+list_files $datadir/test #sql*;
+list_files $datadir/mysql #sql*;
--enable_query_log
diff --git a/mysql-test/r/cte_nonrecursive.result b/mysql-test/r/cte_nonrecursive.result
index 3ad6fb8fabe..d0e42cf4042 100644
--- a/mysql-test/r/cte_nonrecursive.result
+++ b/mysql-test/r/cte_nonrecursive.result
@@ -1079,3 +1079,71 @@ id select_type table type possible_keys key key_len ref rows Extra
3 DERIVED t2 ALL NULL NULL NULL NULL 3 Using where; Using join buffer (flat, BNL join)
NULL UNION RESULT <union1,4> ALL NULL NULL NULL NULL NULL
DROP TABLE t1,t2;
+#
+# MDEV-13780: tower of embedding CTEs with multiple usage of them
+#
+create table t1 (a int);
+insert into t1 values (3), (2), (4), (7), (1), (2), (5);
+with cte_e as
+(
+with cte_o as
+(
+with cte_i as (select * from t1 where a < 7)
+select * from cte_i where a > 1
+)
+select * from cte_o as cto_o1 where a < 3
+union
+select * from cte_o as cto_o2 where a > 4
+)
+select * from cte_e as cte_e1 where a > 1
+union
+select * from cte_e as cte_e2;
+a
+2
+5
+explain extended with cte_e as
+(
+with cte_o as
+(
+with cte_i as (select * from t1 where a < 7)
+select * from cte_i where a > 1
+)
+select * from cte_o as cto_o1 where a < 3
+union
+select * from cte_o as cto_o2 where a > 4
+)
+select * from cte_e as cte_e1 where a > 1
+union
+select * from cte_e as cte_e2;
+id select_type table type possible_keys key key_len ref rows filtered Extra
+1 PRIMARY <derived2> ALL NULL NULL NULL NULL 14 100.00 Using where
+2 DERIVED t1 ALL NULL NULL NULL NULL 7 100.00 Using where
+5 UNION t1 ALL NULL NULL NULL NULL 7 100.00 Using where
+NULL UNION RESULT <union2,5> ALL NULL NULL NULL NULL NULL NULL
+6 UNION <derived9> ALL NULL NULL NULL NULL 14 100.00
+9 DERIVED t1 ALL NULL NULL NULL NULL 7 100.00 Using where
+12 UNION t1 ALL NULL NULL NULL NULL 7 100.00 Using where
+NULL UNION RESULT <union9,12> ALL NULL NULL NULL NULL NULL NULL
+NULL UNION RESULT <union1,6> ALL NULL NULL NULL NULL NULL NULL
+Warnings:
+Note 1003 with cte_e as (with cte_o as (with cte_i as (/* select#4 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` < 7)/* select#3 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > 1)/* select#2 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` < 3 and `test`.`t1`.`a` > 1 and `test`.`t1`.`a` < 7 and `test`.`t1`.`a` > 1 union /* select#5 */ select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` > 4 and `test`.`t1`.`a` > 1 and `test`.`t1`.`a` < 7 and `test`.`t1`.`a` > 1)/* select#1 */ select `cte_e1`.`a` AS `a` from `cte_e` `cte_e1` where `cte_e1`.`a` > 1 union /* select#6 */ select `cte_e2`.`a` AS `a` from `cte_e` `cte_e2`
+drop table t1;
+#
+# MDEV-13753: embedded CTE in a VIEW created in prepared statement
+#
+SET @sql_query = "
+ CREATE OR REPLACE VIEW cte_test AS
+ WITH cte1 AS ( SELECT 1 as a from dual )
+ , cte2 AS ( SELECT * FROM cte1 )
+ SELECT * FROM cte2;
+";
+PREPARE stmt FROM @sql_query;
+EXECUTE stmt;
+DEALLOCATE PREPARE stmt;
+SHOW CREATE VIEW cte_test;
+View Create View character_set_client collation_connection
+cte_test CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `cte_test` AS with cte1 as (select 1 AS `a`), cte2 as (select `cte1`.`a` AS `a` from `cte1`)select `cte2`.`a` AS `a` from `cte2` latin1 latin1_swedish_ci
+SELECT * FROM cte_test;
+a
+1
+DROP VIEW cte_test;
diff --git a/mysql-test/r/cte_recursive.result b/mysql-test/r/cte_recursive.result
index 8cb47190a6f..b902333ddc4 100644
--- a/mysql-test/r/cte_recursive.result
+++ b/mysql-test/r/cte_recursive.result
@@ -2882,6 +2882,28 @@ f
set standard_compliant_cte=default;
DROP TABLE t;
#
+# mdev-14184: recursive CTE embedded into CTE with multiple references
+#
+WITH
+cte1 AS (
+SELECT n FROM (
+WITH RECURSIVE rec_cte(n) AS (
+SELECT 1 as n1
+UNION ALL
+SELECT n+1 as n2 FROM rec_cte WHERE n < 3
+) SELECT n FROM rec_cte
+) AS X
+),
+cte2 as (
+SELECT 2 FROM cte1
+)
+SELECT *
+FROM cte1;
+n
+1
+2
+3
+#
# MDEV-14217 [db crash] Recursive CTE when SELECT includes new field
#
CREATE TEMPORARY TABLE a_tbl (
diff --git a/mysql-test/r/delimiter_command_case_sensitivity.result b/mysql-test/r/delimiter_command_case_sensitivity.result
new file mode 100644
index 00000000000..6ed281c757a
--- /dev/null
+++ b/mysql-test/r/delimiter_command_case_sensitivity.result
@@ -0,0 +1,2 @@
+1
+1
diff --git a/mysql-test/r/derived_cond_pushdown.result b/mysql-test/r/derived_cond_pushdown.result
index 9001c5fef43..d8d03d6d062 100644
--- a/mysql-test/r/derived_cond_pushdown.result
+++ b/mysql-test/r/derived_cond_pushdown.result
@@ -8783,6 +8783,47 @@ EXPLAIN
DROP VIEW v2;
DROP TABLE t1,t2;
#
+# MDEV-14237: derived with regexp_substr() in select list
+#
+create table t1 (a char(8));
+insert into t1 values ('b'), ('a'), ('xx');
+select *
+from ( select distinct regexp_substr(t1.a,'^[A-Za-z]+') as f from t1) as t
+where t.f = 'a' or t.f = 'b';
+f
+b
+a
+explain format=json select *
+from ( select distinct regexp_substr(t1.a,'^[A-Za-z]+') as f from t1) as t
+where t.f = 'a' or t.f = 'b';
+EXPLAIN
+{
+ "query_block": {
+ "select_id": 1,
+ "table": {
+ "table_name": "<derived2>",
+ "access_type": "ALL",
+ "rows": 3,
+ "filtered": 100,
+ "attached_condition": "t.f = 'a' or t.f = 'b'",
+ "materialized": {
+ "query_block": {
+ "select_id": 2,
+ "temporary_table": {
+ "table": {
+ "table_name": "t1",
+ "access_type": "ALL",
+ "rows": 3,
+ "filtered": 100
+ }
+ }
+ }
+ }
+ }
+ }
+}
+drop table t1;
+#
# MDEV-10855: Pushdown into derived with window functions
#
set @save_optimizer_switch= @@optimizer_switch;
diff --git a/mysql-test/r/func_misc.result b/mysql-test/r/func_misc.result
index 299b6344192..f2934804426 100644
--- a/mysql-test/r/func_misc.result
+++ b/mysql-test/r/func_misc.result
@@ -1458,6 +1458,20 @@ CONCAT(NAME_CONST('name',15),'오')
15오
SET NAMES latin1;
#
+# MDEV-14116 INET6_NTOA output is set as null to varchar(39) variable
+#
+CREATE PROCEDURE p1()
+BEGIN
+DECLARE ip_full_addr varchar(39) DEFAULT "";
+SELECT INET6_NTOA(UNHEX('20000000000000000000000000000000')) into ip_full_addr;
+SELECT ip_full_addr;
+END;
+$$
+CALL p1();
+ip_full_addr
+2000::
+DROP PROCEDURE p1;
+#
# Start of 10.2 tests
#
#
diff --git a/mysql-test/r/subselect_exists2in.result b/mysql-test/r/subselect_exists2in.result
index 8b525436c2f..95fc1c19b82 100644
--- a/mysql-test/r/subselect_exists2in.result
+++ b/mysql-test/r/subselect_exists2in.result
@@ -934,5 +934,42 @@ f2
foo
set optimizer_switch= @optimizer_switch_save;
DROP TABLE t1;
+#
+# MDEV-14164: Unknown column error when adding aggregate to function
+# in oracle style procedure FOR loop
+#
+CREATE TABLE t1(id INT, val INT);
+CREATE PROCEDURE p1()
+BEGIN
+DECLARE cur1 CURSOR FOR SELECT * FROM (
+SELECT DISTINCT id FROM t1) a
+WHERE NOT EXISTS (SELECT * FROM ( SELECT id FROM t1) b
+WHERE a.id=b.id);
+OPEN cur1;
+CLOSE cur1;
+OPEN cur1;
+CLOSE cur1;
+END;
+//
+CALL p1();
+DROP PROCEDURE p1;
+DROP TABLE t1;
+CREATE TABLE t1(id INT, val INT);
+CREATE PROCEDURE p1()
+BEGIN
+SELECT * FROM (SELECT DISTINCT id FROM t1) a
+WHERE NOT a.id IN (SELECT b.id FROM t1 b);
+SELECT * FROM (SELECT DISTINCT id FROM t1) a
+WHERE NOT EXISTS (SELECT * FROM t1 b WHERE a.id=b.id);
+END;
+//
+CALL p1();
+id
+id
+CALL p1();
+id
+id
+DROP PROCEDURE p1;
+DROP TABLE t1;
# End of 10.0 tests
set optimizer_switch=default;
diff --git a/mysql-test/r/type_bit.result b/mysql-test/r/type_bit.result
index b2067907391..30cd94c9277 100644
--- a/mysql-test/r/type_bit.result
+++ b/mysql-test/r/type_bit.result
@@ -806,3 +806,27 @@ SUM(a)
NULL
DROP TABLE t1;
End of 5.1 tests
+#
+# Start of 10.1 tests
+#
+#
+# MDEV-8867 Wrong field type or metadata for COALESCE(bit_column, 1)
+#
+CREATE TABLE t1 (val bit(1));
+INSERT INTO t1 VALUES (0);
+CREATE TABLE t2 AS SELECT COALESCE(val, 1) AS c FROM t1;
+SELECT * FROM t2;
+c
+0
+SHOW CREATE TABLE t2;
+Table Create Table
+t2 CREATE TABLE `t2` (
+ `c` decimal(1,0) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+DROP TABLE t2;
+SELECT COALESCE(val, 1) FROM t1;
+Catalog Database Table Table_alias Column Column_alias Type Length Max length Is_null Flags Decimals Charsetnr
+def COALESCE(val, 1) 246 2 1 Y 32896 0 63
+COALESCE(val, 1)
+0
+DROP TABLE t1;
diff --git a/mysql-test/r/type_date.result b/mysql-test/r/type_date.result
index d56fac962fe..69bdf569787 100644
--- a/mysql-test/r/type_date.result
+++ b/mysql-test/r/type_date.result
@@ -852,6 +852,17 @@ Warning 1292 Incorrect datetime value: '1'
Warning 1292 Incorrect datetime value: '1'
DROP TABLE t1;
#
+# MDEV-14221 Assertion `0' failed in Item::field_type_for_temporal_comparison
+#
+CREATE TABLE t1 (d DATE);
+INSERT INTO t1 VALUES ('1985-05-13'),('1989-12-24');
+SELECT d, COUNT(*) FROM t1 GROUP BY d WITH ROLLUP HAVING CASE d WHEN '2017-05-25' THEN 0 ELSE 1 END;
+d COUNT(*)
+1985-05-13 1
+1989-12-24 1
+NULL 2
+DROP TABLE t1;
+#
# End of 10.1 tests
#
#
diff --git a/mysql-test/r/type_time.result b/mysql-test/r/type_time.result
index 1600732cec3..89718ea8363 100644
--- a/mysql-test/r/type_time.result
+++ b/mysql-test/r/type_time.result
@@ -1245,6 +1245,20 @@ a b c
2070 00:00:00 00:00:00
DROP TABLE t1,t2;
#
+# MDEV-10817 CAST(MAX(DATE'2001-01-01') AS TIME) returns a wrong result
+#
+SELECT CAST(DATE'2001-01-01' AS TIME);
+CAST(DATE'2001-01-01' AS TIME)
+00:00:00
+SELECT CAST(MAX(DATE'2001-01-01') AS TIME);
+CAST(MAX(DATE'2001-01-01') AS TIME)
+00:00:00
+CREATE FUNCTION f1() RETURNS DATE RETURN DATE'2001-01-01';
+SELECT CAST(f1() AS TIME);
+CAST(f1() AS TIME)
+00:00:00
+DROP FUNCTION f1;
+#
# End of 10.2 tests
#
#
diff --git a/mysql-test/suite/mariabackup/data_directory.result b/mysql-test/suite/mariabackup/data_directory.result
new file mode 100644
index 00000000000..e7201918cbd
--- /dev/null
+++ b/mysql-test/suite/mariabackup/data_directory.result
@@ -0,0 +1,13 @@
+CREATE TABLE t(a INT) ENGINE=InnoDB DATA DIRECTORY='table_data_dir';
+INSERT INTO t VALUES(1);
+# xtrabackup backup
+# xtrabackup prepare
+DROP TABLE t;
+# shutdown server
+# remove datadir
+# xtrabackup move back
+# restart server
+SELECT * FROM t;
+a
+1
+DROP TABLE t;
diff --git a/mysql-test/suite/mariabackup/data_directory.test b/mysql-test/suite/mariabackup/data_directory.test
new file mode 100644
index 00000000000..50789a34c78
--- /dev/null
+++ b/mysql-test/suite/mariabackup/data_directory.test
@@ -0,0 +1,23 @@
+let $table_data_dir=$MYSQLTEST_VARDIR/ddir;
+mkdir $table_data_dir;
+--replace_result $table_data_dir table_data_dir
+EVAL CREATE TABLE t(a INT) ENGINE=InnoDB DATA DIRECTORY='$table_data_dir';
+INSERT INTO t VALUES(1);
+echo # xtrabackup backup;
+let $targetdir=$MYSQLTEST_VARDIR/tmp/backup;
+--disable_result_log
+exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir;
+--enable_result_log
+--source include/shutdown_mysqld.inc
+echo # xtrabackup prepare;
+--disable_result_log
+exec $XTRABACKUP --prepare --target-dir=$targetdir;
+--source include/start_mysqld.inc
+DROP TABLE t;
+rmdir $table_data_dir;
+-- source include/restart_and_restore.inc
+--enable_result_log
+SELECT * FROM t;
+DROP TABLE t;
+rmdir $targetdir;
+rmdir $table_data_dir;
diff --git a/mysql-test/suite/mariabackup/incremental_backup.result b/mysql-test/suite/mariabackup/incremental_backup.result
index eeedc751d83..cc7277bdde9 100644
--- a/mysql-test/suite/mariabackup/incremental_backup.result
+++ b/mysql-test/suite/mariabackup/incremental_backup.result
@@ -1,13 +1,22 @@
call mtr.add_suppression("InnoDB: New log files created");
-CREATE TABLE t(i INT) ENGINE INNODB;
+CREATE TABLE t(i INT PRIMARY KEY) ENGINE INNODB;
+BEGIN;
+INSERT INTO t VALUES(2);
+connect con1,localhost,root,,;
+SET GLOBAL innodb_flush_log_at_trx_commit = 1;
INSERT INTO t VALUES(1);
# Create full backup , modify table, then create incremental/differential backup
-INSERT INTO t VALUES(2);
+BEGIN;
+INSERT INTO t VALUES(0);
+DELETE FROM t WHERE i=0;
+connection default;
+COMMIT;
SELECT * FROM t;
i
1
2
# Prepare full backup, apply incremental one
+disconnect con1;
# Restore and check results
# shutdown server
# remove datadir
diff --git a/mysql-test/suite/mariabackup/incremental_backup.test b/mysql-test/suite/mariabackup/incremental_backup.test
index b60b151563f..8fbfa701999 100644
--- a/mysql-test/suite/mariabackup/incremental_backup.test
+++ b/mysql-test/suite/mariabackup/incremental_backup.test
@@ -5,14 +5,22 @@ call mtr.add_suppression("InnoDB: New log files created");
let $basedir=$MYSQLTEST_VARDIR/tmp/backup;
let $incremental_dir=$MYSQLTEST_VARDIR/tmp/backup_inc1;
-CREATE TABLE t(i INT) ENGINE INNODB;
+CREATE TABLE t(i INT PRIMARY KEY) ENGINE INNODB;
+BEGIN;
+INSERT INTO t VALUES(2);
+connect (con1,localhost,root,,);
+SET GLOBAL innodb_flush_log_at_trx_commit = 1;
INSERT INTO t VALUES(1);
echo # Create full backup , modify table, then create incremental/differential backup;
--disable_result_log
exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$basedir;
--enable_result_log
-INSERT INTO t VALUES(2);
+BEGIN;
+INSERT INTO t VALUES(0);
+DELETE FROM t WHERE i=0;
+connection default;
+COMMIT;
SELECT * FROM t;
exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --ftwrl-wait-timeout=5 --ftwrl-wait-threshold=300 --ftwrl-wait-query-type=all --target-dir=$incremental_dir --incremental-basedir=$basedir;
@@ -21,6 +29,7 @@ echo # Prepare full backup, apply incremental one;
exec $XTRABACKUP --prepare --target-dir=$basedir;
exec $XTRABACKUP --prepare --target-dir=$basedir --incremental-dir=$incremental_dir ;
+disconnect con1;
echo # Restore and check results;
let $targetdir=$basedir;
-- source include/restart_and_restore.inc
diff --git a/mysql-test/suite/mariabackup/partition_datadir.opt b/mysql-test/suite/mariabackup/partition_datadir.opt
new file mode 100644
index 00000000000..8a3240370eb
--- /dev/null
+++ b/mysql-test/suite/mariabackup/partition_datadir.opt
@@ -0,0 +1 @@
+--partition \ No newline at end of file
diff --git a/mysql-test/suite/mariabackup/partition_datadir.result b/mysql-test/suite/mariabackup/partition_datadir.result
new file mode 100644
index 00000000000..3fc5fe30907
--- /dev/null
+++ b/mysql-test/suite/mariabackup/partition_datadir.result
@@ -0,0 +1,22 @@
+CREATE TABLE t(i int)
+ENGINE=InnoDB
+PARTITION BY RANGE (i)
+(PARTITION p0 VALUES LESS THAN (100),
+PARTITION P1 VALUES LESS THAN (200),
+PARTITION p2 VALUES LESS THAN (300) DATA DIRECTORY = 'MYSQLTEST_VARDIR/partitdata',
+PARTITION p3 VALUES LESS THAN (400) DATA DIRECTORY = 'MYSQLTEST_VARDIR/partitdata',
+PARTITION p4 VALUES LESS THAN MAXVALUE);
+INSERT INTO t VALUES (1), (101), (201), (301), (401);
+DROP TABLE t;
+# shutdown server
+# remove datadir
+# xtrabackup move back
+# restart server
+SELECT * FROM t;
+i
+1
+101
+201
+301
+401
+DROP TABLE t;
diff --git a/mysql-test/suite/mariabackup/partition_datadir.test b/mysql-test/suite/mariabackup/partition_datadir.test
new file mode 100644
index 00000000000..882b0111267
--- /dev/null
+++ b/mysql-test/suite/mariabackup/partition_datadir.test
@@ -0,0 +1,24 @@
+let $targetdir=$MYSQLTEST_VARDIR/backup;
+mkdir $targetdir;
+mkdir $MYSQLTEST_VARDIR/partitdata;
+
+--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR
+eval CREATE TABLE t(i int)
+ENGINE=InnoDB
+PARTITION BY RANGE (i)
+(PARTITION p0 VALUES LESS THAN (100),
+ PARTITION P1 VALUES LESS THAN (200),
+ PARTITION p2 VALUES LESS THAN (300) DATA DIRECTORY = '$MYSQLTEST_VARDIR/partitdata',
+ PARTITION p3 VALUES LESS THAN (400) DATA DIRECTORY = '$MYSQLTEST_VARDIR/partitdata',
+ PARTITION p4 VALUES LESS THAN MAXVALUE);
+INSERT INTO t VALUES (1), (101), (201), (301), (401);
+exec $XTRABACKUP --defaults-file=$MYSQLTEST_VARDIR/my.cnf --backup --target-dir=$targetdir;
+exec $XTRABACKUP --prepare --target-dir=$targetdir;
+DROP TABLE t;
+rmdir $MYSQLTEST_VARDIR/partitdata;
+--source include/restart_and_restore.inc
+--enable_result_log
+SELECT * FROM t;
+DROP TABLE t;
+rmdir $targetdir;
+rmdir $MYSQLTEST_VARDIR/partitdata;
diff --git a/mysql-test/suite/plugins/r/server_audit.result b/mysql-test/suite/plugins/r/server_audit.result
index 45206c8bcb4..0d02ae47586 100644
--- a/mysql-test/suite/plugins/r/server_audit.result
+++ b/mysql-test/suite/plugins/r/server_audit.result
@@ -52,6 +52,7 @@ alter table t1 rename renamed_t1;
set global server_audit_events='connect,query';
select 1,
2,
+# comment
3;
1 2 3
1 2 3
@@ -170,7 +171,9 @@ id
2
CREATE USER u1 IDENTIFIED BY 'pwd-123';
GRANT ALL ON sa_db TO u2 IDENTIFIED BY "pwd-321";
-SET PASSWORD FOR u1 = PASSWORD('pwd 098');
+SET PASSWORD
+# comment
+FOR u1 = PASSWORD('pwd 098');
SET PASSWORD FOR u1=<secret>;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '<secret>' at line 1
CREATE USER u3 IDENTIFIED BY '';
@@ -262,7 +265,7 @@ TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,index_stats,
TIME,HOSTNAME,root,localhost,ID,ID,RENAME,test,t1|test.renamed_t1,
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'alter table t1 rename renamed_t1',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'set global server_audit_events=\'connect,query\'',0
-TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select 1, 2, 3',0
+TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select 1,\n2,\n# comment\n3',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'insert into t2 values (1), (2)',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select * from t2',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select * from t_doesnt_exist',ID
@@ -345,7 +348,7 @@ TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'/*! select 2*/',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'/*comment*/ select 2',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'CREATE USER u1 IDENTIFIED BY *****',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'GRANT ALL ON sa_db TO u2 IDENTIFIED BY *****',0
-TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'SET PASSWORD FOR u1 = PASSWORD(*****)',0
+TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'SET PASSWORD \n# comment\nFOR u1 = PASSWORD(*****)',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'SET PASSWORD FOR u1=<secret>',ID
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'CREATE USER u3 IDENTIFIED BY *****',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'drop user u1, u2, u3',0
diff --git a/mysql-test/suite/plugins/r/thread_pool_server_audit.result b/mysql-test/suite/plugins/r/thread_pool_server_audit.result
index 45206c8bcb4..cf09ccb3a51 100644
--- a/mysql-test/suite/plugins/r/thread_pool_server_audit.result
+++ b/mysql-test/suite/plugins/r/thread_pool_server_audit.result
@@ -52,6 +52,7 @@ alter table t1 rename renamed_t1;
set global server_audit_events='connect,query';
select 1,
2,
+# comment
3;
1 2 3
1 2 3
@@ -170,7 +171,9 @@ id
2
CREATE USER u1 IDENTIFIED BY 'pwd-123';
GRANT ALL ON sa_db TO u2 IDENTIFIED BY "pwd-321";
-SET PASSWORD FOR u1 = PASSWORD('pwd 098');
+SET PASSWORD
+# comment
+FOR u1 = PASSWORD('pwd 098');
SET PASSWORD FOR u1=<secret>;
ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '<secret>' at line 1
CREATE USER u3 IDENTIFIED BY '';
@@ -262,7 +265,7 @@ TIME,HOSTNAME,root,localhost,ID,ID,WRITE,mysql,index_stats,
TIME,HOSTNAME,root,localhost,ID,ID,RENAME,test,t1|test.renamed_t1,
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'alter table t1 rename renamed_t1',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'set global server_audit_events=\'connect,query\'',0
-TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select 1, 2, 3',0
+TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select 1,\n2,\n# comment\n3',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'insert into t2 values (1), (2)',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select * from t2',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,test,'select * from t_doesnt_exist',ID
@@ -345,7 +348,7 @@ TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'/*! select 2*/',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'/*comment*/ select 2',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'CREATE USER u1 IDENTIFIED BY *****',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'GRANT ALL ON sa_db TO u2 IDENTIFIED BY *****',0
-TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'SET PASSWORD FOR u1 = PASSWORD(*****)',0
+TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'SET PASSWORD\n# comment\nFOR u1 = PASSWORD(*****)',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'SET PASSWORD FOR u1=<secret>',ID
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'CREATE USER u3 IDENTIFIED BY *****',0
TIME,HOSTNAME,root,localhost,ID,ID,QUERY,sa_db,'drop user u1, u2, u3',0
diff --git a/mysql-test/suite/plugins/t/server_audit.test b/mysql-test/suite/plugins/t/server_audit.test
index 52428909c3b..9be0d5556f0 100644
--- a/mysql-test/suite/plugins/t/server_audit.test
+++ b/mysql-test/suite/plugins/t/server_audit.test
@@ -38,6 +38,7 @@ alter table t1 rename renamed_t1;
set global server_audit_events='connect,query';
select 1,
2,
+# comment
3;
insert into t2 values (1), (2);
select * from t2;
@@ -106,7 +107,9 @@ insert into t1 values (1), (2);
select * from t1;
CREATE USER u1 IDENTIFIED BY 'pwd-123';
GRANT ALL ON sa_db TO u2 IDENTIFIED BY "pwd-321";
-SET PASSWORD FOR u1 = PASSWORD('pwd 098');
+SET PASSWORD
+# comment
+FOR u1 = PASSWORD('pwd 098');
--error 1064
SET PASSWORD FOR u1=<secret>;
CREATE USER u3 IDENTIFIED BY '';
diff --git a/mysql-test/suite/plugins/t/thread_pool_server_audit.test b/mysql-test/suite/plugins/t/thread_pool_server_audit.test
index 626d4136c47..724000c9789 100644
--- a/mysql-test/suite/plugins/t/thread_pool_server_audit.test
+++ b/mysql-test/suite/plugins/t/thread_pool_server_audit.test
@@ -38,6 +38,7 @@ alter table t1 rename renamed_t1;
set global server_audit_events='connect,query';
select 1,
2,
+# comment
3;
insert into t2 values (1), (2);
select * from t2;
@@ -106,7 +107,9 @@ insert into t1 values (1), (2);
select * from t1;
CREATE USER u1 IDENTIFIED BY 'pwd-123';
GRANT ALL ON sa_db TO u2 IDENTIFIED BY "pwd-321";
-SET PASSWORD FOR u1 = PASSWORD('pwd 098');
+SET PASSWORD
+# comment
+FOR u1 = PASSWORD('pwd 098');
--error 1064
SET PASSWORD FOR u1=<secret>;
CREATE USER u3 IDENTIFIED BY '';
diff --git a/mysql-test/suite/sys_vars/r/innodb_buffer_pool_dump_now_basic.result b/mysql-test/suite/sys_vars/r/innodb_buffer_pool_dump_now_basic.result
index 9c3a37f892b..522d5731a6d 100644
--- a/mysql-test/suite/sys_vars/r/innodb_buffer_pool_dump_now_basic.result
+++ b/mysql-test/suite/sys_vars/r/innodb_buffer_pool_dump_now_basic.result
@@ -1,7 +1,8 @@
-SET @orig = @@global.innodb_buffer_pool_dump_now;
-SELECT @orig;
-@orig
+SELECT @@global.innodb_buffer_pool_dump_now;
+@@global.innodb_buffer_pool_dump_now
0
+SELECT variable_value INTO @old_dump_status FROM information_schema.global_status
+WHERE LOWER(variable_name) = 'innodb_buffer_pool_dump_status';
SET GLOBAL innodb_buffer_pool_dump_now = ON;
SELECT @@global.innodb_buffer_pool_dump_now;
@@global.innodb_buffer_pool_dump_now
diff --git a/mysql-test/suite/sys_vars/r/innodb_buffer_pool_dump_pct_basic.result b/mysql-test/suite/sys_vars/r/innodb_buffer_pool_dump_pct_basic.result
index 485136ccc4c..93a85ffbf43 100644
--- a/mysql-test/suite/sys_vars/r/innodb_buffer_pool_dump_pct_basic.result
+++ b/mysql-test/suite/sys_vars/r/innodb_buffer_pool_dump_pct_basic.result
@@ -1,7 +1,9 @@
SET @orig = @@global.innodb_buffer_pool_dump_pct;
-SELECT @@global.innodb_buffer_pool_dump_pct;
-@@global.innodb_buffer_pool_dump_pct
+SELECT @orig;
+@orig
25
+SET GLOBAL innodb_buffer_pool_dump_pct=3;
+# Do the dump
SET GLOBAL innodb_buffer_pool_dump_pct=20;
SELECT @@global.innodb_buffer_pool_dump_pct;
@@global.innodb_buffer_pool_dump_pct
diff --git a/mysql-test/suite/sys_vars/r/innodb_buffer_pool_load_now_basic.result b/mysql-test/suite/sys_vars/r/innodb_buffer_pool_load_now_basic.result
index 3185d1ca170..eebed4d0f4a 100644
--- a/mysql-test/suite/sys_vars/r/innodb_buffer_pool_load_now_basic.result
+++ b/mysql-test/suite/sys_vars/r/innodb_buffer_pool_load_now_basic.result
@@ -1,8 +1,6 @@
-SET @orig = @@global.innodb_buffer_pool_load_now;
-SELECT @orig;
-@orig
+SELECT @@global.innodb_buffer_pool_load_now;
+@@global.innodb_buffer_pool_load_now
0
-SET GLOBAL innodb_buffer_pool_dump_now = ON;
SET GLOBAL innodb_buffer_pool_load_now = ON;
SELECT variable_value
FROM information_schema.global_status
diff --git a/mysql-test/suite/sys_vars/t/innodb_buffer_pool_dump_now_basic.test b/mysql-test/suite/sys_vars/t/innodb_buffer_pool_dump_now_basic.test
index 0bae347428e..8c5f8fa7bf0 100644
--- a/mysql-test/suite/sys_vars/t/innodb_buffer_pool_dump_now_basic.test
+++ b/mysql-test/suite/sys_vars/t/innodb_buffer_pool_dump_now_basic.test
@@ -5,8 +5,31 @@
-- source include/have_innodb.inc
# Check the default value
-SET @orig = @@global.innodb_buffer_pool_dump_now;
-SELECT @orig;
+SELECT @@global.innodb_buffer_pool_dump_now;
+
+-- let $file = `SELECT CONCAT(@@datadir, @@global.innodb_buffer_pool_filename)`
+-- error 0,1
+-- remove_file $file
+
+SELECT variable_value INTO @old_dump_status FROM information_schema.global_status
+ WHERE LOWER(variable_name) = 'innodb_buffer_pool_dump_status';
+
+# A previous test could have run buffer pool dump already;
+# in this case we want to make sure that the current time is different
+# from the timestamp in the status variable.
+# We should have had a smart wait condition here, like the commented one below,
+# let $wait_condition =
+# SELECT TRIM(SUBSTR('$old_status', -8)) != DATE_FORMAT(CURTIME(), '%k:%i:%s');
+# -- source include/wait_condition.inc
+
+# ... but we can't because of MDEV-9867, so there will be just sleep instead.
+# And it might be not enough to sleep one second, so we'll have to sleep two.
+
+if (`SELECT variable_value LIKE '%completed at%' FROM information_schema.global_status
+ WHERE LOWER(variable_name) = 'innodb_buffer_pool_dump_status'`)
+{
+ -- sleep 2
+}
# Do the dump
SET GLOBAL innodb_buffer_pool_dump_now = ON;
@@ -15,11 +38,11 @@ SELECT @@global.innodb_buffer_pool_dump_now;
# Wait for the dump to complete
let $wait_condition =
- SELECT SUBSTR(variable_value, 1, 33) = 'Buffer pool(s) dump completed at '
+ SELECT variable_value != @old_dump_status
+ AND SUBSTR(variable_value, 1, 33) = 'Buffer pool(s) dump completed at '
FROM information_schema.global_status
WHERE LOWER(variable_name) = 'innodb_buffer_pool_dump_status';
-- source include/wait_condition.inc
# Confirm that the dump file has been created
--- let $file = `SELECT CONCAT(@@datadir, @@global.innodb_buffer_pool_filename)`
-- file_exists $file
diff --git a/mysql-test/suite/sys_vars/t/innodb_buffer_pool_dump_pct_basic.test b/mysql-test/suite/sys_vars/t/innodb_buffer_pool_dump_pct_basic.test
index 99d3f79fb27..9b4edafb17e 100644
--- a/mysql-test/suite/sys_vars/t/innodb_buffer_pool_dump_pct_basic.test
+++ b/mysql-test/suite/sys_vars/t/innodb_buffer_pool_dump_pct_basic.test
@@ -11,9 +11,17 @@
# Save the default value
SET @orig = @@global.innodb_buffer_pool_dump_pct;
+SELECT @orig;
-# Check the default value
-SELECT @@global.innodb_buffer_pool_dump_pct;
+SET GLOBAL innodb_buffer_pool_dump_pct=3;
+
+--echo # Do the dump
+
+--disable_query_log
+--disable_result_log
+--source innodb_buffer_pool_dump_now_basic.test
+--enable_result_log
+--enable_query_log
# Set the valid value
SET GLOBAL innodb_buffer_pool_dump_pct=20;
diff --git a/mysql-test/suite/sys_vars/t/innodb_buffer_pool_load_now_basic.opt b/mysql-test/suite/sys_vars/t/innodb_buffer_pool_load_now_basic.opt
new file mode 100644
index 00000000000..e462be3c368
--- /dev/null
+++ b/mysql-test/suite/sys_vars/t/innodb_buffer_pool_load_now_basic.opt
@@ -0,0 +1 @@
+--innodb-buffer-pool-load-at-startup=off
diff --git a/mysql-test/suite/sys_vars/t/innodb_buffer_pool_load_now_basic.test b/mysql-test/suite/sys_vars/t/innodb_buffer_pool_load_now_basic.test
index a260dc2516b..15536d338e1 100644
--- a/mysql-test/suite/sys_vars/t/innodb_buffer_pool_load_now_basic.test
+++ b/mysql-test/suite/sys_vars/t/innodb_buffer_pool_load_now_basic.test
@@ -5,44 +5,22 @@
-- source include/have_innodb.inc
# Check the default value
-SET @orig = @@global.innodb_buffer_pool_load_now;
-SELECT @orig;
+SELECT @@global.innodb_buffer_pool_load_now;
-let $old_status= `SELECT variable_value FROM information_schema.global_status
- WHERE LOWER(variable_name) = 'innodb_buffer_pool_dump_status'`;
+# Make sure there is a dump file to load
-# A previous test could have run buffer pool dump already;
-# in this case we want to make sure that the current time is different
-# from the timestamp in the status variable.
-# We should have had a smart wait condition here, like the commented one below,
-# but we can't because of MDEV-9867, so there will be just sleep instead.
-# And it might be not enough to sleep one second, so we'll have to sleep two.
-# let $wait_condition =
-# SELECT TRIM(SUBSTR('$old_status', -8)) != DATE_FORMAT(CURTIME(), '%k:%i:%s');
-# -- source include/wait_condition.inc
-if (`SELECT count(*) > 0 FROM information_schema.global_status
- WHERE (LOWER(variable_name) = 'innodb_buffer_pool_dump_status' or
- LOWER(variable_name) = 'innodb_buffer_pool_load_status')
- and variable_value LIKE '%completed at%'`)
-{
- -- sleep 2
-}
-# Do the dump
-SET GLOBAL innodb_buffer_pool_dump_now = ON;
-
-# Wait for the dump to complete
-let $wait_condition =
- SELECT variable_value != '$old_status'
- AND SUBSTR(variable_value, 1, 33) = 'Buffer pool(s) dump completed at '
- FROM information_schema.global_status
- WHERE LOWER(variable_name) = 'innodb_buffer_pool_dump_status';
---disable_warnings
--- source include/wait_condition.inc
---enable_warnings
-
-# Confirm the file is really created
-- let $file = `SELECT CONCAT(@@datadir, @@global.innodb_buffer_pool_filename)`
+-- error 0,1
-- file_exists $file
+if ($errno)
+{
+ # Dump file does not exist, get it created
+ --disable_query_log
+ --disable_result_log
+ --source innodb_buffer_pool_dump_now_basic.test
+ --enable_result_log
+ --enable_query_log
+}
let $old_load_status=
`SELECT variable_value FROM information_schema.global_status
diff --git a/mysql-test/t/cte_nonrecursive.test b/mysql-test/t/cte_nonrecursive.test
index 57b7ae1658f..742e8f6e4d7 100644
--- a/mysql-test/t/cte_nonrecursive.test
+++ b/mysql-test/t/cte_nonrecursive.test
@@ -743,3 +743,50 @@ eval $q;
eval explain $q;
DROP TABLE t1,t2;
+
+--echo #
+--echo # MDEV-13780: tower of embedding CTEs with multiple usage of them
+--echo #
+
+create table t1 (a int);
+insert into t1 values (3), (2), (4), (7), (1), (2), (5);
+
+let $q=
+with cte_e as
+(
+ with cte_o as
+ (
+ with cte_i as (select * from t1 where a < 7)
+ select * from cte_i where a > 1
+ )
+ select * from cte_o as cto_o1 where a < 3
+ union
+ select * from cte_o as cto_o2 where a > 4
+)
+select * from cte_e as cte_e1 where a > 1
+union
+select * from cte_e as cte_e2;
+
+eval $q;
+eval explain extended $q;
+
+drop table t1;
+
+--echo #
+--echo # MDEV-13753: embedded CTE in a VIEW created in prepared statement
+--echo #
+
+SET @sql_query = "
+ CREATE OR REPLACE VIEW cte_test AS
+ WITH cte1 AS ( SELECT 1 as a from dual )
+ , cte2 AS ( SELECT * FROM cte1 )
+ SELECT * FROM cte2;
+";
+PREPARE stmt FROM @sql_query;
+EXECUTE stmt;
+DEALLOCATE PREPARE stmt;
+
+SHOW CREATE VIEW cte_test;
+SELECT * FROM cte_test;
+
+DROP VIEW cte_test;
diff --git a/mysql-test/t/cte_recursive.test b/mysql-test/t/cte_recursive.test
index 67be840c002..7d7600f0e88 100644
--- a/mysql-test/t/cte_recursive.test
+++ b/mysql-test/t/cte_recursive.test
@@ -1928,6 +1928,25 @@ set standard_compliant_cte=default;
DROP TABLE t;
+--echo #
+--echo # mdev-14184: recursive CTE embedded into CTE with multiple references
+--echo #
+
+WITH
+cte1 AS (
+ SELECT n FROM (
+ WITH RECURSIVE rec_cte(n) AS (
+ SELECT 1 as n1
+ UNION ALL
+ SELECT n+1 as n2 FROM rec_cte WHERE n < 3
+ ) SELECT n FROM rec_cte
+ ) AS X
+),
+cte2 as (
+ SELECT 2 FROM cte1
+)
+SELECT *
+FROM cte1;
--echo #
--echo # MDEV-14217 [db crash] Recursive CTE when SELECT includes new field
@@ -1956,3 +1975,4 @@ DROP TABLE a_tbl;
--error ER_WRONG_NUMBER_OF_COLUMNS_IN_SELECT
WITH RECURSIVE x AS (SELECT 1,2 UNION ALL SELECT 1 FROM x) SELECT * FROM x;
+
diff --git a/mysql-test/t/delimiter_case_mdev_10728.sql b/mysql-test/t/delimiter_case_mdev_10728.sql
new file mode 100644
index 00000000000..72a1dcd9a9e
--- /dev/null
+++ b/mysql-test/t/delimiter_case_mdev_10728.sql
@@ -0,0 +1,3 @@
+DeLiMiTeR A;
+SELECT 1 A;
+delimiter ;
diff --git a/mysql-test/t/delimiter_command_case_sensitivity.test b/mysql-test/t/delimiter_command_case_sensitivity.test
new file mode 100644
index 00000000000..11d1cf75aa0
--- /dev/null
+++ b/mysql-test/t/delimiter_command_case_sensitivity.test
@@ -0,0 +1,4 @@
+source include/not_embedded.inc;
+
+# MDEV-10728
+--exec $MYSQL --default-character-set=binary < "t/delimiter_case_mdev_10728.sql"
diff --git a/mysql-test/t/derived_cond_pushdown.test b/mysql-test/t/derived_cond_pushdown.test
index c4f1ee7d734..a9bb998bc33 100644
--- a/mysql-test/t/derived_cond_pushdown.test
+++ b/mysql-test/t/derived_cond_pushdown.test
@@ -1550,6 +1550,23 @@ DROP VIEW v2;
DROP TABLE t1,t2;
--echo #
+--echo # MDEV-14237: derived with regexp_substr() in select list
+--echo #
+
+create table t1 (a char(8));
+insert into t1 values ('b'), ('a'), ('xx');
+
+let $q=
+select *
+from ( select distinct regexp_substr(t1.a,'^[A-Za-z]+') as f from t1) as t
+where t.f = 'a' or t.f = 'b';
+
+eval $q;
+eval explain format=json $q;
+
+drop table t1;
+
+--echo #
--echo # MDEV-10855: Pushdown into derived with window functions
--echo #
@@ -1834,3 +1851,4 @@ SELECT * FROM v3 JOIN t1 ON (bmax = b);
DROP VIEW v1,v2,v3;
DROP TABLE t1,t2;
+
diff --git a/mysql-test/t/func_misc.test b/mysql-test/t/func_misc.test
index ac983048129..da4a7633166 100644
--- a/mysql-test/t/func_misc.test
+++ b/mysql-test/t/func_misc.test
@@ -1104,6 +1104,23 @@ SELECT CONCAT(NAME_CONST('name',15),'오');
SET NAMES latin1;
--echo #
+--echo # MDEV-14116 INET6_NTOA output is set as null to varchar(39) variable
+--echo #
+
+DELIMITER $$;
+CREATE PROCEDURE p1()
+BEGIN
+ DECLARE ip_full_addr varchar(39) DEFAULT "";
+ SELECT INET6_NTOA(UNHEX('20000000000000000000000000000000')) into ip_full_addr;
+ SELECT ip_full_addr;
+END;
+$$
+DELIMITER ;$$
+CALL p1();
+DROP PROCEDURE p1;
+
+
+--echo #
--echo # Start of 10.2 tests
--echo #
diff --git a/mysql-test/t/show_check.test b/mysql-test/t/show_check.test
index 13ca9a528c6..4024d2e522c 100644
--- a/mysql-test/t/show_check.test
+++ b/mysql-test/t/show_check.test
@@ -423,7 +423,7 @@ create table t1 (
SHOW CREATE TABLE t1;
DROP TABLE t1;
-# Test for Bug#93 4.1 protocl crash on corupted frm and SHOW TABLE STATUS
+# Test for Bug#93 4.1 protocol crash on corrupted frm and SHOW TABLE STATUS
flush tables;
@@ -437,7 +437,7 @@ show create table t1;
--disable_warnings
drop table if exists t1;
--enable_warnings
---error 1,0
+--error 0,1
--remove_file $MYSQLD_DATADIR/test/t1.frm
#
diff --git a/mysql-test/t/subselect_exists2in.test b/mysql-test/t/subselect_exists2in.test
index a4fdbe5c50b..5a8ddb3612f 100644
--- a/mysql-test/t/subselect_exists2in.test
+++ b/mysql-test/t/subselect_exists2in.test
@@ -786,6 +786,46 @@ set optimizer_switch= @optimizer_switch_save;
DROP TABLE t1;
+--echo #
+--echo # MDEV-14164: Unknown column error when adding aggregate to function
+--echo # in oracle style procedure FOR loop
+--echo #
+
+CREATE TABLE t1(id INT, val INT);
+DELIMITER //;
+CREATE PROCEDURE p1()
+BEGIN
+ DECLARE cur1 CURSOR FOR SELECT * FROM (
+ SELECT DISTINCT id FROM t1) a
+ WHERE NOT EXISTS (SELECT * FROM ( SELECT id FROM t1) b
+ WHERE a.id=b.id);
+ OPEN cur1;
+ CLOSE cur1;
+ OPEN cur1;
+ CLOSE cur1;
+END;
+//
+DELIMITER ;//
+CALL p1();
+DROP PROCEDURE p1;
+DROP TABLE t1;
+
+CREATE TABLE t1(id INT, val INT);
+DELIMITER //;
+CREATE PROCEDURE p1()
+BEGIN
+ SELECT * FROM (SELECT DISTINCT id FROM t1) a
+ WHERE NOT a.id IN (SELECT b.id FROM t1 b);
+ SELECT * FROM (SELECT DISTINCT id FROM t1) a
+ WHERE NOT EXISTS (SELECT * FROM t1 b WHERE a.id=b.id);
+END;
+//
+DELIMITER ;//
+CALL p1();
+CALL p1();
+DROP PROCEDURE p1;
+DROP TABLE t1;
+
--echo # End of 10.0 tests
#restore defaults
diff --git a/mysql-test/t/type_bit.test b/mysql-test/t/type_bit.test
index 761f200fe0c..bb282fc15e5 100644
--- a/mysql-test/t/type_bit.test
+++ b/mysql-test/t/type_bit.test
@@ -439,3 +439,22 @@ SELECT SUM(a) FROM t1 GROUP BY c, b, a;
DROP TABLE t1;
--echo End of 5.1 tests
+
+--echo #
+--echo # Start of 10.1 tests
+--echo #
+
+--echo #
+--echo # MDEV-8867 Wrong field type or metadata for COALESCE(bit_column, 1)
+--echo #
+
+CREATE TABLE t1 (val bit(1));
+INSERT INTO t1 VALUES (0);
+CREATE TABLE t2 AS SELECT COALESCE(val, 1) AS c FROM t1;
+SELECT * FROM t2;
+SHOW CREATE TABLE t2;
+DROP TABLE t2;
+--enable_metadata
+SELECT COALESCE(val, 1) FROM t1;
+--disable_metadata
+DROP TABLE t1;
diff --git a/mysql-test/t/type_date.test b/mysql-test/t/type_date.test
index 7c4af618c23..8d29a54a26c 100644
--- a/mysql-test/t/type_date.test
+++ b/mysql-test/t/type_date.test
@@ -582,6 +582,15 @@ SELECT DATE(a), DATE(b), DATE(c) FROM t1;
SELECT DATE(COALESCE(a)), DATE(COALESCE(b)), DATE(COALESCE(c)) FROM t1;
DROP TABLE t1;
+--echo #
+--echo # MDEV-14221 Assertion `0' failed in Item::field_type_for_temporal_comparison
+--echo #
+
+CREATE TABLE t1 (d DATE);
+INSERT INTO t1 VALUES ('1985-05-13'),('1989-12-24');
+SELECT d, COUNT(*) FROM t1 GROUP BY d WITH ROLLUP HAVING CASE d WHEN '2017-05-25' THEN 0 ELSE 1 END;
+DROP TABLE t1;
+
--echo #
--echo # End of 10.1 tests
diff --git a/mysql-test/t/type_time.test b/mysql-test/t/type_time.test
index 6662a3d9bb0..5f3f58df166 100644
--- a/mysql-test/t/type_time.test
+++ b/mysql-test/t/type_time.test
@@ -747,6 +747,17 @@ DROP TABLE t1,t2;
--echo #
+--echo # MDEV-10817 CAST(MAX(DATE'2001-01-01') AS TIME) returns a wrong result
+--echo #
+
+SELECT CAST(DATE'2001-01-01' AS TIME);
+SELECT CAST(MAX(DATE'2001-01-01') AS TIME);
+CREATE FUNCTION f1() RETURNS DATE RETURN DATE'2001-01-01';
+SELECT CAST(f1() AS TIME);
+DROP FUNCTION f1;
+
+
+--echo #
--echo # End of 10.2 tests
--echo #
diff --git a/mysql-test/t/view.test b/mysql-test/t/view.test
index 4850b6c06cb..847fb843ec8 100644
--- a/mysql-test/t/view.test
+++ b/mysql-test/t/view.test
@@ -1,3 +1,4 @@
+--source include/have_partition.inc
# Save the initial number of concurrent sessions.
--source include/count_sessions.inc
diff --git a/plugin/server_audit/server_audit.c b/plugin/server_audit/server_audit.c
index 87a18e47fc5..b75f6b9a863 100644
--- a/plugin/server_audit/server_audit.c
+++ b/plugin/server_audit/server_audit.c
@@ -15,7 +15,7 @@
#define PLUGIN_VERSION 0x104
-#define PLUGIN_STR_VERSION "1.4.2"
+#define PLUGIN_STR_VERSION "1.4.3"
#define _my_thread_var loc_thread_var
@@ -1118,6 +1118,21 @@ do { \
} while(0)
+#define ESC_MAP_SIZE 0x60
+static const char esc_map[ESC_MAP_SIZE]=
+{
+ 0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, '\'', 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, '\\', 0, 0, 0
+};
+
+static char escaped_char(char c)
+{
+ return ((unsigned char ) c) >= ESC_MAP_SIZE ? 0 : esc_map[(unsigned char) c];
+}
static void setup_connection_initdb(struct connection_info *cn,
@@ -1324,21 +1339,16 @@ static size_t escape_string(const char *str, unsigned int len,
const char *res_end= result + result_len - 2;
while (len)
{
+ char esc_c;
+
if (result >= res_end)
break;
- if (*str == '\'')
- {
- if (result+1 >= res_end)
- break;
- *(result++)= '\\';
- *(result++)= '\'';
- }
- else if (*str == '\\')
+ if ((esc_c= escaped_char(*str)))
{
if (result+1 >= res_end)
break;
*(result++)= '\\';
- *(result++)= '\\';
+ *(result++)= esc_c;
}
else if (is_space(*str))
*(result++)= ' ';
@@ -1427,19 +1437,12 @@ static size_t escape_string_hide_passwords(const char *str, unsigned int len,
no_password:
if (result >= res_end)
break;
- if (*str == '\'')
+ if ((b_char= escaped_char(*str)))
{
if (result+1 >= res_end)
break;
*(result++)= '\\';
- *(result++)= '\'';
- }
- else if (*str == '\\')
- {
- if (result+1 >= res_end)
- break;
- *(result++)= '\\';
- *(result++)= '\\';
+ *(result++)= b_char;
}
else if (is_space(*str))
*(result++)= ' ';
diff --git a/sql/datadict.cc b/sql/datadict.cc
index edc9fe5681b..5b70639174c 100644
--- a/sql/datadict.cc
+++ b/sql/datadict.cc
@@ -46,11 +46,13 @@ static int read_string(File file, uchar**to, size_t length)
engine_name is a LEX_CSTRING, where engine_name->str must point to
a buffer of at least NAME_CHAR_LEN+1 bytes.
+ If engine_name is 0, then the function will only test if the file is a
+ view or not
@param[out] is_sequence 1 if table is a SEQUENCE, 0 otherwise
@retval TABLE_TYPE_UNKNOWN error
- @retval TABLE_TYPE_TABLE table
+ @retval TABLE_TYPE_NORMAL table
@retval TABLE_TYPE_SEQUENCE sequence table
@retval TABLE_TYPE_VIEW view
*/
@@ -80,12 +82,26 @@ Table_type dd_frm_type(THD *thd, char *path, LEX_CSTRING *engine_name,
goto err;
}
+ /*
+ We return TABLE_TYPE_NORMAL if we can read the .frm file. This allows us
+ to drop a bad .frm file with DROP TABLE
+ */
type= TABLE_TYPE_NORMAL;
- if (!is_binary_frm_header(header) || !engine_name)
+ /* engine_name is 0 if we only want to know if table is view or not */
+ if (!engine_name)
goto err;
+ /*
+ Initialize engine name in case we are not able to find it out
+ The cast is safe, as engine_name->str points to a usable buffer.
+ */
engine_name->length= 0;
+ ((char*) (engine_name->str))[0]= 0;
+
+ if (!is_binary_frm_header(header))
+ goto err;
+
dbt= header[3];
if (((header[39] >> 4) & 3) == HA_CHOICE_YES)
diff --git a/sql/handler.cc b/sql/handler.cc
index 589a82200be..81c6b60d256 100644
--- a/sql/handler.cc
+++ b/sql/handler.cc
@@ -5089,8 +5089,13 @@ bool ha_table_exists(THD *thd, const char *db, const char *table_name,
{
char engine_buf[NAME_CHAR_LEN + 1];
LEX_CSTRING engine= { engine_buf, 0 };
+ Table_type type;
- if (dd_frm_type(thd, path, &engine, is_sequence) != TABLE_TYPE_VIEW)
+ if ((type= dd_frm_type(thd, path, &engine, is_sequence)) ==
+ TABLE_TYPE_UNKNOWN)
+ DBUG_RETURN(0);
+
+ if (type != TABLE_TYPE_VIEW)
{
plugin_ref p= plugin_lock_by_name(thd, &engine,
MYSQL_STORAGE_ENGINE_PLUGIN);
diff --git a/sql/item.cc b/sql/item.cc
index e5e1d83f228..3daf1e8393e 100644
--- a/sql/item.cc
+++ b/sql/item.cc
@@ -3238,7 +3238,8 @@ table_map Item_field::all_used_tables() const
return (get_depended_from() ? OUTER_REF_TABLE_BIT : field->table->map);
}
-void Item_field::fix_after_pullout(st_select_lex *new_parent, Item **ref)
+void Item_field::fix_after_pullout(st_select_lex *new_parent, Item **ref,
+ bool merge)
{
if (new_parent == get_depended_from())
depended_from= NULL;
@@ -3282,6 +3283,19 @@ void Item_field::fix_after_pullout(st_select_lex *new_parent, Item **ref)
if (!need_change)
return;
+ if (!merge)
+ {
+ /*
+ It is transformation without merge.
+ This field was "outer" for the inner SELECT where it was taken and
+ moved up.
+ "Outer" fields uses normal SELECT_LEX context of upper SELECTs for
+ name resolution, so we can switch everything to it safely.
+ */
+ this->context= &new_parent->context;
+ return;
+ }
+
Name_resolution_context *ctx= new Name_resolution_context();
if (context->select_lex == new_parent)
{
@@ -8698,18 +8712,19 @@ bool Item_outer_ref::fix_fields(THD *thd, Item **reference)
void Item_outer_ref::fix_after_pullout(st_select_lex *new_parent,
- Item **ref_arg)
+ Item **ref_arg, bool merge)
{
if (get_depended_from() == new_parent)
{
*ref_arg= outer_ref;
- (*ref_arg)->fix_after_pullout(new_parent, ref_arg);
+ (*ref_arg)->fix_after_pullout(new_parent, ref_arg, merge);
}
}
-void Item_ref::fix_after_pullout(st_select_lex *new_parent, Item **refptr)
+void Item_ref::fix_after_pullout(st_select_lex *new_parent, Item **refptr,
+ bool merge)
{
- (*ref)->fix_after_pullout(new_parent, ref);
+ (*ref)->fix_after_pullout(new_parent, ref, merge);
if (get_depended_from() == new_parent)
depended_from= NULL;
}
diff --git a/sql/item.h b/sql/item.h
index c128251dae9..b7ba236e4b1 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -733,7 +733,9 @@ public:
Fix after some tables has been pulled out. Basically re-calculate all
attributes that are dependent on the tables.
*/
- virtual void fix_after_pullout(st_select_lex *new_parent, Item **ref) {};
+ virtual void fix_after_pullout(st_select_lex *new_parent, Item **ref,
+ bool merge)
+ {};
/*
This method should be used in case where we are sure that we do not need
@@ -2760,7 +2762,7 @@ public:
bool send(Protocol *protocol, st_value *buffer);
void reset_field(Field *f);
bool fix_fields(THD *, Item **);
- void fix_after_pullout(st_select_lex *new_parent, Item **ref);
+ void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge);
void make_field(THD *thd, Send_field *tmp_field);
int save_in_field(Field *field,bool no_conversions);
void save_org_in_field(Field *field, fast_field_copier optimizer_data);
@@ -3026,6 +3028,17 @@ public:
Field *result_field;
Item_null_result(THD *thd): Item_null(thd), result_field(0) {}
bool is_result_field() { return result_field != 0; }
+#if MARIADB_VERSION_ID < 100300
+ enum_field_types field_type() const
+ {
+ return result_field->type();
+ }
+#else
+ const Type_handler *type_handler() const
+ {
+ return result_field->type_handler();
+ }
+#endif
void save_in_result_field(bool no_conversions)
{
save_in_field(result_field, no_conversions);
@@ -4390,7 +4403,7 @@ public:
bool send(Protocol *prot, st_value *buffer);
void make_field(THD *thd, Send_field *field);
bool fix_fields(THD *, Item **);
- void fix_after_pullout(st_select_lex *new_parent, Item **ref);
+ void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge);
int save_in_field(Field *field, bool no_conversions);
void save_org_in_field(Field *field, fast_field_copier optimizer_data);
fast_field_copier setup_fast_field_copier(Field *field)
@@ -4698,9 +4711,9 @@ public:
Item *it= ((Item *) item)->real_item();
return orig_item->eq(it, binary_cmp);
}
- void fix_after_pullout(st_select_lex *new_parent, Item **refptr)
+ void fix_after_pullout(st_select_lex *new_parent, Item **refptr, bool merge)
{
- orig_item->fix_after_pullout(new_parent, &orig_item);
+ orig_item->fix_after_pullout(new_parent, &orig_item, merge);
}
int save_in_field(Field *to, bool no_conversions);
const Type_handler *type_handler() const { return orig_item->type_handler(); }
@@ -4969,7 +4982,7 @@ public:
outer_ref->save_org_in_field(result_field, NULL);
}
bool fix_fields(THD *, Item **);
- void fix_after_pullout(st_select_lex *new_parent, Item **ref);
+ void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge);
table_map used_tables() const
{
return (*ref)->const_item() ? 0 : OUTER_REF_TABLE_BIT;
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 90b150a8b4a..f72426bd18c 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -1220,10 +1220,11 @@ bool Item_in_optimizer::is_top_level_item()
}
-void Item_in_optimizer::fix_after_pullout(st_select_lex *new_parent, Item **ref)
+void Item_in_optimizer::fix_after_pullout(st_select_lex *new_parent,
+ Item **ref, bool merge)
{
/* This will re-calculate attributes of our Item_in_subselect: */
- Item_bool_func::fix_after_pullout(new_parent, ref);
+ Item_bool_func::fix_after_pullout(new_parent, ref, merge);
/* Then, re-calculate not_null_tables_cache: */
eval_not_null_tables(NULL);
@@ -2050,10 +2051,11 @@ bool Item_func_between::count_sargable_conds(void *arg)
}
-void Item_func_between::fix_after_pullout(st_select_lex *new_parent, Item **ref)
+void Item_func_between::fix_after_pullout(st_select_lex *new_parent,
+ Item **ref, bool merge)
{
/* This will re-calculate attributes of the arguments */
- Item_func_opt_neg::fix_after_pullout(new_parent, ref);
+ Item_func_opt_neg::fix_after_pullout(new_parent, ref, merge);
/* Then, re-calculate not_null_tables_cache according to our special rules */
eval_not_null_tables(NULL);
}
@@ -2378,10 +2380,11 @@ Item_func_if::eval_not_null_tables(void *opt_arg)
}
-void Item_func_if::fix_after_pullout(st_select_lex *new_parent, Item **ref)
+void Item_func_if::fix_after_pullout(st_select_lex *new_parent,
+ Item **ref, bool merge)
{
/* This will re-calculate attributes of the arguments */
- Item_func::fix_after_pullout(new_parent, ref);
+ Item_func::fix_after_pullout(new_parent, ref, merge);
/* Then, re-calculate not_null_tables_cache according to our special rules */
eval_not_null_tables(NULL);
}
@@ -4144,10 +4147,11 @@ Item_func_in::eval_not_null_tables(void *opt_arg)
}
-void Item_func_in::fix_after_pullout(st_select_lex *new_parent, Item **ref)
+void Item_func_in::fix_after_pullout(st_select_lex *new_parent, Item **ref,
+ bool merge)
{
/* This will re-calculate attributes of the arguments */
- Item_func_opt_neg::fix_after_pullout(new_parent, ref);
+ Item_func_opt_neg::fix_after_pullout(new_parent, ref, merge);
/* Then, re-calculate not_null_tables_cache according to our special rules */
eval_not_null_tables(NULL);
}
@@ -4651,7 +4655,8 @@ Item_cond::eval_not_null_tables(void *opt_arg)
}
-void Item_cond::fix_after_pullout(st_select_lex *new_parent, Item **ref)
+void Item_cond::fix_after_pullout(st_select_lex *new_parent, Item **ref,
+ bool merge)
{
List_iterator<Item> li(list);
Item *item;
@@ -4664,7 +4669,7 @@ void Item_cond::fix_after_pullout(st_select_lex *new_parent, Item **ref)
while ((item=li++))
{
table_map tmp_table_map;
- item->fix_after_pullout(new_parent, li.ref());
+ item->fix_after_pullout(new_parent, li.ref(), merge);
item= *li.ref();
used_tables_and_const_cache_join(item);
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index 62066ef61e5..49716fb3c8f 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -375,7 +375,7 @@ public:
virtual void get_cache_parameters(List<Item> &parameters);
bool is_top_level_item();
bool eval_not_null_tables(void *opt_arg);
- void fix_after_pullout(st_select_lex *new_parent, Item **ref);
+ void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge);
bool invisible_mode();
void reset_cache() { cache= NULL; }
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -908,7 +908,7 @@ public:
bool fix_length_and_dec_numeric(THD *);
virtual void print(String *str, enum_query_type query_type);
bool eval_not_null_tables(void *opt_arg);
- void fix_after_pullout(st_select_lex *new_parent, Item **ref);
+ void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge);
bool count_sargable_conds(void *arg);
void add_key_fields(JOIN *join, KEY_FIELD **key_fields,
uint *and_level, table_map usable_tables,
@@ -1144,7 +1144,7 @@ public:
}
const char *func_name() const { return "if"; }
bool eval_not_null_tables(void *opt_arg);
- void fix_after_pullout(st_select_lex *new_parent, Item **ref);
+ void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge);
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_if>(thd, mem_root, this); }
private:
@@ -2378,7 +2378,7 @@ public:
const char *func_name() const { return "in"; }
enum precedence precedence() const { return CMP_PRECEDENCE; }
bool eval_not_null_tables(void *opt_arg);
- void fix_after_pullout(st_select_lex *new_parent, Item **ref);
+ void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge);
bool count_sargable_conds(void *arg);
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_in>(thd, mem_root, this); }
@@ -2902,7 +2902,7 @@ public:
list.append(nlist);
}
bool fix_fields(THD *, Item **ref);
- void fix_after_pullout(st_select_lex *new_parent, Item **ref);
+ void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge);
enum Type type() const { return COND_ITEM; }
List<Item>* argument_list() { return &list; }
diff --git a/sql/item_func.cc b/sql/item_func.cc
index fc7417411e8..e9cf5a695d0 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -406,7 +406,8 @@ Item_func::eval_not_null_tables(void *opt_arg)
}
-void Item_func::fix_after_pullout(st_select_lex *new_parent, Item **ref)
+void Item_func::fix_after_pullout(st_select_lex *new_parent, Item **ref,
+ bool merge)
{
Item **arg,**arg_end;
@@ -417,7 +418,7 @@ void Item_func::fix_after_pullout(st_select_lex *new_parent, Item **ref)
{
for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++)
{
- (*arg)->fix_after_pullout(new_parent, arg);
+ (*arg)->fix_after_pullout(new_parent, arg, merge);
Item *item= *arg;
used_tables_and_const_cache_join(item);
diff --git a/sql/item_func.h b/sql/item_func.h
index 409a712a5c5..58df7b8b3c6 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -129,7 +129,7 @@ public:
Item_func_or_sum::cleanup();
used_tables_and_const_cache_init();
}
- void fix_after_pullout(st_select_lex *new_parent, Item **ref);
+ void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge);
void quick_fix_field();
table_map not_null_tables() const;
void update_used_tables()
@@ -2809,6 +2809,13 @@ public:
return sp_result_field->val_decimal(dec_buf);
}
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+ {
+ if (execute())
+ return true;
+ return sp_result_field->get_date(ltime, fuzzydate);
+ }
+
String *val_str(String *str)
{
String buf;
diff --git a/sql/item_inetfunc.cc b/sql/item_inetfunc.cc
index 9aaa64823f7..ff671536002 100644
--- a/sql/item_inetfunc.cc
+++ b/sql/item_inetfunc.cc
@@ -181,7 +181,8 @@ String *Item_func_inet_str_base::val_str_ascii(String *buffer)
return NULL;
}
- String *arg_str= args[0]->val_str(buffer);
+ StringBuffer<STRING_BUFFER_USUAL_SIZE> tmp;
+ String *arg_str= args[0]->val_str(&tmp);
if (!arg_str) // Out-of memory happened. The error has been reported.
{ // Or: the underlying field is NULL
null_value= true;
@@ -679,7 +680,7 @@ static void ipv6_to_str(const in6_addr *ipv6, char *str)
@retval true The string has been converted sucessfully.
*/
-bool Item_func_inet6_aton::calc_value(String *arg, String *buffer)
+bool Item_func_inet6_aton::calc_value(const String *arg, String *buffer)
{
// ipv4-string -> varbinary(4)
// ipv6-string -> varbinary(16)
@@ -719,7 +720,7 @@ bool Item_func_inet6_aton::calc_value(String *arg, String *buffer)
@retval true The string has been converted sucessfully.
*/
-bool Item_func_inet6_ntoa::calc_value(String *arg, String *buffer)
+bool Item_func_inet6_ntoa::calc_value(const String *arg, String *buffer)
{
if (arg->charset() != &my_charset_bin)
return false;
diff --git a/sql/item_inetfunc.h b/sql/item_inetfunc.h
index 13ce003a374..bd0a95b5270 100644
--- a/sql/item_inetfunc.h
+++ b/sql/item_inetfunc.h
@@ -105,7 +105,7 @@ public:
virtual String *val_str_ascii(String *buffer);
protected:
- virtual bool calc_value(String *arg, String *buffer) = 0;
+ virtual bool calc_value(const String *arg, String *buffer) = 0;
};
@@ -134,7 +134,7 @@ public:
{ return get_item_copy<Item_func_inet6_aton>(thd, mem_root, this); }
protected:
- virtual bool calc_value(String *arg, String *buffer);
+ virtual bool calc_value(const String *arg, String *buffer);
};
@@ -168,7 +168,7 @@ public:
{ return get_item_copy<Item_func_inet6_ntoa>(thd, mem_root, this); }
protected:
- virtual bool calc_value(String *arg, String *buffer);
+ virtual bool calc_value(const String *arg, String *buffer);
};
diff --git a/sql/item_row.cc b/sql/item_row.cc
index 6486bb66615..3660c983f87 100644
--- a/sql/item_row.cc
+++ b/sql/item_row.cc
@@ -110,13 +110,14 @@ void Item_row::split_sum_func(THD *thd, Ref_ptr_array ref_pointer_array,
}
-void Item_row::fix_after_pullout(st_select_lex *new_parent, Item **ref)
+void Item_row::fix_after_pullout(st_select_lex *new_parent, Item **ref,
+ bool merge)
{
used_tables_and_const_cache_init();
not_null_tables_cache= 0;
for (uint i= 0; i < arg_count; i++)
{
- args[i]->fix_after_pullout(new_parent, &args[i]);
+ args[i]->fix_after_pullout(new_parent, &args[i], merge);
used_tables_and_const_cache_join(args[i]);
not_null_tables_cache|= args[i]->not_null_tables();
}
diff --git a/sql/item_row.h b/sql/item_row.h
index 83e9743fede..a6fdd2b212c 100644
--- a/sql/item_row.h
+++ b/sql/item_row.h
@@ -81,7 +81,7 @@ public:
return 0;
};
bool fix_fields(THD *thd, Item **ref);
- void fix_after_pullout(st_select_lex *new_parent, Item **ref);
+ void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge);
void cleanup();
void split_sum_func(THD *thd, Ref_ptr_array ref_pointer_array,
List<Item> &fields, uint flags);
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index c322136bef2..fbcf69d00ce 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -400,8 +400,7 @@ public:
bool fix_fields(THD *thd, Item **ref);
void fix_length_and_dec();
const char *func_name() const { return "regexp_replace"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_regexp_replace>(thd, mem_root, this); }
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return 0;}
};
@@ -423,8 +422,7 @@ public:
bool fix_fields(THD *thd, Item **ref);
void fix_length_and_dec();
const char *func_name() const { return "regexp_substr"; }
- Item *get_copy(THD *thd, MEM_ROOT *mem_root)
- { return get_item_copy<Item_func_regexp_substr>(thd, mem_root, this); }
+ Item *get_copy(THD *thd, MEM_ROOT *mem_root) { return 0; }
};
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index 63d1fd99f62..678b4192f45 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -452,7 +452,8 @@ bool Item_subselect::mark_as_dependent(THD *thd, st_select_lex *select,
OUTER_REF_TABLE_BIT.
*/
-void Item_subselect::fix_after_pullout(st_select_lex *new_parent, Item **ref)
+void Item_subselect::fix_after_pullout(st_select_lex *new_parent,
+ Item **ref, bool merge)
{
recalc_used_tables(new_parent, TRUE);
parent_select= new_parent;
@@ -1160,7 +1161,8 @@ Item_singlerow_subselect::select_transformer(JOIN *join)
/*
as far as we moved content to upper level we have to fix dependences & Co
*/
- substitution->fix_after_pullout(select_lex->outer_select(), &substitution);
+ substitution->fix_after_pullout(select_lex->outer_select(),
+ &substitution, TRUE);
}
DBUG_RETURN(false);
}
@@ -2937,7 +2939,7 @@ bool Item_exists_subselect::exists2in_processor(void *opt_arg)
goto out;
}
}
- outer_exp->fix_after_pullout(unit->outer_select(), &outer_exp);
+ outer_exp->fix_after_pullout(unit->outer_select(), &outer_exp, FALSE);
outer_exp->update_used_tables();
outer.push_back(outer_exp, thd->mem_root);
}
@@ -3318,10 +3320,11 @@ err:
}
-void Item_in_subselect::fix_after_pullout(st_select_lex *new_parent, Item **ref)
+void Item_in_subselect::fix_after_pullout(st_select_lex *new_parent,
+ Item **ref, bool merge)
{
- left_expr->fix_after_pullout(new_parent, &left_expr);
- Item_subselect::fix_after_pullout(new_parent, ref);
+ left_expr->fix_after_pullout(new_parent, &left_expr, merge);
+ Item_subselect::fix_after_pullout(new_parent, ref, merge);
used_tables_cache |= left_expr->used_tables();
}
diff --git a/sql/item_subselect.h b/sql/item_subselect.h
index 6112c1c22f4..df94ceb2493 100644
--- a/sql/item_subselect.h
+++ b/sql/item_subselect.h
@@ -183,7 +183,7 @@ public:
}
bool fix_fields(THD *thd, Item **ref);
bool mark_as_dependent(THD *thd, st_select_lex *select, Item *item);
- void fix_after_pullout(st_select_lex *new_parent, Item **ref);
+ void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge);
void recalc_used_tables(st_select_lex *new_parent, bool after_pullout);
virtual bool exec();
/*
@@ -624,7 +624,7 @@ public:
enum precedence precedence() const { return CMP_PRECEDENCE; }
bool fix_fields(THD *thd, Item **ref);
void fix_length_and_dec();
- void fix_after_pullout(st_select_lex *new_parent, Item **ref);
+ void fix_after_pullout(st_select_lex *new_parent, Item **ref, bool merge);
bool const_item() const
{
return Item_subselect::const_item() && left_expr->const_item();
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 4a3f107796d..c0c5e1a43b4 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -2019,6 +2019,18 @@ void Item_sum_hybrid::clear()
null_value= 1;
}
+bool
+Item_sum_hybrid::get_date(MYSQL_TIME *ltime, ulonglong fuzzydate)
+{
+ DBUG_ASSERT(fixed == 1);
+ if (null_value)
+ return true;
+ bool retval= value->get_date(ltime, fuzzydate);
+ if ((null_value= value->null_value))
+ DBUG_ASSERT(retval == true);
+ return retval;
+}
+
double Item_sum_hybrid::val_real()
{
DBUG_ASSERT(fixed == 1);
diff --git a/sql/item_sum.h b/sql/item_sum.h
index 7845ed3318f..0cb5be391a2 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -1034,6 +1034,7 @@ protected:
double val_real();
longlong val_int();
my_decimal *val_decimal(my_decimal *);
+ bool get_date(MYSQL_TIME *ltime, ulonglong fuzzydate);
void reset_field();
String *val_str(String *);
const Type_handler *real_type_handler() const
diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc
index cc9cfbd127f..04d0a9b4a3f 100644
--- a/sql/opt_subselect.cc
+++ b/sql/opt_subselect.cc
@@ -1642,7 +1642,7 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
{
tl->jtbm_table_no= table_no;
Item *dummy= tl->jtbm_subselect;
- tl->jtbm_subselect->fix_after_pullout(parent_lex, &dummy);
+ tl->jtbm_subselect->fix_after_pullout(parent_lex, &dummy, true);
DBUG_ASSERT(dummy == tl->jtbm_subselect);
}
SELECT_LEX *old_sl= tl->select_lex;
@@ -1783,7 +1783,8 @@ static bool convert_subq_to_sj(JOIN *parent_join, Item_in_subselect *subq_pred)
Walk through sj nest's WHERE and ON expressions and call
item->fix_table_changes() for all items.
*/
- sj_nest->sj_on_expr->fix_after_pullout(parent_lex, &sj_nest->sj_on_expr);
+ sj_nest->sj_on_expr->fix_after_pullout(parent_lex, &sj_nest->sj_on_expr,
+ TRUE);
fix_list_after_tbl_changes(parent_lex, &sj_nest->nested_join->join_list);
@@ -1942,7 +1943,7 @@ static bool convert_subq_to_jtbm(JOIN *parent_join,
DBUG_ASSERT(parent_join->table_count < MAX_TABLES);
Item *conds= hash_sj_engine->semi_join_conds;
- conds->fix_after_pullout(parent_lex, &conds);
+ conds->fix_after_pullout(parent_lex, &conds, TRUE);
DBUG_EXECUTE("where", print_where(conds,"SJ-EXPR", QT_ORDINARY););
@@ -1994,7 +1995,7 @@ void fix_list_after_tbl_changes(SELECT_LEX *new_parent, List<TABLE_LIST> *tlist)
while ((table= it++))
{
if (table->on_expr)
- table->on_expr->fix_after_pullout(new_parent, &table->on_expr);
+ table->on_expr->fix_after_pullout(new_parent, &table->on_expr, TRUE);
if (table->nested_join)
fix_list_after_tbl_changes(new_parent, &table->nested_join->join_list);
}
diff --git a/sql/sql_cte.cc b/sql/sql_cte.cc
index 54a56103d21..0d91d813dfc 100644
--- a/sql/sql_cte.cc
+++ b/sql/sql_cte.cc
@@ -349,7 +349,10 @@ void With_element::check_dependencies_in_select(st_select_lex *sl,
/* Now look for the dependencies in the subqueries of sl */
st_select_lex_unit *inner_unit= sl->first_inner_unit();
for (; inner_unit; inner_unit= inner_unit->next_unit())
- check_dependencies_in_unit(inner_unit, ctxt, in_subq, dep_map);
+ {
+ if (!inner_unit->with_element)
+ check_dependencies_in_unit(inner_unit, ctxt, in_subq, dep_map);
+ }
}
@@ -837,7 +840,6 @@ st_select_lex_unit *With_element::clone_parsed_spec(THD *thd,
with_table->next_global= spec_tables;
}
res= &lex->unit;
- res->set_with_clause(owner);
lex->unit.include_down(with_table->select_lex);
lex->unit.set_slave(with_select);
@@ -846,6 +848,8 @@ st_select_lex_unit *With_element::clone_parsed_spec(THD *thd,
insert_chain_before(
(st_select_lex_node **) &(old_lex->all_selects_list),
with_select));
+ if (check_dependencies_in_with_clauses(lex->with_clauses_list))
+ res= NULL;
lex_end(lex);
err:
if (arena)
@@ -989,14 +993,18 @@ With_element *st_select_lex::find_table_def_in_with_clauses(TABLE_LIST *table)
and it was unsuccesful. Yet for units cloned from the spec it has not
been done yet.
*/
- if (with_elem && sl->master_unit() == with_elem->spec)
+ With_clause *attached_with_clause=sl->get_with_clause();
+ if (attached_with_clause &&
+ (found= attached_with_clause->find_table_def(table, NULL)))
break;
- With_clause *with_clause=sl->get_with_clause();
- if (with_clause)
+ if (with_elem)
{
- With_element *barrier= with_clause->with_recursive ? NULL : with_elem;
- if ((found= with_clause->find_table_def(table, barrier)))
+ With_clause *containing_with_clause= with_elem->get_owner();
+ With_element *barrier= containing_with_clause->with_recursive ?
+ NULL : with_elem;
+ if ((found= containing_with_clause->find_table_def(table, barrier)))
break;
+ sl= sl->master_unit()->outer_select();
}
master_unit= sl->master_unit();
/* Do not look for the table's definition beyond the scope of the view */
diff --git a/sql/sql_derived.cc b/sql/sql_derived.cc
index 8dff001d4d0..5554faf7baf 100644
--- a/sql/sql_derived.cc
+++ b/sql/sql_derived.cc
@@ -468,7 +468,8 @@ bool mysql_derived_merge(THD *thd, LEX *lex, TABLE_LIST *derived)
// Update used tables cache according to new table map
if (derived->on_expr)
{
- derived->on_expr->fix_after_pullout(parent_lex, &derived->on_expr);
+ derived->on_expr->fix_after_pullout(parent_lex, &derived->on_expr,
+ TRUE);
fix_list_after_tbl_changes(parent_lex, &derived->nested_join->join_list);
}
}
@@ -641,7 +642,8 @@ bool mysql_derived_prepare(THD *thd, LEX *lex, TABLE_LIST *derived)
SELECT_LEX_UNIT *unit= derived->get_unit();
DBUG_ENTER("mysql_derived_prepare");
bool res= FALSE;
- DBUG_PRINT("enter", ("unit %p", unit));
+ DBUG_PRINT("enter", ("unit: %p table_list: %p Alias '%s'",
+ unit, derived, derived->alias));
if (!unit)
DBUG_RETURN(FALSE);
diff --git a/storage/innobase/buf/buf0buf.cc b/storage/innobase/buf/buf0buf.cc
index 5ce8b1d584d..3a201f5cef4 100644
--- a/storage/innobase/buf/buf0buf.cc
+++ b/storage/innobase/buf/buf0buf.cc
@@ -4168,7 +4168,8 @@ buf_page_get_gen(
ulint retries = 0;
buf_pool_t* buf_pool = buf_pool_get(page_id);
- ut_ad(mtr->is_active());
+ ut_ad((mtr == NULL) == (mode == BUF_EVICT_IF_IN_POOL));
+ ut_ad(!mtr || mtr->is_active());
ut_ad((rw_latch == RW_S_LATCH)
|| (rw_latch == RW_X_LATCH)
|| (rw_latch == RW_SX_LATCH)
@@ -4180,29 +4181,31 @@ buf_page_get_gen(
#ifdef UNIV_DEBUG
switch (mode) {
+ case BUF_EVICT_IF_IN_POOL:
+ /* After DISCARD TABLESPACE, the tablespace would not exist,
+ but in IMPORT TABLESPACE, PageConverter::operator() must
+ replace any old pages, which were not evicted during DISCARD.
+ Skip the assertion on space_page_size. */
+ break;
+ default:
+ ut_error;
case BUF_GET_NO_LATCH:
ut_ad(rw_latch == RW_NO_LATCH);
- break;
+ /* fall through */
case BUF_GET:
case BUF_GET_IF_IN_POOL:
case BUF_PEEK_IF_IN_POOL:
case BUF_GET_IF_IN_POOL_OR_WATCH:
case BUF_GET_POSSIBLY_FREED:
- break;
- default:
- ut_error;
+ bool found;
+ const page_size_t& space_page_size
+ = fil_space_get_page_size(page_id.space(), &found);
+ ut_ad(found);
+ ut_ad(page_size.equals_to(space_page_size));
}
-
- bool found;
- const page_size_t& space_page_size
- = fil_space_get_page_size(page_id.space(), &found);
-
- ut_ad(found);
-
- ut_ad(page_size.equals_to(space_page_size));
#endif /* UNIV_DEBUG */
- ut_ad(!ibuf_inside(mtr)
+ ut_ad(!mtr || !ibuf_inside(mtr)
|| ibuf_page_low(page_id, page_size, FALSE, file, line, NULL));
buf_pool->stat.n_page_gets++;
@@ -4290,13 +4293,15 @@ loop:
rw_lock_x_unlock(hash_lock);
}
- if (mode == BUF_GET_IF_IN_POOL
- || mode == BUF_PEEK_IF_IN_POOL
- || mode == BUF_GET_IF_IN_POOL_OR_WATCH) {
-
+ switch (mode) {
+ case BUF_GET_IF_IN_POOL:
+ case BUF_GET_IF_IN_POOL_OR_WATCH:
+ case BUF_PEEK_IF_IN_POOL:
+ case BUF_EVICT_IF_IN_POOL:
+#ifdef UNIV_SYNC_DEBUG
ut_ad(!rw_lock_own(hash_lock, RW_LOCK_X));
ut_ad(!rw_lock_own(hash_lock, RW_LOCK_S));
-
+#endif /* UNIV_SYNC_DEBUG */
return(NULL);
}
@@ -4390,8 +4395,10 @@ loop:
got_block:
- if (mode == BUF_GET_IF_IN_POOL || mode == BUF_PEEK_IF_IN_POOL) {
-
+ switch (mode) {
+ case BUF_GET_IF_IN_POOL:
+ case BUF_PEEK_IF_IN_POOL:
+ case BUF_EVICT_IF_IN_POOL:
buf_page_t* fix_page = &fix_block->page;
BPageMutex* fix_mutex = buf_page_get_mutex(fix_page);
mutex_enter(fix_mutex);
@@ -4423,6 +4430,20 @@ got_block:
os_thread_sleep(WAIT_FOR_WRITE);
goto loop;
}
+
+ if (UNIV_UNLIKELY(mode == BUF_EVICT_IF_IN_POOL)) {
+evict_from_pool:
+ ut_ad(!fix_block->page.oldest_modification);
+ buf_pool_mutex_enter(buf_pool);
+ buf_block_unfix(fix_block);
+
+ if (!buf_LRU_free_page(&fix_block->page, true)) {
+ ut_ad(0);
+ }
+
+ buf_pool_mutex_exit(buf_pool);
+ return(NULL);
+ }
break;
case BUF_BLOCK_ZIP_PAGE:
@@ -4455,6 +4476,10 @@ got_block:
goto loop;
}
+ if (UNIV_UNLIKELY(mode == BUF_EVICT_IF_IN_POOL)) {
+ goto evict_from_pool;
+ }
+
/* Buffer-fix the block so that it cannot be evicted
or relocated while we are attempting to allocate an
uncompressed page. */
diff --git a/storage/innobase/buf/buf0flu.cc b/storage/innobase/buf/buf0flu.cc
index e7a2a844330..4661a4e0d14 100644
--- a/storage/innobase/buf/buf0flu.cc
+++ b/storage/innobase/buf/buf0flu.cc
@@ -3821,24 +3821,16 @@ FlushObserver::notify_remove(
void
FlushObserver::flush()
{
- buf_remove_t buf_remove;
-
- if (m_interrupted) {
- buf_remove = BUF_REMOVE_FLUSH_NO_WRITE;
- } else {
- buf_remove = BUF_REMOVE_FLUSH_WRITE;
-
- if (m_stage != NULL) {
- ulint pages_to_flush =
- buf_flush_get_dirty_pages_count(
- m_space_id, this);
-
- m_stage->begin_phase_flush(pages_to_flush);
- }
+ if (!m_interrupted && m_stage) {
+ m_stage->begin_phase_flush(buf_flush_get_dirty_pages_count(
+ m_space_id, this));
}
- /* Flush or remove dirty pages. */
- buf_LRU_flush_or_remove_pages(m_space_id, buf_remove, m_trx);
+ /* MDEV-14317 FIXME: Discard all changes to only those pages
+ that will be freed by the clean-up of the ALTER operation.
+ (Maybe, instead of buf_pool->flush_list, use a dedicated list
+ for pages on which redo logging has been disabled.) */
+ buf_LRU_flush_or_remove_pages(m_space_id, m_trx);
/* Wait for all dirty pages were flushed. */
for (ulint i = 0; i < srv_buf_pool_instances; i++) {
diff --git a/storage/innobase/buf/buf0lru.cc b/storage/innobase/buf/buf0lru.cc
index 2137760e815..9d0d9627d26 100644
--- a/storage/innobase/buf/buf0lru.cc
+++ b/storage/innobase/buf/buf0lru.cc
@@ -586,8 +586,8 @@ rescan:
/* If flush observer is NULL, flush page for space id,
or flush page for flush observer. */
- if ((observer != NULL && observer != bpage->flush_observer)
- || (observer == NULL && id != bpage->id.space())) {
+ if (observer ? (observer != bpage->flush_observer)
+ : (id != bpage->id.space())) {
/* Skip this block, as it does not belong to
the target space. */
@@ -657,24 +657,27 @@ rescan:
return(all_freed ? DB_SUCCESS : DB_FAIL);
}
-/******************************************************************//**
-Remove or flush all the dirty pages that belong to a given tablespace
+/** Remove or flush all the dirty pages that belong to a given tablespace
inside a specific buffer pool instance. The pages will remain in the LRU
list and will be evicted from the LRU list as they age and move towards
-the tail of the LRU list. */
+the tail of the LRU list.
+@param[in,out] buf_pool buffer pool
+@param[in] id tablespace identifier
+@param[in] observer flush observer,
+ or NULL if the files should not be written to
+@param[in] trx transaction (to check for interrupt),
+ or NULL if the files should not be written to
+*/
static
void
buf_flush_dirty_pages(
-/*==================*/
- buf_pool_t* buf_pool, /*!< buffer pool instance */
- ulint id, /*!< in: space id */
- FlushObserver* observer, /*!< in: flush observer */
- bool flush, /*!< in: flush to disk if true otherwise
- remove the pages without flushing */
- const trx_t* trx) /*!< to check if the operation must
- be interrupted */
+ buf_pool_t* buf_pool,
+ ulint id,
+ FlushObserver* observer,
+ const trx_t* trx)
{
dberr_t err;
+ bool flush = trx != NULL;
do {
buf_pool_mutex_enter(buf_pool);
@@ -708,238 +711,30 @@ buf_flush_dirty_pages(
|| buf_pool_get_dirty_pages_count(buf_pool, id, observer) == 0);
}
-/******************************************************************//**
-Remove all pages that belong to a given tablespace inside a specific
-buffer pool instance when we are DISCARDing the tablespace. */
-static
-void
-buf_LRU_remove_all_pages(
-/*=====================*/
- buf_pool_t* buf_pool, /*!< buffer pool instance */
- ulint id) /*!< in: space id */
-{
- buf_page_t* bpage;
- ibool all_freed;
-
-scan_again:
- buf_pool_mutex_enter(buf_pool);
-
- all_freed = TRUE;
-
- for (bpage = UT_LIST_GET_LAST(buf_pool->LRU);
- bpage != NULL;
- /* No op */) {
-
- rw_lock_t* hash_lock;
- buf_page_t* prev_bpage;
- BPageMutex* block_mutex;
-
- ut_a(buf_page_in_file(bpage));
- ut_ad(bpage->in_LRU_list);
-
- prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
-
- /* bpage->id.space() and bpage->io_fix are protected by
- buf_pool->mutex and the block_mutex. It is safe to check
- them while holding buf_pool->mutex only. */
-
- if (bpage->id.space() != id) {
- /* Skip this block, as it does not belong to
- the space that is being invalidated. */
- goto next_page;
- } else if (buf_page_get_io_fix(bpage) != BUF_IO_NONE) {
- /* We cannot remove this page during this scan
- yet; maybe the system is currently reading it
- in, or flushing the modifications to the file */
-
- all_freed = FALSE;
- goto next_page;
- } else {
- hash_lock = buf_page_hash_lock_get(buf_pool, bpage->id);
-
- rw_lock_x_lock(hash_lock);
-
- block_mutex = buf_page_get_mutex(bpage);
-
- mutex_enter(block_mutex);
-
- if (bpage->buf_fix_count > 0) {
-
- mutex_exit(block_mutex);
-
- rw_lock_x_unlock(hash_lock);
-
- /* We cannot remove this page during
- this scan yet; maybe the system is
- currently reading it in, or flushing
- the modifications to the file */
-
- all_freed = FALSE;
-
- goto next_page;
- }
- }
-
- ut_ad(mutex_own(block_mutex));
-
- DBUG_PRINT("ib_buf", ("evict page %u:%u"
- " state %u",
- bpage->id.space(),
- bpage->id.page_no(),
- bpage->state));
-#ifdef BTR_CUR_HASH_ADAPT
- if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) {
- /* Do nothing, because the adaptive hash index
- covers uncompressed pages only. */
- } else if (((buf_block_t*) bpage)->index) {
- buf_pool_mutex_exit(buf_pool);
-
- rw_lock_x_unlock(hash_lock);
-
- mutex_exit(block_mutex);
-
- /* Note that the following call will acquire
- and release block->lock X-latch.
- Note that the table cannot be evicted during
- the execution of ALTER TABLE...DISCARD TABLESPACE
- because MySQL is keeping the table handle open. */
-
- btr_search_drop_page_hash_when_freed(
- bpage->id, bpage->size);
-
- goto scan_again;
- } else {
- /* This debug check uses a dirty read that could
- theoretically cause false positives while
- buf_pool_clear_hash_index() is executing,
- if the writes to block->index=NULL and
- block->n_pointers=0 are reordered.
- (Other conflicting access paths to the adaptive hash
- index should not be possible, because when a
- tablespace is being discarded or dropped, there must
- be no concurrect access to the contained tables.) */
- assert_block_ahi_empty((buf_block_t*) bpage);
- }
-#endif /* BTR_CUR_HASH_ADAPT */
-
- if (bpage->oldest_modification != 0) {
-
- buf_flush_remove(bpage);
- }
-
- ut_ad(!bpage->in_flush_list);
-
- /* Remove from the LRU list. */
-
- if (buf_LRU_block_remove_hashed(bpage, true)) {
- buf_LRU_block_free_hashed_page((buf_block_t*) bpage);
- } else {
- ut_ad(block_mutex == &buf_pool->zip_mutex);
- }
-
- ut_ad(!mutex_own(block_mutex));
-
- /* buf_LRU_block_remove_hashed() releases the hash_lock */
- ut_ad(!rw_lock_own(hash_lock, RW_LOCK_X));
- ut_ad(!rw_lock_own(hash_lock, RW_LOCK_S));
-
-next_page:
- bpage = prev_bpage;
- }
-
- buf_pool_mutex_exit(buf_pool);
-
- if (!all_freed) {
- os_thread_sleep(20000);
-
- goto scan_again;
- }
-}
-
-/******************************************************************//**
-Remove pages belonging to a given tablespace inside a specific
-buffer pool instance when we are deleting the data file(s) of that
-tablespace. The pages still remain a part of LRU and are evicted from
-the list as they age towards the tail of the LRU only if buf_remove
-is BUF_REMOVE_FLUSH_NO_WRITE. */
-static
+/** Empty the flush list for all pages belonging to a tablespace.
+@param[in] id tablespace identifier
+@param[in] trx transaction, for checking for user interrupt;
+ or NULL if nothing is to be written
+@param[in] drop_ahi whether to drop the adaptive hash index */
void
-buf_LRU_remove_pages(
-/*=================*/
- buf_pool_t* buf_pool, /*!< buffer pool instance */
- ulint id, /*!< in: space id */
- buf_remove_t buf_remove, /*!< in: remove or flush strategy */
- const trx_t* trx) /*!< to check if the operation must
- be interrupted */
+buf_LRU_flush_or_remove_pages(ulint id, const trx_t* trx, bool drop_ahi)
{
FlushObserver* observer = (trx == NULL) ? NULL : trx->flush_observer;
+ /* Pages in the system tablespace must never be discarded. */
+ ut_ad(id || trx);
- switch (buf_remove) {
- case BUF_REMOVE_ALL_NO_WRITE:
- buf_LRU_remove_all_pages(buf_pool, id);
- break;
-
- case BUF_REMOVE_FLUSH_NO_WRITE:
- /* Pass trx as NULL to avoid interruption check. */
- buf_flush_dirty_pages(buf_pool, id, observer, false, NULL);
- break;
-
- case BUF_REMOVE_FLUSH_WRITE:
- buf_flush_dirty_pages(buf_pool, id, observer, true, trx);
-
- if (observer == NULL) {
- /* Ensure that all asynchronous IO is completed. */
- os_aio_wait_until_no_pending_writes();
- fil_flush(id);
+ for (ulint i = 0; i < srv_buf_pool_instances; i++) {
+ buf_pool_t* buf_pool = buf_pool_from_array(i);
+ if (drop_ahi) {
+ buf_LRU_drop_page_hash_for_tablespace(buf_pool, id);
}
-
- break;
+ buf_flush_dirty_pages(buf_pool, id, observer, trx);
}
-}
-/******************************************************************//**
-Flushes all dirty pages or removes all pages belonging
-to a given tablespace. A PROBLEM: if readahead is being started, what
-guarantees that it will not try to read in pages after this operation
-has completed? */
-void
-buf_LRU_flush_or_remove_pages(
-/*==========================*/
- ulint id, /*!< in: space id */
- buf_remove_t buf_remove, /*!< in: remove or flush strategy */
- const trx_t* trx) /*!< to check if the operation must
- be interrupted */
-{
- ulint i;
-
- /* Before we attempt to drop pages one by one we first
- attempt to drop page hash index entries in batches to make
- it more efficient. The batching attempt is a best effort
- attempt and does not guarantee that all pages hash entries
- will be dropped. We get rid of remaining page hash entries
- one by one below. */
- for (i = 0; i < srv_buf_pool_instances; i++) {
- buf_pool_t* buf_pool;
-
- buf_pool = buf_pool_from_array(i);
-#ifdef BTR_CUR_HASH_ADAPT
- switch (buf_remove) {
- case BUF_REMOVE_ALL_NO_WRITE:
- buf_LRU_drop_page_hash_for_tablespace(buf_pool, id);
- break;
-
- case BUF_REMOVE_FLUSH_NO_WRITE:
- /* It is a DROP TABLE for a single table
- tablespace. No AHI entries exist because
- we already dealt with them when freeing up
- extents. */
- case BUF_REMOVE_FLUSH_WRITE:
- /* We allow read-only queries against the
- table, there is no need to drop the AHI entries. */
- break;
- }
-#endif /* BTR_CUR_HASH_ADAPT */
- buf_LRU_remove_pages(buf_pool, id, buf_remove, trx);
+ if (trx && !observer && !trx_is_interrupted(trx)) {
+ /* Ensure that all asynchronous IO is completed. */
+ os_aio_wait_until_no_pending_writes();
+ fil_flush(id);
}
}
diff --git a/storage/innobase/dict/dict0dict.cc b/storage/innobase/dict/dict0dict.cc
index c2b08f03848..3879df433e9 100644
--- a/storage/innobase/dict/dict0dict.cc
+++ b/storage/innobase/dict/dict0dict.cc
@@ -1641,7 +1641,7 @@ dict_table_rename_in_cache(
return(DB_OUT_OF_MEMORY);
}
- fil_delete_tablespace(table->space, BUF_REMOVE_ALL_NO_WRITE);
+ fil_delete_tablespace(table->space, true);
/* Delete any temp file hanging around. */
if (os_file_status(filepath, &exists, &ftype)
diff --git a/storage/innobase/fil/fil0fil.cc b/storage/innobase/fil/fil0fil.cc
index 73132754fdf..90a3baa6f83 100644
--- a/storage/innobase/fil/fil0fil.cc
+++ b/storage/innobase/fil/fil0fil.cc
@@ -2449,7 +2449,7 @@ fil_recreate_tablespace(
/* Step-1: Invalidate buffer pool pages belonging to the tablespace
to re-create. */
- buf_LRU_flush_or_remove_pages(space_id, BUF_REMOVE_ALL_NO_WRITE, 0);
+ buf_LRU_flush_or_remove_pages(space_id, NULL);
/* Remove all insert buffer entries for the tablespace */
ibuf_delete_for_discarded_space(space_id);
@@ -2907,7 +2907,7 @@ fil_close_tablespace(
completely and permanently. The flag stop_new_ops also prevents
fil_flush() from being applied to this tablespace. */
- buf_LRU_flush_or_remove_pages(id, BUF_REMOVE_FLUSH_WRITE, trx);
+ buf_LRU_flush_or_remove_pages(id, trx);
/* If the free is successful, the X lock will be released before
the space memory data structure is freed. */
@@ -2959,17 +2959,12 @@ fil_table_accessible(const dict_table_t* table)
}
}
-/** Deletes an IBD tablespace, either general or single-table.
-The tablespace must be cached in the memory cache. This will delete the
-datafile, fil_space_t & fil_node_t entries from the file_system_t cache.
-@param[in] space_id Tablespace id
-@param[in] buf_remove Specify the action to take on the pages
-for this table in the buffer pool.
-@return DB_SUCCESS or error */
+/** Delete a tablespace and associated .ibd file.
+@param[in] id tablespace identifier
+@param[in] drop_ahi whether to drop the adaptive hash index
+@return DB_SUCCESS or error */
dberr_t
-fil_delete_tablespace(
- ulint id,
- buf_remove_t buf_remove)
+fil_delete_tablespace(ulint id, bool drop_ahi)
{
char* path = 0;
fil_space_t* space = 0;
@@ -3012,7 +3007,7 @@ fil_delete_tablespace(
To deal with potential read requests, we will check the
::stop_new_ops flag in fil_io(). */
- buf_LRU_flush_or_remove_pages(id, buf_remove, 0);
+ buf_LRU_flush_or_remove_pages(id, NULL, drop_ahi);
/* If it is a delete then also delete any generated files, otherwise
when we drop the database the remove directory will fail. */
@@ -3103,7 +3098,7 @@ fil_truncate_tablespace(
/* Step-2: Invalidate buffer pool pages belonging to the tablespace
to re-create. Remove all insert buffer entries for the tablespace */
- buf_LRU_flush_or_remove_pages(space_id, BUF_REMOVE_ALL_NO_WRITE, 0);
+ buf_LRU_flush_or_remove_pages(space_id, NULL);
/* Step-3: Truncate the tablespace and accordingly update
the fil_space_t handler that is used to access this tablespace. */
@@ -3199,7 +3194,7 @@ fil_reinit_space_header_for_table(
from disabling AHI during the scan */
btr_search_s_lock_all();
DEBUG_SYNC_C("buffer_pool_scan");
- buf_LRU_flush_or_remove_pages(id, BUF_REMOVE_ALL_NO_WRITE, 0);
+ buf_LRU_flush_or_remove_pages(id, NULL);
btr_search_s_unlock_all();
row_mysql_lock_data_dictionary(trx);
@@ -3292,7 +3287,7 @@ fil_discard_tablespace(
{
dberr_t err;
- switch (err = fil_delete_tablespace(id, BUF_REMOVE_ALL_NO_WRITE)) {
+ switch (err = fil_delete_tablespace(id, true)) {
case DB_SUCCESS:
break;
@@ -4348,8 +4343,19 @@ fil_ibd_discover(
/* Look for a remote file-per-table tablespace. */
- df_rem_per.set_name(db);
- if (df_rem_per.open_link_file() == DB_SUCCESS) {
+ switch (srv_operation) {
+ case SRV_OPERATION_BACKUP:
+ case SRV_OPERATION_RESTORE_DELTA:
+ ut_ad(0);
+ break;
+ case SRV_OPERATION_RESTORE_EXPORT:
+ case SRV_OPERATION_RESTORE:
+ break;
+ case SRV_OPERATION_NORMAL:
+ df_rem_per.set_name(db);
+ if (df_rem_per.open_link_file() != DB_SUCCESS) {
+ break;
+ }
/* An ISL file was found with contents. */
if (df_rem_per.open_read_only(false) != DB_SUCCESS
@@ -4439,6 +4445,18 @@ fil_ibd_load(
return(FIL_LOAD_OK);
}
+ if (srv_operation == SRV_OPERATION_RESTORE) {
+ /* Replace absolute DATA DIRECTORY file paths with
+ short names relative to the backup directory. */
+ if (const char* name = strrchr(filename, OS_PATH_SEPARATOR)) {
+ while (--name > filename
+ && *name != OS_PATH_SEPARATOR);
+ if (name > filename) {
+ filename = name + 1;
+ }
+ }
+ }
+
Datafile file;
file.set_filepath(filename);
file.open_read_only(false);
diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc
index 3ecbf562bdb..c2d8ac0b065 100644
--- a/storage/innobase/handler/ha_innodb.cc
+++ b/storage/innobase/handler/ha_innodb.cc
@@ -20217,7 +20217,7 @@ wsrep_innobase_kill_one_trx(
wsrep_thd_awake(thd, signal);
} else {
/* abort currently executing query */
- DBUG_PRINT("wsrep",("sending KILL_QUERY to: %ld",
+ DBUG_PRINT("wsrep",("sending KILL_QUERY to: %lu",
thd_get_thread_id(thd)));
WSREP_DEBUG("kill query for: %ld",
thd_get_thread_id(thd));
@@ -20361,7 +20361,8 @@ wsrep_fake_trx_id(
mutex_enter(&trx_sys->mutex);
trx_id_t trx_id = trx_sys_get_new_trx_id();
mutex_exit(&trx_sys->mutex);
- WSREP_DEBUG("innodb fake trx id: %lu thd: %s", trx_id, wsrep_thd_query(thd));
+ WSREP_DEBUG("innodb fake trx id: " TRX_ID_FMT " thd: %s",
+ trx_id, wsrep_thd_query(thd));
wsrep_ws_handle_for_trx(wsrep_thd_ws_handle(thd), trx_id);
}
diff --git a/storage/innobase/ibuf/ibuf0ibuf.cc b/storage/innobase/ibuf/ibuf0ibuf.cc
index ea083381757..d26391a80f4 100644
--- a/storage/innobase/ibuf/ibuf0ibuf.cc
+++ b/storage/innobase/ibuf/ibuf0ibuf.cc
@@ -4962,21 +4962,36 @@ ibuf_check_bitmap_on_import(
const trx_t* trx, /*!< in: transaction */
ulint space_id) /*!< in: tablespace identifier */
{
- ulint size;
ulint page_no;
ut_ad(space_id);
ut_ad(trx->mysql_thd);
- bool found;
- const page_size_t& page_size
- = fil_space_get_page_size(space_id, &found);
-
- if (!found) {
+ FilSpace space(space_id);
+ if (!space()) {
return(DB_TABLE_NOT_FOUND);
}
- size = fil_space_get_size(space_id);
+ const page_size_t page_size(space->flags);
+ /* fil_space_t::size and fil_space_t::free_limit would still be 0
+ at this point. So, we will have to read page 0. */
+ ut_ad(!space->free_limit);
+ ut_ad(!space->size);
+
+ mtr_t mtr;
+ ulint size;
+ mtr.start();
+ if (buf_block_t* sp = buf_page_get(page_id_t(space_id, 0), page_size,
+ RW_S_LATCH, &mtr)) {
+ size = std::min(
+ mach_read_from_4(FSP_HEADER_OFFSET + FSP_FREE_LIMIT
+ + sp->frame),
+ mach_read_from_4(FSP_HEADER_OFFSET + FSP_SIZE
+ + sp->frame));
+ } else {
+ size = 0;
+ }
+ mtr.commit();
if (size == 0) {
return(DB_TABLE_NOT_FOUND);
@@ -4991,7 +5006,6 @@ ibuf_check_bitmap_on_import(
the space, as usual. */
for (page_no = 0; page_no < size; page_no += page_size.physical()) {
- mtr_t mtr;
page_t* bitmap_page;
ulint i;
diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h
index 516898066aa..4a54c30629b 100644
--- a/storage/innobase/include/buf0buf.h
+++ b/storage/innobase/include/buf0buf.h
@@ -65,6 +65,7 @@ struct fil_addr_t;
#define BUF_GET_POSSIBLY_FREED 16
/*!< Like BUF_GET, but do not mind
if the file page has been freed. */
+#define BUF_EVICT_IF_IN_POOL 20 /*!< evict a clean block if found */
/* @} */
/** @name Modes for buf_page_get_known_nowait */
/* @{ */
diff --git a/storage/innobase/include/buf0lru.h b/storage/innobase/include/buf0lru.h
index 3cc01473da1..54c001ce478 100644
--- a/storage/innobase/include/buf0lru.h
+++ b/storage/innobase/include/buf0lru.h
@@ -50,18 +50,14 @@ These are low-level functions
/** Minimum LRU list length for which the LRU_old pointer is defined */
#define BUF_LRU_OLD_MIN_LEN 512 /* 8 megabytes of 16k pages */
-/******************************************************************//**
-Flushes all dirty pages or removes all pages belonging
-to a given tablespace. A PROBLEM: if readahead is being started, what
-guarantees that it will not try to read in pages after this operation
-has completed? */
+/** Empty the flush list for all pages belonging to a tablespace.
+@param[in] id tablespace identifier
+@param[in] trx transaction, for checking for user interrupt;
+ or NULL if nothing is to be written
+@param[in] drop_ahi whether to drop the adaptive hash index */
+UNIV_INTERN
void
-buf_LRU_flush_or_remove_pages(
-/*==========================*/
- ulint id, /*!< in: space id */
- buf_remove_t buf_remove, /*!< in: remove or flush strategy */
- const trx_t* trx); /*!< to check if the operation must
- be interrupted */
+buf_LRU_flush_or_remove_pages(ulint id, const trx_t* trx, bool drop_ahi=false);
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
/********************************************************************//**
diff --git a/storage/innobase/include/buf0types.h b/storage/innobase/include/buf0types.h
index 102b831ec61..719699f5ee2 100644
--- a/storage/innobase/include/buf0types.h
+++ b/storage/innobase/include/buf0types.h
@@ -59,17 +59,6 @@ enum buf_flush_t {
BUF_FLUSH_N_TYPES /*!< index of last element + 1 */
};
-/** Algorithm to remove the pages for a tablespace from the buffer pool.
-See buf_LRU_flush_or_remove_pages(). */
-enum buf_remove_t {
- BUF_REMOVE_ALL_NO_WRITE, /*!< Remove all pages from the buffer
- pool, don't write or sync to disk */
- BUF_REMOVE_FLUSH_NO_WRITE, /*!< Remove only, from the flush list,
- don't write or sync to disk */
- BUF_REMOVE_FLUSH_WRITE /*!< Flush dirty pages to disk only
- don't remove from the buffer pool */
-};
-
/** Flags for io_fix types */
enum buf_io_fix {
BUF_IO_NONE = 0, /**< no pending I/O */
diff --git a/storage/innobase/include/fil0fil.h b/storage/innobase/include/fil0fil.h
index d3336c5f5b5..9fa507c2114 100644
--- a/storage/innobase/include/fil0fil.h
+++ b/storage/innobase/include/fil0fil.h
@@ -929,17 +929,12 @@ bool
fil_table_accessible(const dict_table_t* table)
MY_ATTRIBUTE((warn_unused_result, nonnull));
-/** Deletes an IBD tablespace, either general or single-table.
-The tablespace must be cached in the memory cache. This will delete the
-datafile, fil_space_t & fil_node_t entries from the file_system_t cache.
-@param[in] space_id Tablespace id
-@param[in] buf_remove Specify the action to take on the pages
-for this table in the buffer pool.
-@return true if success */
+/** Delete a tablespace and associated .ibd file.
+@param[in] id tablespace identifier
+@param[in] drop_ahi whether to drop the adaptive hash index
+@return DB_SUCCESS or error */
dberr_t
-fil_delete_tablespace(
- ulint id,
- buf_remove_t buf_remove);
+fil_delete_tablespace(ulint id, bool drop_ahi = false);
/** Truncate the tablespace to needed size.
@param[in] space_id id of tablespace to truncate
diff --git a/storage/innobase/row/row0import.cc b/storage/innobase/row/row0import.cc
index 1804cba7065..f06bc878c3b 100644
--- a/storage/innobase/row/row0import.cc
+++ b/storage/innobase/row/row0import.cc
@@ -1537,18 +1537,16 @@ PageConverter::PageConverter(
:
AbstractCallback(trx),
m_cfg(cfg),
+ m_index(cfg->m_indexes),
+ m_current_lsn(log_get_lsn()),
m_page_zip_ptr(0),
- m_heap(0) UNIV_NOTHROW
+ m_rec_iter(),
+ m_offsets_(), m_offsets(m_offsets_),
+ m_heap(0),
+ m_cluster_index(dict_table_get_first_index(cfg->m_table)) UNIV_NOTHROW
{
- m_index = m_cfg->m_indexes;
-
- m_current_lsn = log_get_lsn();
ut_a(m_current_lsn > 0);
-
- m_offsets = m_offsets_;
rec_offs_init(m_offsets_);
-
- m_cluster_index = dict_table_get_first_index(m_cfg->m_table);
}
/** Adjust the BLOB reference for a single column that is externally stored
@@ -2008,7 +2006,7 @@ PageConverter::operator() (
we can work on them */
if ((err = update_page(block, page_type)) != DB_SUCCESS) {
- return(err);
+ break;
}
/* Note: For compressed pages this function will write to the
@@ -2047,9 +2045,15 @@ PageConverter::operator() (
<< " at offset " << offset
<< " looks corrupted in file " << m_filepath;
- return(DB_CORRUPTION);
+ err = DB_CORRUPTION;
}
+ /* If we already had and old page with matching number
+ in the buffer pool, evict it now, because
+ we no longer evict the pages on DISCARD TABLESPACE. */
+ buf_page_get_gen(block->page.id, get_page_size(),
+ RW_NO_LATCH, NULL, BUF_EVICT_IF_IN_POOL,
+ __FILE__, __LINE__, NULL, NULL);
return(err);
}
@@ -3649,8 +3653,7 @@ row_import_for_mysql(
The only dirty pages generated should be from the pessimistic purge
of delete marked records that couldn't be purged in Phase I. */
- buf_LRU_flush_or_remove_pages(
- prebuilt->table->space, BUF_REMOVE_FLUSH_WRITE, trx);
+ buf_LRU_flush_or_remove_pages(prebuilt->table->space, trx);
if (trx_is_interrupted(trx)) {
ib::info() << "Phase III - Flush interrupted";
diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc
index 3f6fa713b6d..1b71751a9dd 100644
--- a/storage/innobase/row/row0mysql.cc
+++ b/storage/innobase/row/row0mysql.cc
@@ -2505,10 +2505,7 @@ err_exit:
/* We already have .ibd file here. it should be deleted. */
if (dict_table_is_file_per_table(table)
- && fil_delete_tablespace(
- table->space,
- BUF_REMOVE_FLUSH_NO_WRITE)
- != DB_SUCCESS) {
+ && fil_delete_tablespace(table->space) != DB_SUCCESS) {
ib::error() << "Not able to delete tablespace "
<< table->space << " of table "
@@ -3175,9 +3172,6 @@ row_discard_tablespace(
4) FOREIGN KEY operations: if table->n_foreign_key_checks_running > 0,
we do not allow the discard. */
- /* Play safe and remove all insert buffer entries, though we should
- have removed them already when DISCARD TABLESPACE was called */
-
ibuf_delete_for_discarded_space(table->space);
table_id_t new_id;
@@ -3542,8 +3536,7 @@ row_drop_single_table_tablespace(
ib::info() << "Removed datafile " << filepath
<< " for table " << tablename;
- } else if (fil_delete_tablespace(space_id, BUF_REMOVE_FLUSH_NO_WRITE)
- != DB_SUCCESS) {
+ } else if (fil_delete_tablespace(space_id) != DB_SUCCESS) {
ib::error() << "We removed the InnoDB internal data"
" dictionary entry of table " << tablename
diff --git a/storage/innobase/row/row0quiesce.cc b/storage/innobase/row/row0quiesce.cc
index 54583956107..ccf58b9e73f 100644
--- a/storage/innobase/row/row0quiesce.cc
+++ b/storage/innobase/row/row0quiesce.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -536,8 +537,7 @@ row_quiesce_table_start(
}
if (!trx_is_interrupted(trx)) {
- buf_LRU_flush_or_remove_pages(
- table->space, BUF_REMOVE_FLUSH_WRITE, trx);
+ buf_LRU_flush_or_remove_pages(table->space, trx);
if (trx_is_interrupted(trx)) {
diff --git a/storage/innobase/srv/srv0start.cc b/storage/innobase/srv/srv0start.cc
index d6dd5805186..dc1b1eca0ef 100644
--- a/storage/innobase/srv/srv0start.cc
+++ b/storage/innobase/srv/srv0start.cc
@@ -1100,21 +1100,22 @@ srv_undo_tablespaces_init(bool create_new_db)
mtr_commit(&mtr);
/* Step-2: Flush the dirty pages from the buffer pool. */
+ trx_t* trx = trx_allocate_for_background();
+
for (undo::undo_spaces_t::const_iterator it
= undo::Truncate::s_fix_up_spaces.begin();
it != undo::Truncate::s_fix_up_spaces.end();
++it) {
- buf_LRU_flush_or_remove_pages(
- TRX_SYS_SPACE, BUF_REMOVE_FLUSH_WRITE, NULL);
+ buf_LRU_flush_or_remove_pages(TRX_SYS_SPACE, trx);
- buf_LRU_flush_or_remove_pages(
- *it, BUF_REMOVE_FLUSH_WRITE, NULL);
+ buf_LRU_flush_or_remove_pages(*it, trx);
/* Remove the truncate redo log file. */
undo::Truncate undo_trunc;
undo_trunc.done_logging(*it);
}
+ trx_free_for_background(trx);
}
return(DB_SUCCESS);
diff --git a/storage/rocksdb/mysql-test/rocksdb/r/read_only_tx.result b/storage/rocksdb/mysql-test/rocksdb/r/read_only_tx.result
index b83f0a474cc..db21c3c01d4 100644
--- a/storage/rocksdb/mysql-test/rocksdb/r/read_only_tx.result
+++ b/storage/rocksdb/mysql-test/rocksdb/r/read_only_tx.result
@@ -1,11 +1,14 @@
DROP TABLE IF EXISTS t1;
+connect con1,localhost,root,,;
+connect con2,localhost,root,,;
+connection con1;
CREATE TABLE t1 (id INT, value int, PRIMARY KEY (id), INDEX (value)) ENGINE=RocksDB;
INSERT INTO t1 VALUES (1,1);
select variable_value into @p from information_schema.global_status where variable_name='rocksdb_number_sst_entry_put';
select variable_value into @s from information_schema.global_status where variable_name='rocksdb_number_sst_entry_singledelete';
-START TRANSACTION WITH CONSISTENT ROCKSDB SNAPSHOT;
-File Position Gtid_executed
-master-bin.000001 734 uuid:1-3
+START TRANSACTION WITH CONSISTENT SNAPSHOT;
+connection con2;
+connection con1;
select case when variable_value-@p < 1000 then 'true' else variable_value-@p end from information_schema.global_status where variable_name='rocksdb_number_sst_entry_put';
case when variable_value-@p < 1000 then 'true' else variable_value-@p end
true
@@ -27,10 +30,15 @@ id value
1 10001
2 2
BEGIN;
+connection con2;
+connection con1;
SELECT COUNT(*) FROM t1;
COUNT(*)
9998
COMMIT;
+connection default;
+disconnect con1;
+disconnect con2;
OPTIMIZE TABLE t1;
Table Op Msg_type Msg_text
test.t1 optimize status OK
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace_crash.test b/storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace_crash.test
index 84fe0046e7b..d715eb7df7a 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace_crash.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/add_index_inplace_crash.test
@@ -105,3 +105,13 @@ SHOW CREATE TABLE t1;
SELECT COUNT(*) FROM t1;
DROP TABLE t1;
+
+# Cleanup temporary #sql files. In the future server will remove these
+# automatically but for now we need to do the delete explicit
+
+--disable_query_log
+--disable_result_log
+let $datadir=`select @@datadir`;
+--remove_files_wildcard $datadir/test #sql*
+--enable_result_log
+--enable_query_log
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/disabled.def b/storage/rocksdb/mysql-test/rocksdb/t/disabled.def
index 54cafbf24ba..118d8598de3 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/disabled.def
+++ b/storage/rocksdb/mysql-test/rocksdb/t/disabled.def
@@ -82,5 +82,5 @@ autoinc_vars_thread: debug sync point wait timed out
##
information_schema : MariaRocks: requires GTIDs
mysqlbinlog_gtid_skip_empty_trans_rocksdb : MariaRocks: requires GTIDs
-read_only_tx : MariaRocks: requires GTIDs
+#read_only_tx : MariaRocks: requires GTIDs
rpl_row_triggers : MariaRocks: requires GTIDs
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/read_only_tx-master.opt b/storage/rocksdb/mysql-test/rocksdb/t/read_only_tx-master.opt
index 52f4895dc2f..221b35c672a 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/read_only_tx-master.opt
+++ b/storage/rocksdb/mysql-test/rocksdb/t/read_only_tx-master.opt
@@ -1 +1 @@
---rocksdb_default_cf_options=write_buffer_size=16k --log-bin --binlog_format=row --gtid_mode=ON --enforce_gtid_consistency --log-slave-updates
+--rocksdb_default_cf_options=write_buffer_size=16k --log-bin --binlog_format=row --log-slave-updates
diff --git a/storage/rocksdb/mysql-test/rocksdb/t/read_only_tx.test b/storage/rocksdb/mysql-test/rocksdb/t/read_only_tx.test
index 52f65095d33..3a1025a3623 100644
--- a/storage/rocksdb/mysql-test/rocksdb/t/read_only_tx.test
+++ b/storage/rocksdb/mysql-test/rocksdb/t/read_only_tx.test
@@ -2,9 +2,9 @@
--source include/have_rocksdb.inc
--source include/count_sessions.inc
--disable_warnings
---source include/have_gtid.inc
+#--source include/have_gtid.inc
--enable_warnings
--- let $uuid = `select @@server_uuid;`
+#-- let $uuid = `select @@server_uuid;`
--disable_warnings
DROP TABLE IF EXISTS t1;
@@ -20,8 +20,8 @@ INSERT INTO t1 VALUES (1,1);
# Read-only, long-running transaction. SingleDelete/Put shouldn't increase much.
select variable_value into @p from information_schema.global_status where variable_name='rocksdb_number_sst_entry_put';
select variable_value into @s from information_schema.global_status where variable_name='rocksdb_number_sst_entry_singledelete';
--- replace_result $uuid uuid
-START TRANSACTION WITH CONSISTENT ROCKSDB SNAPSHOT;
+#-- replace_result $uuid uuid
+START TRANSACTION WITH CONSISTENT SNAPSHOT;
connection con2;
--disable_query_log
diff --git a/storage/xtradb/buf/buf0buf.cc b/storage/xtradb/buf/buf0buf.cc
index 7eb0474091e..51e2453a853 100644
--- a/storage/xtradb/buf/buf0buf.cc
+++ b/storage/xtradb/buf/buf0buf.cc
@@ -730,6 +730,8 @@ buf_page_is_corrupted(
ulint zip_size,
const fil_space_t* space)
{
+ DBUG_EXECUTE_IF("buf_page_import_corrupt_failure", return(TRUE); );
+
ulint checksum_field1;
ulint checksum_field2;
ulint space_id = mach_read_from_4(
@@ -838,8 +840,6 @@ buf_page_is_corrupted(
return(false);
}
- DBUG_EXECUTE_IF("buf_page_is_corrupt_failure", return(true); );
-
ulint page_no = mach_read_from_4(read_buf + FIL_PAGE_OFFSET);
const srv_checksum_algorithm_t curr_algo =
@@ -2956,8 +2956,8 @@ buf_page_get_gen(
ib_mutex_t* fix_mutex = NULL;
buf_pool_t* buf_pool = buf_pool_get(space, offset);
- ut_ad(mtr);
- ut_ad(mtr->state == MTR_ACTIVE);
+ ut_ad((mtr == NULL) == (mode == BUF_EVICT_IF_IN_POOL));
+ ut_ad(!mtr || mtr->state == MTR_ACTIVE);
ut_ad((rw_latch == RW_S_LATCH)
|| (rw_latch == RW_X_LATCH)
|| (rw_latch == RW_NO_LATCH));
@@ -2968,23 +2968,29 @@ buf_page_get_gen(
#ifdef UNIV_DEBUG
switch (mode) {
+ case BUF_EVICT_IF_IN_POOL:
+ /* After DISCARD TABLESPACE, the tablespace would not exist,
+ but in IMPORT TABLESPACE, PageConverter::operator() must
+ replace any old pages, which were not evicted during DISCARD.
+ Skip the assertion on zip_size. */
+ break;
case BUF_GET_NO_LATCH:
ut_ad(rw_latch == RW_NO_LATCH);
- break;
+ /* fall through */
case BUF_GET:
case BUF_GET_IF_IN_POOL:
case BUF_PEEK_IF_IN_POOL:
case BUF_GET_IF_IN_POOL_OR_WATCH:
case BUF_GET_POSSIBLY_FREED:
+ ut_ad(zip_size == fil_space_get_zip_size(space));
break;
default:
ut_error;
}
#endif /* UNIV_DEBUG */
- ut_ad(zip_size == fil_space_get_zip_size(space));
ut_ad(ut_is_2pow(zip_size));
#ifndef UNIV_LOG_DEBUG
- ut_ad(!ibuf_inside(mtr)
+ ut_ad(!mtr || !ibuf_inside(mtr)
|| ibuf_page_low(space, zip_size, offset,
FALSE, file, line, NULL));
#endif
@@ -3054,9 +3060,11 @@ loop:
rw_lock_x_unlock(hash_lock);
}
- if (mode == BUF_GET_IF_IN_POOL
- || mode == BUF_PEEK_IF_IN_POOL
- || mode == BUF_GET_IF_IN_POOL_OR_WATCH) {
+ switch (mode) {
+ case BUF_GET_IF_IN_POOL:
+ case BUF_GET_IF_IN_POOL_OR_WATCH:
+ case BUF_PEEK_IF_IN_POOL:
+ case BUF_EVICT_IF_IN_POOL:
#ifdef UNIV_SYNC_DEBUG
ut_ad(!rw_lock_own(hash_lock, RW_LOCK_EX));
ut_ad(!rw_lock_own(hash_lock, RW_LOCK_SHARED));
@@ -3145,8 +3153,10 @@ got_block:
ut_ad(page_zip_get_size(&block->page.zip) == zip_size);
- if (mode == BUF_GET_IF_IN_POOL || mode == BUF_PEEK_IF_IN_POOL) {
-
+ switch (mode) {
+ case BUF_GET_IF_IN_POOL:
+ case BUF_PEEK_IF_IN_POOL:
+ case BUF_EVICT_IF_IN_POOL:
bool must_read;
{
@@ -3184,6 +3194,22 @@ got_block:
case BUF_BLOCK_FILE_PAGE:
ut_ad(fix_mutex != &buf_pool->zip_mutex);
+
+ if (UNIV_UNLIKELY(mode == BUF_EVICT_IF_IN_POOL)) {
+evict_from_pool:
+ ut_ad(!fix_block->page.oldest_modification);
+ mutex_enter(&buf_pool->LRU_list_mutex);
+ buf_block_unfix(fix_block);
+ mutex_enter(fix_mutex);
+
+ if (!buf_LRU_free_page(&fix_block->page, true)) {
+ ut_ad(0);
+ mutex_exit(&buf_pool->LRU_list_mutex);
+ }
+
+ mutex_exit(fix_mutex);
+ return(NULL);
+ }
break;
case BUF_BLOCK_ZIP_PAGE:
@@ -3218,6 +3244,10 @@ got_block:
goto loop;
}
+ if (UNIV_UNLIKELY(mode == BUF_EVICT_IF_IN_POOL)) {
+ goto evict_from_pool;
+ }
+
/* Buffer-fix the block so that it cannot be evicted
or relocated while we are attempting to allocate an
uncompressed page. */
@@ -4798,7 +4828,7 @@ database_corrupted:
if (err != DB_SUCCESS) {
/* Not a real corruption if it was triggered by
error injection */
- DBUG_EXECUTE_IF("buf_page_is_corrupt_failure",
+ DBUG_EXECUTE_IF("buf_page_import_corrupt_failure",
if (bpage->space > TRX_SYS_SPACE) {
buf_mark_space_corrupt(bpage);
ib_logf(IB_LOG_LEVEL_INFO,
@@ -4866,7 +4896,7 @@ database_corrupted:
}
}
- DBUG_EXECUTE_IF("buf_page_is_corrupt_failure",
+ DBUG_EXECUTE_IF("buf_page_import_corrupt_failure",
page_not_corrupt: bpage = bpage; );
if (recv_recovery_is_on()) {
diff --git a/storage/xtradb/buf/buf0lru.cc b/storage/xtradb/buf/buf0lru.cc
index d979eb44a96..c71d45009e4 100644
--- a/storage/xtradb/buf/buf0lru.cc
+++ b/storage/xtradb/buf/buf0lru.cc
@@ -571,26 +571,20 @@ buf_flush_or_remove_page(
return(processed);
}
-/******************************************************************//**
-Remove all dirty pages belonging to a given tablespace inside a specific
+/** Remove all dirty pages belonging to a given tablespace inside a specific
buffer pool instance when we are deleting the data file(s) of that
tablespace. The pages still remain a part of LRU and are evicted from
the list as they age towards the tail of the LRU.
+@param[in,out] buf_pool buffer pool
+@param[in] id tablespace identifier
+@param[in] trx transaction (to check for interrupt),
+ or NULL if the files should not be written to
@retval DB_SUCCESS if all freed
@retval DB_FAIL if not all freed
@retval DB_INTERRUPTED if the transaction was interrupted */
static MY_ATTRIBUTE((nonnull(1), warn_unused_result))
dberr_t
-buf_flush_or_remove_pages(
-/*======================*/
- buf_pool_t* buf_pool, /*!< buffer pool instance */
- ulint id, /*!< in: target space id for which
- to remove or flush pages */
- bool flush, /*!< in: flush to disk if true but
- don't remove else remove without
- flushing to disk */
- const trx_t* trx) /*!< to check if the operation must
- be interrupted, can be 0 */
+buf_flush_or_remove_pages(buf_pool_t* buf_pool, ulint id, const trx_t* trx)
{
buf_page_t* prev;
buf_page_t* bpage;
@@ -621,7 +615,7 @@ rescan:
/* Skip this block, as it does not belong to
the target space. */
- } else if (!buf_flush_or_remove_page(buf_pool, bpage, flush,
+ } else if (!buf_flush_or_remove_page(buf_pool, bpage, trx,
&must_restart)) {
/* Remove was unsuccessful, we have to try again
@@ -647,7 +641,7 @@ rescan:
/* Cannot trust the prev pointer */
break;
}
- } else if (flush) {
+ } else if (trx) {
/* The processing was successful. And during the
processing we have released all the buf_pool mutexes
@@ -674,19 +668,17 @@ rescan:
break;
}
-#ifdef DBUG_OFF
- if (flush) {
+ if (trx) {
DBUG_EXECUTE_IF("ib_export_flush_crash",
static ulint n_pages;
if (++n_pages == 4) {DBUG_SUICIDE();});
- }
-#endif /* DBUG_OFF */
- /* The check for trx is interrupted is expensive, we want
- to check every N iterations. */
- if (!processed && trx && trx_is_interrupted(trx)) {
- buf_flush_list_mutex_exit(buf_pool);
- return(DB_INTERRUPTED);
+ /* The check for trx is interrupted is
+ expensive, we want to check every N iterations. */
+ if (!processed && trx_is_interrupted(trx)) {
+ buf_flush_list_mutex_exit(buf_pool);
+ return(DB_INTERRUPTED);
+ }
}
}
@@ -695,28 +687,25 @@ rescan:
return(all_freed ? DB_SUCCESS : DB_FAIL);
}
-/******************************************************************//**
-Remove or flush all the dirty pages that belong to a given tablespace
+/** Remove or flush all the dirty pages that belong to a given tablespace
inside a specific buffer pool instance. The pages will remain in the LRU
list and will be evicted from the LRU list as they age and move towards
-the tail of the LRU list. */
+the tail of the LRU list.
+@param[in,out] buf_pool buffer pool
+@param[in] id tablespace identifier
+@param[in] trx transaction (to check for interrupt),
+ or NULL if the files should not be written to
+*/
static MY_ATTRIBUTE((nonnull(1)))
void
-buf_flush_dirty_pages(
-/*==================*/
- buf_pool_t* buf_pool, /*!< buffer pool instance */
- ulint id, /*!< in: space id */
- bool flush, /*!< in: flush to disk if true otherwise
- remove the pages without flushing */
- const trx_t* trx) /*!< to check if the operation must
- be interrupted */
+buf_flush_dirty_pages(buf_pool_t* buf_pool, ulint id, const trx_t* trx)
{
dberr_t err;
do {
mutex_enter(&buf_pool->LRU_list_mutex);
- err = buf_flush_or_remove_pages(buf_pool, id, flush, trx);
+ err = buf_flush_or_remove_pages(buf_pool, id, trx);
mutex_exit(&buf_pool->LRU_list_mutex);
@@ -737,239 +726,27 @@ buf_flush_dirty_pages(
|| buf_pool_get_dirty_pages_count(buf_pool, id) == 0);
}
-/******************************************************************//**
-Remove all pages that belong to a given tablespace inside a specific
-buffer pool instance when we are DISCARDing the tablespace. */
-static MY_ATTRIBUTE((nonnull))
+/** Empty the flush list for all pages belonging to a tablespace.
+@param[in] id tablespace identifier
+@param[in] trx transaction, for checking for user interrupt;
+ or NULL if nothing is to be written
+@param[in] drop_ahi whether to drop the adaptive hash index */
+UNIV_INTERN
void
-buf_LRU_remove_all_pages(
-/*=====================*/
- buf_pool_t* buf_pool, /*!< buffer pool instance */
- ulint id) /*!< in: space id */
+buf_LRU_flush_or_remove_pages(ulint id, const trx_t* trx, bool drop_ahi)
{
- buf_page_t* bpage;
- ibool all_freed;
-
-scan_again:
- mutex_enter(&buf_pool->LRU_list_mutex);
-
- all_freed = TRUE;
-
- for (bpage = UT_LIST_GET_LAST(buf_pool->LRU);
- bpage != NULL;
- /* No op */) {
-
- prio_rw_lock_t* hash_lock;
- buf_page_t* prev_bpage;
- ib_mutex_t* block_mutex = NULL;
-
- ut_a(buf_page_in_file(bpage));
- ut_ad(bpage->in_LRU_list);
-
- prev_bpage = UT_LIST_GET_PREV(LRU, bpage);
-
- /* It is safe to check bpage->space and bpage->io_fix while
- holding buf_pool->LRU_list_mutex only and later recheck
- while holding the buf_page_get_mutex() mutex. */
-
- if (buf_page_get_space(bpage) != id) {
- /* Skip this block, as it does not belong to
- the space that is being invalidated. */
- goto next_page;
- } else if (UNIV_UNLIKELY(buf_page_get_io_fix_unlocked(bpage)
- != BUF_IO_NONE)) {
- /* We cannot remove this page during this scan
- yet; maybe the system is currently reading it
- in, or flushing the modifications to the file */
-
- all_freed = FALSE;
- goto next_page;
- } else {
- ulint fold = buf_page_address_fold(
- bpage->space, bpage->offset);
-
- hash_lock = buf_page_hash_lock_get(buf_pool, fold);
-
- rw_lock_x_lock(hash_lock);
-
- block_mutex = buf_page_get_mutex(bpage);
- mutex_enter(block_mutex);
-
- if (UNIV_UNLIKELY(
- buf_page_get_space(bpage) != id
- || bpage->buf_fix_count > 0
- || (buf_page_get_io_fix(bpage)
- != BUF_IO_NONE))) {
-
- mutex_exit(block_mutex);
-
- rw_lock_x_unlock(hash_lock);
-
- /* We cannot remove this page during
- this scan yet; maybe the system is
- currently reading it in, or flushing
- the modifications to the file */
-
- all_freed = FALSE;
-
- goto next_page;
- }
- }
-
- ut_ad(mutex_own(block_mutex));
-
-#ifdef UNIV_DEBUG
- if (buf_debug_prints) {
- fprintf(stderr,
- "Dropping space %lu page %lu\n",
- (ulong) buf_page_get_space(bpage),
- (ulong) buf_page_get_page_no(bpage));
- }
-#endif
- if (buf_page_get_state(bpage) != BUF_BLOCK_FILE_PAGE) {
- /* Do nothing, because the adaptive hash index
- covers uncompressed pages only. */
- } else if (((buf_block_t*) bpage)->index) {
- ulint page_no;
- ulint zip_size;
-
- mutex_exit(&buf_pool->LRU_list_mutex);
-
- zip_size = buf_page_get_zip_size(bpage);
- page_no = buf_page_get_page_no(bpage);
-
- mutex_exit(block_mutex);
-
- rw_lock_x_unlock(hash_lock);
-
- /* Note that the following call will acquire
- and release block->lock X-latch. */
-
- btr_search_drop_page_hash_when_freed(
- id, zip_size, page_no);
-
- goto scan_again;
- }
-
- if (bpage->oldest_modification != 0) {
-
- buf_flush_remove(bpage);
- }
-
- ut_ad(!bpage->in_flush_list);
-
- /* Remove from the LRU list. */
-
- if (buf_LRU_block_remove_hashed(bpage, true)) {
-
- mutex_enter(block_mutex);
- buf_LRU_block_free_hashed_page((buf_block_t*) bpage);
- mutex_exit(block_mutex);
- } else {
- ut_ad(block_mutex == &buf_pool->zip_mutex);
+ for (ulint i = 0; i < srv_buf_pool_instances; i++) {
+ buf_pool_t* buf_pool = buf_pool_from_array(i);
+ if (drop_ahi) {
+ buf_LRU_drop_page_hash_for_tablespace(buf_pool, id);
}
-
- ut_ad(!mutex_own(block_mutex));
-
-#ifdef UNIV_SYNC_DEBUG
- /* buf_LRU_block_remove_hashed() releases the hash_lock */
- ut_ad(!rw_lock_own(hash_lock, RW_LOCK_EX));
- ut_ad(!rw_lock_own(hash_lock, RW_LOCK_SHARED));
-#endif /* UNIV_SYNC_DEBUG */
-
-next_page:
- bpage = prev_bpage;
+ buf_flush_dirty_pages(buf_pool, id, trx);
}
- mutex_exit(&buf_pool->LRU_list_mutex);
-
- if (!all_freed) {
- os_thread_sleep(20000);
-
- goto scan_again;
- }
-}
-
-/******************************************************************//**
-Remove pages belonging to a given tablespace inside a specific
-buffer pool instance when we are deleting the data file(s) of that
-tablespace. The pages still remain a part of LRU and are evicted from
-the list as they age towards the tail of the LRU only if buf_remove
-is BUF_REMOVE_FLUSH_NO_WRITE. */
-static MY_ATTRIBUTE((nonnull(1)))
-void
-buf_LRU_remove_pages(
-/*=================*/
- buf_pool_t* buf_pool, /*!< buffer pool instance */
- ulint id, /*!< in: space id */
- buf_remove_t buf_remove, /*!< in: remove or flush strategy */
- const trx_t* trx) /*!< to check if the operation must
- be interrupted */
-{
- switch (buf_remove) {
- case BUF_REMOVE_ALL_NO_WRITE:
- buf_LRU_remove_all_pages(buf_pool, id);
- break;
-
- case BUF_REMOVE_FLUSH_NO_WRITE:
- ut_a(trx == 0);
- buf_flush_dirty_pages(buf_pool, id, false, NULL);
- break;
-
- case BUF_REMOVE_FLUSH_WRITE:
- ut_a(trx != 0);
- buf_flush_dirty_pages(buf_pool, id, true, trx);
+ if (trx && !trx_is_interrupted(trx)) {
/* Ensure that all asynchronous IO is completed. */
os_aio_wait_until_no_pending_writes();
fil_flush(id);
- break;
- }
-}
-
-/******************************************************************//**
-Flushes all dirty pages or removes all pages belonging
-to a given tablespace. A PROBLEM: if readahead is being started, what
-guarantees that it will not try to read in pages after this operation
-has completed? */
-UNIV_INTERN
-void
-buf_LRU_flush_or_remove_pages(
-/*==========================*/
- ulint id, /*!< in: space id */
- buf_remove_t buf_remove, /*!< in: remove or flush strategy */
- const trx_t* trx) /*!< to check if the operation must
- be interrupted */
-{
- ulint i;
-
- /* Before we attempt to drop pages one by one we first
- attempt to drop page hash index entries in batches to make
- it more efficient. The batching attempt is a best effort
- attempt and does not guarantee that all pages hash entries
- will be dropped. We get rid of remaining page hash entries
- one by one below. */
- for (i = 0; i < srv_buf_pool_instances; i++) {
- buf_pool_t* buf_pool;
-
- buf_pool = buf_pool_from_array(i);
-
- switch (buf_remove) {
- case BUF_REMOVE_ALL_NO_WRITE:
- buf_LRU_drop_page_hash_for_tablespace(buf_pool, id);
- break;
-
- case BUF_REMOVE_FLUSH_NO_WRITE:
- /* It is a DROP TABLE for a single table
- tablespace. No AHI entries exist because
- we already dealt with them when freeing up
- extents. */
- case BUF_REMOVE_FLUSH_WRITE:
- /* We allow read-only queries against the
- table, there is no need to drop the AHI entries. */
- break;
- }
-
- buf_LRU_remove_pages(buf_pool, id, buf_remove, trx);
}
}
diff --git a/storage/xtradb/dict/dict0dict.cc b/storage/xtradb/dict/dict0dict.cc
index 1558c6d50ac..5af3a635a96 100644
--- a/storage/xtradb/dict/dict0dict.cc
+++ b/storage/xtradb/dict/dict0dict.cc
@@ -1679,7 +1679,7 @@ dict_table_rename_in_cache(
filepath = fil_make_ibd_name(table->name, false);
}
- fil_delete_tablespace(table->space, BUF_REMOVE_ALL_NO_WRITE);
+ fil_delete_tablespace(table->space, true);
/* Delete any temp file hanging around. */
if (os_file_status(filepath, &exists, &ftype)
diff --git a/storage/xtradb/fil/fil0fil.cc b/storage/xtradb/fil/fil0fil.cc
index 3dd8aa8081b..445c564e9cf 100644
--- a/storage/xtradb/fil/fil0fil.cc
+++ b/storage/xtradb/fil/fil0fil.cc
@@ -2572,8 +2572,7 @@ fil_op_log_parse_or_replay(
switch (type) {
case MLOG_FILE_DELETE:
if (fil_tablespace_exists_in_mem(space_id)) {
- dberr_t err = fil_delete_tablespace(
- space_id, BUF_REMOVE_FLUSH_NO_WRITE);
+ dberr_t err = fil_delete_tablespace(space_id);
ut_a(err == DB_SUCCESS);
}
@@ -2851,7 +2850,7 @@ fil_close_tablespace(
completely and permanently. The flag stop_new_ops also prevents
fil_flush() from being applied to this tablespace. */
- buf_LRU_flush_or_remove_pages(id, BUF_REMOVE_FLUSH_WRITE, trx);
+ buf_LRU_flush_or_remove_pages(id, trx);
#endif
mutex_enter(&fil_system->mutex);
@@ -2878,18 +2877,13 @@ fil_close_tablespace(
return(err);
}
-/*******************************************************************//**
-Deletes a single-table tablespace. The tablespace must be cached in the
-memory cache.
+/** Delete a tablespace and associated .ibd file.
+@param[in] id tablespace identifier
+@param[in] drop_ahi whether to drop the adaptive hash index
@return DB_SUCCESS or error */
UNIV_INTERN
dberr_t
-fil_delete_tablespace(
-/*==================*/
- ulint id, /*!< in: space id */
- buf_remove_t buf_remove) /*!< in: specify the action to take
- on the tables pages in the buffer
- pool */
+fil_delete_tablespace(ulint id, bool drop_ahi)
{
char* path = 0;
fil_space_t* space = 0;
@@ -2945,7 +2939,7 @@ fil_delete_tablespace(
To deal with potential read requests by checking the
::stop_new_ops flag in fil_io() */
- buf_LRU_flush_or_remove_pages(id, buf_remove, 0);
+ buf_LRU_flush_or_remove_pages(id, NULL, drop_ahi);
#endif /* !UNIV_HOTBACKUP */
@@ -3056,7 +3050,7 @@ fil_discard_tablespace(
{
dberr_t err;
- switch (err = fil_delete_tablespace(id, BUF_REMOVE_ALL_NO_WRITE)) {
+ switch (err = fil_delete_tablespace(id, true)) {
case DB_SUCCESS:
break;
@@ -4863,7 +4857,7 @@ fil_load_single_table_tablespace(
/* Check for a link file which locates a remote tablespace. */
- remote.success = fil_open_linked_file(
+ remote.success = (IS_XTRABACKUP() && !srv_backup_mode) ? 0 : fil_open_linked_file(
tablename, &remote.filepath, &remote.file, FALSE);
/* Read the first page of the remote tablespace */
diff --git a/storage/xtradb/handler/ha_innodb.cc b/storage/xtradb/handler/ha_innodb.cc
index 9a1a387e1d7..987e86c3927 100644
--- a/storage/xtradb/handler/ha_innodb.cc
+++ b/storage/xtradb/handler/ha_innodb.cc
@@ -10947,7 +10947,7 @@ wsrep_append_foreign_key(
shared ? WSREP_KEY_SHARED : WSREP_KEY_EXCLUSIVE,
copy);
if (rcode) {
- DBUG_PRINT("wsrep", ("row key failed: %lu", rcode));
+ DBUG_PRINT("wsrep", ("row key failed: %zu", rcode));
WSREP_ERROR("Appending cascaded fk row key failed: %s, %lu",
(wsrep_thd_query(thd)) ?
wsrep_thd_query(thd) : "void", rcode);
@@ -19714,7 +19714,7 @@ wsrep_innobase_kill_one_trx(
wsrep_thd_awake(thd, signal);
} else {
/* abort currently executing query */
- DBUG_PRINT("wsrep",("sending KILL_QUERY to: %ld",
+ DBUG_PRINT("wsrep",("sending KILL_QUERY to: %lu",
thd_get_thread_id(thd)));
WSREP_DEBUG("kill query for: %ld",
thd_get_thread_id(thd));
@@ -19841,7 +19841,8 @@ wsrep_fake_trx_id(
mutex_enter(&trx_sys->mutex);
trx_id_t trx_id = trx_sys_get_new_trx_id();
mutex_exit(&trx_sys->mutex);
- WSREP_DEBUG("innodb fake trx id: %lu thd: %s", trx_id, wsrep_thd_query(thd));
+ WSREP_DEBUG("innodb fake trx id: " TRX_ID_FMT " thd: %s",
+ trx_id, wsrep_thd_query(thd));
wsrep_ws_handle_for_trx(wsrep_thd_ws_handle(thd), trx_id);
}
diff --git a/storage/xtradb/ibuf/ibuf0ibuf.cc b/storage/xtradb/ibuf/ibuf0ibuf.cc
index 17741b324c9..6925cd3abb5 100644
--- a/storage/xtradb/ibuf/ibuf0ibuf.cc
+++ b/storage/xtradb/ibuf/ibuf0ibuf.cc
@@ -5178,7 +5178,20 @@ ibuf_check_bitmap_on_import(
return(DB_TABLE_NOT_FOUND);
}
- size = fil_space_get_size(space_id);
+ mtr_t mtr;
+ mtr_start(&mtr);
+ {
+ buf_block_t* sp = buf_page_get(space_id, zip_size, 0,
+ RW_S_LATCH, &mtr);
+ if (sp) {
+ size = mach_read_from_4(
+ FSP_HEADER_OFFSET + FSP_FREE_LIMIT
+ + sp->frame);
+ } else {
+ size = 0;
+ }
+ }
+ mtr_commit(&mtr);
if (size == 0) {
return(DB_TABLE_NOT_FOUND);
@@ -5189,7 +5202,6 @@ ibuf_check_bitmap_on_import(
page_size = zip_size ? zip_size : UNIV_PAGE_SIZE;
for (page_no = 0; page_no < size; page_no += page_size) {
- mtr_t mtr;
page_t* bitmap_page;
ulint i;
diff --git a/storage/xtradb/include/buf0buf.h b/storage/xtradb/include/buf0buf.h
index 88ee042e8c3..7661ba1785d 100644
--- a/storage/xtradb/include/buf0buf.h
+++ b/storage/xtradb/include/buf0buf.h
@@ -58,6 +58,7 @@ Created 11/5/1995 Heikki Tuuri
#define BUF_GET_POSSIBLY_FREED 16
/*!< Like BUF_GET, but do not mind
if the file page has been freed. */
+#define BUF_EVICT_IF_IN_POOL 20 /*!< evict a clean block if found */
/* @} */
/** @name Modes for buf_page_get_known_nowait */
/* @{ */
diff --git a/storage/xtradb/include/buf0lru.h b/storage/xtradb/include/buf0lru.h
index f056c6c4116..1bc11937fa1 100644
--- a/storage/xtradb/include/buf0lru.h
+++ b/storage/xtradb/include/buf0lru.h
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 1995, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -53,19 +54,14 @@ These are low-level functions
/** Minimum LRU list length for which the LRU_old pointer is defined */
#define BUF_LRU_OLD_MIN_LEN 512 /* 8 megabytes of 16k pages */
-/******************************************************************//**
-Flushes all dirty pages or removes all pages belonging
-to a given tablespace. A PROBLEM: if readahead is being started, what
-guarantees that it will not try to read in pages after this operation
-has completed? */
+/** Empty the flush list for all pages belonging to a tablespace.
+@param[in] id tablespace identifier
+@param[in] trx transaction, for checking for user interrupt;
+ or NULL if nothing is to be written
+@param[in] drop_ahi whether to drop the adaptive hash index */
UNIV_INTERN
void
-buf_LRU_flush_or_remove_pages(
-/*==========================*/
- ulint id, /*!< in: space id */
- buf_remove_t buf_remove, /*!< in: remove or flush strategy */
- const trx_t* trx); /*!< to check if the operation must
- be interrupted */
+buf_LRU_flush_or_remove_pages(ulint id, const trx_t* trx, bool drop_ahi=false);
#if defined UNIV_DEBUG || defined UNIV_BUF_DEBUG
/********************************************************************//**
diff --git a/storage/xtradb/include/buf0types.h b/storage/xtradb/include/buf0types.h
index 4eb5ea18cef..6db3cb1238c 100644
--- a/storage/xtradb/include/buf0types.h
+++ b/storage/xtradb/include/buf0types.h
@@ -58,17 +58,6 @@ enum buf_flush_t {
BUF_FLUSH_N_TYPES /*!< index of last element + 1 */
};
-/** Algorithm to remove the pages for a tablespace from the buffer pool.
-See buf_LRU_flush_or_remove_pages(). */
-enum buf_remove_t {
- BUF_REMOVE_ALL_NO_WRITE, /*!< Remove all pages from the buffer
- pool, don't write or sync to disk */
- BUF_REMOVE_FLUSH_NO_WRITE, /*!< Remove only, from the flush list,
- don't write or sync to disk */
- BUF_REMOVE_FLUSH_WRITE /*!< Flush dirty pages to disk only
- don't remove from the buffer pool */
-};
-
/** Flags for io_fix types */
enum buf_io_fix {
BUF_IO_NONE = 0, /**< no pending I/O */
diff --git a/storage/xtradb/include/fil0fil.h b/storage/xtradb/include/fil0fil.h
index a33cec65ed5..5fe2d20b4f0 100644
--- a/storage/xtradb/include/fil0fil.h
+++ b/storage/xtradb/include/fil0fil.h
@@ -849,18 +849,13 @@ fil_op_log_parse_or_replay(
only be parsed but not replayed */
ulint log_flags); /*!< in: redo log flags
(stored in the page number parameter) */
-/*******************************************************************//**
-Deletes a single-table tablespace. The tablespace must be cached in the
-memory cache.
-@return TRUE if success */
+/** Delete a tablespace and associated .ibd file.
+@param[in] id tablespace identifier
+@param[in] drop_ahi whether to drop the adaptive hash index
+@return DB_SUCCESS or error */
UNIV_INTERN
dberr_t
-fil_delete_tablespace(
-/*==================*/
- ulint id, /*!< in: space id */
- buf_remove_t buf_remove); /*!< in: specify the action to take
- on the tables pages in the buffer
- pool */
+fil_delete_tablespace(ulint id, bool drop_ahi = false);
/*******************************************************************//**
Closes a single-table tablespace. The tablespace must be cached in the
memory cache. Free all pages used by the tablespace.
diff --git a/storage/xtradb/lock/lock0lock.cc b/storage/xtradb/lock/lock0lock.cc
index 8759cea9e6d..ddaeff69f10 100644
--- a/storage/xtradb/lock/lock0lock.cc
+++ b/storage/xtradb/lock/lock0lock.cc
@@ -2141,6 +2141,7 @@ lock_rec_insert_by_trx_age(
return DB_SUCCESS;
}
+#ifdef UNIV_DEBUG
static
bool
lock_queue_validate(
@@ -2174,6 +2175,7 @@ lock_queue_validate(
}
return true;
}
+#endif /* UNIV_DEBUG */
static
void
diff --git a/storage/xtradb/os/os0file.cc b/storage/xtradb/os/os0file.cc
index 183f65bcbd8..8b0fa059100 100644
--- a/storage/xtradb/os/os0file.cc
+++ b/storage/xtradb/os/os0file.cc
@@ -2570,8 +2570,8 @@ os_file_get_size(
return(offset);
#else
- return((os_offset_t) lseek(file, 0, SEEK_END));
-
+ struct stat statbuf;
+ return fstat(file, &statbuf) ? os_offset_t(-1) : statbuf.st_size;
#endif /* __WIN__ */
}
@@ -2625,19 +2625,29 @@ os_file_set_size(
if (srv_use_posix_fallocate) {
int err;
do {
- err = posix_fallocate(file, 0, size);
+ os_offset_t current_size = os_file_get_size(file);
+ err = current_size >= size
+ ? 0 : posix_fallocate(file, current_size,
+ size - current_size);
} while (err == EINTR
&& srv_shutdown_state == SRV_SHUTDOWN_NONE);
- if (err) {
+ switch (err) {
+ case 0:
+ return true;
+ default:
ib_logf(IB_LOG_LEVEL_ERROR,
"preallocating " INT64PF " bytes for"
"file %s failed with error %d",
size, name, err);
+ /* fall through */
+ case EINTR:
+ errno = err;
+ return false;
+ case EINVAL:
+ /* fall back to the code below */
+ break;
}
- /* Set errno because posix_fallocate() does not do it.*/
- errno = err;
- return(!err);
}
# endif
@@ -2679,11 +2689,12 @@ os_file_set_size(
}
current_size += n_bytes;
- } while (current_size < size);
+ } while (current_size < size
+ && srv_shutdown_state == SRV_SHUTDOWN_NONE);
free(buf2);
- return(ret && os_file_flush(file));
+ return(ret && current_size >= size && os_file_flush(file));
#endif
}
diff --git a/storage/xtradb/row/row0import.cc b/storage/xtradb/row/row0import.cc
index 130f50ec9ed..7689c362c0d 100644
--- a/storage/xtradb/row/row0import.cc
+++ b/storage/xtradb/row/row0import.cc
@@ -1602,18 +1602,16 @@ PageConverter::PageConverter(
:
AbstractCallback(trx),
m_cfg(cfg),
+ m_index(cfg->m_indexes),
+ m_current_lsn(log_get_lsn()),
m_page_zip_ptr(0),
- m_heap(0) UNIV_NOTHROW
+ m_rec_iter(),
+ m_offsets_(), m_offsets(m_offsets_),
+ m_heap(0),
+ m_cluster_index(dict_table_get_first_index(cfg->m_table)) UNIV_NOTHROW
{
- m_index = m_cfg->m_indexes;
-
- m_current_lsn = log_get_lsn();
ut_a(m_current_lsn > 0);
-
- m_offsets = m_offsets_;
rec_offs_init(m_offsets_);
-
- m_cluster_index = dict_table_get_first_index(m_cfg->m_table);
}
/**
@@ -2104,7 +2102,7 @@ PageConverter::operator() (
we can work on them */
if ((err = update_page(block, page_type)) != DB_SUCCESS) {
- return(err);
+ break;
}
/* Note: For compressed pages this function will write to the
@@ -2141,9 +2139,15 @@ PageConverter::operator() (
"%s: Page %lu at offset " UINT64PF " looks corrupted.",
m_filepath, (ulong) (offset / m_page_size), offset);
- return(DB_CORRUPTION);
+ err = DB_CORRUPTION;
}
+ /* If we already had and old page with matching number
+ in the buffer pool, evict it now, because
+ we no longer evict the pages on DISCARD TABLESPACE. */
+ buf_page_get_gen(get_space_id(), get_zip_size(), block->page.offset,
+ RW_NO_LATCH, NULL, BUF_EVICT_IF_IN_POOL,
+ __FILE__, __LINE__, NULL);
return(err);
}
@@ -3717,8 +3721,7 @@ row_import_for_mysql(
The only dirty pages generated should be from the pessimistic purge
of delete marked records that couldn't be purged in Phase I. */
- buf_LRU_flush_or_remove_pages(
- prebuilt->table->space, BUF_REMOVE_FLUSH_WRITE, trx);
+ buf_LRU_flush_or_remove_pages(prebuilt->table->space, trx);
if (trx_is_interrupted(trx)) {
ib_logf(IB_LOG_LEVEL_INFO, "Phase III - Flush interrupted");
diff --git a/storage/xtradb/row/row0mysql.cc b/storage/xtradb/row/row0mysql.cc
index 67eb1d7de94..3f79c3af6c8 100644
--- a/storage/xtradb/row/row0mysql.cc
+++ b/storage/xtradb/row/row0mysql.cc
@@ -2494,10 +2494,7 @@ err_exit:
/* We already have .ibd file here. it should be deleted. */
if (table->space
- && fil_delete_tablespace(
- table->space,
- BUF_REMOVE_FLUSH_NO_WRITE)
- != DB_SUCCESS) {
+ && fil_delete_tablespace(table->space) != DB_SUCCESS) {
ut_print_timestamp(stderr);
fprintf(stderr,
@@ -3132,9 +3129,6 @@ row_discard_tablespace(
4) FOREIGN KEY operations: if table->n_foreign_key_checks_running > 0,
we do not allow the discard. */
- /* Play safe and remove all insert buffer entries, though we should
- have removed them already when DISCARD TABLESPACE was called */
-
ibuf_delete_for_discarded_space(table->space);
table_id_t new_id;
@@ -4516,9 +4510,7 @@ row_drop_table_for_mysql(
fil_delete_file(filepath);
- } else if (fil_delete_tablespace(
- space_id,
- BUF_REMOVE_FLUSH_NO_WRITE)
+ } else if (fil_delete_tablespace(space_id)
!= DB_SUCCESS) {
fprintf(stderr,
"InnoDB: We removed now the InnoDB"
diff --git a/storage/xtradb/row/row0quiesce.cc b/storage/xtradb/row/row0quiesce.cc
index 583fbe60fb3..6c4e6adb96c 100644
--- a/storage/xtradb/row/row0quiesce.cc
+++ b/storage/xtradb/row/row0quiesce.cc
@@ -1,6 +1,7 @@
/*****************************************************************************
Copyright (c) 2012, 2016, Oracle and/or its affiliates. All Rights Reserved.
+Copyright (c) 2017, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -542,8 +543,7 @@ row_quiesce_table_start(
}
if (!trx_is_interrupted(trx)) {
- buf_LRU_flush_or_remove_pages(
- table->space, BUF_REMOVE_FLUSH_WRITE, trx);
+ buf_LRU_flush_or_remove_pages(table->space, trx);
if (trx_is_interrupted(trx)) {
diff --git a/storage/xtradb/trx/trx0undo.cc b/storage/xtradb/trx/trx0undo.cc
index 0cc3048e624..3259bcb70b1 100644
--- a/storage/xtradb/trx/trx0undo.cc
+++ b/storage/xtradb/trx/trx0undo.cc
@@ -2025,6 +2025,7 @@ trx_undo_free_prepared(
/* lock_trx_release_locks() assigns
trx->is_recovered=false */
ut_a(srv_read_only_mode
+ || srv_apply_log_only
|| srv_force_recovery >= SRV_FORCE_NO_TRX_UNDO);
break;
default: