1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-08 11:22:35 +03:00

Merge remote-tracking branch 'origin/10.2' into bb-10.2-ext

This commit is contained in:
Alexander Barkov
2016-12-27 07:07:36 +04:00
101 changed files with 1247 additions and 853 deletions

View File

@@ -67,7 +67,7 @@ script:
- export MYSQL_BUILD_CC=/usr/bin/gcc-${GCC_VERSION} MYSQL_BUILD_CXX=/usr/bin/g++-${GCC_VERSION} - export MYSQL_BUILD_CC=/usr/bin/gcc-${GCC_VERSION} MYSQL_BUILD_CXX=/usr/bin/g++-${GCC_VERSION}
- ${MYSQL_BUILD_CC} --version ; ${MYSQL_BUILD_CXX} --version - ${MYSQL_BUILD_CC} --version ; ${MYSQL_BUILD_CXX} --version
- cd "${TRAVIS_BUILD_DIR}" - cd "${TRAVIS_BUILD_DIR}"
- env DEB_BUILD_OPTIONS="parallel=4" debian/autobake-deb.sh; - env DEB_BUILD_OPTIONS="parallel=3" debian/autobake-deb.sh;
notifications: notifications:
irc: irc:

View File

@@ -1,3 +1,3 @@
MYSQL_VERSION_MAJOR=10 MYSQL_VERSION_MAJOR=10
MYSQL_VERSION_MINOR=2 MYSQL_VERSION_MINOR=2
MYSQL_VERSION_PATCH=3 MYSQL_VERSION_PATCH=4

View File

@@ -1,5 +1,4 @@
usr/bin/mysql_config usr/bin/mysql_config
usr/include/mariadb
usr/include/mysql/*.h usr/include/mysql/*.h
usr/include/mysql/psi/*.h usr/include/mysql/psi/*.h
usr/lib/*/libmariadb.so usr/lib/*/libmariadb.so

View File

@@ -1,5 +1,5 @@
usr/lib/*/libmariadbclient.so.* usr/lib/*/libmariadbclient.so.*
usr/lib/*/libmysqlclient.so.* usr/lib/*/libmysqlclient.so.*
usr/lib/mariadb/libmariadb.so.* usr/lib/*/libmariadb.so.*
usr/lib/mysql/plugin/dialog.so usr/lib/mysql/plugin/dialog.so
usr/lib/mysql/plugin/mysql_clear_password.so usr/lib/mysql/plugin/mysql_clear_password.so

8
debian/rules vendored
View File

@@ -158,12 +158,12 @@ override_dh_auto_install:
install -D -m 644 debian/mariadb-server-10.2.py $(TMP)/usr/share/apport/package-hooks/source_mariadb-10.2.py install -D -m 644 debian/mariadb-server-10.2.py $(TMP)/usr/share/apport/package-hooks/source_mariadb-10.2.py
# Install libmariadbclient18 compatibility links # Install libmariadbclient18 compatibility links
ln -s /usr/lib/mariadb/libmariadb.so.3 $(TMP)/usr/lib/$(DEB_HOST_MULTIARCH)/libmariadbclient.so.18 ln -s $(TMP)/usr/lib/$(DEB_HOST_MULTIARCH)/libmariadb.so.3 $(TMP)/usr/lib/$(DEB_HOST_MULTIARCH)/libmariadbclient.so.18
# Install libmysqlclientclientXX compatibility links # Install libmysqlclientclientXX compatibility links
ln -s /usr/lib/mariadb/libmariadb.so.3 $(TMP)/usr/lib/$(DEB_HOST_MULTIARCH)/libmysqlclient.so.18 ln -s $(TMP)/usr/lib/$(DEB_HOST_MULTIARCH)/libmariadb.so.3 $(TMP)/usr/lib/$(DEB_HOST_MULTIARCH)/libmysqlclient.so.18
ln -s /usr/lib/mariadb/libmariadb.so.3 $(TMP)/usr/lib/$(DEB_HOST_MULTIARCH)/libmysqlclient.so.19 ln -s $(TMP)/usr/lib/$(DEB_HOST_MULTIARCH)/libmariadb.so.3 $(TMP)/usr/lib/$(DEB_HOST_MULTIARCH)/libmysqlclient.so.19
ln -s /usr/lib/mariadb/libmariadb.so.3 $(TMP)/usr/lib/$(DEB_HOST_MULTIARCH)/libmysqlclient.so.20 ln -s $(TMP)/usr/lib/$(DEB_HOST_MULTIARCH)/libmariadb.so.3 $(TMP)/usr/lib/$(DEB_HOST_MULTIARCH)/libmysqlclient.so.20
touch $@ touch $@

View File

@@ -236,6 +236,15 @@ create table t2i (a int);
insert into t2m values (5); insert into t2m values (5);
insert into t2i values (5); insert into t2i values (5);
-- disable_query_log
-- disable_result_log
analyze table t1i;
analyze table t1m;
analyze table t2i;
analyze table t2m;
-- enable_result_log
-- enable_query_log
# test with $engine_type # test with $engine_type
select min(a) from t1i; select min(a) from t1i;
select min(7) from t1i; select min(7) from t1i;
@@ -411,6 +420,13 @@ if ($test_foreign_keys)
INSERT INTO t1 VALUES (1,'A1'),(2,'A2'),(3,'B'); INSERT INTO t1 VALUES (1,'A1'),(2,'A2'),(3,'B');
INSERT INTO t2 VALUES (1,1),(2,2),(3,2),(4,3),(5,3); INSERT INTO t2 VALUES (1,1),(2,2),(3,2),(4,3),(5,3);
-- disable_query_log
-- disable_result_log
ANALYZE TABLE t1;
ANALYZE TABLE t2;
-- enable_result_log
-- enable_query_log
EXPLAIN EXPLAIN
SELECT COUNT(*) FROM t2 LEFT JOIN t1 ON t2.fkey = t1.id SELECT COUNT(*) FROM t2 LEFT JOIN t1 ON t2.fkey = t1.id
WHERE t1.name LIKE 'A%'; WHERE t1.name LIKE 'A%';
@@ -572,12 +588,22 @@ OPTIMIZE TABLE t1;
SELECT COUNT(*) FROM t1; SELECT COUNT(*) FROM t1;
SELECT COUNT(*) FROM t1 WHERE acct_id=785; SELECT COUNT(*) FROM t1 WHERE acct_id=785;
-- disable_query_log
-- disable_result_log
ANALYZE TABLE t1;
-- enable_result_log
-- enable_query_log
EXPLAIN SELECT COUNT(*) FROM t1 WHERE stat_id IN (1,3) AND acct_id=785; EXPLAIN SELECT COUNT(*) FROM t1 WHERE stat_id IN (1,3) AND acct_id=785;
INSERT INTO t2 SELECT * FROM t1; INSERT INTO t2 SELECT * FROM t1;
OPTIMIZE TABLE t2; OPTIMIZE TABLE t2;
EXPLAIN SELECT COUNT(*) FROM t2 WHERE stat_id IN (1,3) AND acct_id=785; -- disable_query_log
-- disable_result_log
ANALYZE TABLE t2;
-- enable_result_log
-- enable_query_log
DROP TABLE t1,t2; DROP TABLE t1,t2;
@@ -654,9 +680,11 @@ INSERT INTO t2 VALUES (1);
CONNECTION c2; CONNECTION c2;
SET AUTOCOMMIT=0; SET AUTOCOMMIT=0;
SET @old_lock_wait_timeout= @@lock_wait_timeout;
SET lock_wait_timeout= 1;
--error ER_LOCK_WAIT_TIMEOUT --error ER_LOCK_WAIT_TIMEOUT
LOCK TABLES t1 READ, t2 READ; LOCK TABLES t1 READ, t2 READ;
SET @@lock_wait_timeout= @old_lock_wait_timeout;
CONNECTION c1; CONNECTION c1;
COMMIT; COMMIT;
INSERT INTO t1 VALUES (1); INSERT INTO t1 VALUES (1);
@@ -702,6 +730,13 @@ INSERT INTO t1(b,c) SELECT b,c FROM t2;
UPDATE t2 SET c='2007-01-03'; UPDATE t2 SET c='2007-01-03';
INSERT INTO t1(b,c) SELECT b,c FROM t2; INSERT INTO t1(b,c) SELECT b,c FROM t2;
-- disable_query_log
-- disable_result_log
ANALYZE TABLE t1;
ANALYZE TABLE t2;
-- enable_result_log
-- enable_query_log
set @@sort_buffer_size=8192; set @@sort_buffer_size=8192;
SELECT COUNT(*) FROM t1; SELECT COUNT(*) FROM t1;
@@ -791,6 +826,12 @@ INSERT INTO t1 SELECT a + 16, MOD(a + 16, 20), 1 FROM t1;
INSERT INTO t1 SELECT a + 32, MOD(a + 32, 20), 1 FROM t1; INSERT INTO t1 SELECT a + 32, MOD(a + 32, 20), 1 FROM t1;
INSERT INTO t1 SELECT a + 64, MOD(a + 64, 20), 1 FROM t1; INSERT INTO t1 SELECT a + 64, MOD(a + 64, 20), 1 FROM t1;
-- disable_query_log
-- disable_result_log
ANALYZE TABLE t1;
-- enable_result_log
-- enable_query_log
EXPLAIN SELECT b, SUM(c) FROM t1 GROUP BY b; EXPLAIN SELECT b, SUM(c) FROM t1 GROUP BY b;
EXPLAIN SELECT SQL_BIG_RESULT b, SUM(c) FROM t1 GROUP BY b; EXPLAIN SELECT SQL_BIG_RESULT b, SUM(c) FROM t1 GROUP BY b;
DROP TABLE t1; DROP TABLE t1;
@@ -853,6 +894,11 @@ CREATE TABLE t1 (a int, b int, PRIMARY KEY (a), KEY bkey (b)) ENGINE=InnoDB;
INSERT INTO t1 VALUES (1,2),(3,2),(2,2),(4,2),(5,2),(6,2),(7,2),(8,2); INSERT INTO t1 VALUES (1,2),(3,2),(2,2),(4,2),(5,2),(6,2),(7,2),(8,2);
INSERT INTO t1 SELECT a + 8, 2 FROM t1; INSERT INTO t1 SELECT a + 8, 2 FROM t1;
INSERT INTO t1 SELECT a + 16, 1 FROM t1; INSERT INTO t1 SELECT a + 16, 1 FROM t1;
-- disable_query_log
-- disable_result_log
ANALYZE TABLE t1;
-- enable_result_log
-- enable_query_log
query_vertical EXPLAIN SELECT * FROM t1 WHERE b=2 ORDER BY a; query_vertical EXPLAIN SELECT * FROM t1 WHERE b=2 ORDER BY a;
SELECT * FROM t1 WHERE b=2 ORDER BY a; SELECT * FROM t1 WHERE b=2 ORDER BY a;
query_vertical EXPLAIN SELECT * FROM t1 WHERE b BETWEEN 1 AND 2 ORDER BY a; query_vertical EXPLAIN SELECT * FROM t1 WHERE b BETWEEN 1 AND 2 ORDER BY a;
@@ -866,6 +912,12 @@ INSERT INTO t2 VALUES (1,1,1),(3,1,1),(2,1,1),(4,1,1);
INSERT INTO t2 SELECT a + 4, 1, 1 FROM t2; INSERT INTO t2 SELECT a + 4, 1, 1 FROM t2;
INSERT INTO t2 SELECT a + 8, 1, 1 FROM t2; INSERT INTO t2 SELECT a + 8, 1, 1 FROM t2;
-- disable_query_log
-- disable_result_log
ANALYZE TABLE t2;
-- enable_result_log
-- enable_query_log
query_vertical EXPLAIN SELECT * FROM t2 WHERE b=1 ORDER BY a; query_vertical EXPLAIN SELECT * FROM t2 WHERE b=1 ORDER BY a;
SELECT * FROM t2 WHERE b=1 ORDER BY a; SELECT * FROM t2 WHERE b=1 ORDER BY a;
query_vertical EXPLAIN SELECT * FROM t2 WHERE b=1 AND c=1 ORDER BY a; query_vertical EXPLAIN SELECT * FROM t2 WHERE b=1 AND c=1 ORDER BY a;
@@ -982,6 +1034,12 @@ CREATE TABLE t1(
INSERT INTO t1 VALUES (1,1,1,50), (1,2,3,40), (2,1,3,4); INSERT INTO t1 VALUES (1,1,1,50), (1,2,3,40), (2,1,3,4);
-- disable_query_log
-- disable_result_log
ANALYZE TABLE t1;
-- enable_result_log
-- enable_query_log
EXPLAIN SELECT c,b,d FROM t1 GROUP BY c,b,d; EXPLAIN SELECT c,b,d FROM t1 GROUP BY c,b,d;
SELECT c,b,d FROM t1 GROUP BY c,b,d; SELECT c,b,d FROM t1 GROUP BY c,b,d;
EXPLAIN SELECT c,b,d FROM t1 GROUP BY c,b,d ORDER BY NULL; EXPLAIN SELECT c,b,d FROM t1 GROUP BY c,b,d ORDER BY NULL;
@@ -1002,6 +1060,12 @@ DROP TABLE t1;
CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a), INDEX b (b)) ENGINE=InnoDB; CREATE TABLE t1 (a INT, b INT, PRIMARY KEY (a), INDEX b (b)) ENGINE=InnoDB;
INSERT INTO t1(a,b) VALUES (1,1), (2,2), (3,2); INSERT INTO t1(a,b) VALUES (1,1), (2,2), (3,2);
-- disable_query_log
-- disable_result_log
ANALYZE TABLE t1;
-- enable_result_log
-- enable_query_log
#The two queries below should produce different results, but they don't. #The two queries below should produce different results, but they don't.
query_vertical EXPLAIN SELECT * FROM t1 WHERE b=2 ORDER BY a ASC; query_vertical EXPLAIN SELECT * FROM t1 WHERE b=2 ORDER BY a ASC;
SELECT * FROM t1 WHERE b=2 ORDER BY a ASC; SELECT * FROM t1 WHERE b=2 ORDER BY a ASC;
@@ -1085,6 +1149,12 @@ CREATE TABLE t1 (id int, type char(6), d int, INDEX idx(id,d)) ENGINE=InnoDB;
INSERT INTO t1 VALUES INSERT INTO t1 VALUES
(191, 'member', 1), (NULL, 'member', 3), (NULL, 'member', 4), (201, 'member', 2); (191, 'member', 1), (NULL, 'member', 3), (NULL, 'member', 4), (201, 'member', 2);
-- disable_query_log
-- disable_result_log
ANALYZE TABLE t1;
-- enable_result_log
-- enable_query_log
EXPLAIN SELECT * FROM t1 WHERE id=191 OR id IS NULL ORDER BY d; EXPLAIN SELECT * FROM t1 WHERE id=191 OR id IS NULL ORDER BY d;
SELECT * FROM t1 WHERE id=191 OR id IS NULL ORDER BY d; SELECT * FROM t1 WHERE id=191 OR id IS NULL ORDER BY d;
@@ -1113,12 +1183,13 @@ CREATE TABLE t1 (a int, b int, c int, PRIMARY KEY (a), KEY t1_b (b))
INSERT INTO t1 (a,b,c) VALUES (1,1,1), (2,1,1), (3,1,1), (4,1,1); INSERT INTO t1 (a,b,c) VALUES (1,1,1), (2,1,1), (3,1,1), (4,1,1);
INSERT INTO t1 (a,b,c) SELECT a+4,b,c FROM t1; INSERT INTO t1 (a,b,c) SELECT a+4,b,c FROM t1;
# should be range access -- disable_query_log
-- disable_result_log
ANALYZE TABLE t1;
-- enable_result_log
-- enable_query_log
# # should be range access
# InnoDB uses "where", while xtradb "index condition"
#
--replace_regex /where/index condition/
EXPLAIN SELECT a, b, c FROM t1 WHERE b = 1 ORDER BY a DESC LIMIT 5; EXPLAIN SELECT a, b, c FROM t1 WHERE b = 1 ORDER BY a DESC LIMIT 5;
# should produce '8 7 6 5 4' for a # should produce '8 7 6 5 4' for a
@@ -1512,6 +1583,12 @@ INSERT INTO t1 VALUES
(4,1,3,'pk',NULL),(5,1,3,'c2',NULL), (4,1,3,'pk',NULL),(5,1,3,'c2',NULL),
(2,1,4,'c_extra',NULL),(3,1,4,'c_extra',NULL); (2,1,4,'c_extra',NULL),(3,1,4,'c_extra',NULL);
-- disable_query_log
-- disable_result_log
ANALYZE TABLE t1;
-- enable_result_log
-- enable_query_log
EXPLAIN SELECT * FROM t1 FORCE INDEX (PRIMARY) WHERE tid = 1 AND vid = 3 ORDER BY idx DESC; EXPLAIN SELECT * FROM t1 FORCE INDEX (PRIMARY) WHERE tid = 1 AND vid = 3 ORDER BY idx DESC;
SELECT * FROM t1 FORCE INDEX (PRIMARY) WHERE tid = 1 AND vid = 3 ORDER BY idx DESC; SELECT * FROM t1 FORCE INDEX (PRIMARY) WHERE tid = 1 AND vid = 3 ORDER BY idx DESC;
@@ -1529,6 +1606,12 @@ CREATE TABLE t1 (c1 INT, c2 INT, c3 INT, KEY (c3), KEY (c2, c3))
ENGINE=$engine_type; ENGINE=$engine_type;
INSERT INTO t1 VALUES (1,1,1), (1,1,1), (1,1,2), (1,1,1), (1,1,2); INSERT INTO t1 VALUES (1,1,1), (1,1,1), (1,1,2), (1,1,1), (1,1,2);
-- disable_query_log
-- disable_result_log
ANALYZE TABLE t1;
-- enable_result_log
-- enable_query_log
SELECT 1 FROM (SELECT COUNT(DISTINCT c1) SELECT 1 FROM (SELECT COUNT(DISTINCT c1)
FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x; FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x;
EXPLAIN EXPLAIN
@@ -1542,6 +1625,12 @@ CREATE TABLE t1 (c1 REAL, c2 REAL, c3 REAL, KEY (c3), KEY (c2, c3))
ENGINE=$engine_type; ENGINE=$engine_type;
INSERT INTO t1 VALUES (1,1,1), (1,1,1), (1,1,2), (1,1,1), (1,1,2); INSERT INTO t1 VALUES (1,1,1), (1,1,1), (1,1,2), (1,1,1), (1,1,2);
-- disable_query_log
-- disable_result_log
ANALYZE TABLE t1;
-- enable_result_log
-- enable_query_log
SELECT 1 FROM (SELECT COUNT(DISTINCT c1) SELECT 1 FROM (SELECT COUNT(DISTINCT c1)
FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x; FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x;
EXPLAIN EXPLAIN
@@ -1556,6 +1645,12 @@ CREATE TABLE t1 (c1 DECIMAL(12,2), c2 DECIMAL(12,2), c3 DECIMAL(12,2),
ENGINE=$engine_type; ENGINE=$engine_type;
INSERT INTO t1 VALUES (1,1,1), (1,1,1), (1,1,2), (1,1,1), (1,1,2); INSERT INTO t1 VALUES (1,1,1), (1,1,1), (1,1,2), (1,1,1), (1,1,2);
-- disable_query_log
-- disable_result_log
ANALYZE TABLE t1;
-- enable_result_log
-- enable_query_log
SELECT 1 FROM (SELECT COUNT(DISTINCT c1) SELECT 1 FROM (SELECT COUNT(DISTINCT c1)
FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x; FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x;
EXPLAIN EXPLAIN
@@ -1583,6 +1678,13 @@ CREATE TABLE t2 (
insert into t1 values (0),(1),(2),(3),(4); insert into t1 values (0),(1),(2),(3),(4);
insert into t2 select A.a + 10 *B.a, 1, 'filler' from t1 A, t1 B; insert into t2 select A.a + 10 *B.a, 1, 'filler' from t1 A, t1 B;
-- disable_query_log
-- disable_result_log
analyze table t1;
analyze table t2;
-- enable_result_log
-- enable_query_log
explain select * from t1, t2 where t2.a=t1.a and t2.b + 1; explain select * from t1, t2 where t2.a=t1.a and t2.b + 1;
select * from t1, t2 where t2.a=t1.a and t2.b + 1; select * from t1, t2 where t2.a=t1.a and t2.b + 1;

View File

@@ -265,17 +265,31 @@ connection default;
DROP TABLE t1; DROP TABLE t1;
SET DEBUG_SYNC= 'RESET'; SET DEBUG_SYNC= 'RESET';
DROP TABLE IF EXISTS t1; DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (c1 INT); CREATE TABLE t1 (c1 INT) ENGINE=MyISAM;
LOCK TABLE t1 READ; INSERT INTO t1 VALUES (1);
SELECT GET_LOCK('mysqltest_lock', 100);
GET_LOCK('mysqltest_lock', 100)
1
connect con1,localhost,root,,; connect con1,localhost,root,,;
# Sending:
UPDATE t1 SET c1=GET_LOCK('mysqltest_lock', 100);;
connect con2,localhost,root,,;
SET DEBUG_SYNC= 'wait_for_lock SIGNAL locked EXECUTE 2'; SET DEBUG_SYNC= 'wait_for_lock SIGNAL locked EXECUTE 2';
INSERT INTO t1 VALUES (1); INSERT INTO t1 VALUES (1);
connection default; connection default;
SET DEBUG_SYNC= 'now WAIT_FOR locked'; SET DEBUG_SYNC= 'now WAIT_FOR locked';
UNLOCK TABLES; SELECT RELEASE_LOCK('mysqltest_lock');
RELEASE_LOCK('mysqltest_lock')
1
connection con1; connection con1;
# Reaping UPDATE
SELECT RELEASE_LOCK('mysqltest_lock');
RELEASE_LOCK('mysqltest_lock')
1
connection con2;
retrieve INSERT result. retrieve INSERT result.
disconnect con1; disconnect con1;
disconnect con2;
connection default; connection default;
DROP TABLE t1; DROP TABLE t1;
SET DEBUG_SYNC= 'RESET'; SET DEBUG_SYNC= 'RESET';

View File

@@ -8140,3 +8140,104 @@ EXPLAIN
} }
} }
DROP TABLE t1,t2; DROP TABLE t1,t2;
#
# MDEV-11593: pushdown of condition with NULLIF
#
CREATE TABLE t1 (i INT);
CREATE OR REPLACE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
INSERT INTO t1 VALUES (2), (1);
SELECT * FROM v1 WHERE NULLIF(1, i);
i
2
EXPLAIN FORMAT=JSON
SELECT * FROM v1 WHERE NULLIF(1, i);
EXPLAIN
{
"query_block": {
"select_id": 1,
"table": {
"table_name": "<derived2>",
"access_type": "ALL",
"rows": 2,
"filtered": 100,
"attached_condition": "nullif(1,v1.i)",
"materialized": {
"query_block": {
"select_id": 2,
"table": {
"table_name": "t1",
"access_type": "ALL",
"rows": 2,
"filtered": 100,
"attached_condition": "nullif(1,t1.i)"
}
}
}
}
}
}
DROP VIEW v1;
DROP TABLE t1;
#
# MDEV-11608: pushdown of the predicate with cached null value
#
CREATE TABLE t1 (c VARCHAR(3));
CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
INSERT INTO t1 VALUES ('foo'),('bar');
CREATE TABLE t2 (c VARCHAR(3));
INSERT INTO t2 VALUES ('foo'),('xyz');
SELECT * FROM v1 WHERE v1.c IN ( SELECT MIN(c) FROM t2 WHERE 0 );
c
EXPLAIN FORMAT=JSON
SELECT * FROM v1 WHERE v1.c IN ( SELECT MIN(c) FROM t2 WHERE 0 );
EXPLAIN
{
"query_block": {
"select_id": 1,
"table": {
"table_name": "<subquery2>",
"access_type": "system",
"rows": 1,
"filtered": 100,
"materialized": {
"unique": 1,
"query_block": {
"select_id": 2,
"table": {
"message": "Impossible WHERE"
}
}
}
},
"table": {
"table_name": "<derived3>",
"access_type": "ALL",
"rows": 2,
"filtered": 100,
"attached_condition": "v1.c = NULL",
"materialized": {
"query_block": {
"select_id": 3,
"table": {
"table_name": "t1",
"access_type": "ALL",
"rows": 2,
"filtered": 100,
"attached_condition": "t1.c = NULL"
}
}
}
}
}
}
DROP VIEW v1;
DROP TABLE t1,t2;
CREATE TABLE t1 (d DECIMAL(10,2));
CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
INSERT INTO t1 VALUES (5.37),(1.1);
CREATE TABLE t2 (d DECIMAL(10,2));
INSERT INTO t2 VALUES ('1.1'),('2.23');
SELECT * FROM v1 WHERE v1.d IN ( SELECT MIN(d) FROM t2 WHERE 0 );
d
DROP VIEW v1;
DROP TABLE t1,t2;

View File

@@ -147,4 +147,5 @@ v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VI
select 30 + (20010101 + interval 2 day), x from v1; select 30 + (20010101 + interval 2 day), x from v1;
30 + (20010101 + interval 2 day) x 30 + (20010101 + interval 2 day) x
20010133 20010133 20010133 20010133
drop view v1;
End of 10.2 tests End of 10.2 tests

View File

@@ -209,6 +209,9 @@ json_extract('[10, 20, [{"a":3}, 30, 40]]', '$[2][*]')
select json_extract('1', '$'); select json_extract('1', '$');
json_extract('1', '$') json_extract('1', '$')
1 1
select json_extract('[10, 20, [30, 40], 1, 10]', '$[1]');
json_extract('[10, 20, [30, 40], 1, 10]', '$[1]')
20
select json_insert('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.b.k1', 'word'); select json_insert('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.b.k1', 'word');
json_insert('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.b.k1', 'word') json_insert('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.b.k1', 'word')
{"a":1, "b":{"c":1, "k1":"word"}, "d":[1, 2]} {"a":1, "b":{"c":1, "k1":"word"}, "d":[1, 2]}
@@ -315,6 +318,9 @@ Warning 4038 Syntax error in JSON text in argument 1 to function 'json_merge' at
select json_merge('{"a":"b"}','{"c":"d"}'); select json_merge('{"a":"b"}','{"c":"d"}');
json_merge('{"a":"b"}','{"c":"d"}') json_merge('{"a":"b"}','{"c":"d"}')
{"a":"b", "c":"d"} {"a":"b", "c":"d"}
SELECT JSON_MERGE('[1, 2]', '{"id": 47}');
JSON_MERGE('[1, 2]', '{"id": 47}')
[1, 2, {"id": 47}]
select json_type('{"k1":123, "k2":345}'); select json_type('{"k1":123, "k2":345}');
json_type('{"k1":123, "k2":345}') json_type('{"k1":123, "k2":345}')
OBJECT OBJECT
@@ -419,6 +425,12 @@ json_length('{}')
select json_length('[1, 2, {"a": 3}]'); select json_length('[1, 2, {"a": 3}]');
json_length('[1, 2, {"a": 3}]') json_length('[1, 2, {"a": 3}]')
3 3
select json_length('{"a": 1, "b": {"c": 30}}', '$.b');
json_length('{"a": 1, "b": {"c": 30}}', '$.b')
1
select json_length('{"a": 1, "b": {"c": 30}}');
json_length('{"a": 1, "b": {"c": 30}}')
2
create table json (j INT); create table json (j INT);
show create table json; show create table json;
Table Create Table Table Create Table

View File

@@ -36,6 +36,7 @@ connection con3;
set @@autocommit=1; set @@autocommit=1;
connection default; connection default;
disconnect con1; disconnect con1;
disconnect con2;
disconnect con3; disconnect con3;
# #
# Test for bug #37346 "innodb does not detect deadlock between update # Test for bug #37346 "innodb does not detect deadlock between update
@@ -72,34 +73,6 @@ connection default;
disconnect con37346; disconnect con37346;
drop table t1; drop table t1;
# #
# Bug #42147 Concurrent DML and LOCK TABLE ... READ for InnoDB
# table cause warnings in errlog
#
#
# Note that this test for now relies on a global suppression of
# the warning "Found lock of type 6 that is write and read locked"
# This suppression rule can be removed once Bug#42147 is properly
# fixed. See bug page for more info.
#
DROP TABLE IF EXISTS t1;
CREATE TABLE t1 (i INT) engine= innodb;
# Get user-level lock
connection con2;
SELECT get_lock('bug42147_lock', 60);
get_lock('bug42147_lock', 60)
1
connection default;
INSERT INTO t1 SELECT get_lock('bug42147_lock', 60);
connection con2;
LOCK TABLES t1 READ;
SELECT release_lock('bug42147_lock');
release_lock('bug42147_lock')
1
UNLOCK TABLES;
connection default;
disconnect con2;
DROP TABLE t1;
#
# Bug#53798 OPTIMIZE TABLE breaks repeatable read # Bug#53798 OPTIMIZE TABLE breaks repeatable read
# #
DROP TABLE IF EXISTS t1; DROP TABLE IF EXISTS t1;

View File

@@ -119,33 +119,5 @@ DROP USER user20989@localhost;
disconnect root; disconnect root;
connection default; connection default;
DROP DATABASE meow; DROP DATABASE meow;
connection: default
set low_priority_updates=1;
drop table if exists t1;
create table t1 (a int, b int, unique key t1$a (a));
lock table t1 read;
connect update,localhost,root,,;
connection update;
connection: update
set low_priority_updates=1;
show variables like 'low_priority_updates';
Variable_name Value
low_priority_updates ON
insert into t1 values (1, 2) ON DUPLICATE KEY UPDATE b = 2;;
connection default;
connect select,localhost,root,,;
connection: select
select * from t1;
a b
connection default;
connection: default
select * from t1;
a b
connection default;
disconnect update;
disconnect select;
unlock tables;
drop table t1;
set low_priority_updates=default;
set local sql_mode=default; set local sql_mode=default;
set global sql_mode=default; set global sql_mode=default;

View File

@@ -784,3 +784,74 @@ DROP VIEW v1;
DROP TABLE t1; DROP TABLE t1;
disconnect con1; disconnect con1;
disconnect con2; disconnect con2;
#
# Bug#28587 SELECT is blocked by INSERT waiting on read lock, even with low_priority_updates
#
set low_priority_updates=1;
drop table if exists t1;
drop table if exists t2;
set debug_sync='RESET';
create table t1 (a int, b int, unique key t1$a (a));
create table t2 (j int, k int);
set debug_sync='after_lock_tables_takes_lock SIGNAL parked WAIT_FOR go';
# Sending:
insert into t2 select * from t1;;
connect update,localhost,root,,;
connection update;
set debug_sync='now WAIT_FOR parked';
set low_priority_updates=1;
show variables like 'low_priority_updates';
Variable_name Value
low_priority_updates ON
insert into t1 values (1, 2) ON DUPLICATE KEY UPDATE b = 2;;
connect select,localhost,root,,;
select * from t1;
a b
set debug_sync='now SIGNAL go';
connection default;
disconnect update;
disconnect select;
# Reaping INSERT SELECT
drop tables t1, t2;
set low_priority_updates=default;
set debug_sync='RESET';
#
# Additional test coverage for LOCK TABLES ... READ LOCAL
# for InnoDB tables.
#
# Check that we correctly handle deadlocks which can occur
# during metadata lock upgrade which happens when one tries
# to use LOCK TABLES ... READ LOCAL for InnoDB tables.
CREATE TABLE t1 (i INT) ENGINE=InnoDB;
CREATE TABLE t2 (j INT) ENGINE=InnoDB;
# Execute LOCK TABLE READ LOCK which will pause after acquiring
# SR metadata lock and before upgrading it to SRO lock.
SET DEBUG_SYNC="after_open_table_mdl_shared SIGNAL locked WAIT_FOR go";
# Sending:
LOCK TABLE t1 READ LOCAL;
connect con1, localhost, root;
SET DEBUG_SYNC="now WAIT_FOR locked";
# Execute RENAME TABLE which will try to acquire X lock.
# Sending:
RENAME TABLE t1 TO t3, t2 TO t1, t3 TO t2;
connect con2, localhost, root;
# Wait until RENAME TABLE is blocked.
# Resume LOCK TABLE statement. It should try to
# upgrade SR lock to SRO lock which will create
# deadlock due to presence of pending X lock.
# Deadlock should be detected and LOCK TABLES should
# release its MDL and retry opening of tables.
SET DEBUG_SYNC="now SIGNAL go";
connection con1;
# RENAME TABLE should be able to complete. Reap it.
connection default;
# Reap LOCK TABLES.
# Check that we see new version of table.
SELECT * FROM t1;
j
UNLOCK TABLES;
# Clean-up.
SET DEBUG_SYNC="RESET";
disconnect con1;
disconnect con2;
DROP TABLES t1, t2;

View File

@@ -9,6 +9,7 @@ disconnect con1;
connection con2; connection con2;
SELECT * FROM t1; SELECT * FROM t1;
a a
10
DROP TABLE t1; DROP TABLE t1;
connection default; connection default;
disconnect con2; disconnect con2;

View File

@@ -281,7 +281,7 @@ UNLOCK TABLES;
SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS
WHERE VARIABLE_NAME LIKE 'HANDLER_%' AND VARIABLE_VALUE > 0; WHERE VARIABLE_NAME LIKE 'HANDLER_%' AND VARIABLE_VALUE > 0;
VARIABLE_NAME VARIABLE_VALUE VARIABLE_NAME VARIABLE_VALUE
HANDLER_COMMIT 3 HANDLER_COMMIT 2
HANDLER_READ_RND_NEXT 54 HANDLER_READ_RND_NEXT 54
HANDLER_TMP_WRITE 75 HANDLER_TMP_WRITE 75
HANDLER_WRITE 2 HANDLER_WRITE 2
@@ -440,7 +440,7 @@ UNLOCK TABLES;
SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS
WHERE VARIABLE_NAME LIKE 'HANDLER_%' AND VARIABLE_VALUE > 0; WHERE VARIABLE_NAME LIKE 'HANDLER_%' AND VARIABLE_VALUE > 0;
VARIABLE_NAME VARIABLE_VALUE VARIABLE_NAME VARIABLE_VALUE
HANDLER_COMMIT 6 HANDLER_COMMIT 5
HANDLER_READ_FIRST 3 HANDLER_READ_FIRST 3
HANDLER_READ_NEXT 4 HANDLER_READ_NEXT 4
HANDLER_READ_RND_NEXT 108 HANDLER_READ_RND_NEXT 108
@@ -665,7 +665,7 @@ UNLOCK TABLES;
SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS
WHERE VARIABLE_NAME LIKE 'HANDLER_%' AND VARIABLE_VALUE > 0; WHERE VARIABLE_NAME LIKE 'HANDLER_%' AND VARIABLE_VALUE > 0;
VARIABLE_NAME VARIABLE_VALUE VARIABLE_NAME VARIABLE_VALUE
HANDLER_COMMIT 6 HANDLER_COMMIT 5
HANDLER_DELETE 2 HANDLER_DELETE 2
HANDLER_READ_FIRST 1 HANDLER_READ_FIRST 1
HANDLER_READ_KEY 3 HANDLER_READ_KEY 3
@@ -758,7 +758,7 @@ UNLOCK TABLES;
SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS
WHERE VARIABLE_NAME LIKE 'HANDLER_%' AND VARIABLE_VALUE > 0; WHERE VARIABLE_NAME LIKE 'HANDLER_%' AND VARIABLE_VALUE > 0;
VARIABLE_NAME VARIABLE_VALUE VARIABLE_NAME VARIABLE_VALUE
HANDLER_COMMIT 3 HANDLER_COMMIT 2
HANDLER_READ_RND_NEXT 54 HANDLER_READ_RND_NEXT 54
HANDLER_TMP_WRITE 75 HANDLER_TMP_WRITE 75
HANDLER_WRITE 10 HANDLER_WRITE 10
@@ -953,7 +953,7 @@ UNLOCK TABLES;
SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS
WHERE VARIABLE_NAME LIKE 'HANDLER_%' AND VARIABLE_VALUE > 0; WHERE VARIABLE_NAME LIKE 'HANDLER_%' AND VARIABLE_VALUE > 0;
VARIABLE_NAME VARIABLE_VALUE VARIABLE_NAME VARIABLE_VALUE
HANDLER_COMMIT 4 HANDLER_COMMIT 3
HANDLER_DELETE 1 HANDLER_DELETE 1
HANDLER_READ_KEY 2 HANDLER_READ_KEY 2
HANDLER_READ_RND 2 HANDLER_READ_RND 2
@@ -1039,7 +1039,7 @@ UNLOCK TABLES;
SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS
WHERE VARIABLE_NAME LIKE 'HANDLER_%' AND VARIABLE_VALUE > 0; WHERE VARIABLE_NAME LIKE 'HANDLER_%' AND VARIABLE_VALUE > 0;
VARIABLE_NAME VARIABLE_VALUE VARIABLE_NAME VARIABLE_VALUE
HANDLER_COMMIT 4 HANDLER_COMMIT 3
HANDLER_DELETE 2 HANDLER_DELETE 2
HANDLER_READ_KEY 3 HANDLER_READ_KEY 3
HANDLER_READ_NEXT 1 HANDLER_READ_NEXT 1

View File

@@ -4,6 +4,7 @@ SET @old_log_output = @@global.log_output;
SET GLOBAL LOG_OUTPUT = 'FILE'; SET GLOBAL LOG_OUTPUT = 'FILE';
connect con1,localhost,root,,; connect con1,localhost,root,,;
connect con2,localhost,root,,; connect con2,localhost,root,,;
connection default;
flush status; flush status;
show status like 'Table_lock%'; show status like 'Table_lock%';
Variable_name Value Variable_name Value
@@ -13,33 +14,42 @@ select * from information_schema.session_status where variable_name like 'Table_
VARIABLE_NAME VARIABLE_VALUE VARIABLE_NAME VARIABLE_VALUE
TABLE_LOCKS_IMMEDIATE 0 TABLE_LOCKS_IMMEDIATE 0
TABLE_LOCKS_WAITED 0 TABLE_LOCKS_WAITED 0
connection con1;
set sql_log_bin=0; set sql_log_bin=0;
set @old_general_log = @@global.general_log; set @old_general_log = @@global.general_log;
set global general_log = 'OFF'; set global general_log = 'OFF';
drop table if exists t1; drop table if exists t1;
create table t1(n int) engine=myisam; create table t1(n int) engine=myisam;
insert into t1 values(1); insert into t1 values(1);
select 1; select get_lock('mysqltest_lock', 100);
1 get_lock('mysqltest_lock', 100)
1 1
connection con2; connection con2;
lock tables t1 read; # Sending:
unlock tables; update t1 set n = get_lock('mysqltest_lock', 100);
lock tables t1 read;
connection con1; connection con1;
# Wait for the first UPDATE to get blocked.
# Sending:
update t1 set n = 3; update t1 set n = 3;
connection default;
# wait for the second UPDATE to get blocked
select release_lock('mysqltest_lock');
release_lock('mysqltest_lock')
1
connection con2; connection con2;
unlock tables; # Reaping first UPDATE
select release_lock('mysqltest_lock');
release_lock('mysqltest_lock')
1
connection con1; connection con1;
# Reaping second UPDATE
show status like 'Table_locks_waited'; show status like 'Table_locks_waited';
Variable_name Value Variable_name Value
Table_locks_waited 1 Table_locks_waited 1
connection default;
drop table t1; drop table t1;
set global general_log = @old_general_log; set global general_log = @old_general_log;
disconnect con2; disconnect con2;
disconnect con1; disconnect con1;
connection default;
select 1; select 1;
1 1
1 1

View File

@@ -4792,21 +4792,24 @@ DROP TABLE t1, t2;
# Bug#48315 Metadata lock is not taken for merged views that # Bug#48315 Metadata lock is not taken for merged views that
# use an INFORMATION_SCHEMA table # use an INFORMATION_SCHEMA table
# #
DROP TABLE IF EXISTS t1;
DROP VIEW IF EXISTS v1; DROP VIEW IF EXISTS v1;
DROP PROCEDURE IF EXISTS p1; DROP PROCEDURE IF EXISTS p1;
connect con2, localhost, root; connect con2, localhost, root;
connect con3, localhost, root; connect con3, localhost, root;
connection default; connection default;
CREATE VIEW v1 AS SELECT schema_name FROM information_schema.schemata; CREATE VIEW v1 AS SELECT schema_name FROM information_schema.schemata;
CREATE TABLE t1 (str VARCHAR(50)); CREATE PROCEDURE p1() SELECT COUNT(*), GET_LOCK('blocker', 100) FROM v1;
CREATE PROCEDURE p1() INSERT INTO t1 SELECT * FROM v1;
# CALL p1() so the view is merged. # CALL p1() so the view is merged.
CALL p1(); CALL p1();
SELECT RELEASE_LOCK('blocker');
RELEASE_LOCK('blocker')
1
connection con3; connection con3;
LOCK TABLE t1 READ; SELECT GET_LOCK('blocker', 100);
GET_LOCK('blocker', 100)
1
connection default; connection default;
# Try to CALL p1() again, this time it should block for t1. # Try to CALL p1() again, this time it should block on "blocker".
# Sending: # Sending:
CALL p1(); CALL p1();
connection con2; connection con2;
@@ -4815,14 +4818,18 @@ connection con2;
DROP VIEW v1; DROP VIEW v1;
connection con3; connection con3;
# Now allow CALL p1() to complete # Now allow CALL p1() to complete
UNLOCK TABLES; SELECT RELEASE_LOCK('blocker');
RELEASE_LOCK('blocker')
1
connection default; connection default;
# Reaping: CALL p1() # Reaping: CALL p1()
SELECT RELEASE_LOCK('blocker');
RELEASE_LOCK('blocker')
1
connection con2; connection con2;
# Reaping: DROP VIEW v1 # Reaping: DROP VIEW v1
connection default; connection default;
DROP PROCEDURE p1; DROP PROCEDURE p1;
DROP TABLE t1;
disconnect con2; disconnect con2;
disconnect con3; disconnect con3;
# #

View File

@@ -9,13 +9,13 @@ innodb_encryption_threads 4
select space,name,current_key_version from information_schema.innodb_tablespaces_encryption order by space; select space,name,current_key_version from information_schema.innodb_tablespaces_encryption order by space;
space name current_key_version space name current_key_version
0 NULL 1 0 NULL 1
2 mysql/innodb_table_stats 1 1 mysql/innodb_table_stats 1
3 mysql/innodb_index_stats 1 2 mysql/innodb_index_stats 1
set global debug_key_management_version=10; set global debug_key_management_version=10;
select space,name,current_key_version from information_schema.innodb_tablespaces_encryption order by space; select space,name,current_key_version from information_schema.innodb_tablespaces_encryption order by space;
space name current_key_version space name current_key_version
0 NULL 10 0 NULL 10
2 mysql/innodb_table_stats 10 1 mysql/innodb_table_stats 10
3 mysql/innodb_index_stats 10 2 mysql/innodb_index_stats 10
set global innodb_encrypt_tables=OFF; set global innodb_encrypt_tables=OFF;
set global debug_key_management_version=1; set global debug_key_management_version=1;

View File

@@ -16,7 +16,7 @@ Warning 131 Using innodb_file_format is deprecated and the parameter may be remo
SET GLOBAL innodb_file_per_table = ON; SET GLOBAL innodb_file_per_table = ON;
CHECK TABLE t1; CHECK TABLE t1;
Table Op Msg_type Msg_text Table Op Msg_type Msg_text
test.t1 check Warning Table test/t1 in tablespace 7 is encrypted but encryption service or used key_id is not available. Can't continue reading table. test.t1 check Warning Table test/t1 in tablespace # is encrypted but encryption service or used key_id is not available. Can't continue reading table.
test.t1 check Warning Table test/t1 is encrypted but encryption service or used key_id is not available. Can't continue checking table. test.t1 check Warning Table test/t1 is encrypted but encryption service or used key_id is not available. Can't continue checking table.
test.t1 check error Corrupt test.t1 check error Corrupt
SHOW WARNINGS; SHOW WARNINGS;

View File

@@ -59,6 +59,7 @@ EOF
SET GLOBAL innodb_file_format = `Barracuda`; SET GLOBAL innodb_file_format = `Barracuda`;
SET GLOBAL innodb_file_per_table = ON; SET GLOBAL innodb_file_per_table = ON;
--replace_regex /tablespace [0-9]*/tablespace #/
CHECK TABLE t1; CHECK TABLE t1;
SHOW WARNINGS; SHOW WARNINGS;

View File

@@ -30,7 +30,6 @@ galera_gcs_fragment : Incorrect arguments to SET
galera_flush_local : Fails sporadically galera_flush_local : Fails sporadically
galera_binlog_stmt_autoinc : TODO: investigate galera_binlog_stmt_autoinc : TODO: investigate
galera_concurrent_ctas : Test times out, investigate galera_concurrent_ctas : Test times out, investigate
galera_var_innodb_disallow_writes : MDEV-11035
MW-286 : TODO: investigate MW-286 : TODO: investigate
galera_sst_xtrabackup-v2-options : TODO: Fix test case galera_sst_xtrabackup-v2-options : TODO: Fix test case
galera_sst_xtrabackup-v2 : MDEV-11208 galera_sst_xtrabackup-v2 : MDEV-11208

View File

@@ -2,20 +2,28 @@ CREATE TABLE rand_table (f1 FLOAT);
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 CHAR(1)); CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 CHAR(1));
INSERT INTO t1 VALUES (1, 'a'); INSERT INTO t1 VALUES (1, 'a');
INSERT INTO t1 VALUES (2, 'a'); INSERT INTO t1 VALUES (2, 'a');
connection node_1;
SET AUTOCOMMIT=ON; SET AUTOCOMMIT=ON;
START TRANSACTION; START TRANSACTION;
UPDATE t1 SET f2 = 'b' WHERE f1 = 1; UPDATE t1 SET f2 = 'b' WHERE f1 = 1;
SELECT * FROM t1 WHERE f1 = 2 FOR UPDATE; SELECT * FROM t1 WHERE f1 = 2 FOR UPDATE;
f1 f2 f1 f2
2 a 2 a
connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
SET GLOBAL wsrep_provider_options = 'dbug=d,commit_monitor_enter_sync'; SET GLOBAL wsrep_provider_options = 'dbug=d,commit_monitor_enter_sync';
connection node_1;
COMMIT;; COMMIT;;
connection node_1a;
SET SESSION wsrep_sync_wait = 0; SET SESSION wsrep_sync_wait = 0;
SET SESSION wsrep_on = 0; SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 1; SET SESSION wsrep_on = 1;
connection node_2;
UPDATE t1 SET f2 = 'c' WHERE f1 = 2; UPDATE t1 SET f2 = 'c' WHERE f1 = 2;
connection node_1a;
connection node_1a;
SET GLOBAL wsrep_provider_options = 'dbug='; SET GLOBAL wsrep_provider_options = 'dbug=';
SET GLOBAL wsrep_provider_options = 'signal=commit_monitor_enter_sync'; SET GLOBAL wsrep_provider_options = 'signal=commit_monitor_enter_sync';
connection node_1;
SELECT TIMEDIFF(SYSDATE(), NOW()) < 2; SELECT TIMEDIFF(SYSDATE(), NOW()) < 2;
TIMEDIFF(SYSDATE(), NOW()) < 2 TIMEDIFF(SYSDATE(), NOW()) < 2
1 1
@@ -26,5 +34,6 @@ COUNT(DISTINCT f1) = 10
1 1
wsrep_local_replays wsrep_local_replays
1 1
connection node_2;
DROP TABLE t1; DROP TABLE t1;
DROP TABLE rand_table; DROP TABLE rand_table;

View File

@@ -9,7 +9,7 @@ SET SESSION binlog_format = 'MIXED';
Warnings: Warnings:
Warning 1105 MariaDB Galera does not support binlog format: MIXED Warning 1105 MariaDB Galera does not support binlog format: MIXED
INSERT INTO t1 VALUES (2); INSERT INTO t1 VALUES (2);
SHOW BINLOG EVENTS IN 'mysqld-bin.000001' FROM 249; SHOW BINLOG EVENTS IN 'mysqld-bin.000001' FROM 256;
Log_name Pos Event_type Server_id End_log_pos Info Log_name Pos Event_type Server_id End_log_pos Info
mysqld-bin.000001 <Pos> Gtid_list 1 <End_log_pos> [] mysqld-bin.000001 <Pos> Gtid_list 1 <End_log_pos> []
mysqld-bin.000001 <Pos> Binlog_checkpoint 1 <End_log_pos> mysqld-bin.000001 mysqld-bin.000001 <Pos> Binlog_checkpoint 1 <End_log_pos> mysqld-bin.000001

View File

@@ -1,3 +1,5 @@
connection node_1;
connection node_2;
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 CHAR(1)); CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 CHAR(1));
INSERT INTO t1 VALUES (1, 'a'), (2, 'a'), (3, 'a'), (4, 'a'), (5, 'a'),(6, 'a'); INSERT INTO t1 VALUES (1, 'a'), (2, 'a'), (3, 'a'), (4, 'a'), (5, 'a'),(6, 'a');
connection node_2; connection node_2;
@@ -52,3 +54,5 @@ COUNT(*) = 0
1 1
connection node_1; connection node_1;
DROP TABLE t1, t2, t3; DROP TABLE t1, t2, t3;
disconnect node_2;
disconnect node_1;

View File

@@ -7,7 +7,7 @@ Killing server ...
connection node_1; connection node_1;
CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB; CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB;
ERROR 40001: Deadlock found when trying to get lock; try restarting transaction ERROR 40001: Deadlock found when trying to get lock; try restarting transaction
SET GLOBAL wsrep_cluster_address = ''; connection node_2;
connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2; connect node_2a, 127.0.0.1, root, , test, $NODE_MYPORT_2;
disconnect node_2; disconnect node_2;
disconnect node_1; disconnect node_1;

View File

@@ -39,6 +39,7 @@ SELECT COUNT(*) = 1 FROM t1 WHERE f2 = 'c';
COUNT(*) = 1 COUNT(*) = 1
1 1
DROP TABLE t1; DROP TABLE t1;
connection node_1;
CREATE TABLE t1 (i int primary key, j int) ENGINE=INNODB; CREATE TABLE t1 (i int primary key, j int) ENGINE=INNODB;
INSERT INTO t1 VALUES (1, 0), (3, 0); INSERT INTO t1 VALUES (1, 0), (3, 0);
SELECT * FROM t1; SELECT * FROM t1;
@@ -46,23 +47,32 @@ i j
1 0 1 0
3 0 3 0
PREPARE stmt1 FROM "UPDATE t1 SET j = 1 where i > 0"; PREPARE stmt1 FROM "UPDATE t1 SET j = 1 where i > 0";
connection node_1a;
SET GLOBAL wsrep_provider_options = 'dbug=d,commit_monitor_enter_sync'; SET GLOBAL wsrep_provider_options = 'dbug=d,commit_monitor_enter_sync';
connection node_1;
EXECUTE stmt1;; EXECUTE stmt1;;
connection node_1a;
SET SESSION wsrep_sync_wait = 0; SET SESSION wsrep_sync_wait = 0;
SET SESSION wsrep_on = 0; SET SESSION wsrep_on = 0;
SET SESSION wsrep_on = 1; SET SESSION wsrep_on = 1;
connection node_2;
INSERT INTO t1 VALUES(2,2); INSERT INTO t1 VALUES(2,2);
connection node_1a;
connection node_1a;
SET GLOBAL wsrep_provider_options = 'dbug='; SET GLOBAL wsrep_provider_options = 'dbug=';
SET GLOBAL wsrep_provider_options = 'signal=commit_monitor_enter_sync'; SET GLOBAL wsrep_provider_options = 'signal=commit_monitor_enter_sync';
connection node_1;
SELECT * FROM t1; SELECT * FROM t1;
i j i j
1 1 1 1
2 2 2 2
3 1 3 1
connection node_2;
SELECT * FROM t1; SELECT * FROM t1;
i j i j
1 1 1 1
2 2 2 2
3 1 3 1
connection node_1;
DEALLOCATE PREPARE stmt1; DEALLOCATE PREPARE stmt1;
DROP TABLE t1; DROP TABLE t1;

View File

@@ -1,9 +1,9 @@
connection node_1; connection node_1;
connection node_2; connection node_2;
connection node_1; connection node_2;
SET GLOBAL wsrep_cluster_address = 'foo://'; SET GLOBAL wsrep_cluster_address = 'foo://';
SET SESSION wsrep_sync_wait=0; SET SESSION wsrep_sync_wait=0;
SELECT * FROM INFORMATION_SCHEMA.GLOBAL_STATUS; SELECT COUNT(*) > 0 FROM INFORMATION_SCHEMA.GLOBAL_STATUS;
ERROR 08S01: WSREP has not yet prepared node for application use ERROR 08S01: WSREP has not yet prepared node for application use
SHOW STATUS LIKE 'wsrep_ready'; SHOW STATUS LIKE 'wsrep_ready';
Variable_name Value Variable_name Value
@@ -17,16 +17,14 @@ wsrep_local_state 0
SHOW STATUS LIKE 'wsrep_local_state_comment'; SHOW STATUS LIKE 'wsrep_local_state_comment';
Variable_name Value Variable_name Value
wsrep_local_state_comment Initialized wsrep_local_state_comment Initialized
connection node_2; connection node_1;
SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
VARIABLE_VALUE = 1 VARIABLE_VALUE = 1
1 1
SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status';
VARIABLE_VALUE = 'Primary' VARIABLE_VALUE = 'Primary'
1 1
connection node_1;
connection node_2; connection node_2;
SET GLOBAL wsrep_cluster_address = @@wsrep_cluster_address;
connection node_1; connection node_1;
SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status';
VARIABLE_VALUE = 'Primary' VARIABLE_VALUE = 'Primary'
@@ -34,29 +32,16 @@ VARIABLE_VALUE = 'Primary'
SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
VARIABLE_VALUE = 2 VARIABLE_VALUE = 2
1 1
connection node_1;
SET GLOBAL wsrep_cluster_address = 'gcomm://192.0.2.1';
SELECT * FROM INFORMATION_SCHEMA.GLOBAL_STATUS;
ERROR 08S01: WSREP has not yet prepared node for application use
SHOW STATUS LIKE 'wsrep_ready';
Variable_name Value
wsrep_ready OFF
SHOW STATUS LIKE 'wsrep_cluster_status';
Variable_name Value
wsrep_cluster_status non-Primary
SHOW STATUS LIKE 'wsrep_local_state';
Variable_name Value
wsrep_local_state 0
SHOW STATUS LIKE 'wsrep_local_state_comment';
Variable_name Value
wsrep_local_state_comment Initialized
connection node_1;
connection node_2; connection node_2;
SET GLOBAL wsrep_cluster_address = @@wsrep_cluster_address; CALL mtr.add_suppression("Backend not supported: foo");
connection node_1; CALL mtr.add_suppression("Failed to initialize backend using 'foo");
SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; CALL mtr.add_suppression("Failed to open channel 'my_wsrep_cluster' at 'foo");
VARIABLE_VALUE = 'Primary' CALL mtr.add_suppression("gcs connect failed: Socket type not supported");
1 CALL mtr.add_suppression("wsrep::connect\\(\\) failed: 7");
SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; CALL mtr.add_suppression("gcs_caused\\(\\) returned -103 \\(Software caused connection abort\\)");
VARIABLE_VALUE = 2 CALL mtr.add_suppression("failed to open gcomm backend connection: 110: failed to reach primary view: 110");
1 CALL mtr.add_suppression("Failed to open backend connection: -110 \\(Connection timed out\\)");
CALL mtr.add_suppression("gcs connect failed: Connection timed out");
CALL mtr.add_suppression("WSREP: wsrep::connect\\(foo://\\) failed: 7");
disconnect node_2;
disconnect node_1;

View File

@@ -94,6 +94,16 @@ connection node_1;
COMMIT; COMMIT;
DROP TABLE t1; DROP TABLE t1;
DROP TABLE t2; DROP TABLE t2;
#
# MDEV-11152: wsrep_replicate_myisam: SELECT gets replicated using TO
#
connection node_1;
CREATE TABLE t1 (i INT) ENGINE=INNODB;
INSERT INTO t1 VALUES(1);
SELECT * FROM t1;
i
1
DROP TABLE t1;
connection node_1; connection node_1;
SET GLOBAL wsrep_replicate_myisam = 0; SET GLOBAL wsrep_replicate_myisam = 0;
connection node_2; connection node_2;

View File

@@ -20,7 +20,7 @@ INSERT INTO t1 VALUES (2);
--replace_regex /xid=[0-9]+/xid=###/ /table_id: [0-9]+/table_id: ###/ --replace_regex /xid=[0-9]+/xid=###/ /table_id: [0-9]+/table_id: ###/
--replace_column 2 <Pos> 5 <End_log_pos> --replace_column 2 <Pos> 5 <End_log_pos>
SHOW BINLOG EVENTS IN 'mysqld-bin.000001' FROM 249; SHOW BINLOG EVENTS IN 'mysqld-bin.000001' FROM 256;
DROP TABLE t1; DROP TABLE t1;

View File

@@ -25,11 +25,8 @@ CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB;
# Reset the master and restart the slave so that post-test checks can run # Reset the master and restart the slave so that post-test checks can run
SET GLOBAL wsrep_cluster_address = '';
--disable_query_log
--eval SET GLOBAL wsrep_cluster_address = '$wsrep_cluster_address_orig';
--enable_query_log
--connection node_2
--source include/start_mysqld.inc --source include/start_mysqld.inc
--sleep 5 --sleep 5
--source include/wait_until_connected_again.inc --source include/wait_until_connected_again.inc

View File

@@ -6,17 +6,15 @@
--source include/have_innodb.inc --source include/have_innodb.inc
# Save original auto_increment_offset values. # Save original auto_increment_offset values.
--connection node_1 --let $node_1=node_1
let $auto_increment_offset_node_1 = `SELECT @@global.auto_increment_offset`; --let $node_2=node_2
--connection node_2 --source include/auto_increment_offset_save.inc
let $auto_increment_offset_node_2 = `SELECT @@global.auto_increment_offset`;
# #
# Set to invalid value # Set to invalid value
# #
--connection node_1 --connection node_2
--let $wsrep_cluster_address_node1 = `SELECT @@wsrep_cluster_address` --let $wsrep_cluster_address_node2 = `SELECT @@wsrep_cluster_address`
SET GLOBAL wsrep_cluster_address = 'foo://'; SET GLOBAL wsrep_cluster_address = 'foo://';
# With wsrep_sync_wait, this returns an error # With wsrep_sync_wait, this returns an error
@@ -26,7 +24,7 @@ SET GLOBAL wsrep_cluster_address = 'foo://';
SET SESSION wsrep_sync_wait=0; SET SESSION wsrep_sync_wait=0;
--error ER_UNKNOWN_COM_ERROR --error ER_UNKNOWN_COM_ERROR
SELECT * FROM INFORMATION_SCHEMA.GLOBAL_STATUS; SELECT COUNT(*) > 0 FROM INFORMATION_SCHEMA.GLOBAL_STATUS;
# Must return 'OFF' # Must return 'OFF'
SHOW STATUS LIKE 'wsrep_ready'; SHOW STATUS LIKE 'wsrep_ready';
@@ -38,9 +36,9 @@ SHOW STATUS LIKE 'wsrep_cluster_status';
SHOW STATUS LIKE 'wsrep_local_state'; SHOW STATUS LIKE 'wsrep_local_state';
SHOW STATUS LIKE 'wsrep_local_state_comment'; SHOW STATUS LIKE 'wsrep_local_state_comment';
--connection node_2 --connection node_1
--sleep 1 --sleep 1
# Node #2 thinks that it is now part of a single-node primary cluster # Node #1 thinks that it is now part of a single-node primary cluster
SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; SELECT VARIABLE_VALUE = 1 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status';
@@ -48,13 +46,10 @@ SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VA
# Reset everything as it was # Reset everything as it was
# #
--connection node_1
--disable_query_log
--eval SET GLOBAL wsrep_cluster_address = '$wsrep_cluster_address_node1';
--enable_query_log
--connection node_2 --connection node_2
SET GLOBAL wsrep_cluster_address = @@wsrep_cluster_address; --disable_query_log
--eval SET GLOBAL wsrep_cluster_address = '$wsrep_cluster_address_node2';
--enable_query_log
--source include/wait_until_connected_again.inc --source include/wait_until_connected_again.inc
@@ -62,49 +57,19 @@ SET GLOBAL wsrep_cluster_address = @@wsrep_cluster_address;
SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status';
SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
#
# Set to invalid host
#
--connection node_1
SET GLOBAL wsrep_cluster_address = 'gcomm://192.0.2.1';
--error ER_UNKNOWN_COM_ERROR
SELECT * FROM INFORMATION_SCHEMA.GLOBAL_STATUS;
# Must return 'OFF'
SHOW STATUS LIKE 'wsrep_ready';
# Must return 'Non-primary'
SHOW STATUS LIKE 'wsrep_cluster_status';
# Must return 0 = 'Initialized'
SHOW STATUS LIKE 'wsrep_local_state';
SHOW STATUS LIKE 'wsrep_local_state_comment';
#
# Reset everything as it was
#
--connection node_1
--disable_query_log
--eval SET GLOBAL wsrep_cluster_address = '$wsrep_cluster_address_node1';
--enable_query_log
--connection node_2 --connection node_2
SET GLOBAL wsrep_cluster_address = @@wsrep_cluster_address; CALL mtr.add_suppression("Backend not supported: foo");
--sleep 1 CALL mtr.add_suppression("Failed to initialize backend using 'foo");
CALL mtr.add_suppression("Failed to open channel 'my_wsrep_cluster' at 'foo");
--connection node_1 CALL mtr.add_suppression("gcs connect failed: Socket type not supported");
SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status'; CALL mtr.add_suppression("wsrep::connect\\(\\) failed: 7");
SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size'; CALL mtr.add_suppression("gcs_caused\\(\\) returned -103 \\(Software caused connection abort\\)");
CALL mtr.add_suppression("failed to open gcomm backend connection: 110: failed to reach primary view: 110");
CALL mtr.add_suppression("Failed to open backend connection: -110 \\(Connection timed out\\)");
CALL mtr.add_suppression("gcs connect failed: Connection timed out");
CALL mtr.add_suppression("WSREP: wsrep::connect\\(foo://\\) failed: 7");
# Restore original auto_increment_offset values. # Restore original auto_increment_offset values.
--disable_query_log --source include/auto_increment_offset_restore.inc
--connection node_1
--eval SET @@global.auto_increment_offset = $auto_increment_offset_node_1;
--connection node_2
--eval SET @@global.auto_increment_offset = $auto_increment_offset_node_2;
--enable_query_log
--source include/galera_end.inc

View File

@@ -132,6 +132,16 @@ COMMIT;
DROP TABLE t1; DROP TABLE t1;
DROP TABLE t2; DROP TABLE t2;
--echo #
--echo # MDEV-11152: wsrep_replicate_myisam: SELECT gets replicated using TO
--echo #
--connection node_1
CREATE TABLE t1 (i INT) ENGINE=INNODB;
INSERT INTO t1 VALUES(1);
# This command should not get replicated.
SELECT * FROM t1;
DROP TABLE t1;
--connection node_1 --connection node_1
--eval SET GLOBAL wsrep_replicate_myisam = $wsrep_replicate_myisam_orig --eval SET GLOBAL wsrep_replicate_myisam = $wsrep_replicate_myisam_orig

View File

@@ -1,13 +1,23 @@
connection node_1;
connection node_2;
connection node_3;
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY); CREATE TABLE t1 (f1 INTEGER PRIMARY KEY);
INSERT INTO t1 VALUES (01), (02), (03), (04), (05); INSERT INTO t1 VALUES (01), (02), (03), (04), (05);
connection node_2;
Unloading wsrep provider ... Unloading wsrep provider ...
SET GLOBAL wsrep_provider = 'none'; SET GLOBAL wsrep_provider = 'none';
connection node_3;
Unloading wsrep provider ... Unloading wsrep provider ...
SET GLOBAL wsrep_provider = 'none'; SET GLOBAL wsrep_provider = 'none';
connection node_1;
INSERT INTO t1 VALUES (11), (12), (13), (14), (15); INSERT INTO t1 VALUES (11), (12), (13), (14), (15);
INSERT INTO t1 VALUES (21), (22), (23), (24), (25); INSERT INTO t1 VALUES (21), (22), (23), (24), (25);
SET GLOBAL wsrep_provider_options = 'dbug=d,ist_sender_send_after_get_buffers'; SET GLOBAL wsrep_provider_options = 'dbug=d,ist_sender_send_after_get_buffers';
connection node_2;
connection node_1;
INSERT INTO t1 VALUES (31), (32), (33), (34), (35); INSERT INTO t1 VALUES (31), (32), (33), (34), (35);
connection node_3;
connection node_1;
SHOW STATUS LIKE 'wsrep_debug_sync_waiters'; SHOW STATUS LIKE 'wsrep_debug_sync_waiters';
Variable_name Value Variable_name Value
wsrep_debug_sync_waiters ist_sender_send_after_get_buffers ist_sender_send_after_get_buffers wsrep_debug_sync_waiters ist_sender_send_after_get_buffers ist_sender_send_after_get_buffers
@@ -19,6 +29,9 @@ INSERT INTO t2 VALUES (REPEAT('x', 512 * 1024));
SET GLOBAL wsrep_provider_options = 'dbug='; SET GLOBAL wsrep_provider_options = 'dbug=';
SET GLOBAL wsrep_provider_options = 'signal=ist_sender_send_after_get_buffers'; SET GLOBAL wsrep_provider_options = 'signal=ist_sender_send_after_get_buffers';
INSERT INTO t1 VALUES (51), (52), (53), (54), (55); INSERT INTO t1 VALUES (51), (52), (53), (54), (55);
connection node_2;
connection node_3;
connection node_2;
SELECT COUNT(*) = 30 FROM t1; SELECT COUNT(*) = 30 FROM t1;
COUNT(*) = 30 COUNT(*) = 30
1 1
@@ -31,6 +44,7 @@ LENGTH(f1) = 512 * 1024
1 1
1 1
CALL mtr.add_suppression("WSREP: Unsupported protocol downgrade: incremental data collection disabled"); CALL mtr.add_suppression("WSREP: Unsupported protocol downgrade: incremental data collection disabled");
connection node_3;
SELECT COUNT(*) = 30 FROM t1; SELECT COUNT(*) = 30 FROM t1;
COUNT(*) = 30 COUNT(*) = 30
1 1
@@ -44,3 +58,6 @@ LENGTH(f1) = 512 * 1024
1 1
CALL mtr.add_suppression("WSREP: Unsupported protocol downgrade: incremental data collection disabled"); CALL mtr.add_suppression("WSREP: Unsupported protocol downgrade: incremental data collection disabled");
DROP TABLE t1, t2; DROP TABLE t1, t2;
disconnect node_3;
disconnect node_2;
disconnect node_1;

View File

@@ -17,6 +17,12 @@
--let $galera_server_number = 3 --let $galera_server_number = 3
--source include/galera_connect.inc --source include/galera_connect.inc
# Save original auto_increment_offset values.
--let $node_1=node_1
--let $node_2=node_2
--let $node_3=node_3
--source ../galera/include/auto_increment_offset_save.inc
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY); CREATE TABLE t1 (f1 INTEGER PRIMARY KEY);
INSERT INTO t1 VALUES (01), (02), (03), (04), (05); INSERT INTO t1 VALUES (01), (02), (03), (04), (05);
@@ -99,3 +105,9 @@ SELECT LENGTH(f1) = 512 * 1024 FROM t2;
CALL mtr.add_suppression("WSREP: Unsupported protocol downgrade: incremental data collection disabled"); CALL mtr.add_suppression("WSREP: Unsupported protocol downgrade: incremental data collection disabled");
DROP TABLE t1, t2; DROP TABLE t1, t2;
# Restore original auto_increment_offset values.
--source ../galera/include/auto_increment_offset_restore.inc
--let $galera_cluster_size=3
--source include/galera_end.inc

View File

@@ -36,8 +36,11 @@ drop table t1;
# Old lock method (where LOCK TABLE was ignored by InnoDB) no longer # Old lock method (where LOCK TABLE was ignored by InnoDB) no longer
# works when LOCK TABLE ... WRITE is used due to fix for bugs #46272 # works when LOCK TABLE ... WRITE is used due to fix for bugs #46272
# "MySQL 5.4.4, new MDL: unnecessary and bug #37346 "innodb does not # "MySQL 5.4.4, new MDL: unnecessary and bug #37346 "innodb does not
# detect deadlock between update and alter table". But it still works # detect deadlock between update and alter table".
# for LOCK TABLE ... READ. # After WL#6671 "Improve scalability by not using thr_lock.c locks
# for InnoDB tables" was implemented it no longer works for LOCK TABLES
# ,,, READ as well.
# LOCK TABLES locks are now completely handled by MDL subsystem.
# #
set @@innodb_table_locks=0; set @@innodb_table_locks=0;
create table t1 (id integer primary key, x integer) engine=INNODB; create table t1 (id integer primary key, x integer) engine=INNODB;
@@ -73,28 +76,26 @@ select * from t1 where id = 0 for update;
id x id x
0 1 0 1
connection con2; connection con2;
# The below statement should not be blocked as LOCK TABLES ... READ # The following statement should block because SQL-level lock
# does not take strong SQL-level lock on t1. SELECTs which do not # is taken on t1 which will wait until concurrent transaction
# conflict with transaction in the first connections should not be # is commited.
# blocked. # Sending:
lock table t1 read; lock table t1 read;;
select * from t1;
id x
0 1
1 1
2 2
select * from t1 where id = 1 lock in share mode;
id x
1 1
unlock tables;
select * from t1;
id x
0 1
1 1
2 2
commit;
connection con1; connection con1;
# Wait until LOCK TABLE is blocked on SQL-level lock.
# We should be able to do UPDATEs and SELECTs within transaction.
update t1 set x=2 where id = 0;
select * from t1;
id x
0 2
1 1
2 2
# Unblock LOCK TABLE.
commit; commit;
connection con2;
# Reap LOCK TABLE.
unlock tables;
connection default;
drop table t1; drop table t1;
# #
#Bug#12842206 INNODB LOCKING REGRESSION FOR INSERT IGNORE #Bug#12842206 INNODB LOCKING REGRESSION FOR INSERT IGNORE

View File

@@ -1,9 +1,3 @@
set global innodb_support_xa=default;
Warnings:
Warning 131 Using innodb_support_xa is deprecated and the parameter may be removed in future releases.
set session innodb_support_xa=default;
Warnings:
Warning 131 Using innodb_support_xa is deprecated and the parameter may be removed in future releases.
SET SESSION DEFAULT_STORAGE_ENGINE = InnoDB; SET SESSION DEFAULT_STORAGE_ENGINE = InnoDB;
drop table if exists t1,t2,t3,t1m,t1i,t2m,t2i,t4; drop table if exists t1,t2,t3,t1m,t1i,t2m,t2i,t4;
drop procedure if exists p1; drop procedure if exists p1;
@@ -614,9 +608,6 @@ OPTIMIZE TABLE t2;
Table Op Msg_type Msg_text Table Op Msg_type Msg_text
test.t2 optimize note Table does not support optimize, doing recreate + analyze instead test.t2 optimize note Table does not support optimize, doing recreate + analyze instead
test.t2 optimize status OK test.t2 optimize status OK
EXPLAIN SELECT COUNT(*) FROM t2 WHERE stat_id IN (1,3) AND acct_id=785;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t2 range idx1,idx2 idx1 9 NULL 2 Using where; Using index
DROP TABLE t1,t2; DROP TABLE t1,t2;
create table t1(a int) engine=innodb; create table t1(a int) engine=innodb;
alter table t1 comment '123'; alter table t1 comment '123';
@@ -678,8 +669,11 @@ SET AUTOCOMMIT=0;
INSERT INTO t2 VALUES (1); INSERT INTO t2 VALUES (1);
connection c2; connection c2;
SET AUTOCOMMIT=0; SET AUTOCOMMIT=0;
SET @old_lock_wait_timeout= @@lock_wait_timeout;
SET lock_wait_timeout= 1;
LOCK TABLES t1 READ, t2 READ; LOCK TABLES t1 READ, t2 READ;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction ERROR HY000: Lock wait timeout exceeded; try restarting transaction
SET @@lock_wait_timeout= @old_lock_wait_timeout;
connection c1; connection c1;
COMMIT; COMMIT;
INSERT INTO t1 VALUES (1); INSERT INTO t1 VALUES (1);
@@ -1430,7 +1424,7 @@ INSERT INTO t1 (a,b,c) VALUES (1,1,1), (2,1,1), (3,1,1), (4,1,1);
INSERT INTO t1 (a,b,c) SELECT a+4,b,c FROM t1; INSERT INTO t1 (a,b,c) SELECT a+4,b,c FROM t1;
EXPLAIN SELECT a, b, c FROM t1 WHERE b = 1 ORDER BY a DESC LIMIT 5; EXPLAIN SELECT a, b, c FROM t1 WHERE b = 1 ORDER BY a DESC LIMIT 5;
id select_type table type possible_keys key key_len ref rows Extra id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 range t1_b t1_b 5 NULL 8 Using index condition 1 SIMPLE t1 range t1_b t1_b 5 NULL 8 Using where
SELECT a, b, c FROM t1 WHERE b = 1 ORDER BY a DESC LIMIT 5; SELECT a, b, c FROM t1 WHERE b = 1 ORDER BY a DESC LIMIT 5;
a b c a b c
8 1 1 8 1 1
@@ -2275,7 +2269,7 @@ INSERT INTO t1 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5), (6, 6);
INSERT INTO t2 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5); INSERT INTO t2 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);
INSERT INTO t3 VALUES (1, 101), (2, 102), (3, 103), (4, 104), (5, 105), (6, 106); INSERT INTO t3 VALUES (1, 101), (2, 102), (3, 103), (4, 104), (5, 105), (6, 106);
INSERT INTO t4 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5); INSERT INTO t4 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);
UPDATE t1, t2 SET t1.a = t1.a + 100, t2.b = t1.a + 10 UPDATE t2 straight_join t1 SET t1.a = t1.a + 100, t2.b = t1.a + 10
WHERE t1.a BETWEEN 2 AND 4 AND t2.a = t1.b; WHERE t1.a BETWEEN 2 AND 4 AND t2.a = t1.b;
SELECT * FROM t2; SELECT * FROM t2;
a b a b
@@ -2284,7 +2278,7 @@ a b
3 13 3 13
4 14 4 14
5 5 5 5
UPDATE t3, t4 SET t3.a = t3.a + 100, t4.b = t3.a + 10 UPDATE t4 straight_join t3 SET t3.a = t3.a + 100, t4.b = t3.a + 10
WHERE t3.a BETWEEN 2 AND 4 AND t4.a = t3.b - 100; WHERE t3.a BETWEEN 2 AND 4 AND t4.a = t3.b - 100;
SELECT * FROM t4; SELECT * FROM t4;
a b a b
@@ -2335,6 +2329,9 @@ INSERT INTO t1 SELECT c1+1000,c2+1000,c3+1000 from t1;
INSERT INTO t1 SELECT c1+10000,c2+10000,c3+10000 from t1; INSERT INTO t1 SELECT c1+10000,c2+10000,c3+10000 from t1;
INSERT INTO t1 SELECT c1+100000,c2+100000,c3+100000 from t1; INSERT INTO t1 SELECT c1+100000,c2+100000,c3+100000 from t1;
INSERT INTO t1 SELECT c1+1000000,c2+1000000,c3+1000000 from t1; INSERT INTO t1 SELECT c1+1000000,c2+1000000,c3+1000000 from t1;
ANALYZE TABLE t1;
Table Op Msg_type Msg_text
test.t1 analyze status OK
SELECT * FROM t1 WHERE c1 = 99999999 AND c3 > 1 ORDER BY c3; SELECT * FROM t1 WHERE c1 = 99999999 AND c3 > 1 ORDER BY c3;
c1 c2 c3 c1 c2 c3
EXPLAIN SELECT * FROM t1 WHERE c1 = 99999999 AND c3 > 1 ORDER BY c3; EXPLAIN SELECT * FROM t1 WHERE c1 = 99999999 AND c3 > 1 ORDER BY c3;

View File

@@ -60,8 +60,11 @@ drop table t1;
--echo # Old lock method (where LOCK TABLE was ignored by InnoDB) no longer --echo # Old lock method (where LOCK TABLE was ignored by InnoDB) no longer
--echo # works when LOCK TABLE ... WRITE is used due to fix for bugs #46272 --echo # works when LOCK TABLE ... WRITE is used due to fix for bugs #46272
--echo # "MySQL 5.4.4, new MDL: unnecessary and bug #37346 "innodb does not --echo # "MySQL 5.4.4, new MDL: unnecessary and bug #37346 "innodb does not
--echo # detect deadlock between update and alter table". But it still works --echo # detect deadlock between update and alter table".
--echo # for LOCK TABLE ... READ. --echo # After WL#6671 "Improve scalability by not using thr_lock.c locks
--echo # for InnoDB tables" was implemented it no longer works for LOCK TABLES
--echo # ,,, READ as well.
--echo # LOCK TABLES locks are now completely handled by MDL subsystem.
--echo # --echo #
set @@innodb_table_locks=0; set @@innodb_table_locks=0;
@@ -104,20 +107,32 @@ connection con1;
select * from t1 where id = 0 for update; select * from t1 where id = 0 for update;
connection con2; connection con2;
--echo # The below statement should not be blocked as LOCK TABLES ... READ --echo # The following statement should block because SQL-level lock
--echo # does not take strong SQL-level lock on t1. SELECTs which do not --echo # is taken on t1 which will wait until concurrent transaction
--echo # conflict with transaction in the first connections should not be --echo # is commited.
--echo # blocked. --echo # Sending:
lock table t1 read; --send lock table t1 read;
select * from t1;
select * from t1 where id = 1 lock in share mode;
unlock tables;
select * from t1;
commit;
connection con1; connection con1;
--echo # Wait until LOCK TABLE is blocked on SQL-level lock.
let $wait_condition=
select count(*) = 1 from information_schema.processlist
where state = "Waiting for table metadata lock" and
info = "lock table t1 read";
--source include/wait_condition.inc
--echo # We should be able to do UPDATEs and SELECTs within transaction.
update t1 set x=2 where id = 0;
select * from t1;
--echo # Unblock LOCK TABLE.
commit; commit;
connection con2;
--echo # Reap LOCK TABLE.
--reap
unlock tables;
connection default;
drop table t1; drop table t1;
# End of 4.1 tests # End of 4.1 tests

View File

@@ -13,10 +13,8 @@
-- source include/have_innodb.inc -- source include/have_innodb.inc
let $engine_type= InnoDB; let $engine_type= InnoDB;
let $other_engine_type= MEMORY; let $other_engine_type= MEMORY;
# InnoDB does support FOREIGN KEYFOREIGN KEYs # InnoDB does support FOREIGN KEYs
let $test_foreign_keys= 1; let $test_foreign_keys= 1;
set global innodb_support_xa=default;
set session innodb_support_xa=default;
--source include/mix1.inc --source include/mix1.inc
--disable_warnings --disable_warnings
@@ -359,12 +357,16 @@ INSERT INTO t2 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);
INSERT INTO t3 VALUES (1, 101), (2, 102), (3, 103), (4, 104), (5, 105), (6, 106); INSERT INTO t3 VALUES (1, 101), (2, 102), (3, 103), (4, 104), (5, 105), (6, 106);
INSERT INTO t4 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5); INSERT INTO t4 VALUES (1, 1), (2, 2), (3, 3), (4, 4), (5, 5);
UPDATE t1, t2 SET t1.a = t1.a + 100, t2.b = t1.a + 10 # Because t1.a changes and t2.b changes based on t1.a, the result
# depends on join order, so STRAIGHT_JOIN is used to have it repeatable.
UPDATE t2 straight_join t1 SET t1.a = t1.a + 100, t2.b = t1.a + 10
WHERE t1.a BETWEEN 2 AND 4 AND t2.a = t1.b; WHERE t1.a BETWEEN 2 AND 4 AND t2.a = t1.b;
--sorted_result --sorted_result
SELECT * FROM t2; SELECT * FROM t2;
UPDATE t3, t4 SET t3.a = t3.a + 100, t4.b = t3.a + 10 # Because t1.a changes and t2.b changes based on t1.a, the result
# depends on join order, so STRAIGHT_JOIN is used to have it repeatable.
UPDATE t4 straight_join t3 SET t3.a = t3.a + 100, t4.b = t3.a + 10
WHERE t3.a BETWEEN 2 AND 4 AND t4.a = t3.b - 100; WHERE t3.a BETWEEN 2 AND 4 AND t4.a = t3.b - 100;
--sorted_result --sorted_result
SELECT * FROM t4; SELECT * FROM t4;
@@ -420,7 +422,7 @@ INSERT INTO t1 SELECT c1+1000,c2+1000,c3+1000 from t1;
INSERT INTO t1 SELECT c1+10000,c2+10000,c3+10000 from t1; INSERT INTO t1 SELECT c1+10000,c2+10000,c3+10000 from t1;
INSERT INTO t1 SELECT c1+100000,c2+100000,c3+100000 from t1; INSERT INTO t1 SELECT c1+100000,c2+100000,c3+100000 from t1;
INSERT INTO t1 SELECT c1+1000000,c2+1000000,c3+1000000 from t1; INSERT INTO t1 SELECT c1+1000000,c2+1000000,c3+1000000 from t1;
ANALYZE TABLE t1;
# query and no rows will match the c1 condition, whereas all will match c3 # query and no rows will match the c1 condition, whereas all will match c3
SELECT * FROM t1 WHERE c1 = 99999999 AND c3 > 1 ORDER BY c3; SELECT * FROM t1 WHERE c1 = 99999999 AND c3 > 1 ORDER BY c3;

View File

@@ -128,7 +128,7 @@ show create table t3;
Table t3 Table t3
Create Table CREATE TABLE `t3` ( Create Table CREATE TABLE `t3` (
`id` mediumint(9) NOT NULL AUTO_INCREMENT, `id` mediumint(9) NOT NULL AUTO_INCREMENT,
`dt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `dt` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
`user` char(255) DEFAULT NULL, `user` char(255) DEFAULT NULL,
`uuidf` longblob DEFAULT NULL, `uuidf` longblob DEFAULT NULL,
`fkid` mediumint(9) DEFAULT NULL, `fkid` mediumint(9) DEFAULT NULL,

View File

@@ -114,7 +114,7 @@ show create table test.byrange_tbl;
Table byrange_tbl Table byrange_tbl
Create Table CREATE TABLE `byrange_tbl` ( Create Table CREATE TABLE `byrange_tbl` (
`id` mediumint(9) NOT NULL AUTO_INCREMENT, `id` mediumint(9) NOT NULL AUTO_INCREMENT,
`dt` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, `dt` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
`user` char(255) DEFAULT NULL, `user` char(255) DEFAULT NULL,
`uuidf` longblob DEFAULT NULL, `uuidf` longblob DEFAULT NULL,
`fkid` mediumint(9) DEFAULT NULL, `fkid` mediumint(9) DEFAULT NULL,

View File

@@ -410,7 +410,6 @@ LOCK TABLES t11 WRITE;
SET SESSION BINLOG_FORMAT=ROW; SET SESSION BINLOG_FORMAT=ROW;
INSERT INTO t11 VALUES('Several Species of Small Furry Animals Gathered Together in a Cave and Grooving With a Pict'); INSERT INTO t11 VALUES('Several Species of Small Furry Animals Gathered Together in a Cave and Grooving With a Pict');
SET SESSION BINLOG_FORMAT=STATEMENT; SET SESSION BINLOG_FORMAT=STATEMENT;
ERROR HY000: Cannot modify @@session.binlog_format inside a transaction
INSERT INTO t11 VALUES('Careful With That Axe, Eugene'); INSERT INTO t11 VALUES('Careful With That Axe, Eugene');
UNLOCK TABLES; UNLOCK TABLES;
SELECT * FROM t11; SELECT * FROM t11;

View File

@@ -524,7 +524,6 @@ CREATE TABLE t11 (song VARCHAR(255));
LOCK TABLES t11 WRITE; LOCK TABLES t11 WRITE;
SET SESSION BINLOG_FORMAT=ROW; SET SESSION BINLOG_FORMAT=ROW;
INSERT INTO t11 VALUES('Several Species of Small Furry Animals Gathered Together in a Cave and Grooving With a Pict'); INSERT INTO t11 VALUES('Several Species of Small Furry Animals Gathered Together in a Cave and Grooving With a Pict');
--error ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_FORMAT
SET SESSION BINLOG_FORMAT=STATEMENT; SET SESSION BINLOG_FORMAT=STATEMENT;
INSERT INTO t11 VALUES('Careful With That Axe, Eugene'); INSERT INTO t11 VALUES('Careful With That Axe, Eugene');
UNLOCK TABLES; UNLOCK TABLES;

View File

@@ -7,5 +7,5 @@ SELECT @@wsrep_on;
0 0
SELECT @@GLOBAL.wsrep_provider; SELECT @@GLOBAL.wsrep_provider;
@@GLOBAL.wsrep_provider @@GLOBAL.wsrep_provider
/usr/lib/galera/libgalera_smm.so libgalera_smm.so
SET @@GLOBAL.wsrep_cluster_address='gcomm://'; SET @@GLOBAL.wsrep_cluster_address='gcomm://';

View File

@@ -7,7 +7,7 @@
--echo # --echo #
SELECT @@wsrep_on; SELECT @@wsrep_on;
--replace_result /usr/lib64/ /usr/lib/ --replace_regex /.*libgalera_smm.so/libgalera_smm.so/
SELECT @@GLOBAL.wsrep_provider; SELECT @@GLOBAL.wsrep_provider;
SET @@GLOBAL.wsrep_cluster_address='gcomm://'; SET @@GLOBAL.wsrep_cluster_address='gcomm://';

View File

@@ -381,21 +381,40 @@ DROP TABLE IF EXISTS t1;
--enable_warnings --enable_warnings
# #
# Test. # Test.
CREATE TABLE t1 (c1 INT); CREATE TABLE t1 (c1 INT) ENGINE=MyISAM;
LOCK TABLE t1 READ; INSERT INTO t1 VALUES (1);
connect (con1,localhost,root,,); SELECT GET_LOCK('mysqltest_lock', 100);
# Retain action after use. First used by general_log.
SET DEBUG_SYNC= 'wait_for_lock SIGNAL locked EXECUTE 2'; connect (con1,localhost,root,,);
send INSERT INTO t1 VALUES (1); --echo # Sending:
--send UPDATE t1 SET c1=GET_LOCK('mysqltest_lock', 100);
connect (con2,localhost,root,,);
let $wait_condition=
select count(*) = 1 from information_schema.processlist
where state = "User lock" and
info = "UPDATE t1 SET c1=GET_LOCK('mysqltest_lock', 100)";
--source include/wait_condition.inc
# Retain action after use. First used by general_log.
SET DEBUG_SYNC= 'wait_for_lock SIGNAL locked EXECUTE 2';
send INSERT INTO t1 VALUES (1);
connection default; connection default;
# Wait until INSERT waits for lock. # Wait until INSERT waits for lock.
SET DEBUG_SYNC= 'now WAIT_FOR locked'; SET DEBUG_SYNC= 'now WAIT_FOR locked';
# let INSERT continue. # let UPDATE continue.
UNLOCK TABLES; SELECT RELEASE_LOCK('mysqltest_lock');
connection con1; connection con1;
--echo retrieve INSERT result. --echo # Reaping UPDATE
reap; reap;
disconnect con1; SELECT RELEASE_LOCK('mysqltest_lock');
connection con2;
--echo retrieve INSERT result.
reap;
disconnect con1;
disconnect con2;
connection default; connection default;
DROP TABLE t1; DROP TABLE t1;

View File

@@ -1273,3 +1273,49 @@ SELECT * FROM ( SELECT DISTINCT * FROM t1 ) AS sq
WHERE i IN ( SELECT MIN(j) FROM t2 ); WHERE i IN ( SELECT MIN(j) FROM t2 );
DROP TABLE t1,t2; DROP TABLE t1,t2;
--echo #
--echo # MDEV-11593: pushdown of condition with NULLIF
--echo #
CREATE TABLE t1 (i INT);
CREATE OR REPLACE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
INSERT INTO t1 VALUES (2), (1);
SELECT * FROM v1 WHERE NULLIF(1, i);
EXPLAIN FORMAT=JSON
SELECT * FROM v1 WHERE NULLIF(1, i);
DROP VIEW v1;
DROP TABLE t1;
--echo #
--echo # MDEV-11608: pushdown of the predicate with cached null value
--echo #
CREATE TABLE t1 (c VARCHAR(3));
CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
INSERT INTO t1 VALUES ('foo'),('bar');
CREATE TABLE t2 (c VARCHAR(3));
INSERT INTO t2 VALUES ('foo'),('xyz');
SELECT * FROM v1 WHERE v1.c IN ( SELECT MIN(c) FROM t2 WHERE 0 );
EXPLAIN FORMAT=JSON
SELECT * FROM v1 WHERE v1.c IN ( SELECT MIN(c) FROM t2 WHERE 0 );
DROP VIEW v1;
DROP TABLE t1,t2;
CREATE TABLE t1 (d DECIMAL(10,2));
CREATE ALGORITHM=TEMPTABLE VIEW v1 AS SELECT * FROM t1;
INSERT INTO t1 VALUES (5.37),(1.1);
CREATE TABLE t2 (d DECIMAL(10,2));
INSERT INTO t2 VALUES ('1.1'),('2.23');
SELECT * FROM v1 WHERE v1.d IN ( SELECT MIN(d) FROM t2 WHERE 0 );
DROP VIEW v1;
DROP TABLE t1,t2;

View File

@@ -128,4 +128,6 @@ create or replace view v1 as select 30 + (20010101 + interval 2 day) as x;
show create view v1; show create view v1;
select 30 + (20010101 + interval 2 day), x from v1; select 30 + (20010101 + interval 2 day), x from v1;
drop view v1;
--echo End of 10.2 tests --echo End of 10.2 tests

View File

@@ -77,6 +77,7 @@ select json_extract(json_object('foo', 'foobar'),'$');
select json_extract('[10, 20, [30, 40]]', '$[2][*]'); select json_extract('[10, 20, [30, 40]]', '$[2][*]');
select json_extract('[10, 20, [{"a":3}, 30, 40]]', '$[2][*]'); select json_extract('[10, 20, [{"a":3}, 30, 40]]', '$[2][*]');
select json_extract('1', '$'); select json_extract('1', '$');
select json_extract('[10, 20, [30, 40], 1, 10]', '$[1]');
select json_insert('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.b.k1', 'word'); select json_insert('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.b.k1', 'word');
select json_insert('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.d[3]', 3); select json_insert('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.d[3]', 3);
@@ -123,6 +124,7 @@ select json_merge('{"1": 2}', '{"true": false}', '{"3": 4}');
select json_merge(NULL,json_object('foo', 1)); select json_merge(NULL,json_object('foo', 1));
select json_merge('a','b'); select json_merge('a','b');
select json_merge('{"a":"b"}','{"c":"d"}'); select json_merge('{"a":"b"}','{"c":"d"}');
SELECT JSON_MERGE('[1, 2]', '{"id": 47}');
select json_type('{"k1":123, "k2":345}'); select json_type('{"k1":123, "k2":345}');
select json_type('[123, "k2", 345]'); select json_type('[123, "k2", 345]');
@@ -168,6 +170,8 @@ select json_depth('[10, {"a": 20}]');
select json_length(''); select json_length('');
select json_length('{}'); select json_length('{}');
select json_length('[1, 2, {"a": 3}]'); select json_length('[1, 2, {"a": 3}]');
select json_length('{"a": 1, "b": {"c": 30}}', '$.b');
select json_length('{"a": 1, "b": {"c": 30}}');
create table json (j INT); create table json (j INT);
show create table json; show create table json;

View File

@@ -64,6 +64,7 @@ set @@autocommit=1;
connection default; connection default;
disconnect con1; disconnect con1;
disconnect con2;
disconnect con3; disconnect con3;
@@ -116,54 +117,6 @@ connection default;
disconnect con37346; disconnect con37346;
drop table t1; drop table t1;
--echo #
--echo # Bug #42147 Concurrent DML and LOCK TABLE ... READ for InnoDB
--echo # table cause warnings in errlog
--echo #
--echo #
--echo # Note that this test for now relies on a global suppression of
--echo # the warning "Found lock of type 6 that is write and read locked"
--echo # This suppression rule can be removed once Bug#42147 is properly
--echo # fixed. See bug page for more info.
--echo #
--disable_warnings
DROP TABLE IF EXISTS t1;
--enable_warnings
CREATE TABLE t1 (i INT) engine= innodb;
--echo # Get user-level lock
connection con2;
SELECT get_lock('bug42147_lock', 60);
connection default;
--send INSERT INTO t1 SELECT get_lock('bug42147_lock', 60)
connection con2;
let $wait_condition=
SELECT COUNT(*) > 0 FROM information_schema.processlist
WHERE state = 'User lock'
AND info = 'INSERT INTO t1 SELECT get_lock(\'bug42147_lock\', 60)';
--source include/wait_condition.inc
LOCK TABLES t1 READ;
SELECT release_lock('bug42147_lock');
let $wait_condition=
SELECT COUNT(*) > 0 FROM information_schema.processlist
WHERE state = 'executing'
AND info = 'INSERT INTO t1 SELECT get_lock(\'bug42147_lock\', 60)';
--source include/wait_condition.inc
UNLOCK TABLES;
connection default;
--reap
disconnect con2;
DROP TABLE t1;
--echo # --echo #
--echo # Bug#53798 OPTIMIZE TABLE breaks repeatable read --echo # Bug#53798 OPTIMIZE TABLE breaks repeatable read
--echo # --echo #

View File

@@ -156,41 +156,5 @@ connection default;
DROP DATABASE meow; DROP DATABASE meow;
#
# Bug#28587 SELECT is blocked by INSERT waiting on read lock, even with low_priority_updates
#
--echo connection: default
set low_priority_updates=1;
--disable_warnings
drop table if exists t1;
--enable_warnings
create table t1 (a int, b int, unique key t1$a (a));
lock table t1 read;
connect (update,localhost,root,,);
connection update;
--echo connection: update
set low_priority_updates=1;
show variables like 'low_priority_updates';
let $ID= `select connection_id()`;
--send insert into t1 values (1, 2) ON DUPLICATE KEY UPDATE b = 2;
connection default;
# we must wait till the insert opens and locks the table
let $wait_condition=
select count(*) = 1 from information_schema.processlist
where state = "Waiting for table level lock" and id = $ID;
--source include/wait_condition.inc
connect (select,localhost,root,,);
--echo connection: select
select * from t1;
connection default;
--echo connection: default
select * from t1;
connection default;
disconnect update;
disconnect select;
unlock tables;
drop table t1;
set low_priority_updates=default;
set local sql_mode=default; set local sql_mode=default;
set global sql_mode=default; set global sql_mode=default;

View File

@@ -998,6 +998,102 @@ DROP TABLE t1;
disconnect con1; disconnect con1;
disconnect con2; disconnect con2;
--echo #
--echo # Bug#28587 SELECT is blocked by INSERT waiting on read lock, even with low_priority_updates
--echo #
set low_priority_updates=1;
--disable_warnings
drop table if exists t1;
drop table if exists t2;
--enable_warnings
set debug_sync='RESET';
create table t1 (a int, b int, unique key t1$a (a));
create table t2 (j int, k int);
set debug_sync='after_lock_tables_takes_lock SIGNAL parked WAIT_FOR go';
--echo # Sending:
--send insert into t2 select * from t1;
connect (update,localhost,root,,);
connection update;
set debug_sync='now WAIT_FOR parked';
set low_priority_updates=1;
show variables like 'low_priority_updates';
let $ID= `select connection_id()`;
--send insert into t1 values (1, 2) ON DUPLICATE KEY UPDATE b = 2;
connect (select,localhost,root,,);
# we must wait till the insert opens and locks the table
let $wait_condition=
select count(*) = 1 from information_schema.processlist
where state = "Waiting for table level lock" and id = $ID;
--source include/wait_condition.inc
select * from t1;
set debug_sync='now SIGNAL go';
connection default;
disconnect update;
disconnect select;
--echo # Reaping INSERT SELECT
--reap
drop tables t1, t2;
set low_priority_updates=default;
set debug_sync='RESET';
--echo #
--echo # Additional test coverage for LOCK TABLES ... READ LOCAL
--echo # for InnoDB tables.
--echo #
--echo # Check that we correctly handle deadlocks which can occur
--echo # during metadata lock upgrade which happens when one tries
--echo # to use LOCK TABLES ... READ LOCAL for InnoDB tables.
--enable_connect_log
CREATE TABLE t1 (i INT) ENGINE=InnoDB;
CREATE TABLE t2 (j INT) ENGINE=InnoDB;
--echo # Execute LOCK TABLE READ LOCK which will pause after acquiring
--echo # SR metadata lock and before upgrading it to SRO lock.
SET DEBUG_SYNC="after_open_table_mdl_shared SIGNAL locked WAIT_FOR go";
--echo # Sending:
--send LOCK TABLE t1 READ LOCAL
connect (con1, localhost, root);
SET DEBUG_SYNC="now WAIT_FOR locked";
--echo # Execute RENAME TABLE which will try to acquire X lock.
--echo # Sending:
--send RENAME TABLE t1 TO t3, t2 TO t1, t3 TO t2
connect (con2, localhost, root);
--echo # Wait until RENAME TABLE is blocked.
let $wait_condition=
select count(*) = 1 from information_schema.processlist
where state = "Waiting for table metadata lock" and
info = "RENAME TABLE t1 TO t3, t2 TO t1, t3 TO t2";
--source include/wait_condition.inc
--echo # Resume LOCK TABLE statement. It should try to
--echo # upgrade SR lock to SRO lock which will create
--echo # deadlock due to presence of pending X lock.
--echo # Deadlock should be detected and LOCK TABLES should
--echo # release its MDL and retry opening of tables.
SET DEBUG_SYNC="now SIGNAL go";
connection con1;
--echo # RENAME TABLE should be able to complete. Reap it.
--reap
connection default;
--echo # Reap LOCK TABLES.
--reap
--echo # Check that we see new version of table.
SELECT * FROM t1;
UNLOCK TABLES;
--echo # Clean-up.
SET DEBUG_SYNC="RESET";
disconnect con1;
disconnect con2;
DROP TABLES t1, t2;
--disable_connect_log
# Check that all connections opened by test cases in this file are really # Check that all connections opened by test cases in this file are really
# gone so execution of other tests won't be affected by their presence. # gone so execution of other tests won't be affected by their presence.
--source include/wait_until_count_sessions.inc --source include/wait_until_count_sessions.inc

View File

@@ -23,13 +23,13 @@ SET GLOBAL LOG_OUTPUT = 'FILE';
connect (con1,localhost,root,,); connect (con1,localhost,root,,);
connect (con2,localhost,root,,); connect (con2,localhost,root,,);
connection default;
flush status; flush status;
show status like 'Table_lock%'; show status like 'Table_lock%';
select * from information_schema.session_status where variable_name like 'Table_lock%'; select * from information_schema.session_status where variable_name like 'Table_lock%';
connection con1;
set sql_log_bin=0; set sql_log_bin=0;
set @old_general_log = @@global.general_log; set @old_general_log = @@global.general_log;
set global general_log = 'OFF'; set global general_log = 'OFF';
@@ -39,35 +39,46 @@ drop table if exists t1;
create table t1(n int) engine=myisam; create table t1(n int) engine=myisam;
insert into t1 values(1); insert into t1 values(1);
# Execute dummy select in order to ensure that tables used in the select get_lock('mysqltest_lock', 100);
# previous statement are unlocked and closed.
select 1;
connection con2; connection con2;
lock tables t1 read; --echo # Sending:
unlock tables; --send update t1 set n = get_lock('mysqltest_lock', 100)
lock tables t1 read;
connection con1; connection con1;
--echo # Wait for the first UPDATE to get blocked.
let $wait_condition= select count(*) from INFORMATION_SCHEMA.PROCESSLIST
where STATE = "User lock" and
INFO = "update t1 set n = get_lock('mysqltest_lock', 100)";
--source include/wait_condition.inc
let $ID= `select connection_id()`; let $ID= `select connection_id()`;
--echo # Sending:
--send update t1 set n = 3 --send update t1 set n = 3
connection con2; connection default;
# wait for the other query to start executing --echo # wait for the second UPDATE to get blocked
let $wait_condition= select 1 from INFORMATION_SCHEMA.PROCESSLIST let $wait_condition= select 1 from INFORMATION_SCHEMA.PROCESSLIST
where ID = $ID and STATE = "Waiting for table level lock"; where ID = $ID and STATE = "Waiting for table level lock";
--source include/wait_condition.inc --source include/wait_condition.inc
unlock tables; select release_lock('mysqltest_lock');
connection con2;
--echo # Reaping first UPDATE
--reap
select release_lock('mysqltest_lock');
connection con1; connection con1;
--echo # Reaping second UPDATE
reap; reap;
show status like 'Table_locks_waited'; show status like 'Table_locks_waited';
connection default;
drop table t1; drop table t1;
set global general_log = @old_general_log; set global general_log = @old_general_log;
disconnect con2; disconnect con2;
disconnect con1; disconnect con1;
connection default;
# End of 4.1 tests # End of 4.1 tests

View File

@@ -4636,7 +4636,6 @@ DROP TABLE t1, t2;
--echo # --echo #
--disable_warnings --disable_warnings
DROP TABLE IF EXISTS t1;
DROP VIEW IF EXISTS v1; DROP VIEW IF EXISTS v1;
DROP PROCEDURE IF EXISTS p1; DROP PROCEDURE IF EXISTS p1;
--enable_warnings --enable_warnings
@@ -4647,25 +4646,27 @@ connect (con3, localhost, root);
connection default; connection default;
CREATE VIEW v1 AS SELECT schema_name FROM information_schema.schemata; CREATE VIEW v1 AS SELECT schema_name FROM information_schema.schemata;
CREATE TABLE t1 (str VARCHAR(50)); CREATE PROCEDURE p1() SELECT COUNT(*), GET_LOCK('blocker', 100) FROM v1;
CREATE PROCEDURE p1() INSERT INTO t1 SELECT * FROM v1;
--echo # CALL p1() so the view is merged. --echo # CALL p1() so the view is merged.
--disable_result_log
CALL p1(); CALL p1();
--enable_result_log
SELECT RELEASE_LOCK('blocker');
connection con3; connection con3;
LOCK TABLE t1 READ; SELECT GET_LOCK('blocker', 100);
connection default; connection default;
--echo # Try to CALL p1() again, this time it should block for t1. --echo # Try to CALL p1() again, this time it should block on "blocker".
--echo # Sending: --echo # Sending:
--send CALL p1() --send CALL p1()
connection con2; connection con2;
let $wait_condition= let $wait_condition=
SELECT COUNT(*) = 1 from information_schema.processlist SELECT COUNT(*) = 1 from information_schema.processlist
WHERE state = "Waiting for table level lock" AND WHERE state = "User lock" AND
info = "INSERT INTO t1 SELECT * FROM v1"; info = "SELECT COUNT(*), GET_LOCK('blocker', 100) FROM v1";
--source include/wait_condition.inc --source include/wait_condition.inc
--echo # ... then try to drop the view. This should block. --echo # ... then try to drop the view. This should block.
--echo # Sending: --echo # Sending:
@@ -4677,11 +4678,14 @@ let $wait_condition=
WHERE state = "Waiting for table metadata lock" AND info = "DROP VIEW v1"; WHERE state = "Waiting for table metadata lock" AND info = "DROP VIEW v1";
--source include/wait_condition.inc --source include/wait_condition.inc
--echo # Now allow CALL p1() to complete --echo # Now allow CALL p1() to complete
UNLOCK TABLES; SELECT RELEASE_LOCK('blocker');
connection default; connection default;
--echo # Reaping: CALL p1() --echo # Reaping: CALL p1()
--disable_result_log
--reap --reap
--enable_result_log
SELECT RELEASE_LOCK('blocker');
connection con2; connection con2;
--echo # Reaping: DROP VIEW v1 --echo # Reaping: DROP VIEW v1
@@ -4689,7 +4693,6 @@ connection con2;
connection default; connection default;
DROP PROCEDURE p1; DROP PROCEDURE p1;
DROP TABLE t1;
disconnect con2; disconnect con2;
disconnect con3; disconnect con3;

View File

@@ -39,6 +39,7 @@ static const LEX_STRING metadata_lock_info_lock_mode[] = {
{ C_STRING_WITH_LEN("MDL_SHARED_READ") }, { C_STRING_WITH_LEN("MDL_SHARED_READ") },
{ C_STRING_WITH_LEN("MDL_SHARED_WRITE") }, { C_STRING_WITH_LEN("MDL_SHARED_WRITE") },
{ C_STRING_WITH_LEN("MDL_SHARED_UPGRADABLE") }, { C_STRING_WITH_LEN("MDL_SHARED_UPGRADABLE") },
{ C_STRING_WITH_LEN("MDL_SHARED_READ_ONLY") },
{ C_STRING_WITH_LEN("MDL_SHARED_NO_WRITE") }, { C_STRING_WITH_LEN("MDL_SHARED_NO_WRITE") },
{ C_STRING_WITH_LEN("MDL_SHARED_NO_READ_WRITE") }, { C_STRING_WITH_LEN("MDL_SHARED_NO_READ_WRITE") },
{ C_STRING_WITH_LEN("MDL_EXCLUSIVE") }, { C_STRING_WITH_LEN("MDL_EXCLUSIVE") },

View File

@@ -2,7 +2,7 @@
connection node_1; connection node_1;
SELECT * FROM INFORMATION_SCHEMA.WSREP_STATUS; SELECT * FROM INFORMATION_SCHEMA.WSREP_STATUS;
NODE_INDEX NODE_STATUS CLUSTER_STATUS CLUSTER_SIZE CLUSTER_STATE_UUID CLUSTER_STATE_SEQNO CLUSTER_CONF_ID GAP PROTOCOL_VERSION NODE_INDEX NODE_STATUS CLUSTER_STATUS CLUSTER_SIZE CLUSTER_STATE_UUID CLUSTER_STATE_SEQNO CLUSTER_CONF_ID GAP PROTOCOL_VERSION
<IDX> Synced Primary 2 <CLUSTER_STATE_UUID> 0 2 NO 3 <IDX> Synced Primary 2 <CLUSTER_STATE_UUID> 0 <CLUSTER_CONF_ID> NO 3
SELECT * FROM INFORMATION_SCHEMA.WSREP_MEMBERSHIP ORDER BY NAME; SELECT * FROM INFORMATION_SCHEMA.WSREP_MEMBERSHIP ORDER BY NAME;
INDEX UUID NAME ADDRESS INDEX UUID NAME ADDRESS
<IDX> <MEMBER_ID> test-node-1 <ADDRESS> <IDX> <MEMBER_ID> test-node-1 <ADDRESS>
@@ -11,7 +11,7 @@ INDEX UUID NAME ADDRESS
connection node_2; connection node_2;
SELECT * FROM INFORMATION_SCHEMA.WSREP_STATUS; SELECT * FROM INFORMATION_SCHEMA.WSREP_STATUS;
NODE_INDEX NODE_STATUS CLUSTER_STATUS CLUSTER_SIZE CLUSTER_STATE_UUID CLUSTER_STATE_SEQNO CLUSTER_CONF_ID GAP PROTOCOL_VERSION NODE_INDEX NODE_STATUS CLUSTER_STATUS CLUSTER_SIZE CLUSTER_STATE_UUID CLUSTER_STATE_SEQNO CLUSTER_CONF_ID GAP PROTOCOL_VERSION
<IDX> Synced Primary 2 <CLUSTER_STATE_UUID> 0 2 YES 3 <IDX> Synced Primary 2 <CLUSTER_STATE_UUID> 0 <CLUSTER_CONF_ID> YES 3
SELECT * FROM INFORMATION_SCHEMA.WSREP_MEMBERSHIP ORDER BY NAME; SELECT * FROM INFORMATION_SCHEMA.WSREP_MEMBERSHIP ORDER BY NAME;
INDEX UUID NAME ADDRESS INDEX UUID NAME ADDRESS
<IDX> <MEMBER_ID> test-node-1 <ADDRESS> <IDX> <MEMBER_ID> test-node-1 <ADDRESS>

View File

@@ -4,7 +4,7 @@
--echo # On node 1 --echo # On node 1
--connection node_1 --connection node_1
--replace_column 1 <IDX> 5 <CLUSTER_STATE_UUID> --replace_column 1 <IDX> 5 <CLUSTER_STATE_UUID> 7 <CLUSTER_CONF_ID>
SELECT * FROM INFORMATION_SCHEMA.WSREP_STATUS; SELECT * FROM INFORMATION_SCHEMA.WSREP_STATUS;
--replace_column 1 <IDX> 2 <MEMBER_ID> 4 <ADDRESS> --replace_column 1 <IDX> 2 <MEMBER_ID> 4 <ADDRESS>
@@ -13,7 +13,7 @@ SELECT * FROM INFORMATION_SCHEMA.WSREP_MEMBERSHIP ORDER BY NAME;
--echo # On node 2 --echo # On node 2
--connection node_2 --connection node_2
--replace_column 1 <IDX> 5 <CLUSTER_STATE_UUID> --replace_column 1 <IDX> 5 <CLUSTER_STATE_UUID> 7 <CLUSTER_CONF_ID>
SELECT * FROM INFORMATION_SCHEMA.WSREP_STATUS; SELECT * FROM INFORMATION_SCHEMA.WSREP_STATUS;
--replace_column 1 <IDX> 2 <MEMBER_ID> 4 <ADDRESS> --replace_column 1 <IDX> 2 <MEMBER_ID> 4 <ADDRESS>

View File

@@ -9676,12 +9676,15 @@ my_decimal *Item_cache_decimal::val_decimal(my_decimal *val)
Item *Item_cache_decimal::convert_to_basic_const_item(THD *thd) Item *Item_cache_decimal::convert_to_basic_const_item(THD *thd)
{ {
Item *new_item; Item *new_item;
my_decimal decimal_value;
my_decimal *result= val_decimal(&decimal_value);
DBUG_ASSERT(value_cached || example != 0); DBUG_ASSERT(value_cached || example != 0);
new_item= null_value ? if (null_value)
(Item*) new (thd->mem_root) Item_null(thd) : new_item= (Item*) new (thd->mem_root) Item_null(thd);
(Item*) new (thd->mem_root) Item_decimal(thd, result); else
{
my_decimal decimal_value;
my_decimal *result= val_decimal(&decimal_value);
new_item= (Item*) new (thd->mem_root) Item_decimal(thd, result);
}
return new_item; return new_item;
} }
@@ -9768,14 +9771,14 @@ bool Item_cache_row::allocate(THD *thd, uint num)
Item *Item_cache_str::convert_to_basic_const_item(THD *thd) Item *Item_cache_str::convert_to_basic_const_item(THD *thd)
{ {
Item *new_item; Item *new_item;
char buff[MAX_FIELD_WIDTH];
String tmp(buff, sizeof(buff), value->charset());
String *result= val_str(&tmp);
DBUG_ASSERT(value_cached || example != 0); DBUG_ASSERT(value_cached || example != 0);
if (null_value) if (null_value)
new_item= (Item*) new (thd->mem_root) Item_null(thd); new_item= (Item*) new (thd->mem_root) Item_null(thd);
else else
{ {
char buff[MAX_FIELD_WIDTH];
String tmp(buff, sizeof(buff), value->charset());
String *result= val_str(&tmp);
uint length= result->length(); uint length= result->length();
char *tmp_str= thd->strmake(result->ptr(), length); char *tmp_str= thd->strmake(result->ptr(), length);
new_item= new (thd->mem_root) Item_string(thd, tmp_str, length, new_item= new (thd->mem_root) Item_string(thd, tmp_str, length,

View File

@@ -1087,6 +1087,11 @@ class Item_func_nullif :public Item_func_hybrid_field_type
*/ */
Item_cache *m_cache; Item_cache *m_cache;
int compare(); int compare();
void reset_first_arg_if_needed()
{
if (arg_count == 3 && args[0] != args[2])
args[0]= args[2];
}
public: public:
/* /*
Here we pass three arguments to the parent constructor, as NULLIF Here we pass three arguments to the parent constructor, as NULLIF
@@ -1137,6 +1142,12 @@ public:
} }
Item *get_copy(THD *thd, MEM_ROOT *mem_root) Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_nullif>(thd, mem_root, this); } { return get_item_copy<Item_func_nullif>(thd, mem_root, this); }
Item *derived_field_transformer_for_having(THD *thd, uchar *arg)
{ reset_first_arg_if_needed(); return this; }
Item *derived_field_transformer_for_where(THD *thd, uchar *arg)
{ reset_first_arg_if_needed(); return this; }
Item *derived_grouping_field_transformer_for_where(THD *thd, uchar *arg)
{ reset_first_arg_if_needed(); return this; }
}; };

View File

@@ -1522,12 +1522,10 @@ String *Item_func_json_merge::val_str(String *str)
goto error_return; goto error_return;
str->length(0); str->length(0);
if ((je1.value_type == JSON_VALUE_ARRAY && if (je1.value_type == JSON_VALUE_OBJECT &&
je2.value_type == JSON_VALUE_ARRAY) || je2.value_type == JSON_VALUE_OBJECT)
(je1.value_type == JSON_VALUE_OBJECT &&
je2.value_type == JSON_VALUE_OBJECT))
{ {
/* Merge the adjancent arrays or objects. */ /* Wrap as a single objects. */
if (json_skip_level(&je1)) if (json_skip_level(&je1))
goto error_return; goto error_return;
if (str->append(js1->ptr(), if (str->append(js1->ptr(),
@@ -1539,11 +1537,35 @@ String *Item_func_json_merge::val_str(String *str)
} }
else else
{ {
/* Wrap as an array. */ const char *end1, *beg2;
if (str->append("[", 1) ||
str->append(js1->ptr(), js1->length()) || /* Merge as a single array. */
str->append(", ", 2) || if (je1.value_type == JSON_VALUE_ARRAY)
str->append(js2->ptr(), js2->length()) || {
if (json_skip_level(&je1))
goto error_return;
end1= (const char *) (je1.s.c_str - je1.sav_c_len);
}
else
{
if (str->append("[", 1))
goto error_return;
end1= js1->end();
}
if (str->append(js1->ptr(), end1 - js1->ptr()),
str->append(", ", 2))
goto error_return;
if (je2.value_type == JSON_VALUE_ARRAY)
beg2= (const char *) je2.s.c_str;
else
beg2= js2->ptr();
if (str->append(beg2, js2->end() - beg2))
goto error_return;
if (je2.value_type != JSON_VALUE_ARRAY &&
str->append("]", 1)) str->append("]", 1))
goto error_return; goto error_return;
} }
@@ -1577,29 +1599,85 @@ null_return:
} }
void Item_func_json_length::fix_length_and_dec()
{
if (arg_count > 1)
path.set_constant_flag(args[1]->const_item());
}
longlong Item_func_json_length::val_int() longlong Item_func_json_length::val_int()
{ {
String *js= args[0]->val_str(&tmp_js); String *js= args[0]->val_str(&tmp_js);
json_engine_t je; json_engine_t je;
uint length= 0; uint length= 0;
uint array_counters[JSON_DEPTH_LIMIT];
if ((null_value= args[0]->null_value)) if ((null_value= args[0]->null_value))
return 0; return 0;
json_scan_start(&je, js->charset(),(const uchar *) js->ptr(), json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
(const uchar *) js->ptr() + js->length()); (const uchar *) js->ptr() + js->length());
do if (arg_count > 1)
{ {
if (je.state == JST_VALUE) /* Path specified - let's apply it. */
if (!path.parsed)
{
String *s_p= args[1]->val_str(&tmp_path);
if (s_p &&
json_path_setup(&path.p, s_p->charset(), (const uchar *) s_p->ptr(),
(const uchar *) s_p->ptr() + s_p->length()))
{
report_path_error(s_p, &path.p, 2);
goto null_return;
}
path.parsed= path.constant;
}
if (args[1]->null_value)
goto null_return;
path.cur_step= path.p.steps;
if (json_find_path(&je, &path.p, &path.cur_step, array_counters))
{
if (je.s.error)
goto err_return;
goto null_return;
}
}
if (json_read_value(&je))
goto err_return;
if (json_value_scalar(&je))
return 1;
while (json_scan_next(&je) == 0 &&
je.state != JST_OBJ_END && je.state != JST_ARRAY_END)
{
switch (je.state)
{
case JST_VALUE:
case JST_KEY:
length++; length++;
} while (json_scan_next(&je) == 0); break;
case JST_OBJ_START:
case JST_ARRAY_START:
if (json_skip_level(&je))
goto err_return;
break;
default:
break;
};
}
if (!je.s.error) if (!je.s.error)
return length - 1; return length;
err_return:
report_json_error(js, &je, 0); report_json_error(js, &je, 0);
null_return:
null_value= 1; null_value= 1;
return 0; return 0;
} }

View File

@@ -67,8 +67,8 @@ protected:
String tmp_js, tmp_path; String tmp_js, tmp_path;
public: public:
Item_func_json_exists(THD *thd, Item *js, Item *path): Item_func_json_exists(THD *thd, Item *js, Item *i_path):
Item_int_func(thd, js, path) {} Item_int_func(thd, js, i_path) {}
const char *func_name() const { return "json_exists"; } const char *func_name() const { return "json_exists"; }
bool is_bool_type() { return true; } bool is_bool_type() { return true; }
void fix_length_and_dec(); void fix_length_and_dec();
@@ -85,8 +85,8 @@ protected:
String tmp_js, tmp_path; String tmp_js, tmp_path;
public: public:
Item_func_json_value(THD *thd, Item *js, Item *path): Item_func_json_value(THD *thd, Item *js, Item *i_path):
Item_str_func(thd, js, path) {} Item_str_func(thd, js, i_path) {}
const char *func_name() const { return "json_value"; } const char *func_name() const { return "json_value"; }
void fix_length_and_dec(); void fix_length_and_dec();
String *val_str(String *); String *val_str(String *);
@@ -99,8 +99,8 @@ public:
class Item_func_json_query: public Item_func_json_value class Item_func_json_query: public Item_func_json_value
{ {
public: public:
Item_func_json_query(THD *thd, Item *js, Item *path): Item_func_json_query(THD *thd, Item *js, Item *i_path):
Item_func_json_value(thd, js, path) {} Item_func_json_value(thd, js, i_path) {}
const char *func_name() const { return "json_query"; } const char *func_name() const { return "json_query"; }
bool check_and_get_value(json_engine_t *je, String *res, int *error); bool check_and_get_value(json_engine_t *je, String *res, int *error);
Item *get_copy(THD *thd, MEM_ROOT *mem_root) Item *get_copy(THD *thd, MEM_ROOT *mem_root)
@@ -291,12 +291,14 @@ public:
class Item_func_json_length: public Item_int_func class Item_func_json_length: public Item_int_func
{ {
protected: protected:
json_path_with_flags path;
String tmp_js; String tmp_js;
String tmp_path; String tmp_path;
public: public:
Item_func_json_length(THD *thd, List<Item> &list): Item_func_json_length(THD *thd, List<Item> &list):
Item_int_func(thd, list) {} Item_int_func(thd, list) {}
const char *func_name() const { return "json_length"; } const char *func_name() const { return "json_length"; }
void fix_length_and_dec();
longlong val_int(); longlong val_int();
Item *get_copy(THD *thd, MEM_ROOT *mem_root) Item *get_copy(THD *thd, MEM_ROOT *mem_root)
{ return get_item_copy<Item_func_json_length>(thd, mem_root, this); } { return get_item_copy<Item_func_json_length>(thd, mem_root, this); }

View File

@@ -164,18 +164,12 @@ lock_tables_check(THD *thd, TABLE **tables, uint count, uint flags)
write we must own metadata lock of MDL_SHARED_WRITE or stronger write we must own metadata lock of MDL_SHARED_WRITE or stronger
type. For table to be locked for read we must own metadata lock type. For table to be locked for read we must own metadata lock
of MDL_SHARED_READ or stronger type). of MDL_SHARED_READ or stronger type).
The only exception are HANDLER statements which are allowed to
lock table for read while having only MDL_SHARED lock on it.
*/ */
DBUG_ASSERT(t->s->tmp_table || DBUG_ASSERT(t->s->tmp_table ||
thd->mdl_context.is_lock_owner(MDL_key::TABLE, thd->mdl_context.is_lock_owner(MDL_key::TABLE,
t->s->db.str, t->s->table_name.str, t->s->db.str, t->s->table_name.str,
t->reginfo.lock_type >= TL_WRITE_ALLOW_WRITE ? t->reginfo.lock_type >= TL_WRITE_ALLOW_WRITE ?
MDL_SHARED_WRITE : MDL_SHARED_READ) || MDL_SHARED_WRITE : MDL_SHARED_READ));
(t->open_by_handler &&
thd->mdl_context.is_lock_owner(MDL_key::TABLE,
t->s->db.str, t->s->table_name.str,
MDL_SHARED)));
/* /*
Prevent modifications to base tables if READ_ONLY is activated. Prevent modifications to base tables if READ_ONLY is activated.

View File

@@ -391,7 +391,11 @@ public:
virtual const bitmap_t *incompatible_waiting_types_bitmap() const virtual const bitmap_t *incompatible_waiting_types_bitmap() const
{ return m_waiting_incompatible; } { return m_waiting_incompatible; }
virtual bool needs_notification(const MDL_ticket *ticket) const virtual bool needs_notification(const MDL_ticket *ticket) const
{ return (ticket->get_type() >= MDL_SHARED_NO_WRITE); } {
return ticket->get_type() == MDL_SHARED_NO_WRITE ||
ticket->get_type() == MDL_SHARED_NO_READ_WRITE ||
ticket->get_type() == MDL_EXCLUSIVE;
}
/** /**
Notify threads holding a shared metadata locks on object which Notify threads holding a shared metadata locks on object which
@@ -1413,7 +1417,8 @@ const MDL_lock::bitmap_t
MDL_lock::MDL_scoped_lock::m_granted_incompatible[MDL_TYPE_END]= MDL_lock::MDL_scoped_lock::m_granted_incompatible[MDL_TYPE_END]=
{ {
MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_SHARED), MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_SHARED),
MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_INTENTION_EXCLUSIVE), 0, 0, 0, 0, 0, 0, MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_INTENTION_EXCLUSIVE),
0, 0, 0, 0, 0, 0, 0,
MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_SHARED) | MDL_BIT(MDL_INTENTION_EXCLUSIVE) MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_SHARED) | MDL_BIT(MDL_INTENTION_EXCLUSIVE)
}; };
@@ -1421,7 +1426,7 @@ const MDL_lock::bitmap_t
MDL_lock::MDL_scoped_lock::m_waiting_incompatible[MDL_TYPE_END]= MDL_lock::MDL_scoped_lock::m_waiting_incompatible[MDL_TYPE_END]=
{ {
MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_SHARED), MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_SHARED),
MDL_BIT(MDL_EXCLUSIVE), 0, 0, 0, 0, 0, 0, 0 MDL_BIT(MDL_EXCLUSIVE), 0, 0, 0, 0, 0, 0, 0, 0
}; };
@@ -1433,39 +1438,41 @@ MDL_lock::MDL_scoped_lock::m_waiting_incompatible[MDL_TYPE_END]=
The first array specifies if particular type of request can be satisfied The first array specifies if particular type of request can be satisfied
if there is granted lock of certain type. if there is granted lock of certain type.
Request | Granted requests for lock | Request | Granted requests for lock |
type | S SH SR SW SU SNW SNRW X | type | S SH SR SW SU SRO SNW SNRW X |
----------+----------------------------------+ ----------+---------------------------------------+
S | + + + + + + + - | S | + + + + + + + + - |
SH | + + + + + + + - | SH | + + + + + + + + - |
SR | + + + + + + - - | SR | + + + + + + + - - |
SW | + + + + + - - - | SW | + + + + + - - - - |
SU | + + + + - - - - | SU | + + + + - + - - - |
SNW | + + + - - - - - | SRO | + + + - + + + - - |
SNRW | + + - - - - - - | SNW | + + + - - + - - - |
X | - - - - - - - - | SNRW | + + - - - - - - - |
SU -> X | - - - - 0 0 0 0 | X | - - - - - - - - - |
SNW -> X | - - - 0 0 0 0 0 | SU -> X | - - - - 0 - 0 0 0 |
SNRW -> X | - - 0 0 0 0 0 0 | SNW -> X | - - - 0 0 - 0 0 0 |
SNRW -> X | - - 0 0 0 0 0 0 0 |
The second array specifies if particular type of request can be satisfied The second array specifies if particular type of request can be satisfied
if there is waiting request for the same lock of certain type. In other if there is waiting request for the same lock of certain type. In other
words it specifies what is the priority of different lock types. words it specifies what is the priority of different lock types.
Request | Pending requests for lock | Request | Pending requests for lock |
type | S SH SR SW SU SNW SNRW X | type | S SH SR SW SU SRO SNW SNRW X |
----------+---------------------------------+ ----------+--------------------------------------+
S | + + + + + + + - | S | + + + + + + + + - |
SH | + + + + + + + + | SH | + + + + + + + + + |
SR | + + + + + + - - | SR | + + + + + + + - - |
SW | + + + + + - - - | SW | + + + + + + - - - |
SU | + + + + + + + - | SU | + + + + + + + + - |
SNW | + + + + + + + - | SRO | + + + - + + + - - |
SNRW | + + + + + + + - | SNW | + + + + + + + + - |
X | + + + + + + + + | SNRW | + + + + + + + + - |
SU -> X | + + + + + + + + | X | + + + + + + + + + |
SNW -> X | + + + + + + + + | SU -> X | + + + + + + + + + |
SNRW -> X | + + + + + + + + | SNW -> X | + + + + + + + + + |
SNRW -> X | + + + + + + + + + |
Here: "+" -- means that request can be satisfied Here: "+" -- means that request can be satisfied
"-" -- means that request can't be satisfied and should wait "-" -- means that request can't be satisfied and should wait
@@ -1487,19 +1494,23 @@ MDL_lock::MDL_object_lock::m_granted_incompatible[MDL_TYPE_END]=
MDL_BIT(MDL_EXCLUSIVE), MDL_BIT(MDL_EXCLUSIVE),
MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_SHARED_NO_READ_WRITE), MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_SHARED_NO_READ_WRITE),
MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_SHARED_NO_READ_WRITE) | MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_SHARED_NO_READ_WRITE) |
MDL_BIT(MDL_SHARED_NO_WRITE), MDL_BIT(MDL_SHARED_NO_WRITE) | MDL_BIT(MDL_SHARED_READ_ONLY),
MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_SHARED_NO_READ_WRITE) | MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_SHARED_NO_READ_WRITE) |
MDL_BIT(MDL_SHARED_NO_WRITE) | MDL_BIT(MDL_SHARED_UPGRADABLE), MDL_BIT(MDL_SHARED_NO_WRITE) | MDL_BIT(MDL_SHARED_UPGRADABLE),
MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_SHARED_NO_READ_WRITE) |
MDL_BIT(MDL_SHARED_WRITE),
MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_SHARED_NO_READ_WRITE) | MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_SHARED_NO_READ_WRITE) |
MDL_BIT(MDL_SHARED_NO_WRITE) | MDL_BIT(MDL_SHARED_UPGRADABLE) | MDL_BIT(MDL_SHARED_NO_WRITE) | MDL_BIT(MDL_SHARED_UPGRADABLE) |
MDL_BIT(MDL_SHARED_WRITE), MDL_BIT(MDL_SHARED_WRITE),
MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_SHARED_NO_READ_WRITE) | MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_SHARED_NO_READ_WRITE) |
MDL_BIT(MDL_SHARED_NO_WRITE) | MDL_BIT(MDL_SHARED_UPGRADABLE) | MDL_BIT(MDL_SHARED_NO_WRITE) | MDL_BIT(MDL_SHARED_READ_ONLY) |
MDL_BIT(MDL_SHARED_WRITE) | MDL_BIT(MDL_SHARED_READ), MDL_BIT(MDL_SHARED_UPGRADABLE) | MDL_BIT(MDL_SHARED_WRITE) |
MDL_BIT(MDL_SHARED_READ),
MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_SHARED_NO_READ_WRITE) | MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_SHARED_NO_READ_WRITE) |
MDL_BIT(MDL_SHARED_NO_WRITE) | MDL_BIT(MDL_SHARED_UPGRADABLE) | MDL_BIT(MDL_SHARED_NO_WRITE) | MDL_BIT(MDL_SHARED_READ_ONLY) |
MDL_BIT(MDL_SHARED_WRITE) | MDL_BIT(MDL_SHARED_READ) | MDL_BIT(MDL_SHARED_UPGRADABLE) | MDL_BIT(MDL_SHARED_WRITE) |
MDL_BIT(MDL_SHARED_HIGH_PRIO) | MDL_BIT(MDL_SHARED) MDL_BIT(MDL_SHARED_READ) | MDL_BIT(MDL_SHARED_HIGH_PRIO) |
MDL_BIT(MDL_SHARED)
}; };
@@ -1513,6 +1524,8 @@ MDL_lock::MDL_object_lock::m_waiting_incompatible[MDL_TYPE_END]=
MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_SHARED_NO_READ_WRITE) | MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_SHARED_NO_READ_WRITE) |
MDL_BIT(MDL_SHARED_NO_WRITE), MDL_BIT(MDL_SHARED_NO_WRITE),
MDL_BIT(MDL_EXCLUSIVE), MDL_BIT(MDL_EXCLUSIVE),
MDL_BIT(MDL_EXCLUSIVE) | MDL_BIT(MDL_SHARED_NO_READ_WRITE) |
MDL_BIT(MDL_SHARED_WRITE),
MDL_BIT(MDL_EXCLUSIVE), MDL_BIT(MDL_EXCLUSIVE),
MDL_BIT(MDL_EXCLUSIVE), MDL_BIT(MDL_EXCLUSIVE),
0 0
@@ -2306,10 +2319,11 @@ MDL_context::upgrade_shared_lock(MDL_ticket *mdl_ticket,
if (mdl_ticket->has_stronger_or_equal_type(new_type)) if (mdl_ticket->has_stronger_or_equal_type(new_type))
DBUG_RETURN(FALSE); DBUG_RETURN(FALSE);
/* Only allow upgrades from SHARED_UPGRADABLE/NO_WRITE/NO_READ_WRITE */ /* Only allow upgrades from SHARED_UPGRADABLE/NO_WRITE/NO_READ_WRITE/READ */
DBUG_ASSERT(mdl_ticket->m_type == MDL_SHARED_UPGRADABLE || DBUG_ASSERT(mdl_ticket->m_type == MDL_SHARED_UPGRADABLE ||
mdl_ticket->m_type == MDL_SHARED_NO_WRITE || mdl_ticket->m_type == MDL_SHARED_NO_WRITE ||
mdl_ticket->m_type == MDL_SHARED_NO_READ_WRITE); mdl_ticket->m_type == MDL_SHARED_NO_READ_WRITE ||
mdl_ticket->m_type == MDL_SHARED_READ);
mdl_xlock_request.init(&mdl_ticket->m_lock->key, new_type, mdl_xlock_request.init(&mdl_ticket->m_lock->key, new_type,
MDL_TRANSACTION); MDL_TRANSACTION);

View File

@@ -195,6 +195,12 @@ enum enum_mdl_type {
To be used for the first phase of ALTER TABLE. To be used for the first phase of ALTER TABLE.
*/ */
MDL_SHARED_UPGRADABLE, MDL_SHARED_UPGRADABLE,
/*
A shared metadata lock for cases when we need to read data from table
and block all concurrent modifications to it (for both data and metadata).
Used by LOCK TABLES READ statement.
*/
MDL_SHARED_READ_ONLY,
/* /*
An upgradable shared metadata lock which blocks all attempts to update An upgradable shared metadata lock which blocks all attempts to update
table data, allowing reads. table data, allowing reads.
@@ -467,6 +473,19 @@ public:
type= type_arg; type= type_arg;
} }
/**
Is this a request for a lock which allow data to be updated?
@note This method returns true for MDL_SHARED_UPGRADABLE type of
lock. Even though this type of lock doesn't allow updates
it will always be upgraded to one that does.
*/
bool is_write_lock_request() const
{
return (type >= MDL_SHARED_WRITE &&
type != MDL_SHARED_READ_ONLY);
}
/* /*
This is to work around the ugliness of TABLE_LIST This is to work around the ugliness of TABLE_LIST
compiler-generated assignment operator. It is currently used compiler-generated assignment operator. It is currently used

View File

@@ -1495,7 +1495,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, Open_table_context *ot_ctx)
Note that we allow write locks on log tables as otherwise logging Note that we allow write locks on log tables as otherwise logging
to general/slow log would be disabled in read only transactions. to general/slow log would be disabled in read only transactions.
*/ */
if (table_list->mdl_request.type >= MDL_SHARED_WRITE && if (table_list->mdl_request.is_write_lock_request() &&
thd->tx_read_only && thd->tx_read_only &&
!(flags & (MYSQL_LOCK_LOG_TABLE | MYSQL_OPEN_HAS_MDL_LOCK))) !(flags & (MYSQL_LOCK_LOG_TABLE | MYSQL_OPEN_HAS_MDL_LOCK)))
{ {
@@ -1654,7 +1654,7 @@ bool open_table(THD *thd, TABLE_LIST *table_list, Open_table_context *ot_ctx)
pre-acquiring metadata locks at the beggining of pre-acquiring metadata locks at the beggining of
open_tables() call. open_tables() call.
*/ */
if (table_list->mdl_request.type >= MDL_SHARED_WRITE && if (table_list->mdl_request.is_write_lock_request() &&
! (flags & (MYSQL_OPEN_IGNORE_GLOBAL_READ_LOCK | ! (flags & (MYSQL_OPEN_IGNORE_GLOBAL_READ_LOCK |
MYSQL_OPEN_FORCE_SHARED_MDL | MYSQL_OPEN_FORCE_SHARED_MDL |
MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL | MYSQL_OPEN_FORCE_SHARED_HIGH_PRIO_MDL |
@@ -2146,11 +2146,6 @@ Locked_tables_list::unlock_locked_tables(THD *thd)
request for metadata locks and TABLE_LIST elements. request for metadata locks and TABLE_LIST elements.
*/ */
reset(); reset();
if (thd->variables.option_bits & OPTION_AUTOCOMMIT)
{
thd->variables.option_bits&= ~(OPTION_NOT_AUTOCOMMIT);
thd->server_status|= SERVER_STATUS_AUTOCOMMIT;
}
} }
@@ -3605,6 +3600,7 @@ lock_table_names(THD *thd, const DDL_options_st &options,
table= table->next_global) table= table->next_global)
{ {
if (table->mdl_request.type < MDL_SHARED_UPGRADABLE || if (table->mdl_request.type < MDL_SHARED_UPGRADABLE ||
table->mdl_request.type == MDL_SHARED_READ_ONLY ||
table->open_type == OT_TEMPORARY_ONLY || table->open_type == OT_TEMPORARY_ONLY ||
(table->open_type == OT_TEMPORARY_OR_BASE && is_temporary_table(table))) (table->open_type == OT_TEMPORARY_OR_BASE && is_temporary_table(table)))
{ {
@@ -3728,6 +3724,11 @@ open_tables_check_upgradable_mdl(THD *thd, TABLE_LIST *tables_start,
for (table= tables_start; table && table != tables_end; for (table= tables_start; table && table != tables_end;
table= table->next_global) table= table->next_global)
{ {
/*
Check below needs to be updated if this function starts
called for SRO locks.
*/
DBUG_ASSERT(table->mdl_request.type != MDL_SHARED_READ_ONLY);
if (table->mdl_request.type < MDL_SHARED_UPGRADABLE || if (table->mdl_request.type < MDL_SHARED_UPGRADABLE ||
table->open_type == OT_TEMPORARY_ONLY || table->open_type == OT_TEMPORARY_ONLY ||
(table->open_type == OT_TEMPORARY_OR_BASE && is_temporary_table(table))) (table->open_type == OT_TEMPORARY_OR_BASE && is_temporary_table(table)))
@@ -4063,13 +4064,22 @@ restart:
} }
} }
if (WSREP_ON && if (WSREP_ON &&
wsrep_replicate_myisam && wsrep_replicate_myisam &&
(*start) && (*start) &&
(*start)->table && (*start)->table &&
(*start)->table->file->ht == myisam_hton && (*start)->table->file->ht == myisam_hton &&
sqlcom_can_generate_row_events(thd) && wsrep_thd_exec_mode(thd) == LOCAL_STATE &&
thd->get_command() != COM_STMT_PREPARE) !is_stat_table((*start)->db, (*start)->alias) &&
thd->get_command() != COM_STMT_PREPARE &&
((thd->lex->sql_command == SQLCOM_INSERT ||
thd->lex->sql_command == SQLCOM_INSERT_SELECT ||
thd->lex->sql_command == SQLCOM_REPLACE ||
thd->lex->sql_command == SQLCOM_REPLACE_SELECT ||
thd->lex->sql_command == SQLCOM_UPDATE ||
thd->lex->sql_command == SQLCOM_UPDATE_MULTI ||
thd->lex->sql_command == SQLCOM_LOAD ||
thd->lex->sql_command == SQLCOM_DELETE)))
{ {
WSREP_TO_ISOLATION_BEGIN(NULL, NULL, (*start)); WSREP_TO_ISOLATION_BEGIN(NULL, NULL, (*start));
} }

View File

@@ -650,6 +650,28 @@ bool Drop_table_error_handler::handle_condition(THD *thd,
} }
/**
Handle an error from MDL_context::upgrade_lock() and mysql_lock_tables().
Ignore ER_LOCK_ABORTED and ER_LOCK_DEADLOCK errors.
*/
bool
MDL_deadlock_and_lock_abort_error_handler::
handle_condition(THD *thd,
uint sql_errno,
const char *sqlstate,
Sql_condition::enum_warning_level level,
const char* msg,
Sql_condition **cond_hdl)
{
*cond_hdl= NULL;
if (sql_errno == ER_LOCK_ABORTED || sql_errno == ER_LOCK_DEADLOCK)
m_need_reopen= true;
return m_need_reopen;
}
/** /**
Send timeout to thread. Send timeout to thread.

View File

@@ -1744,6 +1744,30 @@ private:
}; };
/**
Internal error handler to process an error from MDL_context::upgrade_lock()
and mysql_lock_tables(). Used by implementations of HANDLER READ and
LOCK TABLES LOCAL.
*/
class MDL_deadlock_and_lock_abort_error_handler: public Internal_error_handler
{
public:
virtual
bool handle_condition(THD *thd,
uint sql_errno,
const char *sqlstate,
Sql_condition::enum_warning_level level,
const char* msg,
Sql_condition **cond_hdl);
bool need_reopen() const { return m_need_reopen; };
void init() { m_need_reopen= FALSE; };
private:
bool m_need_reopen;
};
/** /**
Tables that were locked with LOCK TABLES statement. Tables that were locked with LOCK TABLES statement.

View File

@@ -485,56 +485,6 @@ bool mysql_ha_close(THD *thd, TABLE_LIST *tables)
} }
/**
A helper class to process an error from mysql_lock_tables().
HANDLER READ statement's attempt to lock the subject table
may get aborted if there is a pending DDL. In that case
we close the table, reopen it, and try to read again.
This is implicit and obscure, since HANDLER position
is lost in the process, but it's the legacy server
behaviour we should preserve.
*/
class Sql_handler_lock_error_handler: public Internal_error_handler
{
public:
virtual
bool handle_condition(THD *thd,
uint sql_errno,
const char *sqlstate,
Sql_condition::enum_warning_level level,
const char* msg,
Sql_condition **cond_hdl);
bool need_reopen() const { return m_need_reopen; };
void init() { m_need_reopen= FALSE; };
private:
bool m_need_reopen;
};
/**
Handle an error from mysql_lock_tables().
Ignore ER_LOCK_ABORTED errors.
*/
bool
Sql_handler_lock_error_handler::
handle_condition(THD *thd,
uint sql_errno,
const char *sqlstate,
Sql_condition::enum_warning_level level,
const char* msg,
Sql_condition **cond_hdl)
{
*cond_hdl= NULL;
if (sql_errno == ER_LOCK_ABORTED)
m_need_reopen= TRUE;
return m_need_reopen;
}
/** /**
Finds an open HANDLER table. Finds an open HANDLER table.
@@ -731,7 +681,7 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables,
int error, keyno; int error, keyno;
uint num_rows; uint num_rows;
uchar *UNINIT_VAR(key); uchar *UNINIT_VAR(key);
Sql_handler_lock_error_handler sql_handler_lock_error; MDL_deadlock_and_lock_abort_error_handler sql_handler_lock_error;
DBUG_ENTER("mysql_ha_read"); DBUG_ENTER("mysql_ha_read");
DBUG_PRINT("enter",("'%s'.'%s' as '%s'", DBUG_PRINT("enter",("'%s'.'%s' as '%s'",
tables->db, tables->table_name, tables->alias)); tables->db, tables->table_name, tables->alias));

View File

@@ -2728,27 +2728,76 @@ bool sp_process_definer(THD *thd)
static bool lock_tables_open_and_lock_tables(THD *thd, TABLE_LIST *tables) static bool lock_tables_open_and_lock_tables(THD *thd, TABLE_LIST *tables)
{ {
Lock_tables_prelocking_strategy lock_tables_prelocking_strategy; Lock_tables_prelocking_strategy lock_tables_prelocking_strategy;
MDL_deadlock_and_lock_abort_error_handler deadlock_handler;
MDL_savepoint mdl_savepoint= thd->mdl_context.mdl_savepoint();
uint counter; uint counter;
TABLE_LIST *table; TABLE_LIST *table;
thd->in_lock_tables= 1; thd->in_lock_tables= 1;
retry:
if (open_tables(thd, &tables, &counter, 0, &lock_tables_prelocking_strategy)) if (open_tables(thd, &tables, &counter, 0, &lock_tables_prelocking_strategy))
goto err; goto err;
/*
We allow to change temporary tables even if they were locked for read
by LOCK TABLES. To avoid a discrepancy between lock acquired at LOCK
TABLES time and by the statement which is later executed under LOCK TABLES
we ensure that for temporary tables we always request a write lock (such
discrepancy can cause problems for the storage engine).
We don't set TABLE_LIST::lock_type in this case as this might result in
extra warnings from THD::decide_logging_format() even though binary logging
is totally irrelevant for LOCK TABLES.
*/
for (table= tables; table; table= table->next_global) for (table= tables; table; table= table->next_global)
if (!table->placeholder() && table->table->s->tmp_table) {
table->table->reginfo.lock_type= TL_WRITE; if (!table->placeholder())
{
if (table->table->s->tmp_table)
{
/*
We allow to change temporary tables even if they were locked for read
by LOCK TABLES. To avoid a discrepancy between lock acquired at LOCK
TABLES time and by the statement which is later executed under LOCK
TABLES we ensure that for temporary tables we always request a write
lock (such discrepancy can cause problems for the storage engine).
We don't set TABLE_LIST::lock_type in this case as this might result
in extra warnings from THD::decide_logging_format() even though
binary logging is totally irrelevant for LOCK TABLES.
*/
table->table->reginfo.lock_type= TL_WRITE;
}
else if (table->mdl_request.type == MDL_SHARED_READ &&
! table->prelocking_placeholder &&
table->table->file->lock_count() == 0)
{
/*
In case when LOCK TABLE ... READ LOCAL was issued for table with
storage engine which doesn't support READ LOCAL option and doesn't
use THR_LOCK locks we need to upgrade weak SR metadata lock acquired
in open_tables() to stronger SRO metadata lock.
This is not needed for tables used through stored routines or
triggers as we always acquire SRO (or even stronger SNRW) metadata
lock for them.
*/
deadlock_handler.init();
thd->push_internal_handler(&deadlock_handler);
bool result= thd->mdl_context.upgrade_shared_lock(
table->table->mdl_ticket,
MDL_SHARED_READ_ONLY,
thd->variables.lock_wait_timeout);
thd->pop_internal_handler();
if (deadlock_handler.need_reopen())
{
/*
Deadlock occurred during upgrade of metadata lock.
Let us restart acquring and opening tables for LOCK TABLES.
*/
close_tables_for_reopen(thd, &tables, mdl_savepoint);
if (thd->open_temporary_tables(tables))
goto err;
goto retry;
}
if (result)
goto err;
}
}
}
if (lock_tables(thd, tables, counter, 0) || if (lock_tables(thd, tables, counter, 0) ||
thd->locked_tables_list.init_locked_tables(thd)) thd->locked_tables_list.init_locked_tables(thd))
@@ -3350,6 +3399,10 @@ mysql_execute_command(THD *thd)
case SQLCOM_SHOW_STORAGE_ENGINES: case SQLCOM_SHOW_STORAGE_ENGINES:
case SQLCOM_SHOW_PROFILE: case SQLCOM_SHOW_PROFILE:
{ {
#ifdef WITH_WSREP
DBUG_ASSERT(thd->wsrep_exec_mode != REPL_RECV);
#endif /* WITH_WSREP */
thd->status_var.last_query_cost= 0.0; thd->status_var.last_query_cost= 0.0;
/* /*
@@ -4785,8 +4838,7 @@ end_with_restore_list:
if (lock_tables_precheck(thd, all_tables)) if (lock_tables_precheck(thd, all_tables))
goto error; goto error;
thd->variables.option_bits|= OPTION_TABLE_LOCK | OPTION_NOT_AUTOCOMMIT; thd->variables.option_bits|= OPTION_TABLE_LOCK;
thd->server_status&= ~SERVER_STATUS_AUTOCOMMIT;
res= lock_tables_open_and_lock_tables(thd, all_tables); res= lock_tables_open_and_lock_tables(thd, all_tables);

View File

@@ -3849,3 +3849,21 @@ double Histogram::point_selectivity(double pos, double avg_sel)
return sel; return sel;
} }
/*
Check whether the table is one of the persistent statistical tables.
*/
bool is_stat_table(const char *db, const char *table)
{
DBUG_ASSERT(db && table);
if (!memcmp(db, stat_tables_db_name.str, stat_tables_db_name.length))
{
for (uint i= 0; i < STATISTICS_TABLES; i ++)
{
if (!memcmp(table, stat_table_name[i].str, stat_table_name[i].length))
return true;
}
}
return false;
}

View File

@@ -107,6 +107,7 @@ double get_column_range_cardinality(Field *field,
key_range *min_endp, key_range *min_endp,
key_range *max_endp, key_range *max_endp,
uint range_flag); uint range_flag);
bool is_stat_table(const char *db, const char *table);
class Histogram class Histogram
{ {

View File

@@ -1097,7 +1097,7 @@ btr_free_root_check(
index_id_t index_id, index_id_t index_id,
mtr_t* mtr) mtr_t* mtr)
{ {
ut_ad(page_id.space() != srv_tmp_space.space_id()); ut_ad(page_id.space() != SRV_TMP_SPACE_ID);
ut_ad(index_id != BTR_FREED_INDEX_ID); ut_ad(index_id != BTR_FREED_INDEX_ID);
buf_block_t* block = buf_page_get( buf_block_t* block = buf_page_get(

View File

@@ -6092,7 +6092,7 @@ corrupt:
#endif /* MYSQL_COMPRESSION */ #endif /* MYSQL_COMPRESSION */
&& !recv_no_ibuf_operations && !recv_no_ibuf_operations
&& !Tablespace::is_undo_tablespace(bpage->id.space()) && !Tablespace::is_undo_tablespace(bpage->id.space())
&& bpage->id.space() != srv_tmp_space.space_id() && bpage->id.space() != SRV_TMP_SPACE_ID
&& !srv_is_tablespace_truncated(bpage->id.space()) && !srv_is_tablespace_truncated(bpage->id.space())
&& fil_page_get_type(frame) == FIL_PAGE_INDEX && fil_page_get_type(frame) == FIL_PAGE_INDEX
&& page_is_leaf(frame)) { && page_is_leaf(frame)) {

View File

@@ -571,8 +571,7 @@ dict_build_tablespace_for_table(
supports Redundant and Compact */ supports Redundant and Compact */
ut_ad(dict_tf_get_rec_format(table->flags) ut_ad(dict_tf_get_rec_format(table->flags)
!= REC_FORMAT_COMPRESSED); != REC_FORMAT_COMPRESSED);
table->space = static_cast<uint32_t>( table->space = SRV_TMP_SPACE_ID;
srv_tmp_space.space_id());
} else { } else {
/* Create in the system tablespace. */ /* Create in the system tablespace. */
ut_ad(table->space == srv_sys_space.space_id()); ut_ad(table->space == srv_sys_space.space_id());

View File

@@ -1701,6 +1701,7 @@ struct dict_foreign_remove_partial
if (table != NULL) { if (table != NULL) {
table->referenced_set.erase(foreign); table->referenced_set.erase(foreign);
} }
dict_foreign_free(foreign);
} }
}; };
@@ -3759,7 +3760,6 @@ dict_foreign_add_to_cache(
} }
if (for_in_cache) { if (for_in_cache) {
/* Free the foreign object */
dict_foreign_free(foreign); dict_foreign_free(foreign);
} else { } else {
for_in_cache = foreign; for_in_cache = foreign;
@@ -3789,10 +3789,9 @@ dict_foreign_add_to_cache(
"referenced table do not match" "referenced table do not match"
" the ones in table."); " the ones in table.");
if (for_in_cache == foreign) { if (for_in_cache == foreign) {
mem_heap_free(foreign->heap); dict_foreign_free(foreign);
} }
DBUG_RETURN(DB_CANNOT_ADD_CONSTRAINT); DBUG_RETURN(DB_CANNOT_ADD_CONSTRAINT);
} }
@@ -3846,7 +3845,8 @@ dict_foreign_add_to_cache(
elements removed must elements removed must
be one */ be one */
} }
mem_heap_free(foreign->heap);
dict_foreign_free(foreign);
} }
DBUG_RETURN(DB_CANNOT_ADD_CONSTRAINT); DBUG_RETURN(DB_CANNOT_ADD_CONSTRAINT);

View File

@@ -493,7 +493,7 @@ err_len:
} }
/* This receives a dict_foreign_t* that points to a stack variable. /* This receives a dict_foreign_t* that points to a stack variable.
So mem_heap_free(foreign->heap) is not used as elsewhere. So dict_foreign_free(foreign) is not used as elsewhere.
Since the heap used here is freed elsewhere, foreign->heap Since the heap used here is freed elsewhere, foreign->heap
is not assigned. */ is not assigned. */
foreign->id = mem_heap_strdupl(heap, (const char*) field, len); foreign->id = mem_heap_strdupl(heap, (const char*) field, len);

View File

@@ -138,6 +138,8 @@ fil_space_crypt_cleanup()
/*=====================*/ /*=====================*/
{ {
os_event_destroy(fil_crypt_throttle_sleep_event); os_event_destroy(fil_crypt_throttle_sleep_event);
mutex_free(&fil_crypt_key_mutex);
mutex_free(&crypt_stat_mutex);
} }
/****************************************************************** /******************************************************************
@@ -335,15 +337,9 @@ fil_space_destroy_crypt_data(
and make it unawailable, this does not fully and make it unawailable, this does not fully
avoid the race between drop table and crypt thread */ avoid the race between drop table and crypt thread */
mutex_enter(&fil_crypt_threads_mutex); mutex_enter(&fil_crypt_threads_mutex);
mutex_enter(&(*crypt_data)->mutex); mutex_free(&(*crypt_data)->mutex);
(*crypt_data)->inited = false;
mutex_exit(&(*crypt_data)->mutex);
/* JAN: TODO:
mutex_free(& (*crypt_data)->mutex);
memset(*crypt_data, 0, sizeof(fil_space_crypt_t));
free(*crypt_data); free(*crypt_data);
(*crypt_data) = NULL; *crypt_data = NULL;
*/
mutex_exit(&fil_crypt_threads_mutex); mutex_exit(&fil_crypt_threads_mutex);
} }
} }
@@ -2468,6 +2464,7 @@ fil_crypt_threads_cleanup()
{ {
os_event_destroy(fil_crypt_event); os_event_destroy(fil_crypt_event);
os_event_destroy(fil_crypt_threads_event); os_event_destroy(fil_crypt_threads_event);
mutex_free(&fil_crypt_threads_mutex);
fil_crypt_threads_inited = false; fil_crypt_threads_inited = false;
} }

View File

@@ -185,7 +185,7 @@ fil_is_user_tablespace_id(
ulint space_id) ulint space_id)
{ {
return(space_id > srv_undo_tablespaces_open return(space_id > srv_undo_tablespaces_open
&& space_id != srv_tmp_space.space_id()); && space_id != SRV_TMP_SPACE_ID);
} }
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
@@ -1199,6 +1199,7 @@ fil_space_free_low(
ut_ad(space->size == 0); ut_ad(space->size == 0);
rw_lock_free(&space->latch); rw_lock_free(&space->latch);
fil_space_destroy_crypt_data(&space->crypt_data);
ut_free(space->name); ut_free(space->name);
ut_free(space); ut_free(space);
@@ -1313,7 +1314,7 @@ fil_space_create(
/* This warning is not applicable while MEB scanning the redo logs */ /* This warning is not applicable while MEB scanning the redo logs */
#ifndef UNIV_HOTBACKUP #ifndef UNIV_HOTBACKUP
if (fil_type_is_data(purpose) if ((purpose == FIL_TYPE_TABLESPACE || purpose == FIL_TYPE_IMPORT)
&& !recv_recovery_on && !recv_recovery_on
&& id > fil_system->max_assigned_id) { && id > fil_system->max_assigned_id) {
@@ -5104,10 +5105,13 @@ retry:
ulint pages_per_mb = (1024 * 1024) / page_size; ulint pages_per_mb = (1024 * 1024) / page_size;
ulint size_in_pages = ((node->size / pages_per_mb) * pages_per_mb); ulint size_in_pages = ((node->size / pages_per_mb) * pages_per_mb);
if (space->id == srv_sys_space.space_id()) { switch (space->id) {
case TRX_SYS_SPACE:
srv_sys_space.set_last_file_size(size_in_pages); srv_sys_space.set_last_file_size(size_in_pages);
} else if (space->id == srv_tmp_space.space_id()) { break;
case SRV_TMP_SPACE_ID:
srv_tmp_space.set_last_file_size(size_in_pages); srv_tmp_space.set_last_file_size(size_in_pages);
break;
} }
#else #else
ib::trace() << "extended space : " << space->name << " from " ib::trace() << "extended space : " << space->name << " from "
@@ -6223,6 +6227,8 @@ fil_close(void)
ut_free(fil_system); ut_free(fil_system);
fil_system = NULL; fil_system = NULL;
fil_space_crypt_cleanup();
} }
} }
@@ -6679,18 +6685,18 @@ fil_tablespace_iterate(
iter.io_buffer = static_cast<byte*>( iter.io_buffer = static_cast<byte*>(
ut_align(io_buffer, UNIV_PAGE_SIZE)); ut_align(io_buffer, UNIV_PAGE_SIZE));
/** Add an exta buffer for encryption */ iter.crypt_io_buffer = iter.crypt_data
void* crypt_io_buffer = NULL; ? static_cast<byte*>(
if (iter.crypt_data != NULL) { ut_malloc_nokey(iter.n_io_buffers
crypt_io_buffer = ut_malloc_nokey( * UNIV_PAGE_SIZE))
iter.n_io_buffers * UNIV_PAGE_SIZE); : NULL;
iter.crypt_io_buffer = static_cast<byte*>(
crypt_io_buffer);
}
err = fil_iterate(iter, block, callback); err = fil_iterate(iter, block, callback);
ut_free(io_buffer); ut_free(io_buffer);
ut_free(iter.crypt_io_buffer);
fil_space_destroy_crypt_data(&iter.crypt_data);
} }
} }

View File

@@ -63,22 +63,17 @@ Datafile::shutdown()
ut_free(m_name); ut_free(m_name);
m_name = NULL; m_name = NULL;
ut_free(m_encryption_key);
m_encryption_key = NULL;
/* The fil_space_t::crypt_data was freed in
fil_space_free_low(). Invalidate our redundant pointer. */
m_crypt_info = NULL;
ut_free(m_encryption_iv);
m_encryption_iv = NULL;
free_filepath(); free_filepath();
if (m_encryption_key != NULL) {
ut_free(m_encryption_key);
m_encryption_key = NULL;
}
if (m_crypt_info) {
fil_space_destroy_crypt_data(&m_crypt_info);
}
if (m_encryption_iv != NULL) {
ut_free(m_encryption_iv);
m_encryption_iv = NULL;
}
free_first_page(); free_first_page();
} }

View File

@@ -338,16 +338,6 @@ err_exit:
return (false); return (false);
} }
/** Check if tablespace is system temporary.
@param[in] space_id tablespace ID
@return true if tablespace is system temporary. */
bool
fsp_is_system_temporary(
ulint space_id)
{
return(space_id == srv_tmp_space.space_id());
}
/** Check if checksum is disabled for the given space. /** Check if checksum is disabled for the given space.
@param[in] space_id tablespace ID @param[in] space_id tablespace ID
@return true if checksum is disabled for given space. */ @return true if checksum is disabled for given space. */
@@ -803,8 +793,7 @@ fsp_space_modify_check(
#ifdef UNIV_DEBUG #ifdef UNIV_DEBUG
{ {
const fil_type_t type = fil_space_get_type(id); const fil_type_t type = fil_space_get_type(id);
ut_a(id == srv_tmp_space.space_id() ut_a(srv_is_tablespace_truncated(id)
|| srv_is_tablespace_truncated(id)
|| fil_space_is_being_truncated(id) || fil_space_is_being_truncated(id)
|| fil_space_get_flags(id) == ULINT_UNDEFINED || fil_space_get_flags(id) == ULINT_UNDEFINED
|| type == FIL_TYPE_TEMPORARY || type == FIL_TYPE_TEMPORARY
@@ -814,10 +803,7 @@ fsp_space_modify_check(
#endif /* UNIV_DEBUG */ #endif /* UNIV_DEBUG */
return; return;
case MTR_LOG_ALL: case MTR_LOG_ALL:
/* We must not write redo log for the shared temporary /* We may only write redo log for a persistent tablespace. */
tablespace. */
ut_ad(id != srv_tmp_space.space_id());
/* If we write redo log, the tablespace must exist. */
ut_ad(fil_space_get_type(id) == FIL_TYPE_TABLESPACE); ut_ad(fil_space_get_type(id) == FIL_TYPE_TABLESPACE);
ut_ad(mtr->is_named_space(id)); ut_ad(mtr->is_named_space(id));
return; return;
@@ -1549,15 +1535,14 @@ fsp_try_extend_data_file(
const page_size_t page_size( const page_size_t page_size(
mach_read_from_4(header + FSP_SPACE_FLAGS)); mach_read_from_4(header + FSP_SPACE_FLAGS));
if (space->id == srv_sys_space.space_id()) { switch (space->id) {
case TRX_SYS_SPACE:
size_increase = srv_sys_space.get_increment(); size_increase = srv_sys_space.get_increment();
break;
} else if (space->id == srv_tmp_space.space_id()) { case SRV_TMP_SPACE_ID:
size_increase = srv_tmp_space.get_increment(); size_increase = srv_tmp_space.get_increment();
break;
} else { default:
ulint extent_pages ulint extent_pages
= fsp_get_extent_size_in_pages(page_size); = fsp_get_extent_size_in_pages(page_size);
if (size < extent_pages) { if (size < extent_pages) {
@@ -1679,11 +1664,17 @@ fsp_fill_free_list(
const page_size_t page_size(flags); const page_size_t page_size(flags);
if (size < limit + FSP_EXTENT_SIZE * FSP_FREE_ADD) { if (size < limit + FSP_EXTENT_SIZE * FSP_FREE_ADD) {
if ((!init_space && !is_system_tablespace(space->id)) bool skip_resize = init_space;
|| (space->id == srv_sys_space.space_id() switch (space->id) {
&& srv_sys_space.can_auto_extend_last_file()) case TRX_SYS_SPACE:
|| (space->id == srv_tmp_space.space_id() skip_resize = !srv_sys_space.can_auto_extend_last_file();
&& srv_tmp_space.can_auto_extend_last_file())) { break;
case SRV_TMP_SPACE_ID:
skip_resize = srv_tmp_space.can_auto_extend_last_file();
break;
}
if (!skip_resize) {
ulint n_pages = 0; ulint n_pages = 0;
fsp_try_extend_data_file(space, header, mtr, &n_pages); fsp_try_extend_data_file(space, header, mtr, &n_pages);
size = space->size_in_header; size = space->size_in_header;
@@ -1733,7 +1724,7 @@ fsp_fill_free_list(
order, and we must be able to release its latch. order, and we must be able to release its latch.
Note: Insert-Buffering is disabled for tables that Note: Insert-Buffering is disabled for tables that
reside in the temp-tablespace. */ reside in the temp-tablespace. */
if (space->id != srv_tmp_space.space_id()) { if (space->purpose != FIL_TYPE_TEMPORARY) {
mtr_t ibuf_mtr; mtr_t ibuf_mtr;
mtr_start(&ibuf_mtr); mtr_start(&ibuf_mtr);
@@ -1741,9 +1732,7 @@ fsp_fill_free_list(
/* Avoid logging while truncate table /* Avoid logging while truncate table
fix-up is active. */ fix-up is active. */
if (space->purpose == FIL_TYPE_TEMPORARY if (srv_is_tablespace_truncated(space->id)) {
|| srv_is_tablespace_truncated(
space->id)) {
mtr_set_log_mode( mtr_set_log_mode(
&ibuf_mtr, MTR_LOG_NO_REDO); &ibuf_mtr, MTR_LOG_NO_REDO);
} }

View File

@@ -207,17 +207,6 @@ Tablespace::delete_files()
} }
} }
/** Check if undo tablespace.
@return true if undo tablespace */
bool
Tablespace::is_undo_tablespace(
ulint id)
{
return(id <= srv_undo_tablespaces_open
&& id != srv_sys_space.space_id()
&& id != srv_tmp_space.space_id());
}
/** Use the ADD DATAFILE path to create a Datafile object and add it to the /** Use the ADD DATAFILE path to create a Datafile object and add it to the
front of m_files. front of m_files.
Parse the datafile path into a path and a filename with extension 'ibd'. Parse the datafile path into a path and a filename with extension 'ibd'.

View File

@@ -3727,9 +3727,10 @@ ibuf_insert(
op, page_id.space(), page_id.page_no())); op, page_id.space(), page_id.page_no()));
ut_ad(dtuple_check_typed(entry)); ut_ad(dtuple_check_typed(entry));
ut_ad(page_id.space() != srv_tmp_space.space_id()); ut_ad(page_id.space() != SRV_TMP_SPACE_ID);
ut_a(!dict_index_is_clust(index)); ut_a(!dict_index_is_clust(index));
ut_ad(!dict_table_is_temporary(index->table));
no_counter = use <= IBUF_USE_INSERT; no_counter = use <= IBUF_USE_INSERT;

View File

@@ -97,8 +97,6 @@ extern const char general_space_name[];
struct trx_t; struct trx_t;
class page_id_t; class page_id_t;
class truncate_t; class truncate_t;
struct fil_node_t;
struct fil_space_t;
struct btr_create_t; struct btr_create_t;
/* structure containing encryption specification */ /* structure containing encryption specification */

View File

@@ -219,7 +219,10 @@ public:
/** Check if undo tablespace. /** Check if undo tablespace.
@return true if undo tablespace */ @return true if undo tablespace */
static bool is_undo_tablespace(ulint id); static bool is_undo_tablespace(ulint id)
{
return(id <= srv_undo_tablespaces_open);
}
private: private:
/** /**
@param[in] filename Name to lookup in the data files. @param[in] filename Name to lookup in the data files.

View File

@@ -291,11 +291,9 @@ extern SysTablespace srv_tmp_space;
@return true if id is a system tablespace, false if not. */ @return true if id is a system tablespace, false if not. */
UNIV_INLINE UNIV_INLINE
bool bool
is_system_tablespace( is_system_tablespace(ulint id)
ulint id)
{ {
return(id == srv_sys_space.space_id() return(id == TRX_SYS_SPACE || id == SRV_TMP_SPACE_ID);
|| id == srv_tmp_space.space_id());
} }
/** Check if shared-system or undo tablespace. /** Check if shared-system or undo tablespace.
@@ -305,8 +303,7 @@ bool
is_system_or_undo_tablespace( is_system_or_undo_tablespace(
ulint id) ulint id)
{ {
return(id == srv_sys_space.space_id() return(id <= srv_undo_tablespaces_open);
|| id <= srv_undo_tablespaces_open);
} }
/** Check if predefined shared tablespace. /** Check if predefined shared tablespace.
@@ -319,6 +316,6 @@ is_predefined_tablespace(
ut_ad(srv_sys_space.space_id() == TRX_SYS_SPACE); ut_ad(srv_sys_space.space_id() == TRX_SYS_SPACE);
ut_ad(TRX_SYS_SPACE == 0); ut_ad(TRX_SYS_SPACE == 0);
return(id <= srv_undo_tablespaces_open return(id <= srv_undo_tablespaces_open
|| id == srv_tmp_space.space_id()); || id == SRV_TMP_SPACE_ID);
} }
#endif /* fsp0sysspace_h */ #endif /* fsp0sysspace_h */

View File

@@ -29,6 +29,12 @@ Created May 26, 2009 Vasil Dimov
#ifndef UNIV_INNOCHECKSUM #ifndef UNIV_INNOCHECKSUM
/** The fil_space_t::id of the redo log. All persistent tablespaces
have a smaller fil_space_t::id. */
#define SRV_LOG_SPACE_FIRST_ID 0xFFFFFFF0U
/** The fil_space_t::id of the innodb_temporary tablespace. */
#define SRV_TMP_SPACE_ID 0xFFFFFFFEU
#include "univ.i" #include "univ.i"
#include "ut0byte.h" #include "ut0byte.h"
@@ -196,9 +202,12 @@ fsp_flags_is_valid(
/** Check if tablespace is system temporary. /** Check if tablespace is system temporary.
@param[in] space_id verify is checksum is enabled for given space. @param[in] space_id verify is checksum is enabled for given space.
@return true if tablespace is system temporary. */ @return true if tablespace is system temporary. */
inline
bool bool
fsp_is_system_temporary( fsp_is_system_temporary(ulint space_id)
ulint space_id); {
return(space_id == SRV_TMP_SPACE_ID);
}
/** Check if checksum is disabled for the given space. /** Check if checksum is disabled for the given space.
@param[in] space_id verify is checksum is enabled for given space. @param[in] space_id verify is checksum is enabled for given space.

View File

@@ -1,146 +0,0 @@
/*****************************************************************************
Copyright (c) 2013, 2014, Oracle and/or its affiliates. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
Foundation; version 2 of the License.
This program is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with
this program; if not, write to the Free Software Foundation, Inc.,
51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
*****************************************************************************/
/**************************************************//**
@file include/sess0sess.h
InnoDB session state tracker.
Multi file, shared, system tablespace implementation.
Created 2014-04-30 by Krunal Bauskar
*******************************************************/
#ifndef sess0sess_h
#define sess0sess_h
#include "univ.i"
#include "dict0mem.h"
#include "ut0new.h"
#include <map>
class dict_intrinsic_table_t {
public:
/** Constructor
@param[in,out] handler table handler. */
dict_intrinsic_table_t(dict_table_t* handler)
:
m_handler(handler)
{
/* Do nothing. */
}
/** Destructor */
~dict_intrinsic_table_t()
{
m_handler = NULL;
}
public:
/* Table Handler holding other metadata information commonly needed
for any table. */
dict_table_t* m_handler;
};
/** InnoDB private data that is cached in THD */
typedef std::map<
std::string,
dict_intrinsic_table_t*,
std::less<std::string>,
ut_allocator<std::pair<const std::string, dict_intrinsic_table_t*> > >
table_cache_t;
class innodb_session_t {
public:
/** Constructor */
innodb_session_t()
: m_trx(),
m_open_tables()
{
/* Do nothing. */
}
/** Destructor */
~innodb_session_t()
{
m_trx = NULL;
for (table_cache_t::iterator it = m_open_tables.begin();
it != m_open_tables.end();
++it) {
delete(it->second);
}
}
/** Cache table handler.
@param[in] table_name name of the table
@param[in,out] table table handler to register */
void register_table_handler(
const char* table_name,
dict_table_t* table)
{
ut_ad(lookup_table_handler(table_name) == NULL);
m_open_tables.insert(table_cache_t::value_type(
table_name, new dict_intrinsic_table_t(table)));
}
/** Lookup for table handler given table_name.
@param[in] table_name name of the table to lookup */
dict_table_t* lookup_table_handler(
const char* table_name)
{
table_cache_t::iterator it = m_open_tables.find(table_name);
return((it == m_open_tables.end())
? NULL : it->second->m_handler);
}
/** Remove table handler entry.
@param[in] table_name name of the table to remove */
void unregister_table_handler(
const char* table_name)
{
table_cache_t::iterator it = m_open_tables.find(table_name);
if (it == m_open_tables.end()) {
return;
}
delete(it->second);
m_open_tables.erase(table_name);
}
/** Count of register table handler.
@return number of register table handlers */
uint count_register_table_handler() const
{
return(static_cast<uint>(m_open_tables.size()));
}
public:
/** transaction handler. */
trx_t* m_trx;
/** Handler of tables that are created or open but not added
to InnoDB dictionary as they are session specific.
Currently, limited to intrinsic temporary tables only. */
table_cache_t m_open_tables;
};
#endif /* sess0sess_h */

View File

@@ -46,9 +46,6 @@ struct dict_table_t;
} while (0) } while (0)
#endif /* DBUG_OFF */ #endif /* DBUG_OFF */
/** Log 'spaces' have id's >= this */
#define SRV_LOG_SPACE_FIRST_ID 0xFFFFFFF0UL
/** If buffer pool is less than the size, /** If buffer pool is less than the size,
only one buffer pool instance is used. */ only one buffer pool instance is used. */
#define BUF_POOL_SIZE_THRESHOLD (1024 * 1024 * 1024) #define BUF_POOL_SIZE_THRESHOLD (1024 * 1024 * 1024)

View File

@@ -2278,7 +2278,7 @@ truncate_t::fixup_tables_in_non_system_tablespace()
"id (" << (*it)->m_space_id << ")"; "id (" << (*it)->m_space_id << ")";
/* Temp-tables in temp-tablespace are never restored.*/ /* Temp-tables in temp-tablespace are never restored.*/
ut_ad((*it)->m_space_id != srv_tmp_space.space_id()); ut_ad((*it)->m_space_id != SRV_TMP_SPACE_ID);
err = fil_recreate_table( err = fil_recreate_table(
(*it)->m_space_id, (*it)->m_space_id,

View File

@@ -1123,76 +1123,67 @@ srv_start_wait_for_purge_to_start()
/** Create the temporary file tablespace. /** Create the temporary file tablespace.
@param[in] create_new_db whether we are creating a new database @param[in] create_new_db whether we are creating a new database
@param[in,out] tmp_space Shared Temporary SysTablespace
@return DB_SUCCESS or error code. */ @return DB_SUCCESS or error code. */
static static
dberr_t dberr_t
srv_open_tmp_tablespace( srv_open_tmp_tablespace(bool create_new_db)
bool create_new_db,
SysTablespace* tmp_space)
{ {
ulint sum_of_new_sizes; ulint sum_of_new_sizes;
/* Will try to remove if there is existing file left-over by last /* Will try to remove if there is existing file left-over by last
unclean shutdown */ unclean shutdown */
tmp_space->set_sanity_check_status(true); srv_tmp_space.set_sanity_check_status(true);
tmp_space->delete_files(); srv_tmp_space.delete_files();
tmp_space->set_ignore_read_only(true); srv_tmp_space.set_ignore_read_only(true);
ib::info() << "Creating shared tablespace for temporary tables"; ib::info() << "Creating shared tablespace for temporary tables";
bool create_new_temp_space; bool create_new_temp_space;
ulint temp_space_id = ULINT_UNDEFINED;
dict_hdr_get_new_id(NULL, NULL, &temp_space_id, NULL, true); srv_tmp_space.set_space_id(SRV_TMP_SPACE_ID);
tmp_space->set_space_id(temp_space_id);
RECOVERY_CRASH(100); RECOVERY_CRASH(100);
dberr_t err = tmp_space->check_file_spec( dberr_t err = srv_tmp_space.check_file_spec(
&create_new_temp_space, 12 * 1024 * 1024); &create_new_temp_space, 12 * 1024 * 1024);
if (err == DB_FAIL) { if (err == DB_FAIL) {
ib::error() << "The " << tmp_space->name() ib::error() << "The " << srv_tmp_space.name()
<< " data file must be writable!"; << " data file must be writable!";
err = DB_ERROR; err = DB_ERROR;
} else if (err != DB_SUCCESS) { } else if (err != DB_SUCCESS) {
ib::error() << "Could not create the shared " ib::error() << "Could not create the shared "
<< tmp_space->name() << "."; << srv_tmp_space.name() << ".";
} else if ((err = tmp_space->open_or_create( } else if ((err = srv_tmp_space.open_or_create(
true, create_new_db, &sum_of_new_sizes, NULL)) true, create_new_db, &sum_of_new_sizes, NULL))
!= DB_SUCCESS) { != DB_SUCCESS) {
ib::error() << "Unable to create the shared " ib::error() << "Unable to create the shared "
<< tmp_space->name(); << srv_tmp_space.name();
} else { } else {
mtr_t mtr; mtr_t mtr;
ulint size = tmp_space->get_sum_of_sizes(); ulint size = srv_tmp_space.get_sum_of_sizes();
ut_a(temp_space_id != ULINT_UNDEFINED);
ut_a(tmp_space->space_id() == temp_space_id);
/* Open this shared temp tablespace in the fil_system so that /* Open this shared temp tablespace in the fil_system so that
it stays open until shutdown. */ it stays open until shutdown. */
if (fil_space_open(tmp_space->name())) { if (fil_space_open(srv_tmp_space.name())) {
/* Initialize the header page */ /* Initialize the header page */
mtr_start(&mtr); mtr_start(&mtr);
mtr_set_log_mode(&mtr, MTR_LOG_NO_REDO); mtr_set_log_mode(&mtr, MTR_LOG_NO_REDO);
fsp_header_init(tmp_space->space_id(), size, &mtr); fsp_header_init(SRV_TMP_SPACE_ID, size, &mtr);
mtr_commit(&mtr); mtr_commit(&mtr);
} else { } else {
/* This file was just opened in the code above! */ /* This file was just opened in the code above! */
ib::error() << "The " << tmp_space->name() ib::error() << "The " << srv_tmp_space.name()
<< " data file cannot be re-opened" << " data file cannot be re-opened"
" after check_file_spec() succeeded!"; " after check_file_spec() succeeded!";
@@ -1235,6 +1226,7 @@ srv_shutdown_all_bg_threads()
ulint i; ulint i;
srv_shutdown_state = SRV_SHUTDOWN_EXIT_THREADS; srv_shutdown_state = SRV_SHUTDOWN_EXIT_THREADS;
fil_crypt_threads_end();
if (!srv_start_state) { if (!srv_start_state) {
return; return;
@@ -2439,7 +2431,7 @@ files_checked:
/* Open temp-tablespace and keep it open until shutdown. */ /* Open temp-tablespace and keep it open until shutdown. */
err = srv_open_tmp_tablespace(create_new_db, &srv_tmp_space); err = srv_open_tmp_tablespace(create_new_db);
if (err != DB_SUCCESS) { if (err != DB_SUCCESS) {
return(srv_init_abort(err)); return(srv_init_abort(err));
@@ -2778,9 +2770,6 @@ srv_shutdown_bg_undo_sources(void)
{ {
fts_optimize_shutdown(); fts_optimize_shutdown();
dict_stats_shutdown(); dict_stats_shutdown();
/* Shutdown key rotation threads */
fil_crypt_threads_end();
} }
@@ -2848,9 +2837,7 @@ innobase_shutdown_for_mysql(void)
} }
} }
if (!srv_read_only_mode) { fil_crypt_threads_cleanup();
fil_crypt_threads_cleanup();
}
/* Cleanup data for datafile scrubbing */ /* Cleanup data for datafile scrubbing */
btr_scrub_cleanup(); btr_scrub_cleanup();

View File

@@ -1582,7 +1582,6 @@ sync_latch_meta_init()
} }
/** Destroy the latch meta data */ /** Destroy the latch meta data */
#ifdef JAN_DISABLED_FOR_NOW_AS_THIS_CAUSES_CRASH
static static
void void
sync_latch_meta_destroy() sync_latch_meta_destroy()
@@ -1596,7 +1595,6 @@ sync_latch_meta_destroy()
latch_meta.clear(); latch_meta.clear();
} }
#endif
/** Track mutex file creation name and line number. This is to avoid storing /** Track mutex file creation name and line number. This is to avoid storing
{ const char* name; uint16_t line; } in every instance. This results in the { const char* name; uint16_t line; } in every instance. This results in the
@@ -1810,8 +1808,6 @@ sync_check_close()
create_tracker = NULL; create_tracker = NULL;
#ifdef JAN_DISABLED_FOR_NOW_AS_THIS_CAUSES_CRASH
sync_latch_meta_destroy(); sync_latch_meta_destroy();
#endif
} }

View File

@@ -983,8 +983,7 @@ trx_sys_create_noredo_rsegs(
Slot-1....Slot-N: reserved for temp-tablespace. Slot-1....Slot-N: reserved for temp-tablespace.
Slot-N+1....Slot-127: reserved for system/undo-tablespace. */ Slot-N+1....Slot-127: reserved for system/undo-tablespace. */
for (ulint i = 0; i < n_nonredo_rseg; i++) { for (ulint i = 0; i < n_nonredo_rseg; i++) {
ulint space = srv_tmp_space.space_id(); if (trx_rseg_create(SRV_TMP_SPACE_ID, i) == NULL) {
if (trx_rseg_create(space, i) == NULL) {
break; break;
} }
++n_created; ++n_created;

View File

@@ -83,12 +83,6 @@ mysys/my_perf.c, contributed by Facebook under the following license.
#include "my_config.h" #include "my_config.h"
#include <string.h> #include <string.h>
#if defined(__linux__) && defined(HAVE_CRC32_VPMSUM)
/* Used to detect at runtime if we have vpmsum instructions (PowerISA 2.07) */
#include <sys/auxv.h>
#include <bits/hwcap.h>
#endif
#include "univ.i" #include "univ.i"
#include "ut0crc32.h" #include "ut0crc32.h"
@@ -746,14 +740,8 @@ ut_crc32_init()
} }
#elif defined(HAVE_CRC32_VPMSUM) #elif defined(HAVE_CRC32_VPMSUM)
#if defined(__linux__) ut_crc32 = ut_crc32_power8;
if (getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_2_07) { ut_crc32_implementation = "Using POWER8 crc32 instructions";
#endif
ut_crc32 = ut_crc32_power8;
ut_crc32_implementation = "Using POWER8 crc32 instructions";
#if defined(__linux__)
}
#endif
#endif #endif
} }

View File

@@ -46,6 +46,7 @@ a b
1 10 1 10
2 20 2 20
3 30 3 30
4 40
insert into t2 values (1); insert into t2 values (1);
ERROR HY000: Table 't2' was not locked with LOCK TABLES ERROR HY000: Table 't2' was not locked with LOCK TABLES
commit; commit;
@@ -58,6 +59,7 @@ a b
1 10 1 10
2 20 2 20
3 30 3 30
4 40
select * from t2; select * from t2;
a a
1 1
@@ -70,6 +72,7 @@ a b
1 10 1 10
2 20 2 20
3 30 3 30
4 40
5 50 5 50
select * from t2; select * from t2;
a a
@@ -81,6 +84,7 @@ a b
1 10 1 10
2 20 2 20
3 30 3 30
4 40
5 50 5 50
select * from t2; select * from t2;
a a

View File

@@ -2,8 +2,8 @@ drop table if exists t1,t3;
CREATE TABLE t3(a int,c int,d int)engine=TOKUDB; CREATE TABLE t3(a int,c int,d int)engine=TOKUDB;
lock table t3 read; lock table t3 read;
create temporary table t1 engine=tokudb as SELECT 1; create temporary table t1 engine=tokudb as SELECT 1;
unlock tables;
select * from t1; select * from t1;
1 1
1 1
unlock tables;
drop table t1,t3; drop table t1,t3;

View File

@@ -7,7 +7,7 @@ enable_warnings;
CREATE TABLE t3(a int,c int,d int)engine=TOKUDB; CREATE TABLE t3(a int,c int,d int)engine=TOKUDB;
lock table t3 read; lock table t3 read;
create temporary table t1 engine=tokudb as SELECT 1; create temporary table t1 engine=tokudb as SELECT 1;
unlock tables;
select * from t1; select * from t1;
unlock tables;
drop table t1,t3; drop table t1,t3;

View File

@@ -1643,6 +1643,7 @@ struct dict_foreign_remove_partial
if (table != NULL) { if (table != NULL) {
table->referenced_set.erase(foreign); table->referenced_set.erase(foreign);
} }
dict_foreign_free(foreign);
} }
}; };
@@ -3597,8 +3598,7 @@ dict_foreign_add_to_cache(
} }
if (for_in_cache) { if (for_in_cache) {
/* Free the foreign object */ dict_foreign_free(foreign);
mem_heap_free(foreign->heap);
} else { } else {
for_in_cache = foreign; for_in_cache = foreign;
} }
@@ -3622,7 +3622,7 @@ dict_foreign_add_to_cache(
" the ones in table."); " the ones in table.");
if (for_in_cache == foreign) { if (for_in_cache == foreign) {
mem_heap_free(foreign->heap); dict_foreign_free(foreign);
} }
return(DB_CANNOT_ADD_CONSTRAINT); return(DB_CANNOT_ADD_CONSTRAINT);
@@ -3678,7 +3678,7 @@ dict_foreign_add_to_cache(
be one */ be one */
} }
mem_heap_free(foreign->heap); dict_foreign_free(foreign);
} }
return(DB_CANNOT_ADD_CONSTRAINT); return(DB_CANNOT_ADD_CONSTRAINT);

View File

@@ -490,7 +490,7 @@ err_len:
} }
/* This receives a dict_foreign_t* that points to a stack variable. /* This receives a dict_foreign_t* that points to a stack variable.
So mem_heap_free(foreign->heap) is not used as elsewhere. So dict_foreign_free(foreign) is not used as elsewhere.
Since the heap used here is freed elsewhere, foreign->heap Since the heap used here is freed elsewhere, foreign->heap
is not assigned. */ is not assigned. */
foreign->id = mem_heap_strdupl(heap, (const char*) field, len); foreign->id = mem_heap_strdupl(heap, (const char*) field, len);

View File

@@ -336,13 +336,7 @@ ut_crc32_init()
} }
#elif defined(HAVE_CRC32_VPMSUM) #elif defined(HAVE_CRC32_VPMSUM)
#if defined(__linux__) ut_crc32 = ut_crc32_power8;
if (getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_2_07) { ut_crc32_implementation = "Using POWER8 crc32 instructions";
#endif
ut_crc32 = ut_crc32_power8;
ut_crc32_implementation = "Using POWER8 crc32 instructions";
#if defined(__linux__)
}
#endif
#endif #endif
} }

View File

@@ -1270,7 +1270,7 @@ int json_find_path(json_engine_t *je,
case JST_VALUE: case JST_VALUE:
DBUG_ASSERT(cur_step->type & JSON_PATH_ARRAY); DBUG_ASSERT(cur_step->type & JSON_PATH_ARRAY);
if (cur_step->type & JSON_PATH_WILD || if (cur_step->type & JSON_PATH_WILD ||
cur_step->n_item == array_counters[cur_step - p->steps]) cur_step->n_item == array_counters[cur_step - p->steps]++)
{ {
/* Array item matches. */ /* Array item matches. */
if (cur_step == p->last_step || if (cur_step == p->last_step ||
@@ -1278,10 +1278,7 @@ int json_find_path(json_engine_t *je,
goto exit; goto exit;
} }
else else
{
json_skip_array_item(je); json_skip_array_item(je);
array_counters[cur_step - p->steps]++;
}
break; break;
case JST_OBJ_END: case JST_OBJ_END:
case JST_ARRAY_END: case JST_ARRAY_END:

Some files were not shown because too many files have changed in this diff Show More