mirror of
https://github.com/MariaDB/server.git
synced 2025-12-24 11:21:21 +03:00
Merge remote-tracking branch 'origin/10.2' into 10.3
This commit is contained in:
@@ -67,7 +67,7 @@ script:
|
||||
- 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
|
||||
- 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:
|
||||
irc:
|
||||
|
||||
1
debian/libmariadb-dev.install
vendored
1
debian/libmariadb-dev.install
vendored
@@ -1,5 +1,4 @@
|
||||
usr/bin/mysql_config
|
||||
usr/include/mariadb
|
||||
usr/include/mysql/*.h
|
||||
usr/include/mysql/psi/*.h
|
||||
usr/lib/*/libmariadb.so
|
||||
|
||||
2
debian/libmariadb3.install
vendored
2
debian/libmariadb3.install
vendored
@@ -1,5 +1,5 @@
|
||||
usr/lib/*/libmariadbclient.so.*
|
||||
usr/lib/*/libmysqlclient.so.*
|
||||
usr/lib/mariadb/libmariadb.so.*
|
||||
usr/lib/*/libmariadb.so.*
|
||||
usr/lib/mysql/plugin/dialog.so
|
||||
usr/lib/mysql/plugin/mysql_clear_password.so
|
||||
|
||||
8
debian/rules
vendored
8
debian/rules
vendored
@@ -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 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
|
||||
ln -s /usr/lib/mariadb/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 /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.18
|
||||
ln -s $(TMP)/usr/lib/$(DEB_HOST_MULTIARCH)/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.20
|
||||
|
||||
touch $@
|
||||
|
||||
|
||||
Submodule libmariadb updated: 3837442cbc...cae391f7bf
@@ -236,6 +236,15 @@ create table t2i (a int);
|
||||
insert into t2m 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
|
||||
select min(a) 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 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
|
||||
SELECT COUNT(*) FROM t2 LEFT JOIN t1 ON t2.fkey = t1.id
|
||||
WHERE t1.name LIKE 'A%';
|
||||
@@ -572,12 +588,22 @@ OPTIMIZE TABLE t1;
|
||||
SELECT COUNT(*) FROM t1;
|
||||
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;
|
||||
|
||||
INSERT INTO t2 SELECT * FROM t1;
|
||||
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;
|
||||
|
||||
@@ -654,9 +680,11 @@ INSERT INTO t2 VALUES (1);
|
||||
|
||||
CONNECTION c2;
|
||||
SET AUTOCOMMIT=0;
|
||||
SET @old_lock_wait_timeout= @@lock_wait_timeout;
|
||||
SET lock_wait_timeout= 1;
|
||||
--error ER_LOCK_WAIT_TIMEOUT
|
||||
LOCK TABLES t1 READ, t2 READ;
|
||||
|
||||
SET @@lock_wait_timeout= @old_lock_wait_timeout;
|
||||
CONNECTION c1;
|
||||
COMMIT;
|
||||
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';
|
||||
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;
|
||||
|
||||
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 + 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 SQL_BIG_RESULT b, SUM(c) FROM t1 GROUP BY b;
|
||||
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 SELECT a + 8, 2 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;
|
||||
SELECT * FROM t1 WHERE b=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 + 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;
|
||||
SELECT * FROM t2 WHERE b=1 ORDER BY a;
|
||||
query_vertical EXPLAIN SELECT * FROM t2 WHERE b=1 AND c=1 ORDER BY a;
|
||||
@@ -957,7 +1009,7 @@ SELECT * FROM t1 WHERE b=20 FOR UPDATE;
|
||||
|
||||
--connect (conn2, localhost, root,,test)
|
||||
|
||||
# This statement gives a "failed: 1205: Lock wait timeout exceeded; try
|
||||
# This statement gives a "failed: 1205: Lock wait timeout exceeded; try
|
||||
# restarting transaction" message when the bug is present.
|
||||
START TRANSACTION;
|
||||
SELECT * FROM t1 WHERE b=10 ORDER BY A FOR UPDATE;
|
||||
@@ -982,6 +1034,12 @@ CREATE TABLE t1(
|
||||
|
||||
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;
|
||||
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;
|
||||
@@ -1002,6 +1060,12 @@ DROP TABLE t1;
|
||||
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);
|
||||
|
||||
-- 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.
|
||||
query_vertical EXPLAIN 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
|
||||
(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;
|
||||
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) 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
|
||||
|
||||
#
|
||||
# InnoDB uses "where", while xtradb "index condition"
|
||||
#
|
||||
--replace_regex /where/index condition/
|
||||
# should be range access
|
||||
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
|
||||
@@ -1512,6 +1583,12 @@ INSERT INTO t1 VALUES
|
||||
(4,1,3,'pk',NULL),(5,1,3,'c2',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;
|
||||
|
||||
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;
|
||||
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)
|
||||
FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x;
|
||||
EXPLAIN
|
||||
@@ -1542,6 +1625,12 @@ CREATE TABLE t1 (c1 REAL, c2 REAL, c3 REAL, KEY (c3), KEY (c2, c3))
|
||||
ENGINE=$engine_type;
|
||||
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)
|
||||
FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x;
|
||||
EXPLAIN
|
||||
@@ -1556,6 +1645,12 @@ CREATE TABLE t1 (c1 DECIMAL(12,2), c2 DECIMAL(12,2), c3 DECIMAL(12,2),
|
||||
ENGINE=$engine_type;
|
||||
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)
|
||||
FROM t1 WHERE c2 IN (1, 1) AND c3 = 2 GROUP BY c2) x;
|
||||
EXPLAIN
|
||||
@@ -1583,6 +1678,13 @@ CREATE TABLE t2 (
|
||||
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;
|
||||
|
||||
-- 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;
|
||||
select * from t1, t2 where t2.a=t1.a and t2.b + 1;
|
||||
|
||||
|
||||
@@ -265,17 +265,31 @@ connection default;
|
||||
DROP TABLE t1;
|
||||
SET DEBUG_SYNC= 'RESET';
|
||||
DROP TABLE IF EXISTS t1;
|
||||
CREATE TABLE t1 (c1 INT);
|
||||
LOCK TABLE t1 READ;
|
||||
CREATE TABLE t1 (c1 INT) ENGINE=MyISAM;
|
||||
INSERT INTO t1 VALUES (1);
|
||||
SELECT GET_LOCK('mysqltest_lock', 100);
|
||||
GET_LOCK('mysqltest_lock', 100)
|
||||
1
|
||||
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';
|
||||
INSERT INTO t1 VALUES (1);
|
||||
connection default;
|
||||
SET DEBUG_SYNC= 'now WAIT_FOR locked';
|
||||
UNLOCK TABLES;
|
||||
SELECT RELEASE_LOCK('mysqltest_lock');
|
||||
RELEASE_LOCK('mysqltest_lock')
|
||||
1
|
||||
connection con1;
|
||||
# Reaping UPDATE
|
||||
SELECT RELEASE_LOCK('mysqltest_lock');
|
||||
RELEASE_LOCK('mysqltest_lock')
|
||||
1
|
||||
connection con2;
|
||||
retrieve INSERT result.
|
||||
disconnect con1;
|
||||
disconnect con2;
|
||||
connection default;
|
||||
DROP TABLE t1;
|
||||
SET DEBUG_SYNC= 'RESET';
|
||||
|
||||
@@ -8140,3 +8140,104 @@ EXPLAIN
|
||||
}
|
||||
}
|
||||
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;
|
||||
|
||||
@@ -147,4 +147,5 @@ v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VI
|
||||
select 30 + (20010101 + interval 2 day), x from v1;
|
||||
30 + (20010101 + interval 2 day) x
|
||||
20010133 20010133
|
||||
drop view v1;
|
||||
End of 10.2 tests
|
||||
|
||||
@@ -209,6 +209,9 @@ json_extract('[10, 20, [{"a":3}, 30, 40]]', '$[2][*]')
|
||||
select json_extract('1', '$');
|
||||
json_extract('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');
|
||||
json_insert('{"a":1, "b":{"c":1}, "d":[1, 2]}', '$.b.k1', 'word')
|
||||
{"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"}');
|
||||
json_merge('{"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}');
|
||||
json_type('{"k1":123, "k2":345}')
|
||||
OBJECT
|
||||
@@ -419,6 +425,12 @@ json_length('{}')
|
||||
select json_length('[1, 2, {"a": 3}]');
|
||||
json_length('[1, 2, {"a": 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);
|
||||
show create table json;
|
||||
Table Create Table
|
||||
|
||||
@@ -36,6 +36,7 @@ connection con3;
|
||||
set @@autocommit=1;
|
||||
connection default;
|
||||
disconnect con1;
|
||||
disconnect con2;
|
||||
disconnect con3;
|
||||
#
|
||||
# Test for bug #37346 "innodb does not detect deadlock between update
|
||||
@@ -72,34 +73,6 @@ connection default;
|
||||
disconnect con37346;
|
||||
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
|
||||
#
|
||||
DROP TABLE IF EXISTS t1;
|
||||
|
||||
@@ -119,33 +119,5 @@ DROP USER user20989@localhost;
|
||||
disconnect root;
|
||||
connection default;
|
||||
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 global sql_mode=default;
|
||||
|
||||
@@ -784,3 +784,74 @@ DROP VIEW v1;
|
||||
DROP TABLE t1;
|
||||
disconnect con1;
|
||||
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;
|
||||
|
||||
@@ -9,6 +9,7 @@ disconnect con1;
|
||||
connection con2;
|
||||
SELECT * FROM t1;
|
||||
a
|
||||
10
|
||||
DROP TABLE t1;
|
||||
connection default;
|
||||
disconnect con2;
|
||||
|
||||
@@ -281,7 +281,7 @@ UNLOCK TABLES;
|
||||
SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS
|
||||
WHERE VARIABLE_NAME LIKE 'HANDLER_%' AND VARIABLE_VALUE > 0;
|
||||
VARIABLE_NAME VARIABLE_VALUE
|
||||
HANDLER_COMMIT 3
|
||||
HANDLER_COMMIT 2
|
||||
HANDLER_READ_RND_NEXT 54
|
||||
HANDLER_TMP_WRITE 75
|
||||
HANDLER_WRITE 2
|
||||
@@ -440,7 +440,7 @@ UNLOCK TABLES;
|
||||
SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS
|
||||
WHERE VARIABLE_NAME LIKE 'HANDLER_%' AND VARIABLE_VALUE > 0;
|
||||
VARIABLE_NAME VARIABLE_VALUE
|
||||
HANDLER_COMMIT 6
|
||||
HANDLER_COMMIT 5
|
||||
HANDLER_READ_FIRST 3
|
||||
HANDLER_READ_NEXT 4
|
||||
HANDLER_READ_RND_NEXT 108
|
||||
@@ -665,7 +665,7 @@ UNLOCK TABLES;
|
||||
SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS
|
||||
WHERE VARIABLE_NAME LIKE 'HANDLER_%' AND VARIABLE_VALUE > 0;
|
||||
VARIABLE_NAME VARIABLE_VALUE
|
||||
HANDLER_COMMIT 6
|
||||
HANDLER_COMMIT 5
|
||||
HANDLER_DELETE 2
|
||||
HANDLER_READ_FIRST 1
|
||||
HANDLER_READ_KEY 3
|
||||
@@ -758,7 +758,7 @@ UNLOCK TABLES;
|
||||
SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS
|
||||
WHERE VARIABLE_NAME LIKE 'HANDLER_%' AND VARIABLE_VALUE > 0;
|
||||
VARIABLE_NAME VARIABLE_VALUE
|
||||
HANDLER_COMMIT 3
|
||||
HANDLER_COMMIT 2
|
||||
HANDLER_READ_RND_NEXT 54
|
||||
HANDLER_TMP_WRITE 75
|
||||
HANDLER_WRITE 10
|
||||
@@ -953,7 +953,7 @@ UNLOCK TABLES;
|
||||
SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS
|
||||
WHERE VARIABLE_NAME LIKE 'HANDLER_%' AND VARIABLE_VALUE > 0;
|
||||
VARIABLE_NAME VARIABLE_VALUE
|
||||
HANDLER_COMMIT 4
|
||||
HANDLER_COMMIT 3
|
||||
HANDLER_DELETE 1
|
||||
HANDLER_READ_KEY 2
|
||||
HANDLER_READ_RND 2
|
||||
@@ -1039,7 +1039,7 @@ UNLOCK TABLES;
|
||||
SELECT * FROM INFORMATION_SCHEMA.SESSION_STATUS
|
||||
WHERE VARIABLE_NAME LIKE 'HANDLER_%' AND VARIABLE_VALUE > 0;
|
||||
VARIABLE_NAME VARIABLE_VALUE
|
||||
HANDLER_COMMIT 4
|
||||
HANDLER_COMMIT 3
|
||||
HANDLER_DELETE 2
|
||||
HANDLER_READ_KEY 3
|
||||
HANDLER_READ_NEXT 1
|
||||
|
||||
@@ -4,6 +4,7 @@ SET @old_log_output = @@global.log_output;
|
||||
SET GLOBAL LOG_OUTPUT = 'FILE';
|
||||
connect con1,localhost,root,,;
|
||||
connect con2,localhost,root,,;
|
||||
connection default;
|
||||
flush status;
|
||||
show status like 'Table_lock%';
|
||||
Variable_name Value
|
||||
@@ -13,33 +14,42 @@ select * from information_schema.session_status where variable_name like 'Table_
|
||||
VARIABLE_NAME VARIABLE_VALUE
|
||||
TABLE_LOCKS_IMMEDIATE 0
|
||||
TABLE_LOCKS_WAITED 0
|
||||
connection con1;
|
||||
set sql_log_bin=0;
|
||||
set @old_general_log = @@global.general_log;
|
||||
set global general_log = 'OFF';
|
||||
drop table if exists t1;
|
||||
create table t1(n int) engine=myisam;
|
||||
insert into t1 values(1);
|
||||
select 1;
|
||||
1
|
||||
select get_lock('mysqltest_lock', 100);
|
||||
get_lock('mysqltest_lock', 100)
|
||||
1
|
||||
connection con2;
|
||||
lock tables t1 read;
|
||||
unlock tables;
|
||||
lock tables t1 read;
|
||||
# Sending:
|
||||
update t1 set n = get_lock('mysqltest_lock', 100);
|
||||
connection con1;
|
||||
# Wait for the first UPDATE to get blocked.
|
||||
# Sending:
|
||||
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;
|
||||
unlock tables;
|
||||
# Reaping first UPDATE
|
||||
select release_lock('mysqltest_lock');
|
||||
release_lock('mysqltest_lock')
|
||||
1
|
||||
connection con1;
|
||||
# Reaping second UPDATE
|
||||
show status like 'Table_locks_waited';
|
||||
Variable_name Value
|
||||
Table_locks_waited 1
|
||||
connection default;
|
||||
drop table t1;
|
||||
set global general_log = @old_general_log;
|
||||
disconnect con2;
|
||||
disconnect con1;
|
||||
connection default;
|
||||
select 1;
|
||||
1
|
||||
1
|
||||
|
||||
@@ -4792,21 +4792,24 @@ DROP TABLE t1, t2;
|
||||
# Bug#48315 Metadata lock is not taken for merged views that
|
||||
# use an INFORMATION_SCHEMA table
|
||||
#
|
||||
DROP TABLE IF EXISTS t1;
|
||||
DROP VIEW IF EXISTS v1;
|
||||
DROP PROCEDURE IF EXISTS p1;
|
||||
connect con2, localhost, root;
|
||||
connect con3, localhost, root;
|
||||
connection default;
|
||||
CREATE VIEW v1 AS SELECT schema_name FROM information_schema.schemata;
|
||||
CREATE TABLE t1 (str VARCHAR(50));
|
||||
CREATE PROCEDURE p1() INSERT INTO t1 SELECT * FROM v1;
|
||||
CREATE PROCEDURE p1() SELECT COUNT(*), GET_LOCK('blocker', 100) FROM v1;
|
||||
# CALL p1() so the view is merged.
|
||||
CALL p1();
|
||||
SELECT RELEASE_LOCK('blocker');
|
||||
RELEASE_LOCK('blocker')
|
||||
1
|
||||
connection con3;
|
||||
LOCK TABLE t1 READ;
|
||||
SELECT GET_LOCK('blocker', 100);
|
||||
GET_LOCK('blocker', 100)
|
||||
1
|
||||
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:
|
||||
CALL p1();
|
||||
connection con2;
|
||||
@@ -4815,14 +4818,18 @@ connection con2;
|
||||
DROP VIEW v1;
|
||||
connection con3;
|
||||
# Now allow CALL p1() to complete
|
||||
UNLOCK TABLES;
|
||||
SELECT RELEASE_LOCK('blocker');
|
||||
RELEASE_LOCK('blocker')
|
||||
1
|
||||
connection default;
|
||||
# Reaping: CALL p1()
|
||||
SELECT RELEASE_LOCK('blocker');
|
||||
RELEASE_LOCK('blocker')
|
||||
1
|
||||
connection con2;
|
||||
# Reaping: DROP VIEW v1
|
||||
connection default;
|
||||
DROP PROCEDURE p1;
|
||||
DROP TABLE t1;
|
||||
disconnect con2;
|
||||
disconnect con3;
|
||||
#
|
||||
|
||||
@@ -9,13 +9,13 @@ innodb_encryption_threads 4
|
||||
select space,name,current_key_version from information_schema.innodb_tablespaces_encryption order by space;
|
||||
space name current_key_version
|
||||
0 NULL 1
|
||||
2 mysql/innodb_table_stats 1
|
||||
3 mysql/innodb_index_stats 1
|
||||
1 mysql/innodb_table_stats 1
|
||||
2 mysql/innodb_index_stats 1
|
||||
set global debug_key_management_version=10;
|
||||
select space,name,current_key_version from information_schema.innodb_tablespaces_encryption order by space;
|
||||
space name current_key_version
|
||||
0 NULL 10
|
||||
2 mysql/innodb_table_stats 10
|
||||
3 mysql/innodb_index_stats 10
|
||||
1 mysql/innodb_table_stats 10
|
||||
2 mysql/innodb_index_stats 10
|
||||
set global innodb_encrypt_tables=OFF;
|
||||
set global debug_key_management_version=1;
|
||||
|
||||
@@ -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;
|
||||
CHECK TABLE t1;
|
||||
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 error Corrupt
|
||||
SHOW WARNINGS;
|
||||
|
||||
@@ -59,6 +59,7 @@ EOF
|
||||
SET GLOBAL innodb_file_format = `Barracuda`;
|
||||
SET GLOBAL innodb_file_per_table = ON;
|
||||
|
||||
--replace_regex /tablespace [0-9]*/tablespace #/
|
||||
CHECK TABLE t1;
|
||||
SHOW WARNINGS;
|
||||
|
||||
|
||||
@@ -30,7 +30,6 @@ galera_gcs_fragment : Incorrect arguments to SET
|
||||
galera_flush_local : Fails sporadically
|
||||
galera_binlog_stmt_autoinc : TODO: investigate
|
||||
galera_concurrent_ctas : Test times out, investigate
|
||||
galera_var_innodb_disallow_writes : MDEV-11035
|
||||
MW-286 : TODO: investigate
|
||||
galera_sst_xtrabackup-v2-options : TODO: Fix test case
|
||||
galera_sst_xtrabackup-v2 : MDEV-11208
|
||||
|
||||
@@ -2,20 +2,28 @@ CREATE TABLE rand_table (f1 FLOAT);
|
||||
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY, f2 CHAR(1));
|
||||
INSERT INTO t1 VALUES (1, 'a');
|
||||
INSERT INTO t1 VALUES (2, 'a');
|
||||
connection node_1;
|
||||
SET AUTOCOMMIT=ON;
|
||||
START TRANSACTION;
|
||||
UPDATE t1 SET f2 = 'b' WHERE f1 = 1;
|
||||
SELECT * FROM t1 WHERE f1 = 2 FOR UPDATE;
|
||||
f1 f2
|
||||
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';
|
||||
connection node_1;
|
||||
COMMIT;;
|
||||
connection node_1a;
|
||||
SET SESSION wsrep_sync_wait = 0;
|
||||
SET SESSION wsrep_on = 0;
|
||||
SET SESSION wsrep_on = 1;
|
||||
connection node_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 = 'signal=commit_monitor_enter_sync';
|
||||
connection node_1;
|
||||
SELECT TIMEDIFF(SYSDATE(), NOW()) < 2;
|
||||
TIMEDIFF(SYSDATE(), NOW()) < 2
|
||||
1
|
||||
@@ -26,5 +34,6 @@ COUNT(DISTINCT f1) = 10
|
||||
1
|
||||
wsrep_local_replays
|
||||
1
|
||||
connection node_2;
|
||||
DROP TABLE t1;
|
||||
DROP TABLE rand_table;
|
||||
|
||||
@@ -9,7 +9,7 @@ SET SESSION binlog_format = 'MIXED';
|
||||
Warnings:
|
||||
Warning 1105 MariaDB Galera does not support binlog format: MIXED
|
||||
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
|
||||
mysqld-bin.000001 <Pos> Gtid_list 1 <End_log_pos> []
|
||||
mysqld-bin.000001 <Pos> Binlog_checkpoint 1 <End_log_pos> mysqld-bin.000001
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
connection node_1;
|
||||
connection node_2;
|
||||
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');
|
||||
connection node_2;
|
||||
@@ -52,3 +54,5 @@ COUNT(*) = 0
|
||||
1
|
||||
connection node_1;
|
||||
DROP TABLE t1, t2, t3;
|
||||
disconnect node_2;
|
||||
disconnect node_1;
|
||||
|
||||
@@ -7,7 +7,7 @@ Killing server ...
|
||||
connection node_1;
|
||||
CREATE TABLE t1 (f1 INTEGER) ENGINE=InnoDB;
|
||||
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;
|
||||
disconnect node_2;
|
||||
disconnect node_1;
|
||||
|
||||
@@ -39,6 +39,7 @@ SELECT COUNT(*) = 1 FROM t1 WHERE f2 = 'c';
|
||||
COUNT(*) = 1
|
||||
1
|
||||
DROP TABLE t1;
|
||||
connection node_1;
|
||||
CREATE TABLE t1 (i int primary key, j int) ENGINE=INNODB;
|
||||
INSERT INTO t1 VALUES (1, 0), (3, 0);
|
||||
SELECT * FROM t1;
|
||||
@@ -46,23 +47,32 @@ i j
|
||||
1 0
|
||||
3 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';
|
||||
connection node_1;
|
||||
EXECUTE stmt1;;
|
||||
connection node_1a;
|
||||
SET SESSION wsrep_sync_wait = 0;
|
||||
SET SESSION wsrep_on = 0;
|
||||
SET SESSION wsrep_on = 1;
|
||||
connection node_2;
|
||||
INSERT INTO t1 VALUES(2,2);
|
||||
connection node_1a;
|
||||
connection node_1a;
|
||||
SET GLOBAL wsrep_provider_options = 'dbug=';
|
||||
SET GLOBAL wsrep_provider_options = 'signal=commit_monitor_enter_sync';
|
||||
connection node_1;
|
||||
SELECT * FROM t1;
|
||||
i j
|
||||
1 1
|
||||
2 2
|
||||
3 1
|
||||
connection node_2;
|
||||
SELECT * FROM t1;
|
||||
i j
|
||||
1 1
|
||||
2 2
|
||||
3 1
|
||||
connection node_1;
|
||||
DEALLOCATE PREPARE stmt1;
|
||||
DROP TABLE t1;
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
connection node_1;
|
||||
connection node_2;
|
||||
connection node_1;
|
||||
connection node_2;
|
||||
SET GLOBAL wsrep_cluster_address = 'foo://';
|
||||
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
|
||||
SHOW STATUS LIKE 'wsrep_ready';
|
||||
Variable_name Value
|
||||
@@ -17,16 +17,14 @@ wsrep_local_state 0
|
||||
SHOW STATUS LIKE 'wsrep_local_state_comment';
|
||||
Variable_name Value
|
||||
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';
|
||||
VARIABLE_VALUE = 1
|
||||
1
|
||||
SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status';
|
||||
VARIABLE_VALUE = 'Primary'
|
||||
1
|
||||
connection node_1;
|
||||
connection node_2;
|
||||
SET GLOBAL wsrep_cluster_address = @@wsrep_cluster_address;
|
||||
connection node_1;
|
||||
SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status';
|
||||
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';
|
||||
VARIABLE_VALUE = 2
|
||||
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;
|
||||
SET GLOBAL wsrep_cluster_address = @@wsrep_cluster_address;
|
||||
connection node_1;
|
||||
SELECT VARIABLE_VALUE = 'Primary' FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_status';
|
||||
VARIABLE_VALUE = 'Primary'
|
||||
1
|
||||
SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
|
||||
VARIABLE_VALUE = 2
|
||||
1
|
||||
CALL mtr.add_suppression("Backend not supported: foo");
|
||||
CALL mtr.add_suppression("Failed to initialize backend using 'foo");
|
||||
CALL mtr.add_suppression("Failed to open channel 'my_wsrep_cluster' at 'foo");
|
||||
CALL mtr.add_suppression("gcs connect failed: Socket type not supported");
|
||||
CALL mtr.add_suppression("wsrep::connect\\(\\) failed: 7");
|
||||
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");
|
||||
disconnect node_2;
|
||||
disconnect node_1;
|
||||
|
||||
@@ -94,6 +94,16 @@ connection node_1;
|
||||
COMMIT;
|
||||
DROP TABLE t1;
|
||||
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;
|
||||
SET GLOBAL wsrep_replicate_myisam = 0;
|
||||
connection node_2;
|
||||
|
||||
@@ -20,7 +20,7 @@ INSERT INTO t1 VALUES (2);
|
||||
|
||||
--replace_regex /xid=[0-9]+/xid=###/ /table_id: [0-9]+/table_id: ###/
|
||||
--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;
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
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
|
||||
--sleep 5
|
||||
--source include/wait_until_connected_again.inc
|
||||
|
||||
@@ -6,17 +6,15 @@
|
||||
--source include/have_innodb.inc
|
||||
|
||||
# Save original auto_increment_offset values.
|
||||
--connection node_1
|
||||
let $auto_increment_offset_node_1 = `SELECT @@global.auto_increment_offset`;
|
||||
--connection node_2
|
||||
let $auto_increment_offset_node_2 = `SELECT @@global.auto_increment_offset`;
|
||||
|
||||
--let $node_1=node_1
|
||||
--let $node_2=node_2
|
||||
--source include/auto_increment_offset_save.inc
|
||||
#
|
||||
# Set to invalid value
|
||||
#
|
||||
|
||||
--connection node_1
|
||||
--let $wsrep_cluster_address_node1 = `SELECT @@wsrep_cluster_address`
|
||||
--connection node_2
|
||||
--let $wsrep_cluster_address_node2 = `SELECT @@wsrep_cluster_address`
|
||||
SET GLOBAL wsrep_cluster_address = 'foo://';
|
||||
|
||||
# With wsrep_sync_wait, this returns an error
|
||||
@@ -26,7 +24,7 @@ SET GLOBAL wsrep_cluster_address = 'foo://';
|
||||
SET SESSION wsrep_sync_wait=0;
|
||||
|
||||
--error ER_UNKNOWN_COM_ERROR
|
||||
SELECT * FROM INFORMATION_SCHEMA.GLOBAL_STATUS;
|
||||
SELECT COUNT(*) > 0 FROM INFORMATION_SCHEMA.GLOBAL_STATUS;
|
||||
|
||||
# Must return 'OFF'
|
||||
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_comment';
|
||||
|
||||
--connection node_2
|
||||
--connection node_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 = '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
|
||||
#
|
||||
|
||||
--connection node_1
|
||||
--disable_query_log
|
||||
--eval SET GLOBAL wsrep_cluster_address = '$wsrep_cluster_address_node1';
|
||||
--enable_query_log
|
||||
|
||||
--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
|
||||
|
||||
@@ -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 = 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
|
||||
SET GLOBAL wsrep_cluster_address = @@wsrep_cluster_address;
|
||||
--sleep 1
|
||||
|
||||
--connection node_1
|
||||
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';
|
||||
CALL mtr.add_suppression("Backend not supported: foo");
|
||||
CALL mtr.add_suppression("Failed to initialize backend using 'foo");
|
||||
CALL mtr.add_suppression("Failed to open channel 'my_wsrep_cluster' at 'foo");
|
||||
CALL mtr.add_suppression("gcs connect failed: Socket type not supported");
|
||||
CALL mtr.add_suppression("wsrep::connect\\(\\) failed: 7");
|
||||
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.
|
||||
--disable_query_log
|
||||
--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/auto_increment_offset_restore.inc
|
||||
|
||||
--source include/galera_end.inc
|
||||
|
||||
@@ -132,6 +132,16 @@ COMMIT;
|
||||
DROP TABLE t1;
|
||||
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
|
||||
--eval SET GLOBAL wsrep_replicate_myisam = $wsrep_replicate_myisam_orig
|
||||
|
||||
|
||||
@@ -1,13 +1,23 @@
|
||||
connection node_1;
|
||||
connection node_2;
|
||||
connection node_3;
|
||||
CREATE TABLE t1 (f1 INTEGER PRIMARY KEY);
|
||||
INSERT INTO t1 VALUES (01), (02), (03), (04), (05);
|
||||
connection node_2;
|
||||
Unloading wsrep provider ...
|
||||
SET GLOBAL wsrep_provider = 'none';
|
||||
connection node_3;
|
||||
Unloading wsrep provider ...
|
||||
SET GLOBAL wsrep_provider = 'none';
|
||||
connection node_1;
|
||||
INSERT INTO t1 VALUES (11), (12), (13), (14), (15);
|
||||
INSERT INTO t1 VALUES (21), (22), (23), (24), (25);
|
||||
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);
|
||||
connection node_3;
|
||||
connection node_1;
|
||||
SHOW STATUS LIKE 'wsrep_debug_sync_waiters';
|
||||
Variable_name Value
|
||||
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 = 'signal=ist_sender_send_after_get_buffers';
|
||||
INSERT INTO t1 VALUES (51), (52), (53), (54), (55);
|
||||
connection node_2;
|
||||
connection node_3;
|
||||
connection node_2;
|
||||
SELECT COUNT(*) = 30 FROM t1;
|
||||
COUNT(*) = 30
|
||||
1
|
||||
@@ -31,6 +44,7 @@ LENGTH(f1) = 512 * 1024
|
||||
1
|
||||
1
|
||||
CALL mtr.add_suppression("WSREP: Unsupported protocol downgrade: incremental data collection disabled");
|
||||
connection node_3;
|
||||
SELECT COUNT(*) = 30 FROM t1;
|
||||
COUNT(*) = 30
|
||||
1
|
||||
@@ -44,3 +58,6 @@ LENGTH(f1) = 512 * 1024
|
||||
1
|
||||
CALL mtr.add_suppression("WSREP: Unsupported protocol downgrade: incremental data collection disabled");
|
||||
DROP TABLE t1, t2;
|
||||
disconnect node_3;
|
||||
disconnect node_2;
|
||||
disconnect node_1;
|
||||
|
||||
@@ -17,6 +17,12 @@
|
||||
--let $galera_server_number = 3
|
||||
--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);
|
||||
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");
|
||||
|
||||
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
|
||||
|
||||
@@ -36,8 +36,11 @@ drop table t1;
|
||||
# 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
|
||||
# "MySQL 5.4.4, new MDL: unnecessary and bug #37346 "innodb does not
|
||||
# detect deadlock between update and alter table". But it still works
|
||||
# for LOCK TABLE ... READ.
|
||||
# detect deadlock between update and alter table".
|
||||
# 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;
|
||||
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
|
||||
0 1
|
||||
connection con2;
|
||||
# The below statement should not be blocked as LOCK TABLES ... READ
|
||||
# does not take strong SQL-level lock on t1. SELECTs which do not
|
||||
# conflict with transaction in the first connections should not be
|
||||
# blocked.
|
||||
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;
|
||||
# The following statement should block because SQL-level lock
|
||||
# is taken on t1 which will wait until concurrent transaction
|
||||
# is commited.
|
||||
# Sending:
|
||||
lock table t1 read;;
|
||||
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;
|
||||
connection con2;
|
||||
# Reap LOCK TABLE.
|
||||
unlock tables;
|
||||
connection default;
|
||||
drop table t1;
|
||||
#
|
||||
#Bug#12842206 INNODB LOCKING REGRESSION FOR INSERT IGNORE
|
||||
|
||||
@@ -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;
|
||||
drop table if exists t1,t2,t3,t1m,t1i,t2m,t2i,t4;
|
||||
drop procedure if exists p1;
|
||||
@@ -614,9 +608,6 @@ OPTIMIZE TABLE t2;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t2 optimize note Table does not support optimize, doing recreate + analyze instead
|
||||
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;
|
||||
create table t1(a int) engine=innodb;
|
||||
alter table t1 comment '123';
|
||||
@@ -678,8 +669,11 @@ SET AUTOCOMMIT=0;
|
||||
INSERT INTO t2 VALUES (1);
|
||||
connection c2;
|
||||
SET AUTOCOMMIT=0;
|
||||
SET @old_lock_wait_timeout= @@lock_wait_timeout;
|
||||
SET lock_wait_timeout= 1;
|
||||
LOCK TABLES t1 READ, t2 READ;
|
||||
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
|
||||
SET @@lock_wait_timeout= @old_lock_wait_timeout;
|
||||
connection c1;
|
||||
COMMIT;
|
||||
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;
|
||||
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
|
||||
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;
|
||||
a b c
|
||||
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 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);
|
||||
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;
|
||||
SELECT * FROM t2;
|
||||
a b
|
||||
@@ -2284,7 +2278,7 @@ a b
|
||||
3 13
|
||||
4 14
|
||||
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;
|
||||
SELECT * FROM t4;
|
||||
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+100000,c2+100000,c3+100000 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;
|
||||
c1 c2 c3
|
||||
EXPLAIN SELECT * FROM t1 WHERE c1 = 99999999 AND c3 > 1 ORDER BY c3;
|
||||
|
||||
@@ -60,8 +60,11 @@ drop table t1;
|
||||
--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 # "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 # for LOCK TABLE ... READ.
|
||||
--echo # detect deadlock between update and alter table".
|
||||
--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 #
|
||||
|
||||
set @@innodb_table_locks=0;
|
||||
@@ -104,20 +107,32 @@ connection con1;
|
||||
select * from t1 where id = 0 for update;
|
||||
|
||||
connection con2;
|
||||
--echo # The below statement should not be blocked as LOCK TABLES ... READ
|
||||
--echo # does not take strong SQL-level lock on t1. SELECTs which do not
|
||||
--echo # conflict with transaction in the first connections should not be
|
||||
--echo # blocked.
|
||||
lock table t1 read;
|
||||
select * from t1;
|
||||
select * from t1 where id = 1 lock in share mode;
|
||||
unlock tables;
|
||||
select * from t1;
|
||||
commit;
|
||||
--echo # The following statement should block because SQL-level lock
|
||||
--echo # is taken on t1 which will wait until concurrent transaction
|
||||
--echo # is commited.
|
||||
--echo # Sending:
|
||||
--send lock table t1 read;
|
||||
|
||||
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;
|
||||
|
||||
connection con2;
|
||||
--echo # Reap LOCK TABLE.
|
||||
--reap
|
||||
unlock tables;
|
||||
|
||||
connection default;
|
||||
|
||||
drop table t1;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
||||
@@ -13,10 +13,8 @@
|
||||
-- source include/have_innodb.inc
|
||||
let $engine_type= InnoDB;
|
||||
let $other_engine_type= MEMORY;
|
||||
# InnoDB does support FOREIGN KEYFOREIGN KEYs
|
||||
# InnoDB does support FOREIGN KEYs
|
||||
let $test_foreign_keys= 1;
|
||||
set global innodb_support_xa=default;
|
||||
set session innodb_support_xa=default;
|
||||
--source include/mix1.inc
|
||||
|
||||
--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 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;
|
||||
--sorted_result
|
||||
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;
|
||||
--sorted_result
|
||||
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+100000,c2+100000,c3+100000 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
|
||||
SELECT * FROM t1 WHERE c1 = 99999999 AND c3 > 1 ORDER BY c3;
|
||||
|
||||
|
||||
@@ -128,7 +128,7 @@ show create table t3;
|
||||
Table t3
|
||||
Create Table CREATE TABLE `t3` (
|
||||
`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,
|
||||
`uuidf` longblob DEFAULT NULL,
|
||||
`fkid` mediumint(9) DEFAULT NULL,
|
||||
|
||||
@@ -114,7 +114,7 @@ show create table test.byrange_tbl;
|
||||
Table byrange_tbl
|
||||
Create Table CREATE TABLE `byrange_tbl` (
|
||||
`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,
|
||||
`uuidf` longblob DEFAULT NULL,
|
||||
`fkid` mediumint(9) DEFAULT NULL,
|
||||
|
||||
@@ -410,7 +410,6 @@ LOCK TABLES t11 WRITE;
|
||||
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');
|
||||
SET SESSION BINLOG_FORMAT=STATEMENT;
|
||||
ERROR HY000: Cannot modify @@session.binlog_format inside a transaction
|
||||
INSERT INTO t11 VALUES('Careful With That Axe, Eugene');
|
||||
UNLOCK TABLES;
|
||||
SELECT * FROM t11;
|
||||
|
||||
@@ -524,7 +524,6 @@ CREATE TABLE t11 (song VARCHAR(255));
|
||||
LOCK TABLES t11 WRITE;
|
||||
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');
|
||||
--error ER_INSIDE_TRANSACTION_PREVENTS_SWITCH_BINLOG_FORMAT
|
||||
SET SESSION BINLOG_FORMAT=STATEMENT;
|
||||
INSERT INTO t11 VALUES('Careful With That Axe, Eugene');
|
||||
UNLOCK TABLES;
|
||||
|
||||
@@ -7,5 +7,5 @@ SELECT @@wsrep_on;
|
||||
0
|
||||
SELECT @@GLOBAL.wsrep_provider;
|
||||
@@GLOBAL.wsrep_provider
|
||||
/usr/lib/galera/libgalera_smm.so
|
||||
libgalera_smm.so
|
||||
SET @@GLOBAL.wsrep_cluster_address='gcomm://';
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
--echo #
|
||||
|
||||
SELECT @@wsrep_on;
|
||||
--replace_result /usr/lib64/ /usr/lib/
|
||||
--replace_regex /.*libgalera_smm.so/libgalera_smm.so/
|
||||
SELECT @@GLOBAL.wsrep_provider;
|
||||
SET @@GLOBAL.wsrep_cluster_address='gcomm://';
|
||||
|
||||
|
||||
@@ -381,21 +381,40 @@ DROP TABLE IF EXISTS t1;
|
||||
--enable_warnings
|
||||
#
|
||||
# Test.
|
||||
CREATE TABLE t1 (c1 INT);
|
||||
LOCK TABLE t1 READ;
|
||||
connect (con1,localhost,root,,);
|
||||
# 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);
|
||||
CREATE TABLE t1 (c1 INT) ENGINE=MyISAM;
|
||||
INSERT INTO t1 VALUES (1);
|
||||
SELECT GET_LOCK('mysqltest_lock', 100);
|
||||
|
||||
connect (con1,localhost,root,,);
|
||||
--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;
|
||||
# Wait until INSERT waits for lock.
|
||||
SET DEBUG_SYNC= 'now WAIT_FOR locked';
|
||||
# let INSERT continue.
|
||||
UNLOCK TABLES;
|
||||
connection con1;
|
||||
--echo retrieve INSERT result.
|
||||
reap;
|
||||
disconnect con1;
|
||||
# let UPDATE continue.
|
||||
SELECT RELEASE_LOCK('mysqltest_lock');
|
||||
connection con1;
|
||||
--echo # Reaping UPDATE
|
||||
reap;
|
||||
SELECT RELEASE_LOCK('mysqltest_lock');
|
||||
|
||||
connection con2;
|
||||
--echo retrieve INSERT result.
|
||||
reap;
|
||||
disconnect con1;
|
||||
disconnect con2;
|
||||
connection default;
|
||||
DROP TABLE t1;
|
||||
|
||||
|
||||
@@ -1273,3 +1273,49 @@ SELECT * FROM ( SELECT DISTINCT * FROM t1 ) AS sq
|
||||
WHERE i IN ( SELECT MIN(j) FROM 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;
|
||||
|
||||
@@ -128,4 +128,6 @@ create or replace view v1 as select 30 + (20010101 + interval 2 day) as x;
|
||||
show create view v1;
|
||||
select 30 + (20010101 + interval 2 day), x from v1;
|
||||
|
||||
drop view v1;
|
||||
|
||||
--echo End of 10.2 tests
|
||||
|
||||
@@ -77,6 +77,7 @@ select json_extract(json_object('foo', 'foobar'),'$');
|
||||
select json_extract('[10, 20, [30, 40]]', '$[2][*]');
|
||||
select json_extract('[10, 20, [{"a":3}, 30, 40]]', '$[2][*]');
|
||||
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]}', '$.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('a','b');
|
||||
select json_merge('{"a":"b"}','{"c":"d"}');
|
||||
SELECT JSON_MERGE('[1, 2]', '{"id": 47}');
|
||||
|
||||
select json_type('{"k1":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('[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);
|
||||
show create table json;
|
||||
|
||||
@@ -64,6 +64,7 @@ set @@autocommit=1;
|
||||
connection default;
|
||||
|
||||
disconnect con1;
|
||||
disconnect con2;
|
||||
disconnect con3;
|
||||
|
||||
|
||||
@@ -116,54 +117,6 @@ connection default;
|
||||
disconnect con37346;
|
||||
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 # Bug#53798 OPTIMIZE TABLE breaks repeatable read
|
||||
--echo #
|
||||
|
||||
@@ -156,41 +156,5 @@ connection default;
|
||||
|
||||
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 global sql_mode=default;
|
||||
|
||||
@@ -998,6 +998,102 @@ DROP TABLE t1;
|
||||
disconnect con1;
|
||||
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
|
||||
# gone so execution of other tests won't be affected by their presence.
|
||||
--source include/wait_until_count_sessions.inc
|
||||
|
||||
@@ -23,13 +23,13 @@ SET GLOBAL LOG_OUTPUT = 'FILE';
|
||||
|
||||
connect (con1,localhost,root,,);
|
||||
connect (con2,localhost,root,,);
|
||||
connection default;
|
||||
|
||||
flush status;
|
||||
|
||||
show status like 'Table_lock%';
|
||||
select * from information_schema.session_status where variable_name like 'Table_lock%';
|
||||
|
||||
connection con1;
|
||||
set sql_log_bin=0;
|
||||
set @old_general_log = @@global.general_log;
|
||||
set global general_log = 'OFF';
|
||||
@@ -39,35 +39,46 @@ drop table if exists t1;
|
||||
|
||||
create table t1(n int) engine=myisam;
|
||||
insert into t1 values(1);
|
||||
# Execute dummy select in order to ensure that tables used in the
|
||||
# previous statement are unlocked and closed.
|
||||
select 1;
|
||||
select get_lock('mysqltest_lock', 100);
|
||||
|
||||
connection con2;
|
||||
lock tables t1 read;
|
||||
unlock tables;
|
||||
lock tables t1 read;
|
||||
--echo # Sending:
|
||||
--send update t1 set n = get_lock('mysqltest_lock', 100)
|
||||
|
||||
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()`;
|
||||
--echo # Sending:
|
||||
--send update t1 set n = 3
|
||||
|
||||
connection con2;
|
||||
# wait for the other query to start executing
|
||||
connection default;
|
||||
--echo # wait for the second UPDATE to get blocked
|
||||
let $wait_condition= select 1 from INFORMATION_SCHEMA.PROCESSLIST
|
||||
where ID = $ID and STATE = "Waiting for table level lock";
|
||||
--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;
|
||||
--echo # Reaping second UPDATE
|
||||
reap;
|
||||
show status like 'Table_locks_waited';
|
||||
|
||||
connection default;
|
||||
drop table t1;
|
||||
set global general_log = @old_general_log;
|
||||
|
||||
disconnect con2;
|
||||
disconnect con1;
|
||||
connection default;
|
||||
|
||||
# End of 4.1 tests
|
||||
|
||||
|
||||
@@ -4636,7 +4636,6 @@ DROP TABLE t1, t2;
|
||||
--echo #
|
||||
|
||||
--disable_warnings
|
||||
DROP TABLE IF EXISTS t1;
|
||||
DROP VIEW IF EXISTS v1;
|
||||
DROP PROCEDURE IF EXISTS p1;
|
||||
--enable_warnings
|
||||
@@ -4647,25 +4646,27 @@ connect (con3, localhost, root);
|
||||
connection default;
|
||||
|
||||
CREATE VIEW v1 AS SELECT schema_name FROM information_schema.schemata;
|
||||
CREATE TABLE t1 (str VARCHAR(50));
|
||||
CREATE PROCEDURE p1() INSERT INTO t1 SELECT * FROM v1;
|
||||
CREATE PROCEDURE p1() SELECT COUNT(*), GET_LOCK('blocker', 100) FROM v1;
|
||||
|
||||
--echo # CALL p1() so the view is merged.
|
||||
--disable_result_log
|
||||
CALL p1();
|
||||
--enable_result_log
|
||||
SELECT RELEASE_LOCK('blocker');
|
||||
|
||||
connection con3;
|
||||
LOCK TABLE t1 READ;
|
||||
SELECT GET_LOCK('blocker', 100);
|
||||
|
||||
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:
|
||||
--send CALL p1()
|
||||
|
||||
connection con2;
|
||||
let $wait_condition=
|
||||
SELECT COUNT(*) = 1 from information_schema.processlist
|
||||
WHERE state = "Waiting for table level lock" AND
|
||||
info = "INSERT INTO t1 SELECT * FROM v1";
|
||||
WHERE state = "User lock" AND
|
||||
info = "SELECT COUNT(*), GET_LOCK('blocker', 100) FROM v1";
|
||||
--source include/wait_condition.inc
|
||||
--echo # ... then try to drop the view. This should block.
|
||||
--echo # Sending:
|
||||
@@ -4677,11 +4678,14 @@ let $wait_condition=
|
||||
WHERE state = "Waiting for table metadata lock" AND info = "DROP VIEW v1";
|
||||
--source include/wait_condition.inc
|
||||
--echo # Now allow CALL p1() to complete
|
||||
UNLOCK TABLES;
|
||||
SELECT RELEASE_LOCK('blocker');
|
||||
|
||||
connection default;
|
||||
--echo # Reaping: CALL p1()
|
||||
--disable_result_log
|
||||
--reap
|
||||
--enable_result_log
|
||||
SELECT RELEASE_LOCK('blocker');
|
||||
|
||||
connection con2;
|
||||
--echo # Reaping: DROP VIEW v1
|
||||
@@ -4689,7 +4693,6 @@ connection con2;
|
||||
|
||||
connection default;
|
||||
DROP PROCEDURE p1;
|
||||
DROP TABLE t1;
|
||||
disconnect con2;
|
||||
disconnect con3;
|
||||
|
||||
|
||||
@@ -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_WRITE") },
|
||||
{ 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_READ_WRITE") },
|
||||
{ C_STRING_WITH_LEN("MDL_EXCLUSIVE") },
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
connection node_1;
|
||||
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
|
||||
<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;
|
||||
INDEX UUID NAME ADDRESS
|
||||
<IDX> <MEMBER_ID> test-node-1 <ADDRESS>
|
||||
@@ -11,7 +11,7 @@ INDEX UUID NAME ADDRESS
|
||||
connection node_2;
|
||||
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
|
||||
<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;
|
||||
INDEX UUID NAME ADDRESS
|
||||
<IDX> <MEMBER_ID> test-node-1 <ADDRESS>
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
--echo # On 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;
|
||||
|
||||
--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
|
||||
--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;
|
||||
|
||||
--replace_column 1 <IDX> 2 <MEMBER_ID> 4 <ADDRESS>
|
||||
|
||||
19
sql/item.cc
19
sql/item.cc
@@ -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 *new_item;
|
||||
my_decimal decimal_value;
|
||||
my_decimal *result= val_decimal(&decimal_value);
|
||||
DBUG_ASSERT(value_cached || example != 0);
|
||||
new_item= null_value ?
|
||||
(Item*) new (thd->mem_root) Item_null(thd) :
|
||||
(Item*) new (thd->mem_root) Item_decimal(thd, result);
|
||||
if (null_value)
|
||||
new_item= (Item*) new (thd->mem_root) Item_null(thd);
|
||||
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;
|
||||
}
|
||||
|
||||
@@ -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 *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);
|
||||
if (null_value)
|
||||
new_item= (Item*) new (thd->mem_root) Item_null(thd);
|
||||
else
|
||||
{
|
||||
char buff[MAX_FIELD_WIDTH];
|
||||
String tmp(buff, sizeof(buff), value->charset());
|
||||
String *result= val_str(&tmp);
|
||||
uint length= result->length();
|
||||
char *tmp_str= thd->strmake(result->ptr(), length);
|
||||
new_item= new (thd->mem_root) Item_string(thd, tmp_str, length,
|
||||
|
||||
@@ -1087,6 +1087,11 @@ class Item_func_nullif :public Item_func_hybrid_field_type
|
||||
*/
|
||||
Item_cache *m_cache;
|
||||
int compare();
|
||||
void reset_first_arg_if_needed()
|
||||
{
|
||||
if (arg_count == 3 && args[0] != args[2])
|
||||
args[0]= args[2];
|
||||
}
|
||||
public:
|
||||
/*
|
||||
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)
|
||||
{ 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; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
@@ -1522,12 +1522,10 @@ String *Item_func_json_merge::val_str(String *str)
|
||||
goto error_return;
|
||||
|
||||
str->length(0);
|
||||
if ((je1.value_type == JSON_VALUE_ARRAY &&
|
||||
je2.value_type == JSON_VALUE_ARRAY) ||
|
||||
(je1.value_type == JSON_VALUE_OBJECT &&
|
||||
je2.value_type == JSON_VALUE_OBJECT))
|
||||
if (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))
|
||||
goto error_return;
|
||||
if (str->append(js1->ptr(),
|
||||
@@ -1539,11 +1537,35 @@ String *Item_func_json_merge::val_str(String *str)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Wrap as an array. */
|
||||
if (str->append("[", 1) ||
|
||||
str->append(js1->ptr(), js1->length()) ||
|
||||
str->append(", ", 2) ||
|
||||
str->append(js2->ptr(), js2->length()) ||
|
||||
const char *end1, *beg2;
|
||||
|
||||
/* Merge as a single array. */
|
||||
if (je1.value_type == JSON_VALUE_ARRAY)
|
||||
{
|
||||
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))
|
||||
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()
|
||||
{
|
||||
String *js= args[0]->val_str(&tmp_js);
|
||||
json_engine_t je;
|
||||
uint length= 0;
|
||||
uint array_counters[JSON_DEPTH_LIMIT];
|
||||
|
||||
if ((null_value= args[0]->null_value))
|
||||
return 0;
|
||||
|
||||
|
||||
json_scan_start(&je, js->charset(),(const uchar *) js->ptr(),
|
||||
(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++;
|
||||
} 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)
|
||||
return length - 1;
|
||||
return length;
|
||||
|
||||
err_return:
|
||||
report_json_error(js, &je, 0);
|
||||
null_return:
|
||||
null_value= 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -67,8 +67,8 @@ protected:
|
||||
String tmp_js, tmp_path;
|
||||
|
||||
public:
|
||||
Item_func_json_exists(THD *thd, Item *js, Item *path):
|
||||
Item_int_func(thd, js, path) {}
|
||||
Item_func_json_exists(THD *thd, Item *js, Item *i_path):
|
||||
Item_int_func(thd, js, i_path) {}
|
||||
const char *func_name() const { return "json_exists"; }
|
||||
bool is_bool_type() { return true; }
|
||||
void fix_length_and_dec();
|
||||
@@ -85,8 +85,8 @@ protected:
|
||||
String tmp_js, tmp_path;
|
||||
|
||||
public:
|
||||
Item_func_json_value(THD *thd, Item *js, Item *path):
|
||||
Item_str_func(thd, js, path) {}
|
||||
Item_func_json_value(THD *thd, Item *js, Item *i_path):
|
||||
Item_str_func(thd, js, i_path) {}
|
||||
const char *func_name() const { return "json_value"; }
|
||||
void fix_length_and_dec();
|
||||
String *val_str(String *);
|
||||
@@ -99,8 +99,8 @@ public:
|
||||
class Item_func_json_query: public Item_func_json_value
|
||||
{
|
||||
public:
|
||||
Item_func_json_query(THD *thd, Item *js, Item *path):
|
||||
Item_func_json_value(thd, js, path) {}
|
||||
Item_func_json_query(THD *thd, Item *js, Item *i_path):
|
||||
Item_func_json_value(thd, js, i_path) {}
|
||||
const char *func_name() const { return "json_query"; }
|
||||
bool check_and_get_value(json_engine_t *je, String *res, int *error);
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
@@ -291,12 +291,14 @@ public:
|
||||
class Item_func_json_length: public Item_int_func
|
||||
{
|
||||
protected:
|
||||
json_path_with_flags path;
|
||||
String tmp_js;
|
||||
String tmp_path;
|
||||
public:
|
||||
Item_func_json_length(THD *thd, List<Item> &list):
|
||||
Item_int_func(thd, list) {}
|
||||
const char *func_name() const { return "json_length"; }
|
||||
void fix_length_and_dec();
|
||||
longlong val_int();
|
||||
Item *get_copy(THD *thd, MEM_ROOT *mem_root)
|
||||
{ return get_item_copy<Item_func_json_length>(thd, mem_root, this); }
|
||||
|
||||
@@ -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
|
||||
type. For table to be locked for read we must own metadata lock
|
||||
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 ||
|
||||
thd->mdl_context.is_lock_owner(MDL_key::TABLE,
|
||||
t->s->db.str, t->s->table_name.str,
|
||||
t->reginfo.lock_type >= TL_WRITE_ALLOW_WRITE ?
|
||||
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)));
|
||||
MDL_SHARED_WRITE : MDL_SHARED_READ));
|
||||
|
||||
/*
|
||||
Prevent modifications to base tables if READ_ONLY is activated.
|
||||
|
||||
92
sql/mdl.cc
92
sql/mdl.cc
@@ -391,7 +391,11 @@ public:
|
||||
virtual const bitmap_t *incompatible_waiting_types_bitmap() const
|
||||
{ return m_waiting_incompatible; }
|
||||
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
|
||||
@@ -1413,7 +1417,8 @@ const MDL_lock::bitmap_t
|
||||
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_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)
|
||||
};
|
||||
|
||||
@@ -1421,7 +1426,7 @@ const MDL_lock::bitmap_t
|
||||
MDL_lock::MDL_scoped_lock::m_waiting_incompatible[MDL_TYPE_END]=
|
||||
{
|
||||
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
|
||||
if there is granted lock of certain type.
|
||||
|
||||
Request | Granted requests for lock |
|
||||
type | S SH SR SW SU SNW SNRW X |
|
||||
----------+----------------------------------+
|
||||
S | + + + + + + + - |
|
||||
SH | + + + + + + + - |
|
||||
SR | + + + + + + - - |
|
||||
SW | + + + + + - - - |
|
||||
SU | + + + + - - - - |
|
||||
SNW | + + + - - - - - |
|
||||
SNRW | + + - - - - - - |
|
||||
X | - - - - - - - - |
|
||||
SU -> X | - - - - 0 0 0 0 |
|
||||
SNW -> X | - - - 0 0 0 0 0 |
|
||||
SNRW -> X | - - 0 0 0 0 0 0 |
|
||||
Request | Granted requests for lock |
|
||||
type | S SH SR SW SU SRO SNW SNRW X |
|
||||
----------+---------------------------------------+
|
||||
S | + + + + + + + + - |
|
||||
SH | + + + + + + + + - |
|
||||
SR | + + + + + + + - - |
|
||||
SW | + + + + + - - - - |
|
||||
SU | + + + + - + - - - |
|
||||
SRO | + + + - + + + - - |
|
||||
SNW | + + + - - + - - - |
|
||||
SNRW | + + - - - - - - - |
|
||||
X | - - - - - - - - - |
|
||||
SU -> X | - - - - 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
|
||||
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.
|
||||
|
||||
Request | Pending requests for lock |
|
||||
type | S SH SR SW SU SNW SNRW X |
|
||||
----------+---------------------------------+
|
||||
S | + + + + + + + - |
|
||||
SH | + + + + + + + + |
|
||||
SR | + + + + + + - - |
|
||||
SW | + + + + + - - - |
|
||||
SU | + + + + + + + - |
|
||||
SNW | + + + + + + + - |
|
||||
SNRW | + + + + + + + - |
|
||||
X | + + + + + + + + |
|
||||
SU -> X | + + + + + + + + |
|
||||
SNW -> X | + + + + + + + + |
|
||||
SNRW -> X | + + + + + + + + |
|
||||
Request | Pending requests for lock |
|
||||
type | S SH SR SW SU SRO SNW SNRW X |
|
||||
----------+--------------------------------------+
|
||||
S | + + + + + + + + - |
|
||||
SH | + + + + + + + + + |
|
||||
SR | + + + + + + + - - |
|
||||
SW | + + + + + + - - - |
|
||||
SU | + + + + + + + + - |
|
||||
SRO | + + + - + + + - - |
|
||||
SNW | + + + + + + + + - |
|
||||
SNRW | + + + + + + + + - |
|
||||
X | + + + + + + + + + |
|
||||
SU -> X | + + + + + + + + + |
|
||||
SNW -> X | + + + + + + + + + |
|
||||
SNRW -> X | + + + + + + + + + |
|
||||
|
||||
Here: "+" -- means that request can be satisfied
|
||||
"-" -- 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_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_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_SHARED_NO_WRITE) | MDL_BIT(MDL_SHARED_UPGRADABLE) |
|
||||
MDL_BIT(MDL_SHARED_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_WRITE) | MDL_BIT(MDL_SHARED_READ),
|
||||
MDL_BIT(MDL_SHARED_NO_WRITE) | MDL_BIT(MDL_SHARED_READ_ONLY) |
|
||||
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_SHARED_NO_WRITE) | MDL_BIT(MDL_SHARED_UPGRADABLE) |
|
||||
MDL_BIT(MDL_SHARED_WRITE) | MDL_BIT(MDL_SHARED_READ) |
|
||||
MDL_BIT(MDL_SHARED_HIGH_PRIO) | MDL_BIT(MDL_SHARED)
|
||||
MDL_BIT(MDL_SHARED_NO_WRITE) | MDL_BIT(MDL_SHARED_READ_ONLY) |
|
||||
MDL_BIT(MDL_SHARED_UPGRADABLE) | MDL_BIT(MDL_SHARED_WRITE) |
|
||||
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_SHARED_NO_WRITE),
|
||||
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),
|
||||
0
|
||||
@@ -2306,10 +2319,11 @@ MDL_context::upgrade_shared_lock(MDL_ticket *mdl_ticket,
|
||||
if (mdl_ticket->has_stronger_or_equal_type(new_type))
|
||||
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 ||
|
||||
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_TRANSACTION);
|
||||
|
||||
19
sql/mdl.h
19
sql/mdl.h
@@ -195,6 +195,12 @@ enum enum_mdl_type {
|
||||
To be used for the first phase of ALTER TABLE.
|
||||
*/
|
||||
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
|
||||
table data, allowing reads.
|
||||
@@ -467,6 +473,19 @@ public:
|
||||
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
|
||||
compiler-generated assignment operator. It is currently used
|
||||
|
||||
@@ -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
|
||||
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 &&
|
||||
!(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
|
||||
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 |
|
||||
MYSQL_OPEN_FORCE_SHARED_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.
|
||||
*/
|
||||
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)
|
||||
{
|
||||
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_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;
|
||||
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 ||
|
||||
table->open_type == OT_TEMPORARY_ONLY ||
|
||||
(table->open_type == OT_TEMPORARY_OR_BASE && is_temporary_table(table)))
|
||||
@@ -4063,13 +4064,22 @@ restart:
|
||||
}
|
||||
}
|
||||
|
||||
if (WSREP_ON &&
|
||||
wsrep_replicate_myisam &&
|
||||
(*start) &&
|
||||
(*start)->table &&
|
||||
(*start)->table->file->ht == myisam_hton &&
|
||||
sqlcom_can_generate_row_events(thd) &&
|
||||
thd->get_command() != COM_STMT_PREPARE)
|
||||
if (WSREP_ON &&
|
||||
wsrep_replicate_myisam &&
|
||||
(*start) &&
|
||||
(*start)->table &&
|
||||
(*start)->table->file->ht == myisam_hton &&
|
||||
wsrep_thd_exec_mode(thd) == LOCAL_STATE &&
|
||||
!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));
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -731,7 +681,7 @@ bool mysql_ha_read(THD *thd, TABLE_LIST *tables,
|
||||
int error, keyno;
|
||||
uint num_rows;
|
||||
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_PRINT("enter",("'%s'.'%s' as '%s'",
|
||||
tables->db, tables->table_name, tables->alias));
|
||||
|
||||
@@ -2728,27 +2728,76 @@ bool sp_process_definer(THD *thd)
|
||||
static bool lock_tables_open_and_lock_tables(THD *thd, TABLE_LIST *tables)
|
||||
{
|
||||
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;
|
||||
TABLE_LIST *table;
|
||||
|
||||
thd->in_lock_tables= 1;
|
||||
|
||||
retry:
|
||||
|
||||
if (open_tables(thd, &tables, &counter, 0, &lock_tables_prelocking_strategy))
|
||||
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)
|
||||
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) ||
|
||||
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_PROFILE:
|
||||
{
|
||||
#ifdef WITH_WSREP
|
||||
DBUG_ASSERT(thd->wsrep_exec_mode != REPL_RECV);
|
||||
#endif /* WITH_WSREP */
|
||||
|
||||
thd->status_var.last_query_cost= 0.0;
|
||||
|
||||
/*
|
||||
@@ -4785,8 +4838,7 @@ end_with_restore_list:
|
||||
if (lock_tables_precheck(thd, all_tables))
|
||||
goto error;
|
||||
|
||||
thd->variables.option_bits|= OPTION_TABLE_LOCK | OPTION_NOT_AUTOCOMMIT;
|
||||
thd->server_status&= ~SERVER_STATUS_AUTOCOMMIT;
|
||||
thd->variables.option_bits|= OPTION_TABLE_LOCK;
|
||||
|
||||
res= lock_tables_open_and_lock_tables(thd, all_tables);
|
||||
|
||||
|
||||
@@ -3849,3 +3849,21 @@ double Histogram::point_selectivity(double pos, double avg_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;
|
||||
}
|
||||
|
||||
|
||||
@@ -107,6 +107,7 @@ double get_column_range_cardinality(Field *field,
|
||||
key_range *min_endp,
|
||||
key_range *max_endp,
|
||||
uint range_flag);
|
||||
bool is_stat_table(const char *db, const char *table);
|
||||
|
||||
class Histogram
|
||||
{
|
||||
|
||||
@@ -1097,7 +1097,7 @@ btr_free_root_check(
|
||||
index_id_t index_id,
|
||||
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);
|
||||
|
||||
buf_block_t* block = buf_page_get(
|
||||
|
||||
@@ -6092,7 +6092,7 @@ corrupt:
|
||||
#endif /* MYSQL_COMPRESSION */
|
||||
&& !recv_no_ibuf_operations
|
||||
&& !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())
|
||||
&& fil_page_get_type(frame) == FIL_PAGE_INDEX
|
||||
&& page_is_leaf(frame)) {
|
||||
|
||||
@@ -571,8 +571,7 @@ dict_build_tablespace_for_table(
|
||||
supports Redundant and Compact */
|
||||
ut_ad(dict_tf_get_rec_format(table->flags)
|
||||
!= REC_FORMAT_COMPRESSED);
|
||||
table->space = static_cast<uint32_t>(
|
||||
srv_tmp_space.space_id());
|
||||
table->space = SRV_TMP_SPACE_ID;
|
||||
} else {
|
||||
/* Create in the system tablespace. */
|
||||
ut_ad(table->space == srv_sys_space.space_id());
|
||||
|
||||
@@ -1701,6 +1701,7 @@ struct dict_foreign_remove_partial
|
||||
if (table != NULL) {
|
||||
table->referenced_set.erase(foreign);
|
||||
}
|
||||
dict_foreign_free(foreign);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -3759,7 +3760,6 @@ dict_foreign_add_to_cache(
|
||||
}
|
||||
|
||||
if (for_in_cache) {
|
||||
/* Free the foreign object */
|
||||
dict_foreign_free(foreign);
|
||||
} else {
|
||||
for_in_cache = foreign;
|
||||
@@ -3789,10 +3789,9 @@ dict_foreign_add_to_cache(
|
||||
"referenced table do not match"
|
||||
" the ones in table.");
|
||||
|
||||
if (for_in_cache == foreign) {
|
||||
mem_heap_free(foreign->heap);
|
||||
}
|
||||
|
||||
if (for_in_cache == foreign) {
|
||||
dict_foreign_free(foreign);
|
||||
}
|
||||
|
||||
DBUG_RETURN(DB_CANNOT_ADD_CONSTRAINT);
|
||||
}
|
||||
@@ -3846,7 +3845,8 @@ dict_foreign_add_to_cache(
|
||||
elements removed must
|
||||
be one */
|
||||
}
|
||||
mem_heap_free(foreign->heap);
|
||||
|
||||
dict_foreign_free(foreign);
|
||||
}
|
||||
|
||||
DBUG_RETURN(DB_CANNOT_ADD_CONSTRAINT);
|
||||
|
||||
@@ -493,7 +493,7 @@ err_len:
|
||||
}
|
||||
|
||||
/* 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
|
||||
is not assigned. */
|
||||
foreign->id = mem_heap_strdupl(heap, (const char*) field, len);
|
||||
|
||||
@@ -138,6 +138,8 @@ fil_space_crypt_cleanup()
|
||||
/*=====================*/
|
||||
{
|
||||
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
|
||||
avoid the race between drop table and crypt thread */
|
||||
mutex_enter(&fil_crypt_threads_mutex);
|
||||
mutex_enter(&(*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));
|
||||
mutex_free(&(*crypt_data)->mutex);
|
||||
free(*crypt_data);
|
||||
(*crypt_data) = NULL;
|
||||
*/
|
||||
*crypt_data = NULL;
|
||||
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_threads_event);
|
||||
mutex_free(&fil_crypt_threads_mutex);
|
||||
fil_crypt_threads_inited = false;
|
||||
}
|
||||
|
||||
|
||||
@@ -185,7 +185,7 @@ fil_is_user_tablespace_id(
|
||||
ulint space_id)
|
||||
{
|
||||
return(space_id > srv_undo_tablespaces_open
|
||||
&& space_id != srv_tmp_space.space_id());
|
||||
&& space_id != SRV_TMP_SPACE_ID);
|
||||
}
|
||||
|
||||
#ifdef UNIV_DEBUG
|
||||
@@ -1199,6 +1199,7 @@ fil_space_free_low(
|
||||
ut_ad(space->size == 0);
|
||||
|
||||
rw_lock_free(&space->latch);
|
||||
fil_space_destroy_crypt_data(&space->crypt_data);
|
||||
|
||||
ut_free(space->name);
|
||||
ut_free(space);
|
||||
@@ -1313,7 +1314,7 @@ fil_space_create(
|
||||
|
||||
/* This warning is not applicable while MEB scanning the redo logs */
|
||||
#ifndef UNIV_HOTBACKUP
|
||||
if (fil_type_is_data(purpose)
|
||||
if ((purpose == FIL_TYPE_TABLESPACE || purpose == FIL_TYPE_IMPORT)
|
||||
&& !recv_recovery_on
|
||||
&& id > fil_system->max_assigned_id) {
|
||||
|
||||
@@ -5104,10 +5105,13 @@ retry:
|
||||
ulint pages_per_mb = (1024 * 1024) / page_size;
|
||||
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);
|
||||
} 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);
|
||||
break;
|
||||
}
|
||||
#else
|
||||
ib::trace() << "extended space : " << space->name << " from "
|
||||
@@ -6223,6 +6227,8 @@ fil_close(void)
|
||||
|
||||
ut_free(fil_system);
|
||||
fil_system = NULL;
|
||||
|
||||
fil_space_crypt_cleanup();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6679,18 +6685,18 @@ fil_tablespace_iterate(
|
||||
iter.io_buffer = static_cast<byte*>(
|
||||
ut_align(io_buffer, UNIV_PAGE_SIZE));
|
||||
|
||||
/** Add an exta buffer for encryption */
|
||||
void* crypt_io_buffer = NULL;
|
||||
if (iter.crypt_data != NULL) {
|
||||
crypt_io_buffer = ut_malloc_nokey(
|
||||
iter.n_io_buffers * UNIV_PAGE_SIZE);
|
||||
iter.crypt_io_buffer = static_cast<byte*>(
|
||||
crypt_io_buffer);
|
||||
}
|
||||
iter.crypt_io_buffer = iter.crypt_data
|
||||
? static_cast<byte*>(
|
||||
ut_malloc_nokey(iter.n_io_buffers
|
||||
* UNIV_PAGE_SIZE))
|
||||
: NULL;
|
||||
|
||||
err = fil_iterate(iter, block, callback);
|
||||
|
||||
ut_free(io_buffer);
|
||||
ut_free(iter.crypt_io_buffer);
|
||||
|
||||
fil_space_destroy_crypt_data(&iter.crypt_data);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -63,22 +63,17 @@ Datafile::shutdown()
|
||||
ut_free(m_name);
|
||||
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();
|
||||
|
||||
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();
|
||||
}
|
||||
|
||||
|
||||
@@ -338,16 +338,6 @@ err_exit:
|
||||
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.
|
||||
@param[in] space_id tablespace ID
|
||||
@return true if checksum is disabled for given space. */
|
||||
@@ -803,8 +793,7 @@ fsp_space_modify_check(
|
||||
#ifdef UNIV_DEBUG
|
||||
{
|
||||
const fil_type_t type = fil_space_get_type(id);
|
||||
ut_a(id == srv_tmp_space.space_id()
|
||||
|| srv_is_tablespace_truncated(id)
|
||||
ut_a(srv_is_tablespace_truncated(id)
|
||||
|| fil_space_is_being_truncated(id)
|
||||
|| fil_space_get_flags(id) == ULINT_UNDEFINED
|
||||
|| type == FIL_TYPE_TEMPORARY
|
||||
@@ -814,10 +803,7 @@ fsp_space_modify_check(
|
||||
#endif /* UNIV_DEBUG */
|
||||
return;
|
||||
case MTR_LOG_ALL:
|
||||
/* We must not write redo log for the shared temporary
|
||||
tablespace. */
|
||||
ut_ad(id != srv_tmp_space.space_id());
|
||||
/* If we write redo log, the tablespace must exist. */
|
||||
/* We may only write redo log for a persistent tablespace. */
|
||||
ut_ad(fil_space_get_type(id) == FIL_TYPE_TABLESPACE);
|
||||
ut_ad(mtr->is_named_space(id));
|
||||
return;
|
||||
@@ -1549,15 +1535,14 @@ fsp_try_extend_data_file(
|
||||
const page_size_t page_size(
|
||||
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();
|
||||
|
||||
} else if (space->id == srv_tmp_space.space_id()) {
|
||||
|
||||
break;
|
||||
case SRV_TMP_SPACE_ID:
|
||||
size_increase = srv_tmp_space.get_increment();
|
||||
|
||||
} else {
|
||||
break;
|
||||
default:
|
||||
ulint extent_pages
|
||||
= fsp_get_extent_size_in_pages(page_size);
|
||||
if (size < extent_pages) {
|
||||
@@ -1679,11 +1664,17 @@ fsp_fill_free_list(
|
||||
const page_size_t page_size(flags);
|
||||
|
||||
if (size < limit + FSP_EXTENT_SIZE * FSP_FREE_ADD) {
|
||||
if ((!init_space && !is_system_tablespace(space->id))
|
||||
|| (space->id == srv_sys_space.space_id()
|
||||
&& srv_sys_space.can_auto_extend_last_file())
|
||||
|| (space->id == srv_tmp_space.space_id()
|
||||
&& srv_tmp_space.can_auto_extend_last_file())) {
|
||||
bool skip_resize = init_space;
|
||||
switch (space->id) {
|
||||
case TRX_SYS_SPACE:
|
||||
skip_resize = !srv_sys_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;
|
||||
fsp_try_extend_data_file(space, header, mtr, &n_pages);
|
||||
size = space->size_in_header;
|
||||
@@ -1733,7 +1724,7 @@ fsp_fill_free_list(
|
||||
order, and we must be able to release its latch.
|
||||
Note: Insert-Buffering is disabled for tables that
|
||||
reside in the temp-tablespace. */
|
||||
if (space->id != srv_tmp_space.space_id()) {
|
||||
if (space->purpose != FIL_TYPE_TEMPORARY) {
|
||||
mtr_t ibuf_mtr;
|
||||
|
||||
mtr_start(&ibuf_mtr);
|
||||
@@ -1741,9 +1732,7 @@ fsp_fill_free_list(
|
||||
|
||||
/* Avoid logging while truncate table
|
||||
fix-up is active. */
|
||||
if (space->purpose == FIL_TYPE_TEMPORARY
|
||||
|| srv_is_tablespace_truncated(
|
||||
space->id)) {
|
||||
if (srv_is_tablespace_truncated(space->id)) {
|
||||
mtr_set_log_mode(
|
||||
&ibuf_mtr, MTR_LOG_NO_REDO);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
front of m_files.
|
||||
Parse the datafile path into a path and a filename with extension 'ibd'.
|
||||
|
||||
@@ -3727,9 +3727,10 @@ ibuf_insert(
|
||||
op, page_id.space(), page_id.page_no()));
|
||||
|
||||
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_ad(!dict_table_is_temporary(index->table));
|
||||
|
||||
no_counter = use <= IBUF_USE_INSERT;
|
||||
|
||||
|
||||
@@ -97,8 +97,6 @@ extern const char general_space_name[];
|
||||
struct trx_t;
|
||||
class page_id_t;
|
||||
class truncate_t;
|
||||
struct fil_node_t;
|
||||
struct fil_space_t;
|
||||
struct btr_create_t;
|
||||
|
||||
/* structure containing encryption specification */
|
||||
|
||||
@@ -219,7 +219,10 @@ public:
|
||||
|
||||
/** Check 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:
|
||||
/**
|
||||
@param[in] filename Name to lookup in the data files.
|
||||
|
||||
@@ -291,11 +291,9 @@ extern SysTablespace srv_tmp_space;
|
||||
@return true if id is a system tablespace, false if not. */
|
||||
UNIV_INLINE
|
||||
bool
|
||||
is_system_tablespace(
|
||||
ulint id)
|
||||
is_system_tablespace(ulint id)
|
||||
{
|
||||
return(id == srv_sys_space.space_id()
|
||||
|| id == srv_tmp_space.space_id());
|
||||
return(id == TRX_SYS_SPACE || id == SRV_TMP_SPACE_ID);
|
||||
}
|
||||
|
||||
/** Check if shared-system or undo tablespace.
|
||||
@@ -305,8 +303,7 @@ bool
|
||||
is_system_or_undo_tablespace(
|
||||
ulint id)
|
||||
{
|
||||
return(id == srv_sys_space.space_id()
|
||||
|| id <= srv_undo_tablespaces_open);
|
||||
return(id <= srv_undo_tablespaces_open);
|
||||
}
|
||||
|
||||
/** Check if predefined shared tablespace.
|
||||
@@ -319,6 +316,6 @@ is_predefined_tablespace(
|
||||
ut_ad(srv_sys_space.space_id() == TRX_SYS_SPACE);
|
||||
ut_ad(TRX_SYS_SPACE == 0);
|
||||
return(id <= srv_undo_tablespaces_open
|
||||
|| id == srv_tmp_space.space_id());
|
||||
|| id == SRV_TMP_SPACE_ID);
|
||||
}
|
||||
#endif /* fsp0sysspace_h */
|
||||
|
||||
@@ -29,6 +29,12 @@ Created May 26, 2009 Vasil Dimov
|
||||
|
||||
#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 "ut0byte.h"
|
||||
|
||||
@@ -196,9 +202,12 @@ fsp_flags_is_valid(
|
||||
/** Check if tablespace is system temporary.
|
||||
@param[in] space_id verify is checksum is enabled for given space.
|
||||
@return true if tablespace is system temporary. */
|
||||
inline
|
||||
bool
|
||||
fsp_is_system_temporary(
|
||||
ulint space_id);
|
||||
fsp_is_system_temporary(ulint space_id)
|
||||
{
|
||||
return(space_id == SRV_TMP_SPACE_ID);
|
||||
}
|
||||
|
||||
/** Check if checksum is disabled for the given space.
|
||||
@param[in] space_id verify is checksum is enabled for given space.
|
||||
|
||||
@@ -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 */
|
||||
@@ -46,9 +46,6 @@ struct dict_table_t;
|
||||
} while (0)
|
||||
#endif /* DBUG_OFF */
|
||||
|
||||
/** Log 'spaces' have id's >= this */
|
||||
#define SRV_LOG_SPACE_FIRST_ID 0xFFFFFFF0UL
|
||||
|
||||
/** If buffer pool is less than the size,
|
||||
only one buffer pool instance is used. */
|
||||
#define BUF_POOL_SIZE_THRESHOLD (1024 * 1024 * 1024)
|
||||
|
||||
@@ -2278,7 +2278,7 @@ truncate_t::fixup_tables_in_non_system_tablespace()
|
||||
"id (" << (*it)->m_space_id << ")";
|
||||
|
||||
/* 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(
|
||||
(*it)->m_space_id,
|
||||
|
||||
@@ -1123,76 +1123,67 @@ srv_start_wait_for_purge_to_start()
|
||||
|
||||
/** Create the temporary file tablespace.
|
||||
@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. */
|
||||
static
|
||||
dberr_t
|
||||
srv_open_tmp_tablespace(
|
||||
bool create_new_db,
|
||||
SysTablespace* tmp_space)
|
||||
srv_open_tmp_tablespace(bool create_new_db)
|
||||
{
|
||||
ulint sum_of_new_sizes;
|
||||
|
||||
/* Will try to remove if there is existing file left-over by last
|
||||
unclean shutdown */
|
||||
tmp_space->set_sanity_check_status(true);
|
||||
tmp_space->delete_files();
|
||||
tmp_space->set_ignore_read_only(true);
|
||||
srv_tmp_space.set_sanity_check_status(true);
|
||||
srv_tmp_space.delete_files();
|
||||
srv_tmp_space.set_ignore_read_only(true);
|
||||
|
||||
ib::info() << "Creating shared tablespace for temporary tables";
|
||||
|
||||
bool create_new_temp_space;
|
||||
ulint temp_space_id = ULINT_UNDEFINED;
|
||||
|
||||
dict_hdr_get_new_id(NULL, NULL, &temp_space_id, NULL, true);
|
||||
|
||||
tmp_space->set_space_id(temp_space_id);
|
||||
srv_tmp_space.set_space_id(SRV_TMP_SPACE_ID);
|
||||
|
||||
RECOVERY_CRASH(100);
|
||||
|
||||
dberr_t err = tmp_space->check_file_spec(
|
||||
&create_new_temp_space, 12 * 1024 * 1024);
|
||||
dberr_t err = srv_tmp_space.check_file_spec(
|
||||
&create_new_temp_space, 12 * 1024 * 1024);
|
||||
|
||||
if (err == DB_FAIL) {
|
||||
|
||||
ib::error() << "The " << tmp_space->name()
|
||||
ib::error() << "The " << srv_tmp_space.name()
|
||||
<< " data file must be writable!";
|
||||
|
||||
err = DB_ERROR;
|
||||
|
||||
} else if (err != DB_SUCCESS) {
|
||||
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))
|
||||
!= DB_SUCCESS) {
|
||||
|
||||
ib::error() << "Unable to create the shared "
|
||||
<< tmp_space->name();
|
||||
<< srv_tmp_space.name();
|
||||
|
||||
} else {
|
||||
|
||||
mtr_t mtr;
|
||||
ulint size = tmp_space->get_sum_of_sizes();
|
||||
|
||||
ut_a(temp_space_id != ULINT_UNDEFINED);
|
||||
ut_a(tmp_space->space_id() == temp_space_id);
|
||||
ulint size = srv_tmp_space.get_sum_of_sizes();
|
||||
|
||||
/* Open this shared temp tablespace in the fil_system so that
|
||||
it stays open until shutdown. */
|
||||
if (fil_space_open(tmp_space->name())) {
|
||||
if (fil_space_open(srv_tmp_space.name())) {
|
||||
|
||||
/* Initialize the header page */
|
||||
mtr_start(&mtr);
|
||||
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);
|
||||
} else {
|
||||
/* 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"
|
||||
" after check_file_spec() succeeded!";
|
||||
|
||||
@@ -1235,6 +1226,7 @@ srv_shutdown_all_bg_threads()
|
||||
ulint i;
|
||||
|
||||
srv_shutdown_state = SRV_SHUTDOWN_EXIT_THREADS;
|
||||
fil_crypt_threads_end();
|
||||
|
||||
if (!srv_start_state) {
|
||||
return;
|
||||
@@ -2439,7 +2431,7 @@ files_checked:
|
||||
|
||||
/* 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) {
|
||||
return(srv_init_abort(err));
|
||||
@@ -2778,9 +2770,6 @@ srv_shutdown_bg_undo_sources(void)
|
||||
{
|
||||
fts_optimize_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 */
|
||||
btr_scrub_cleanup();
|
||||
|
||||
@@ -1582,7 +1582,6 @@ sync_latch_meta_init()
|
||||
}
|
||||
|
||||
/** Destroy the latch meta data */
|
||||
#ifdef JAN_DISABLED_FOR_NOW_AS_THIS_CAUSES_CRASH
|
||||
static
|
||||
void
|
||||
sync_latch_meta_destroy()
|
||||
@@ -1596,7 +1595,6 @@ sync_latch_meta_destroy()
|
||||
|
||||
latch_meta.clear();
|
||||
}
|
||||
#endif
|
||||
|
||||
/** 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
|
||||
@@ -1810,8 +1808,6 @@ sync_check_close()
|
||||
|
||||
create_tracker = NULL;
|
||||
|
||||
#ifdef JAN_DISABLED_FOR_NOW_AS_THIS_CAUSES_CRASH
|
||||
sync_latch_meta_destroy();
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -983,8 +983,7 @@ trx_sys_create_noredo_rsegs(
|
||||
Slot-1....Slot-N: reserved for temp-tablespace.
|
||||
Slot-N+1....Slot-127: reserved for system/undo-tablespace. */
|
||||
for (ulint i = 0; i < n_nonredo_rseg; i++) {
|
||||
ulint space = srv_tmp_space.space_id();
|
||||
if (trx_rseg_create(space, i) == NULL) {
|
||||
if (trx_rseg_create(SRV_TMP_SPACE_ID, i) == NULL) {
|
||||
break;
|
||||
}
|
||||
++n_created;
|
||||
|
||||
@@ -83,12 +83,6 @@ mysys/my_perf.c, contributed by Facebook under the following license.
|
||||
#include "my_config.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 "ut0crc32.h"
|
||||
|
||||
@@ -746,14 +740,8 @@ ut_crc32_init()
|
||||
}
|
||||
|
||||
#elif defined(HAVE_CRC32_VPMSUM)
|
||||
#if defined(__linux__)
|
||||
if (getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_2_07) {
|
||||
#endif
|
||||
ut_crc32 = ut_crc32_power8;
|
||||
ut_crc32_implementation = "Using POWER8 crc32 instructions";
|
||||
#if defined(__linux__)
|
||||
}
|
||||
#endif
|
||||
ut_crc32 = ut_crc32_power8;
|
||||
ut_crc32_implementation = "Using POWER8 crc32 instructions";
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
@@ -46,6 +46,7 @@ a b
|
||||
1 10
|
||||
2 20
|
||||
3 30
|
||||
4 40
|
||||
insert into t2 values (1);
|
||||
ERROR HY000: Table 't2' was not locked with LOCK TABLES
|
||||
commit;
|
||||
@@ -58,6 +59,7 @@ a b
|
||||
1 10
|
||||
2 20
|
||||
3 30
|
||||
4 40
|
||||
select * from t2;
|
||||
a
|
||||
1
|
||||
@@ -70,6 +72,7 @@ a b
|
||||
1 10
|
||||
2 20
|
||||
3 30
|
||||
4 40
|
||||
5 50
|
||||
select * from t2;
|
||||
a
|
||||
@@ -81,6 +84,7 @@ a b
|
||||
1 10
|
||||
2 20
|
||||
3 30
|
||||
4 40
|
||||
5 50
|
||||
select * from t2;
|
||||
a
|
||||
|
||||
@@ -2,8 +2,8 @@ drop table if exists t1,t3;
|
||||
CREATE TABLE t3(a int,c int,d int)engine=TOKUDB;
|
||||
lock table t3 read;
|
||||
create temporary table t1 engine=tokudb as SELECT 1;
|
||||
unlock tables;
|
||||
select * from t1;
|
||||
1
|
||||
1
|
||||
unlock tables;
|
||||
drop table t1,t3;
|
||||
|
||||
@@ -7,7 +7,7 @@ enable_warnings;
|
||||
CREATE TABLE t3(a int,c int,d int)engine=TOKUDB;
|
||||
lock table t3 read;
|
||||
create temporary table t1 engine=tokudb as SELECT 1;
|
||||
unlock tables;
|
||||
select * from t1;
|
||||
unlock tables;
|
||||
|
||||
drop table t1,t3;
|
||||
drop table t1,t3;
|
||||
@@ -1643,6 +1643,7 @@ struct dict_foreign_remove_partial
|
||||
if (table != NULL) {
|
||||
table->referenced_set.erase(foreign);
|
||||
}
|
||||
dict_foreign_free(foreign);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -3597,8 +3598,7 @@ dict_foreign_add_to_cache(
|
||||
}
|
||||
|
||||
if (for_in_cache) {
|
||||
/* Free the foreign object */
|
||||
mem_heap_free(foreign->heap);
|
||||
dict_foreign_free(foreign);
|
||||
} else {
|
||||
for_in_cache = foreign;
|
||||
}
|
||||
@@ -3622,7 +3622,7 @@ dict_foreign_add_to_cache(
|
||||
" the ones in table.");
|
||||
|
||||
if (for_in_cache == foreign) {
|
||||
mem_heap_free(foreign->heap);
|
||||
dict_foreign_free(foreign);
|
||||
}
|
||||
|
||||
return(DB_CANNOT_ADD_CONSTRAINT);
|
||||
@@ -3678,7 +3678,7 @@ dict_foreign_add_to_cache(
|
||||
be one */
|
||||
}
|
||||
|
||||
mem_heap_free(foreign->heap);
|
||||
dict_foreign_free(foreign);
|
||||
}
|
||||
|
||||
return(DB_CANNOT_ADD_CONSTRAINT);
|
||||
|
||||
@@ -490,7 +490,7 @@ err_len:
|
||||
}
|
||||
|
||||
/* 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
|
||||
is not assigned. */
|
||||
foreign->id = mem_heap_strdupl(heap, (const char*) field, len);
|
||||
|
||||
@@ -336,13 +336,7 @@ ut_crc32_init()
|
||||
}
|
||||
|
||||
#elif defined(HAVE_CRC32_VPMSUM)
|
||||
#if defined(__linux__)
|
||||
if (getauxval(AT_HWCAP2) & PPC_FEATURE2_ARCH_2_07) {
|
||||
#endif
|
||||
ut_crc32 = ut_crc32_power8;
|
||||
ut_crc32_implementation = "Using POWER8 crc32 instructions";
|
||||
#if defined(__linux__)
|
||||
}
|
||||
#endif
|
||||
ut_crc32 = ut_crc32_power8;
|
||||
ut_crc32_implementation = "Using POWER8 crc32 instructions";
|
||||
#endif
|
||||
}
|
||||
|
||||
@@ -1270,7 +1270,7 @@ int json_find_path(json_engine_t *je,
|
||||
case JST_VALUE:
|
||||
DBUG_ASSERT(cur_step->type & JSON_PATH_ARRAY);
|
||||
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. */
|
||||
if (cur_step == p->last_step ||
|
||||
@@ -1278,10 +1278,7 @@ int json_find_path(json_engine_t *je,
|
||||
goto exit;
|
||||
}
|
||||
else
|
||||
{
|
||||
json_skip_array_item(je);
|
||||
array_counters[cur_step - p->steps]++;
|
||||
}
|
||||
break;
|
||||
case JST_OBJ_END:
|
||||
case JST_ARRAY_END:
|
||||
|
||||
@@ -15386,6 +15386,9 @@ static void test_bug14169()
|
||||
|
||||
rc= mysql_query(mysql, "drop table t1");
|
||||
myquery(rc);
|
||||
|
||||
rc= mysql_query(mysql, "set session group_concat_max_len=@@global.group_concat_max_len");
|
||||
myquery(rc);
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
Reference in New Issue
Block a user