Merge branch '10.1' into 10.2
This commit is contained in:
commit
82aeb6b596
@ -26,7 +26,7 @@ ENDIF()
|
|||||||
OPTION(WITH_WSREP "WSREP replication API (to use, e.g. Galera Replication library)" ${with_wsrep_default})
|
OPTION(WITH_WSREP "WSREP replication API (to use, e.g. Galera Replication library)" ${with_wsrep_default})
|
||||||
|
|
||||||
# Set the patch version
|
# Set the patch version
|
||||||
SET(WSREP_PATCH_VERSION "21")
|
SET(WSREP_PATCH_VERSION "23")
|
||||||
|
|
||||||
# Obtain wsrep API version
|
# Obtain wsrep API version
|
||||||
FILE(STRINGS "${MySQL_SOURCE_DIR}/wsrep/wsrep_api.h" WSREP_API_VERSION
|
FILE(STRINGS "${MySQL_SOURCE_DIR}/wsrep/wsrep_api.h" WSREP_API_VERSION
|
||||||
|
@ -591,6 +591,11 @@ typedef SOCKET_SIZE_TYPE size_socket;
|
|||||||
#ifndef O_CLOEXEC
|
#ifndef O_CLOEXEC
|
||||||
#define O_CLOEXEC 0
|
#define O_CLOEXEC 0
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef __GLIBC__
|
||||||
|
#define STR_O_CLOEXEC "e"
|
||||||
|
#else
|
||||||
|
#define STR_O_CLOEXEC ""
|
||||||
|
#endif
|
||||||
#ifndef SOCK_CLOEXEC
|
#ifndef SOCK_CLOEXEC
|
||||||
#define SOCK_CLOEXEC 0
|
#define SOCK_CLOEXEC 0
|
||||||
#endif
|
#endif
|
||||||
|
@ -8241,6 +8241,19 @@ Warnings:
|
|||||||
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c`,`test`.`t1`.`d` AS `d` from `test`.`t1` where coalesce(`test`.`t1`.`c`,0) = '3 ' and coalesce(`test`.`t1`.`d`,0) = '3 '
|
Note 1003 select `test`.`t1`.`a` AS `a`,`test`.`t1`.`b` AS `b`,`test`.`t1`.`c` AS `c`,`test`.`t1`.`d` AS `d` from `test`.`t1` where coalesce(`test`.`t1`.`c`,0) = '3 ' and coalesce(`test`.`t1`.`d`,0) = '3 '
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
#
|
#
|
||||||
|
# MDEV-15005 ASAN: stack-buffer-overflow in my_strnncollsp_simple
|
||||||
|
#
|
||||||
|
SET NAMES latin1;
|
||||||
|
SELECT CONVERT(1, CHAR) IN ('100', 10, '101');
|
||||||
|
CONVERT(1, CHAR) IN ('100', 10, '101')
|
||||||
|
0
|
||||||
|
SELECT CONVERT(1, CHAR) IN ('100', 10, '1');
|
||||||
|
CONVERT(1, CHAR) IN ('100', 10, '1')
|
||||||
|
1
|
||||||
|
SELECT CONVERT(1, CHAR) IN ('100', '10', '1');
|
||||||
|
CONVERT(1, CHAR) IN ('100', '10', '1')
|
||||||
|
1
|
||||||
|
#
|
||||||
# End of 10.1 tests
|
# End of 10.1 tests
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
@ -10543,6 +10543,19 @@ CAST(_utf8 0xC499 AS CHAR CHARACTER SET latin1)
|
|||||||
Warnings:
|
Warnings:
|
||||||
Warning 1977 Cannot convert 'utf8' character 0xC499 to 'latin1'
|
Warning 1977 Cannot convert 'utf8' character 0xC499 to 'latin1'
|
||||||
#
|
#
|
||||||
|
# MDEV-15005 ASAN: stack-buffer-overflow in my_strnncollsp_simple
|
||||||
|
#
|
||||||
|
SET NAMES utf8;
|
||||||
|
SELECT CONVERT(1, CHAR) IN ('100', 10, '101');
|
||||||
|
CONVERT(1, CHAR) IN ('100', 10, '101')
|
||||||
|
0
|
||||||
|
SELECT CONVERT(1, CHAR) IN ('100', 10, '1');
|
||||||
|
CONVERT(1, CHAR) IN ('100', 10, '1')
|
||||||
|
1
|
||||||
|
SELECT CONVERT(1, CHAR) IN ('100', '10', '1');
|
||||||
|
CONVERT(1, CHAR) IN ('100', '10', '1')
|
||||||
|
1
|
||||||
|
#
|
||||||
# End of 10.1 tests
|
# End of 10.1 tests
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
@ -30,73 +30,372 @@ id fake_id bigfield
|
|||||||
33 1033 yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
|
33 1033 yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
|
||||||
128 1128 zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
|
128 1128 zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
|
||||||
# Baseline sanity check: 0, 0.
|
# Baseline sanity check: 0, 0.
|
||||||
|
select "no-op query";
|
||||||
no-op query
|
no-op query
|
||||||
no-op query
|
no-op query
|
||||||
cluster_lookups_matched
|
select @cluster_lookups;
|
||||||
1
|
@cluster_lookups
|
||||||
cluster_lookups_avoided_matched
|
0
|
||||||
1
|
select @cluster_lookups_avoided;
|
||||||
|
@cluster_lookups_avoided
|
||||||
|
0
|
||||||
# Eligible for optimization.
|
# Eligible for optimization.
|
||||||
|
select id, bigfield from prefixinno where bigfield = repeat('d', 31);
|
||||||
id bigfield
|
id bigfield
|
||||||
31 ddddddddddddddddddddddddddddddd
|
31 ddddddddddddddddddddddddddddddd
|
||||||
cluster_lookups_matched
|
select @cluster_lookups;
|
||||||
1
|
@cluster_lookups
|
||||||
cluster_lookups_avoided_matched
|
0
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
@cluster_lookups_avoided
|
||||||
1
|
1
|
||||||
# Eligible for optimization, access via fake_id only.
|
# Eligible for optimization, access via fake_id only.
|
||||||
|
select id, bigfield from prefixinno where fake_id = 1031;
|
||||||
id bigfield
|
id bigfield
|
||||||
31 ddddddddddddddddddddddddddddddd
|
31 ddddddddddddddddddddddddddddddd
|
||||||
cluster_lookups_matched
|
select @cluster_lookups;
|
||||||
1
|
@cluster_lookups
|
||||||
cluster_lookups_avoided_matched
|
0
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
@cluster_lookups_avoided
|
||||||
1
|
1
|
||||||
# Not eligible for optimization, access via fake_id of big row.
|
# Not eligible for optimization, access via fake_id of big row.
|
||||||
|
select id, bigfield from prefixinno where fake_id = 1033;
|
||||||
id bigfield
|
id bigfield
|
||||||
33 yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
|
33 yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
|
||||||
cluster_lookups_matched
|
select @cluster_lookups;
|
||||||
1
|
@cluster_lookups
|
||||||
cluster_lookups_avoided_matched
|
|
||||||
1
|
1
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
@cluster_lookups_avoided
|
||||||
|
0
|
||||||
# Not eligible for optimization.
|
# Not eligible for optimization.
|
||||||
|
select id, bigfield from prefixinno where bigfield = repeat('x', 32);
|
||||||
id bigfield
|
id bigfield
|
||||||
32 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
32 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
|
||||||
cluster_lookups_matched
|
select @cluster_lookups;
|
||||||
1
|
@cluster_lookups
|
||||||
cluster_lookups_avoided_matched
|
|
||||||
1
|
1
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
@cluster_lookups_avoided
|
||||||
|
0
|
||||||
# Not eligible for optimization.
|
# Not eligible for optimization.
|
||||||
|
select id, bigfield from prefixinno where bigfield = repeat('y', 33);
|
||||||
id bigfield
|
id bigfield
|
||||||
33 yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
|
33 yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
|
||||||
cluster_lookups_matched
|
select @cluster_lookups;
|
||||||
1
|
@cluster_lookups
|
||||||
cluster_lookups_avoided_matched
|
|
||||||
1
|
1
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
@cluster_lookups_avoided
|
||||||
|
0
|
||||||
# Eligible, should not increment lookup counter.
|
# Eligible, should not increment lookup counter.
|
||||||
|
select id, bigfield from prefixinno where bigfield = repeat('b', 8);
|
||||||
id bigfield
|
id bigfield
|
||||||
8 bbbbbbbb
|
8 bbbbbbbb
|
||||||
cluster_lookups_matched
|
select @cluster_lookups;
|
||||||
1
|
@cluster_lookups
|
||||||
cluster_lookups_avoided_matched
|
0
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
@cluster_lookups_avoided
|
||||||
1
|
1
|
||||||
# Eligible, should not increment lookup counter.
|
# Eligible, should not increment lookup counter.
|
||||||
|
select id, bigfield from prefixinno where bigfield = repeat('c', 24);
|
||||||
id bigfield
|
id bigfield
|
||||||
24 cccccccccccccccccccccccc
|
24 cccccccccccccccccccccccc
|
||||||
cluster_lookups_matched
|
select @cluster_lookups;
|
||||||
1
|
@cluster_lookups
|
||||||
cluster_lookups_avoided_matched
|
0
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
@cluster_lookups_avoided
|
||||||
1
|
1
|
||||||
# Should increment lookup counter.
|
# Should increment lookup counter.
|
||||||
|
select id, bigfield from prefixinno where bigfield = repeat('z', 128);
|
||||||
id bigfield
|
id bigfield
|
||||||
128 zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
|
128 zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
|
||||||
cluster_lookups_matched
|
select @cluster_lookups;
|
||||||
1
|
@cluster_lookups
|
||||||
cluster_lookups_avoided_matched
|
|
||||||
1
|
1
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
@cluster_lookups_avoided
|
||||||
|
0
|
||||||
# Disable optimization, confirm we still increment counter.
|
# Disable optimization, confirm we still increment counter.
|
||||||
|
set global innodb_prefix_index_cluster_optimization = OFF;
|
||||||
|
select id, bigfield from prefixinno where fake_id = 1033;
|
||||||
id bigfield
|
id bigfield
|
||||||
33 yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
|
33 yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy
|
||||||
cluster_lookups_matched
|
select @cluster_lookups;
|
||||||
|
@cluster_lookups
|
||||||
1
|
1
|
||||||
cluster_lookups_avoided_matched
|
select @cluster_lookups_avoided;
|
||||||
|
@cluster_lookups_avoided
|
||||||
|
0
|
||||||
|
drop table prefixinno;
|
||||||
|
# Multi-byte handling case
|
||||||
|
set global innodb_prefix_index_cluster_optimization = ON;
|
||||||
|
SET NAMES utf8mb4;
|
||||||
|
CREATE TABLE t1(
|
||||||
|
f1 varchar(10) CHARACTER SET UTF8MB4 COLLATE UTF8MB4_BIN,
|
||||||
|
INDEX (f1(3)))ENGINE=INNODB;
|
||||||
|
INSERT INTO t1 VALUES('a'), ('cccc'), ('až'), ('cčc'), ('ggᵷg'), ('¢¢');
|
||||||
|
INSERT INTO t1 VALUES('தமிழ்'), ('🐱🌑'), ('🌒'), ('🌑');
|
||||||
|
INSERT INTO t1 VALUES('😊me'), ('eu€'), ('ls¢');
|
||||||
|
# Eligible - record length is shorter than prefix
|
||||||
|
SELECT f1 FROM t1 FORCE INDEX (`f1`) WHERE f1 = 'a';
|
||||||
|
f1
|
||||||
|
a
|
||||||
|
select @cluster_lookups;
|
||||||
|
@cluster_lookups
|
||||||
|
0
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
@cluster_lookups_avoided
|
||||||
1
|
1
|
||||||
# make test suite happy by cleaning up our mess
|
# Not eligible - record length longer than prefix length
|
||||||
|
SELECT f1 FROM t1 FORCE INDEX (`f1`) WHERE f1 like 'c%';
|
||||||
|
f1
|
||||||
|
cccc
|
||||||
|
cčc
|
||||||
|
select @cluster_lookups;
|
||||||
|
@cluster_lookups
|
||||||
|
3
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
@cluster_lookups_avoided
|
||||||
|
0
|
||||||
|
# Eligible - record length shorter than prefix length
|
||||||
|
SELECT f1 FROM t1 FORCE INDEX (`f1`) WHERE f1 = 'až';
|
||||||
|
f1
|
||||||
|
až
|
||||||
|
select @cluster_lookups;
|
||||||
|
@cluster_lookups
|
||||||
|
0
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
@cluster_lookups_avoided
|
||||||
|
1
|
||||||
|
# Not eligible - record length longer than prefix length
|
||||||
|
SELECT f1 FROM t1 FORCE INDEX (`f1`) WHERE f1 = 'தமிழ்';
|
||||||
|
f1
|
||||||
|
தமிழ்
|
||||||
|
select @cluster_lookups;
|
||||||
|
@cluster_lookups
|
||||||
|
1
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
@cluster_lookups_avoided
|
||||||
|
0
|
||||||
|
# Not eligible - record length longer than prefix length
|
||||||
|
SELECT f1 FROM t1 FORCE INDEX (`f1`) WHERE f1 like 'ggᵷ%';
|
||||||
|
f1
|
||||||
|
ggᵷg
|
||||||
|
select @cluster_lookups;
|
||||||
|
@cluster_lookups
|
||||||
|
1
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
@cluster_lookups_avoided
|
||||||
|
0
|
||||||
|
# Not eligible - record length longer than prefix length
|
||||||
|
SELECT f1 FROM t1 FORCE INDEX (`f1`) WHERE f1 like '😊%';
|
||||||
|
f1
|
||||||
|
😊me
|
||||||
|
select @cluster_lookups;
|
||||||
|
@cluster_lookups
|
||||||
|
1
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
@cluster_lookups_avoided
|
||||||
|
0
|
||||||
|
# Not eligible - record length longer than prefix length
|
||||||
|
SELECT f1 FROM t1 FORCE INDEX (`f1`) WHERE f1 = 'ls¢';
|
||||||
|
f1
|
||||||
|
ls¢
|
||||||
|
select @cluster_lookups;
|
||||||
|
@cluster_lookups
|
||||||
|
1
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
@cluster_lookups_avoided
|
||||||
|
0
|
||||||
|
# Eligible - record length shorter than prefix length
|
||||||
|
SELECT f1 FROM t1 FORCE INDEX (`f1`) WHERE f1 like '¢¢%';
|
||||||
|
f1
|
||||||
|
¢¢
|
||||||
|
select @cluster_lookups;
|
||||||
|
@cluster_lookups
|
||||||
|
1
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
@cluster_lookups_avoided
|
||||||
|
1
|
||||||
|
# Eligible - record length shorter than prefix length
|
||||||
|
SELECT f1 FROM t1 FORCE INDEX (`f1`) WHERE f1 like '🐱🌑%';
|
||||||
|
f1
|
||||||
|
🐱🌑
|
||||||
|
select @cluster_lookups;
|
||||||
|
@cluster_lookups
|
||||||
|
1
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
@cluster_lookups_avoided
|
||||||
|
1
|
||||||
|
# Not eligible - record length longer than prefix length
|
||||||
|
SELECT f1 FROM t1 FORCE INDEX (`f1`) WHERE f1 like '🌑%';
|
||||||
|
f1
|
||||||
|
🌑
|
||||||
|
select @cluster_lookups;
|
||||||
|
@cluster_lookups
|
||||||
|
0
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
@cluster_lookups_avoided
|
||||||
|
2
|
||||||
|
# Not eligible - record length longer than prefix length
|
||||||
|
SELECT f1 FROM t1 FORCE INDEX (`f1`) WHERE f1 like '🌒%';
|
||||||
|
f1
|
||||||
|
🌒
|
||||||
|
select @cluster_lookups;
|
||||||
|
@cluster_lookups
|
||||||
|
0
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
@cluster_lookups_avoided
|
||||||
|
2
|
||||||
|
DROP TABLE t1;
|
||||||
|
# Multi-byte with minimum character length > 1 bytes
|
||||||
|
CREATE TABLE t1(
|
||||||
|
f1 varchar(10) CHARACTER SET UTF16 COLLATE UTF16_BIN,
|
||||||
|
INDEX (f1(3)))ENGINE=INNODB;
|
||||||
|
INSERT INTO t1 VALUES('a'), ('cccc'), ('až'), ('cčc'), ('ggᵷg'), ('¢¢');
|
||||||
|
INSERT INTO t1 VALUES('தமிழ்'), ('🐱🌑'), ('🌒'), ('🌑');
|
||||||
|
INSERT INTO t1 VALUES('😊me'), ('eu€'), ('ls¢');
|
||||||
|
# Eligible - record length is shorter than prefix
|
||||||
|
SELECT f1 FROM t1 FORCE INDEX (`f1`) WHERE f1 = 'a';
|
||||||
|
f1
|
||||||
|
a
|
||||||
|
select @cluster_lookups;
|
||||||
|
@cluster_lookups
|
||||||
|
0
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
@cluster_lookups_avoided
|
||||||
|
1
|
||||||
|
# Not eligible - record length longer than prefix length
|
||||||
|
SELECT f1 FROM t1 FORCE INDEX (`f1`) WHERE f1 like 'c%';
|
||||||
|
f1
|
||||||
|
cccc
|
||||||
|
cčc
|
||||||
|
select @cluster_lookups;
|
||||||
|
@cluster_lookups
|
||||||
|
3
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
@cluster_lookups_avoided
|
||||||
|
0
|
||||||
|
# Eligible - record length shorter than prefix length
|
||||||
|
SELECT f1 FROM t1 FORCE INDEX (`f1`) WHERE f1 = 'až';
|
||||||
|
f1
|
||||||
|
až
|
||||||
|
select @cluster_lookups;
|
||||||
|
@cluster_lookups
|
||||||
|
0
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
@cluster_lookups_avoided
|
||||||
|
1
|
||||||
|
# Not eligible - record length longer than prefix length
|
||||||
|
SELECT f1 FROM t1 FORCE INDEX (`f1`) WHERE f1 = 'தமிழ்';
|
||||||
|
f1
|
||||||
|
தமிழ்
|
||||||
|
select @cluster_lookups;
|
||||||
|
@cluster_lookups
|
||||||
|
1
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
@cluster_lookups_avoided
|
||||||
|
0
|
||||||
|
# Not eligible - record length longer than prefix length
|
||||||
|
SELECT f1 FROM t1 FORCE INDEX (`f1`) WHERE f1 like 'ggᵷ%';
|
||||||
|
f1
|
||||||
|
ggᵷg
|
||||||
|
select @cluster_lookups;
|
||||||
|
@cluster_lookups
|
||||||
|
2
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
@cluster_lookups_avoided
|
||||||
|
0
|
||||||
|
# Not eligible - record length longer than prefix length
|
||||||
|
SELECT f1 FROM t1 FORCE INDEX (`f1`) WHERE f1 like '😊%';
|
||||||
|
f1
|
||||||
|
😊me
|
||||||
|
select @cluster_lookups;
|
||||||
|
@cluster_lookups
|
||||||
|
1
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
@cluster_lookups_avoided
|
||||||
|
0
|
||||||
|
# Not eligible - record length longer than prefix length
|
||||||
|
SELECT f1 FROM t1 FORCE INDEX (`f1`) WHERE f1 = 'ls¢';
|
||||||
|
f1
|
||||||
|
ls¢
|
||||||
|
select @cluster_lookups;
|
||||||
|
@cluster_lookups
|
||||||
|
1
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
@cluster_lookups_avoided
|
||||||
|
0
|
||||||
|
# Eligible - record length shorter than prefix length
|
||||||
|
SELECT f1 FROM t1 FORCE INDEX(`f1`) WHERE f1 like '¢¢%';
|
||||||
|
f1
|
||||||
|
¢¢
|
||||||
|
select @cluster_lookups;
|
||||||
|
@cluster_lookups
|
||||||
|
1
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
@cluster_lookups_avoided
|
||||||
|
1
|
||||||
|
# Eligible - record length shorter than prefix length
|
||||||
|
SELECT f1 FROM t1 FORCE INDEX (`f1`) WHERE f1 like '🐱🌑%';
|
||||||
|
f1
|
||||||
|
🐱🌑
|
||||||
|
select @cluster_lookups;
|
||||||
|
@cluster_lookups
|
||||||
|
2
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
@cluster_lookups_avoided
|
||||||
|
0
|
||||||
|
# Eligible - record length is shorter than prefix length
|
||||||
|
SELECT f1 FROM t1 FORCE INDEX (`f1`) WHERE f1 like '🌑%';
|
||||||
|
f1
|
||||||
|
🌑
|
||||||
|
select @cluster_lookups;
|
||||||
|
@cluster_lookups
|
||||||
|
0
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
@cluster_lookups_avoided
|
||||||
|
2
|
||||||
|
# Eligible - record length is shorter than prefix length
|
||||||
|
SELECT f1 FROM t1 FORCE INDEX (`f1`) WHERE f1 like '🌒%';
|
||||||
|
f1
|
||||||
|
🌒
|
||||||
|
select @cluster_lookups;
|
||||||
|
@cluster_lookups
|
||||||
|
1
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
@cluster_lookups_avoided
|
||||||
|
1
|
||||||
|
DROP TABLE t1;
|
||||||
|
CREATE TABLE t1(
|
||||||
|
col1 INT,
|
||||||
|
col2 BLOB DEFAULT NULL,
|
||||||
|
INDEX `idx1`(col2(4), col1))ENGINE=INNODB;
|
||||||
|
INSERT INTO t1 VALUES (2, 'test'), (3, repeat('test1', 2000));
|
||||||
|
INSERT INTO t1(col1) VALUES(1);
|
||||||
|
# Eligible - record length is shorter than prefix length
|
||||||
|
SELECT col1 FROM t1 FORCE INDEX (`idx1`) WHERE col2 is NULL;
|
||||||
|
col1
|
||||||
|
1
|
||||||
|
select @cluster_lookups;
|
||||||
|
@cluster_lookups
|
||||||
|
0
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
@cluster_lookups_avoided
|
||||||
|
1
|
||||||
|
# Not eligible - record length longer than prefix index
|
||||||
|
SELECT col1 FROM t1 FORCE INDEX (`idx1`) WHERE col2 like 'test1%';
|
||||||
|
col1
|
||||||
|
3
|
||||||
|
select @cluster_lookups;
|
||||||
|
@cluster_lookups
|
||||||
|
2
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
@cluster_lookups_avoided
|
||||||
|
0
|
||||||
|
DROP TABLE t1;
|
||||||
|
set global innodb_prefix_index_cluster_optimization = OFF;
|
||||||
|
@ -1215,6 +1215,37 @@ MAX(a) MAX(COALESCE(a))
|
|||||||
10:20:30 10:20:30
|
10:20:30 10:20:30
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
#
|
#
|
||||||
|
# MDEV-15321: different results when using value of optimizer_use_condition_selectivity=4 and =1
|
||||||
|
#
|
||||||
|
SET @save_old_mode=@@old_mode;
|
||||||
|
SET @@old_mode=zero_date_time_cast;
|
||||||
|
CREATE TABLE t1 (a TIME);
|
||||||
|
INSERT INTO t1 VALUES ('0000-00-00 10:20:30'),('0000-00-00 10:20:31');
|
||||||
|
INSERT INTO t1 VALUES ('0000-00-01 10:20:30'),('0000-00-01 10:20:31');
|
||||||
|
INSERT INTO t1 VALUES ('31 10:20:30'),('32 10:20:30'),('33 10:20:30'),('34 10:20:30');
|
||||||
|
SET @save_optimizer_use_condition_selectivity= @@optimizer_use_condition_selectivity;
|
||||||
|
SET @@optimizer_use_condition_selectivity=1;
|
||||||
|
SELECT * FROM t1 WHERE a='0000-00-01 10:20:30' AND LENGTH(a)=8;
|
||||||
|
a
|
||||||
|
34:20:30
|
||||||
|
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='0000-00-01 10:20:30' AND LENGTH(a)=8;
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 8 100.00 Using where
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = '0000-00-01 10:20:30' and length(`test`.`t1`.`a`) = 8
|
||||||
|
SET @@optimizer_use_condition_selectivity=4;
|
||||||
|
SELECT * FROM t1 WHERE a='0000-00-01 10:20:30' AND LENGTH(a)=8;
|
||||||
|
a
|
||||||
|
34:20:30
|
||||||
|
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='0000-00-01 10:20:30' AND LENGTH(a)=8;
|
||||||
|
id select_type table type possible_keys key key_len ref rows filtered Extra
|
||||||
|
1 SIMPLE t1 ALL NULL NULL NULL NULL 8 100.00 Using where
|
||||||
|
Warnings:
|
||||||
|
Note 1003 select `test`.`t1`.`a` AS `a` from `test`.`t1` where `test`.`t1`.`a` = '0000-00-01 10:20:30' and length(`test`.`t1`.`a`) = 8
|
||||||
|
drop table t1;
|
||||||
|
SET @@optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity;
|
||||||
|
set @@old_mode= @save_old_mode;
|
||||||
|
#
|
||||||
# End of 10.1 tests
|
# End of 10.1 tests
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
|
@ -10,7 +10,6 @@
|
|||||||
#
|
#
|
||||||
##############################################################################
|
##############################################################################
|
||||||
galera_gra_log : MDEV-13549 Galera test failures
|
galera_gra_log : MDEV-13549 Galera test failures
|
||||||
galera_flush_local : MDEV-13549 Galera test failures
|
|
||||||
galera_flush : MDEV-13549 Galera test failures
|
galera_flush : MDEV-13549 Galera test failures
|
||||||
galera_account_management : MariaDB 10.0 does not support ALTER USER
|
galera_account_management : MariaDB 10.0 does not support ALTER USER
|
||||||
galera_binlog_row_image : MariaDB 10.0 does not support binlog_row_image
|
galera_binlog_row_image : MariaDB 10.0 does not support binlog_row_image
|
||||||
@ -30,7 +29,6 @@ galera_gcache_recover_manytrx : MDEV-13549 Galera test failures
|
|||||||
galera_ist_mysqldump : MDEV-13549 Galera test failures
|
galera_ist_mysqldump : MDEV-13549 Galera test failures
|
||||||
mysql-wsrep#31 : MDEV-13549 Galera test failures
|
mysql-wsrep#31 : MDEV-13549 Galera test failures
|
||||||
galera_migrate : MariaDB 10.0 does not support START SLAVE USER
|
galera_migrate : MariaDB 10.0 does not support START SLAVE USER
|
||||||
galera_concurrent_ctas : MDEV-13549 Galera test failures
|
|
||||||
galera_wsrep_desync_wsrep_on : MDEV-13549 Galera test failures
|
galera_wsrep_desync_wsrep_on : MDEV-13549 Galera test failures
|
||||||
galera_ssl_upgrade : MDEV-13549 Galera test failures
|
galera_ssl_upgrade : MDEV-13549 Galera test failures
|
||||||
mysql-wsrep#33 : MDEV-13549 Galera test failures
|
mysql-wsrep#33 : MDEV-13549 Galera test failures
|
||||||
|
@ -0,0 +1,4 @@
|
|||||||
|
--require suite/galera/r/have_wsrep_replicate_myisam.require
|
||||||
|
disable_query_log;
|
||||||
|
SHOW VARIABLES LIKE 'wsrep_replicate_myisam';
|
||||||
|
enable_query_log;
|
@ -27,3 +27,4 @@ connection node_1;
|
|||||||
DROP PROCEDURE proc_insert;
|
DROP PROCEDURE proc_insert;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
CALL mtr.add_suppression("conflict state 3 after post commit");
|
CALL mtr.add_suppression("conflict state 3 after post commit");
|
||||||
|
set global innodb_status_output=Default;
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
SELECT COUNT(*) = 43 FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME LIKE 'wsrep_%';
|
SELECT COUNT(*) = 43 FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES WHERE VARIABLE_NAME LIKE 'wsrep_%';
|
||||||
COUNT(*) = 43
|
COUNT(*) = 43
|
||||||
1
|
0
|
||||||
SELECT VARIABLE_NAME, VARIABLE_VALUE
|
SELECT VARIABLE_NAME, VARIABLE_VALUE
|
||||||
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
|
FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES
|
||||||
WHERE VARIABLE_NAME LIKE 'wsrep_%'
|
WHERE VARIABLE_NAME LIKE 'wsrep_%'
|
||||||
@ -40,6 +40,7 @@ WSREP_NOTIFY_CMD
|
|||||||
WSREP_ON ON
|
WSREP_ON ON
|
||||||
WSREP_OSU_METHOD TOI
|
WSREP_OSU_METHOD TOI
|
||||||
WSREP_RECOVER OFF
|
WSREP_RECOVER OFF
|
||||||
|
WSREP_REJECT_QUERIES NONE
|
||||||
WSREP_REPLICATE_MYISAM OFF
|
WSREP_REPLICATE_MYISAM OFF
|
||||||
WSREP_RESTART_SLAVE OFF
|
WSREP_RESTART_SLAVE OFF
|
||||||
WSREP_RETRY_AUTOCOMMIT 1
|
WSREP_RETRY_AUTOCOMMIT 1
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
DROP TABLE IF EXISTS t1, t2, x1, x2;
|
DROP TABLE IF EXISTS t1, t2, x1, x2;
|
||||||
|
connection node_1;
|
||||||
CREATE TABLE t1 (f1 INTEGER);
|
CREATE TABLE t1 (f1 INTEGER);
|
||||||
CREATE TABLE t2 (f1 INT PRIMARY KEY AUTO_INCREMENT, f2 INTEGER);
|
CREATE TABLE t2 (f1 INT PRIMARY KEY AUTO_INCREMENT, f2 INTEGER);
|
||||||
CREATE TABLE x1 (f1 INTEGER) ENGINE=MyISAM;
|
CREATE TABLE x1 (f1 INTEGER) ENGINE=MyISAM;
|
||||||
@ -7,6 +8,8 @@ INSERT INTO t1 VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
|
|||||||
INSERT INTO x1 VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
|
INSERT INTO x1 VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
|
||||||
INSERT INTO t2 (f2) SELECT 1 FROM t1 AS a1, t1 AS a2, t1 AS a3, t1 AS a4;
|
INSERT INTO t2 (f2) SELECT 1 FROM t1 AS a1, t1 AS a2, t1 AS a3, t1 AS a4;
|
||||||
INSERT INTO x2 (f2) VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
|
INSERT INTO x2 (f2) VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
|
||||||
|
connection node_2;
|
||||||
|
connection node_1;
|
||||||
FLUSH LOCAL DES_KEY_FILE;
|
FLUSH LOCAL DES_KEY_FILE;
|
||||||
FLUSH LOCAL HOSTS;
|
FLUSH LOCAL HOSTS;
|
||||||
FLUSH LOCAL QUERY CACHE;
|
FLUSH LOCAL QUERY CACHE;
|
||||||
@ -54,6 +57,7 @@ REPAIR LOCAL TABLE x1, x2;
|
|||||||
Table Op Msg_type Msg_text
|
Table Op Msg_type Msg_text
|
||||||
test.x1 repair status OK
|
test.x1 repair status OK
|
||||||
test.x2 repair status OK
|
test.x2 repair status OK
|
||||||
|
connection node_2;
|
||||||
wsrep_last_committed_diff
|
wsrep_last_committed_diff
|
||||||
1
|
1
|
||||||
SELECT COUNT(*) = 10 FROM t1;
|
SELECT COUNT(*) = 10 FROM t1;
|
||||||
@ -68,6 +72,7 @@ COUNT(*) = 10000
|
|||||||
SELECT COUNT(*) = 10 FROM x2;
|
SELECT COUNT(*) = 10 FROM x2;
|
||||||
COUNT(*) = 10
|
COUNT(*) = 10
|
||||||
1
|
1
|
||||||
|
connection node_1;
|
||||||
DROP TABLE t1, t2, x1, x2;
|
DROP TABLE t1, t2, x1, x2;
|
||||||
CREATE TABLE t1 (f1 INTEGER);
|
CREATE TABLE t1 (f1 INTEGER);
|
||||||
CREATE TABLE t2 (f1 INT PRIMARY KEY AUTO_INCREMENT, f2 INTEGER);
|
CREATE TABLE t2 (f1 INT PRIMARY KEY AUTO_INCREMENT, f2 INTEGER);
|
||||||
@ -77,6 +82,8 @@ INSERT INTO t1 VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
|
|||||||
INSERT INTO x1 VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
|
INSERT INTO x1 VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
|
||||||
INSERT INTO t2 (f2) SELECT 1 FROM t1 AS a1, t1 AS a2, t1 AS a3, t1 AS a4;
|
INSERT INTO t2 (f2) SELECT 1 FROM t1 AS a1, t1 AS a2, t1 AS a3, t1 AS a4;
|
||||||
INSERT INTO x2 (f2) VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
|
INSERT INTO x2 (f2) VALUES (1), (2), (3), (4), (5), (6), (7), (8), (9), (10);
|
||||||
|
connection node_2;
|
||||||
|
connection node_1;
|
||||||
set wsrep_on=0;
|
set wsrep_on=0;
|
||||||
FLUSH DES_KEY_FILE;
|
FLUSH DES_KEY_FILE;
|
||||||
FLUSH HOSTS;
|
FLUSH HOSTS;
|
||||||
@ -125,6 +132,7 @@ REPAIR TABLE x1, x2;
|
|||||||
Table Op Msg_type Msg_text
|
Table Op Msg_type Msg_text
|
||||||
test.x1 repair status OK
|
test.x1 repair status OK
|
||||||
test.x2 repair status OK
|
test.x2 repair status OK
|
||||||
|
connection node_2;
|
||||||
wsrep_last_committed_diff
|
wsrep_last_committed_diff
|
||||||
1
|
1
|
||||||
wsrep_last_committed_diff2
|
wsrep_last_committed_diff2
|
||||||
@ -141,5 +149,6 @@ COUNT(*) = 10000
|
|||||||
SELECT COUNT(*) = 10 FROM x2;
|
SELECT COUNT(*) = 10 FROM x2;
|
||||||
COUNT(*) = 10
|
COUNT(*) = 10
|
||||||
1
|
1
|
||||||
|
connection node_1;
|
||||||
set wsrep_on=1;
|
set wsrep_on=1;
|
||||||
DROP TABLE t1, t2, x1, x2;
|
DROP TABLE t1, t2, x1, x2;
|
||||||
|
13
mysql-test/suite/galera/r/galera_schema_dirty_reads.result
Normal file
13
mysql-test/suite/galera/r/galera_schema_dirty_reads.result
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
USE information_schema;
|
||||||
|
SELECT * FROM SESSION_VARIABLES WHERE VARIABLE_NAME LIKE "wsrep_dirty_reads";
|
||||||
|
VARIABLE_NAME VARIABLE_VALUE
|
||||||
|
WSREP_DIRTY_READS OFF
|
||||||
|
SET GLOBAL wsrep_reject_queries=ALL;
|
||||||
|
SELECT * FROM SESSION_VARIABLES WHERE VARIABLE_NAME LIKE "wsrep_dirty_reads";
|
||||||
|
VARIABLE_NAME VARIABLE_VALUE
|
||||||
|
WSREP_DIRTY_READS OFF
|
||||||
|
SET GLOBAL wsrep_reject_queries=NONE;
|
||||||
|
SET SESSION wsrep_dirty_reads=TRUE;
|
||||||
|
SELECT * FROM SESSION_VARIABLES WHERE VARIABLE_NAME LIKE "wsrep_dirty_reads";
|
||||||
|
VARIABLE_NAME VARIABLE_VALUE
|
||||||
|
WSREP_DIRTY_READS ON
|
@ -4,7 +4,8 @@ connection node_2;
|
|||||||
SET GLOBAL wsrep_cluster_address = 'foo://';
|
SET GLOBAL wsrep_cluster_address = 'foo://';
|
||||||
SET SESSION wsrep_sync_wait=0;
|
SET SESSION wsrep_sync_wait=0;
|
||||||
SELECT COUNT(*) > 0 FROM INFORMATION_SCHEMA.GLOBAL_STATUS;
|
SELECT COUNT(*) > 0 FROM INFORMATION_SCHEMA.GLOBAL_STATUS;
|
||||||
ERROR 08S01: WSREP has not yet prepared node for application use
|
COUNT(*) > 0
|
||||||
|
1
|
||||||
SHOW STATUS LIKE 'wsrep_ready';
|
SHOW STATUS LIKE 'wsrep_ready';
|
||||||
Variable_name Value
|
Variable_name Value
|
||||||
wsrep_ready OFF
|
wsrep_ready OFF
|
||||||
|
@ -33,14 +33,15 @@ SET @@session.wsrep_dirty_reads=OFF;
|
|||||||
SELECT i, variable_name, variable_value FROM t1, information_schema.session_variables WHERE variable_name LIKE "wsrep_dirty_reads" AND i = 1;
|
SELECT i, variable_name, variable_value FROM t1, information_schema.session_variables WHERE variable_name LIKE "wsrep_dirty_reads" AND i = 1;
|
||||||
ERROR 08S01: WSREP has not yet prepared node for application use
|
ERROR 08S01: WSREP has not yet prepared node for application use
|
||||||
SELECT 1;
|
SELECT 1;
|
||||||
1
|
ERROR 08S01: WSREP has not yet prepared node for application use
|
||||||
1
|
|
||||||
USE information_schema;
|
USE information_schema;
|
||||||
ERROR 08S01: WSREP has not yet prepared node for application use
|
ERROR 08S01: WSREP has not yet prepared node for application use
|
||||||
SELECT * FROM information_schema.session_variables WHERE variable_name LIKE "wsrep_dirty_reads";
|
SELECT * FROM information_schema.session_variables WHERE variable_name LIKE "wsrep_dirty_reads";
|
||||||
ERROR 08S01: WSREP has not yet prepared node for application use
|
VARIABLE_NAME VARIABLE_VALUE
|
||||||
|
WSREP_DIRTY_READS OFF
|
||||||
SELECT COUNT(*) >= 10 FROM performance_schema.events_statements_history;
|
SELECT COUNT(*) >= 10 FROM performance_schema.events_statements_history;
|
||||||
ERROR 08S01: WSREP has not yet prepared node for application use
|
COUNT(*) >= 10
|
||||||
|
1
|
||||||
connection node_1;
|
connection node_1;
|
||||||
USE test;
|
USE test;
|
||||||
SELECT * FROM t1;
|
SELECT * FROM t1;
|
||||||
|
27
mysql-test/suite/galera/r/galera_var_reject_queries.result
Normal file
27
mysql-test/suite/galera/r/galera_var_reject_queries.result
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
CREATE TABLE t1 (f1 INTEGER);
|
||||||
|
connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1;
|
||||||
|
connection node_1;
|
||||||
|
SET SESSION wsrep_reject_queries = ALL;
|
||||||
|
ERROR HY000: Variable 'wsrep_reject_queries' is a GLOBAL variable and should be set with SET GLOBAL
|
||||||
|
SET GLOBAL wsrep_reject_queries = ALL;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
ERROR 08S01: WSREP has not yet prepared node for application use
|
||||||
|
SET GLOBAL wsrep_reject_queries = ALL_KILL;
|
||||||
|
ERROR HY000: Lost connection to MySQL server during query
|
||||||
|
connection node_1a;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
Got one of the listed errors
|
||||||
|
connect node_1b, 127.0.0.1, root, , test, $NODE_MYPORT_1;
|
||||||
|
SELECT * FROM t1;
|
||||||
|
ERROR 08S01: WSREP has not yet prepared node for application use
|
||||||
|
connection node_2;
|
||||||
|
SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
|
||||||
|
VARIABLE_VALUE = 2
|
||||||
|
1
|
||||||
|
INSERT INTO t1 VALUES (1);
|
||||||
|
connect node_1c, 127.0.0.1, root, , test, $NODE_MYPORT_1;
|
||||||
|
SET GLOBAL wsrep_reject_queries = NONE;
|
||||||
|
SELECT COUNT(*) = 1 FROM t1;
|
||||||
|
COUNT(*) = 1
|
||||||
|
1
|
||||||
|
DROP TABLE t1;
|
@ -0,0 +1,2 @@
|
|||||||
|
Variable_name Value
|
||||||
|
wsrep_replicate_myisam ON
|
@ -85,3 +85,5 @@ DROP TABLE t1;
|
|||||||
|
|
||||||
# Due to MW-330, Multiple "conflict state 3 after post commit" warnings if table is dropped while SP is running
|
# Due to MW-330, Multiple "conflict state 3 after post commit" warnings if table is dropped while SP is running
|
||||||
CALL mtr.add_suppression("conflict state 3 after post commit");
|
CALL mtr.add_suppression("conflict state 3 after post commit");
|
||||||
|
|
||||||
|
set global innodb_status_output=Default;
|
@ -51,7 +51,7 @@ INSERT INTO t1 VALUES (1),(2),(3),(4),(5);
|
|||||||
--let $value = query_get_value(SHOW SLAVE STATUS, Last_SQL_Error, 1)
|
--let $value = query_get_value(SHOW SLAVE STATUS, Last_SQL_Error, 1)
|
||||||
--connection node_3
|
--connection node_3
|
||||||
--disable_query_log
|
--disable_query_log
|
||||||
--eval SELECT "$value" IN ("Error 'Unknown command' on query. Default database: 'test'. Query: 'BEGIN'", "Node has dropped from cluster") AS expected_error
|
--eval SELECT "$value" IN ("Error 'WSREP has not yet prepared node for application use' on query. Default database: 'test'. Query: 'BEGIN'", "Node has dropped from cluster") AS expected_error
|
||||||
--enable_query_log
|
--enable_query_log
|
||||||
|
|
||||||
# Step #4. Bring back the async slave and restart replication
|
# Step #4. Bring back the async slave and restart replication
|
||||||
@ -85,8 +85,9 @@ DROP TABLE t1;
|
|||||||
STOP SLAVE;
|
STOP SLAVE;
|
||||||
RESET SLAVE ALL;
|
RESET SLAVE ALL;
|
||||||
|
|
||||||
CALL mtr.add_suppression("Slave SQL: Error 'Unknown command' on query");
|
CALL mtr.add_suppression("Slave SQL: Error 'WSREP has not yet prepared node for application use' on query");
|
||||||
CALL mtr.add_suppression("Slave: Unknown command Error_code: 1047");
|
CALL mtr.add_suppression("Slave: WSREP has not yet prepared node for application use Error_code: 1047");
|
||||||
|
CALL mtr.add_suppression("TORDERED} returned -107 \\(Transport endpoint is not connected\\)");
|
||||||
CALL mtr.add_suppression("Transport endpoint is not connected");
|
CALL mtr.add_suppression("Transport endpoint is not connected");
|
||||||
CALL mtr.add_suppression("Slave SQL: Error in Xid_log_event: Commit could not be completed, 'Deadlock found when trying to get lock; try restarting transaction', Error_code: 1213");
|
CALL mtr.add_suppression("Slave SQL: Error in Xid_log_event: Commit could not be completed, 'Deadlock found when trying to get lock; try restarting transaction', Error_code: 1213");
|
||||||
CALL mtr.add_suppression("Slave SQL: Node has dropped from cluster, Error_code: 1047");
|
CALL mtr.add_suppression("Slave SQL: Node has dropped from cluster, Error_code: 1047");
|
||||||
|
@ -43,9 +43,9 @@ let $run=10;
|
|||||||
while($run)
|
while($run)
|
||||||
{
|
{
|
||||||
--error 0,1
|
--error 0,1
|
||||||
exec $MYSQL --user=root --host=127.0.0.1 --port=$NODE_MYPORT_1 test
|
exec $MYSQL --user=root --host=127.0.0.1 --port=$NODE_MYPORT_1 test \
|
||||||
< $MYSQLTEST_VARDIR/tmp/galera_concurrent.sql &
|
< $MYSQLTEST_VARDIR/tmp/galera_concurrent.sql & \
|
||||||
$MYSQL --user=root --host=127.0.0.1 --port=$NODE_MYPORT_2 test
|
$MYSQL --user=root --host=127.0.0.1 --port=$NODE_MYPORT_2 test \
|
||||||
< $MYSQLTEST_VARDIR/tmp/galera_concurrent.sql;
|
< $MYSQLTEST_VARDIR/tmp/galera_concurrent.sql;
|
||||||
dec $run;
|
dec $run;
|
||||||
}
|
}
|
||||||
|
@ -1 +1,3 @@
|
|||||||
--query_cache_type=1 --query_cache_size=1000000
|
--query_cache_type=1
|
||||||
|
--query_cache_size=1000000
|
||||||
|
--wsrep_replicate_myisam=ON
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
--source include/galera_cluster.inc
|
--source include/galera_cluster.inc
|
||||||
--source include/have_innodb.inc
|
--source include/have_innodb.inc
|
||||||
--source include/have_query_cache.inc
|
--source include/have_query_cache.inc
|
||||||
|
--source include/have_wsrep_replicate_myisam.inc
|
||||||
|
|
||||||
--disable_warnings
|
--disable_warnings
|
||||||
DROP TABLE IF EXISTS t1, t2, x1, x2;
|
DROP TABLE IF EXISTS t1, t2, x1, x2;
|
||||||
|
13
mysql-test/suite/galera/t/galera_schema_dirty_reads.test
Normal file
13
mysql-test/suite/galera/t/galera_schema_dirty_reads.test
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#
|
||||||
|
# Dirty reads from INFORMATION_SCHEMA tables.
|
||||||
|
#
|
||||||
|
--source include/galera_cluster.inc
|
||||||
|
--source include/have_innodb.inc
|
||||||
|
--disable_info
|
||||||
|
USE information_schema;
|
||||||
|
SELECT * FROM SESSION_VARIABLES WHERE VARIABLE_NAME LIKE "wsrep_dirty_reads";
|
||||||
|
SET GLOBAL wsrep_reject_queries=ALL;
|
||||||
|
SELECT * FROM SESSION_VARIABLES WHERE VARIABLE_NAME LIKE "wsrep_dirty_reads";
|
||||||
|
SET GLOBAL wsrep_reject_queries=NONE;
|
||||||
|
SET SESSION wsrep_dirty_reads=TRUE;
|
||||||
|
SELECT * FROM SESSION_VARIABLES WHERE VARIABLE_NAME LIKE "wsrep_dirty_reads";
|
@ -24,7 +24,6 @@ SET GLOBAL wsrep_cluster_address = 'foo://';
|
|||||||
|
|
||||||
SET SESSION wsrep_sync_wait=0;
|
SET SESSION wsrep_sync_wait=0;
|
||||||
|
|
||||||
--error ER_UNKNOWN_COM_ERROR
|
|
||||||
SELECT COUNT(*) > 0 FROM INFORMATION_SCHEMA.GLOBAL_STATUS;
|
SELECT COUNT(*) > 0 FROM INFORMATION_SCHEMA.GLOBAL_STATUS;
|
||||||
|
|
||||||
# Must return 'OFF'
|
# Must return 'OFF'
|
||||||
|
@ -47,15 +47,14 @@ SET @@session.wsrep_dirty_reads=OFF;
|
|||||||
--error ER_UNKNOWN_COM_ERROR
|
--error ER_UNKNOWN_COM_ERROR
|
||||||
SELECT i, variable_name, variable_value FROM t1, information_schema.session_variables WHERE variable_name LIKE "wsrep_dirty_reads" AND i = 1;
|
SELECT i, variable_name, variable_value FROM t1, information_schema.session_variables WHERE variable_name LIKE "wsrep_dirty_reads" AND i = 1;
|
||||||
|
|
||||||
|
--error ER_UNKNOWN_COM_ERROR
|
||||||
SELECT 1;
|
SELECT 1;
|
||||||
|
|
||||||
--error ER_UNKNOWN_COM_ERROR
|
--error ER_UNKNOWN_COM_ERROR
|
||||||
USE information_schema;
|
USE information_schema;
|
||||||
|
|
||||||
--error ER_UNKNOWN_COM_ERROR
|
|
||||||
SELECT * FROM information_schema.session_variables WHERE variable_name LIKE "wsrep_dirty_reads";
|
SELECT * FROM information_schema.session_variables WHERE variable_name LIKE "wsrep_dirty_reads";
|
||||||
|
|
||||||
--error ER_UNKNOWN_COM_ERROR
|
|
||||||
SELECT COUNT(*) >= 10 FROM performance_schema.events_statements_history;
|
SELECT COUNT(*) >= 10 FROM performance_schema.events_statements_history;
|
||||||
|
|
||||||
--disable_query_log
|
--disable_query_log
|
||||||
|
44
mysql-test/suite/galera/t/galera_var_reject_queries.test
Normal file
44
mysql-test/suite/galera/t/galera_var_reject_queries.test
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
#
|
||||||
|
# Test wsrep_reject_queries
|
||||||
|
#
|
||||||
|
|
||||||
|
--source include/galera_cluster.inc
|
||||||
|
--source include/have_innodb.inc
|
||||||
|
|
||||||
|
CREATE TABLE t1 (f1 INTEGER);
|
||||||
|
|
||||||
|
--connect node_1a, 127.0.0.1, root, , test, $NODE_MYPORT_1
|
||||||
|
|
||||||
|
--connection node_1
|
||||||
|
--error ER_GLOBAL_VARIABLE
|
||||||
|
SET SESSION wsrep_reject_queries = ALL;
|
||||||
|
|
||||||
|
SET GLOBAL wsrep_reject_queries = ALL;
|
||||||
|
|
||||||
|
--error ER_UNKNOWN_COM_ERROR
|
||||||
|
SELECT * FROM t1;
|
||||||
|
|
||||||
|
# Lost connection
|
||||||
|
--error 2013
|
||||||
|
SET GLOBAL wsrep_reject_queries = ALL_KILL;
|
||||||
|
|
||||||
|
--connection node_1a
|
||||||
|
--error ER_CONNECTION_KILLED,2013
|
||||||
|
SELECT * FROM t1;
|
||||||
|
|
||||||
|
--connect node_1b, 127.0.0.1, root, , test, $NODE_MYPORT_1
|
||||||
|
--error ER_UNKNOWN_COM_ERROR
|
||||||
|
SELECT * FROM t1;
|
||||||
|
|
||||||
|
# Confirm that replication continues
|
||||||
|
|
||||||
|
--connection node_2
|
||||||
|
SELECT VARIABLE_VALUE = 2 FROM INFORMATION_SCHEMA.GLOBAL_STATUS WHERE VARIABLE_NAME = 'wsrep_cluster_size';
|
||||||
|
INSERT INTO t1 VALUES (1);
|
||||||
|
|
||||||
|
--connect node_1c, 127.0.0.1, root, , test, $NODE_MYPORT_1
|
||||||
|
SET GLOBAL wsrep_reject_queries = NONE;
|
||||||
|
|
||||||
|
SELECT COUNT(*) = 1 FROM t1;
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
@ -421,6 +421,20 @@ NUMERIC_BLOCK_SIZE NULL
|
|||||||
ENUM_VALUE_LIST OFF,ON
|
ENUM_VALUE_LIST OFF,ON
|
||||||
READ_ONLY YES
|
READ_ONLY YES
|
||||||
COMMAND_LINE_ARGUMENT OPTIONAL
|
COMMAND_LINE_ARGUMENT OPTIONAL
|
||||||
|
VARIABLE_NAME WSREP_REJECT_QUERIES
|
||||||
|
SESSION_VALUE NULL
|
||||||
|
GLOBAL_VALUE NONE
|
||||||
|
GLOBAL_VALUE_ORIGIN COMPILE-TIME
|
||||||
|
DEFAULT_VALUE NONE
|
||||||
|
VARIABLE_SCOPE GLOBAL
|
||||||
|
VARIABLE_TYPE ENUM
|
||||||
|
VARIABLE_COMMENT Variable to set to reject queries
|
||||||
|
NUMERIC_MIN_VALUE NULL
|
||||||
|
NUMERIC_MAX_VALUE NULL
|
||||||
|
NUMERIC_BLOCK_SIZE NULL
|
||||||
|
ENUM_VALUE_LIST NONE,ALL,ALL_KILL
|
||||||
|
READ_ONLY NO
|
||||||
|
COMMAND_LINE_ARGUMENT OPTIONAL
|
||||||
VARIABLE_NAME WSREP_REPLICATE_MYISAM
|
VARIABLE_NAME WSREP_REPLICATE_MYISAM
|
||||||
SESSION_VALUE NULL
|
SESSION_VALUE NULL
|
||||||
GLOBAL_VALUE OFF
|
GLOBAL_VALUE OFF
|
||||||
|
@ -391,6 +391,15 @@ EXPLAIN EXTENDED
|
|||||||
SELECT * FROM t1 WHERE COALESCE(c,0)='3 ' AND COALESCE(d,0)=COALESCE(c,0);
|
SELECT * FROM t1 WHERE COALESCE(c,0)='3 ' AND COALESCE(d,0)=COALESCE(c,0);
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-15005 ASAN: stack-buffer-overflow in my_strnncollsp_simple
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
SET NAMES latin1;
|
||||||
|
SELECT CONVERT(1, CHAR) IN ('100', 10, '101');
|
||||||
|
SELECT CONVERT(1, CHAR) IN ('100', 10, '1');
|
||||||
|
SELECT CONVERT(1, CHAR) IN ('100', '10', '1');
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # End of 10.1 tests
|
--echo # End of 10.1 tests
|
||||||
--echo #
|
--echo #
|
||||||
|
@ -2033,6 +2033,16 @@ SELECT CONVERT(_utf8 0xC499 USING latin1);
|
|||||||
SELECT CAST(_utf8 0xC499 AS CHAR CHARACTER SET latin1);
|
SELECT CAST(_utf8 0xC499 AS CHAR CHARACTER SET latin1);
|
||||||
|
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-15005 ASAN: stack-buffer-overflow in my_strnncollsp_simple
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
SET NAMES utf8;
|
||||||
|
SELECT CONVERT(1, CHAR) IN ('100', 10, '101');
|
||||||
|
SELECT CONVERT(1, CHAR) IN ('100', 10, '1');
|
||||||
|
SELECT CONVERT(1, CHAR) IN ('100', '10', '1');
|
||||||
|
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # End of 10.1 tests
|
--echo # End of 10.1 tests
|
||||||
--echo #
|
--echo #
|
||||||
|
@ -31,120 +31,638 @@ select * from prefixinno;
|
|||||||
let $show_count_statement = show status like 'innodb_secondary_index_triggered_cluster_reads';
|
let $show_count_statement = show status like 'innodb_secondary_index_triggered_cluster_reads';
|
||||||
let $show_opt_statement = show status like 'innodb_secondary_index_triggered_cluster_reads_avoided';
|
let $show_opt_statement = show status like 'innodb_secondary_index_triggered_cluster_reads_avoided';
|
||||||
|
|
||||||
--disable_query_log
|
|
||||||
|
|
||||||
--echo # Baseline sanity check: 0, 0.
|
--echo # Baseline sanity check: 0, 0.
|
||||||
--let $base_count = query_get_value($show_count_statement, Value, 1)
|
let $base_count = query_get_value($show_count_statement, Value, 1);
|
||||||
--let $base_opt = query_get_value($show_opt_statement, Value, 1)
|
let $base_opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
select "no-op query";
|
select "no-op query";
|
||||||
--let $count = query_get_value($show_count_statement, Value, 1)
|
|
||||||
|
let $count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
--disable_query_log
|
||||||
eval select $count - $base_count into @cluster_lookups;
|
eval select $count - $base_count into @cluster_lookups;
|
||||||
select @cluster_lookups = 0 as cluster_lookups_matched;
|
eval select $opt - $base_opt into @cluster_lookups_avoided;
|
||||||
--let $opt = query_get_value($show_opt_statement, Value, 1)
|
--enable_query_log
|
||||||
eval select $opt - $base_opt into @cluster_lookups;
|
|
||||||
select @cluster_lookups = 0 as cluster_lookups_avoided_matched;
|
select @cluster_lookups;
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
|
||||||
--echo # Eligible for optimization.
|
--echo # Eligible for optimization.
|
||||||
--let $base_count = query_get_value($show_count_statement, Value, 1)
|
let $base_count = query_get_value($show_count_statement, Value, 1);
|
||||||
--let $base_opt = query_get_value($show_opt_statement, Value, 1)
|
let $base_opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
select id, bigfield from prefixinno where bigfield = repeat('d', 31);
|
select id, bigfield from prefixinno where bigfield = repeat('d', 31);
|
||||||
--let $count = query_get_value($show_count_statement, Value, 1)
|
|
||||||
|
let $count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
--disable_query_log
|
||||||
eval select $count - $base_count into @cluster_lookups;
|
eval select $count - $base_count into @cluster_lookups;
|
||||||
select @cluster_lookups = 0 as cluster_lookups_matched;
|
eval select $opt - $base_opt into @cluster_lookups_avoided;
|
||||||
--let $opt = query_get_value($show_opt_statement, Value, 1)
|
--enable_query_log
|
||||||
eval select $opt - $base_opt into @cluster_lookups;
|
|
||||||
select @cluster_lookups = 1 as cluster_lookups_avoided_matched;
|
select @cluster_lookups;
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
|
||||||
--echo # Eligible for optimization, access via fake_id only.
|
--echo # Eligible for optimization, access via fake_id only.
|
||||||
--let $base_count = query_get_value($show_count_statement, Value, 1)
|
let $base_count = query_get_value($show_count_statement, Value, 1);
|
||||||
--let $base_opt = query_get_value($show_opt_statement, Value, 1)
|
let $base_opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
select id, bigfield from prefixinno where fake_id = 1031;
|
select id, bigfield from prefixinno where fake_id = 1031;
|
||||||
--let $count = query_get_value($show_count_statement, Value, 1)
|
|
||||||
|
let $count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
--disable_query_log
|
||||||
eval select $count - $base_count into @cluster_lookups;
|
eval select $count - $base_count into @cluster_lookups;
|
||||||
select @cluster_lookups = 0 as cluster_lookups_matched;
|
eval select $opt - $base_opt into @cluster_lookups_avoided;
|
||||||
--let $opt = query_get_value($show_opt_statement, Value, 1)
|
--enable_query_log
|
||||||
eval select $opt - $base_opt into @cluster_lookups;
|
|
||||||
select @cluster_lookups = 1 as cluster_lookups_avoided_matched;
|
select @cluster_lookups;
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
|
||||||
--echo # Not eligible for optimization, access via fake_id of big row.
|
--echo # Not eligible for optimization, access via fake_id of big row.
|
||||||
--let $base_count = query_get_value($show_count_statement, Value, 1)
|
let $base_count = query_get_value($show_count_statement, Value, 1);
|
||||||
--let $base_opt = query_get_value($show_opt_statement, Value, 1)
|
let $base_opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
select id, bigfield from prefixinno where fake_id = 1033;
|
select id, bigfield from prefixinno where fake_id = 1033;
|
||||||
--let $count = query_get_value($show_count_statement, Value, 1)
|
|
||||||
|
let $count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
--disable_query_log
|
||||||
eval select $count - $base_count into @cluster_lookups;
|
eval select $count - $base_count into @cluster_lookups;
|
||||||
select @cluster_lookups = 1 as cluster_lookups_matched;
|
eval select $opt - $base_opt into @cluster_lookups_avoided;
|
||||||
--let $opt = query_get_value($show_opt_statement, Value, 1)
|
--enable_query_log
|
||||||
eval select $opt - $base_opt into @cluster_lookups;
|
|
||||||
select @cluster_lookups = 0 as cluster_lookups_avoided_matched;
|
select @cluster_lookups;
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
|
||||||
--echo # Not eligible for optimization.
|
--echo # Not eligible for optimization.
|
||||||
--let $base_count = query_get_value($show_count_statement, Value, 1)
|
let $base_count = query_get_value($show_count_statement, Value, 1);
|
||||||
--let $base_opt = query_get_value($show_opt_statement, Value, 1)
|
let $base_opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
select id, bigfield from prefixinno where bigfield = repeat('x', 32);
|
select id, bigfield from prefixinno where bigfield = repeat('x', 32);
|
||||||
--let $count = query_get_value($show_count_statement, Value, 1)
|
|
||||||
|
let $count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
--disable_query_log
|
||||||
eval select $count - $base_count into @cluster_lookups;
|
eval select $count - $base_count into @cluster_lookups;
|
||||||
select @cluster_lookups = 1 as cluster_lookups_matched;
|
eval select $opt - $base_opt into @cluster_lookups_avoided;
|
||||||
--let $opt = query_get_value($show_opt_statement, Value, 1)
|
--enable_query_log
|
||||||
eval select $opt - $base_opt into @cluster_lookups;
|
|
||||||
select @cluster_lookups = 0 as cluster_lookups_avoided_matched;
|
select @cluster_lookups;
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
|
||||||
--echo # Not eligible for optimization.
|
--echo # Not eligible for optimization.
|
||||||
--let $base_count = query_get_value($show_count_statement, Value, 1)
|
let $base_count = query_get_value($show_count_statement, Value, 1);
|
||||||
--let $base_opt = query_get_value($show_opt_statement, Value, 1)
|
let $base_opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
select id, bigfield from prefixinno where bigfield = repeat('y', 33);
|
select id, bigfield from prefixinno where bigfield = repeat('y', 33);
|
||||||
--let $count = query_get_value($show_count_statement, Value, 1)
|
|
||||||
|
let $count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
--disable_query_log
|
||||||
eval select $count - $base_count into @cluster_lookups;
|
eval select $count - $base_count into @cluster_lookups;
|
||||||
select @cluster_lookups = 1 as cluster_lookups_matched;
|
eval select $opt - $base_opt into @cluster_lookups_avoided;
|
||||||
--let $opt = query_get_value($show_opt_statement, Value, 1)
|
--enable_query_log
|
||||||
eval select $opt - $base_opt into @cluster_lookups;
|
|
||||||
select @cluster_lookups = 0 as cluster_lookups_avoided_matched;
|
select @cluster_lookups;
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
|
||||||
--echo # Eligible, should not increment lookup counter.
|
--echo # Eligible, should not increment lookup counter.
|
||||||
--let $base_count = query_get_value($show_count_statement, Value, 1)
|
let $base_count = query_get_value($show_count_statement, Value, 1);
|
||||||
--let $base_opt = query_get_value($show_opt_statement, Value, 1)
|
let $base_opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
select id, bigfield from prefixinno where bigfield = repeat('b', 8);
|
select id, bigfield from prefixinno where bigfield = repeat('b', 8);
|
||||||
--let $count = query_get_value($show_count_statement, Value, 1)
|
|
||||||
|
let $count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
--disable_query_log
|
||||||
eval select $count - $base_count into @cluster_lookups;
|
eval select $count - $base_count into @cluster_lookups;
|
||||||
select @cluster_lookups = 0 as cluster_lookups_matched;
|
eval select $opt - $base_opt into @cluster_lookups_avoided;
|
||||||
--let $opt = query_get_value($show_opt_statement, Value, 1)
|
--enable_query_log
|
||||||
eval select $opt - $base_opt into @cluster_lookups;
|
|
||||||
select @cluster_lookups = 1 as cluster_lookups_avoided_matched;
|
select @cluster_lookups;
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
|
||||||
--echo # Eligible, should not increment lookup counter.
|
--echo # Eligible, should not increment lookup counter.
|
||||||
--let $base_count = query_get_value($show_count_statement, Value, 1)
|
let $base_count = query_get_value($show_count_statement, Value, 1);
|
||||||
--let $base_opt = query_get_value($show_opt_statement, Value, 1)
|
let $base_opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
select id, bigfield from prefixinno where bigfield = repeat('c', 24);
|
select id, bigfield from prefixinno where bigfield = repeat('c', 24);
|
||||||
--let $count = query_get_value($show_count_statement, Value, 1)
|
|
||||||
|
let $count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
--disable_query_log
|
||||||
eval select $count - $base_count into @cluster_lookups;
|
eval select $count - $base_count into @cluster_lookups;
|
||||||
select @cluster_lookups = 0 as cluster_lookups_matched;
|
eval select $opt - $base_opt into @cluster_lookups_avoided;
|
||||||
--let $opt = query_get_value($show_opt_statement, Value, 1)
|
--enable_query_log
|
||||||
eval select $opt - $base_opt into @cluster_lookups;
|
|
||||||
select @cluster_lookups = 1 as cluster_lookups_avoided_matched;
|
select @cluster_lookups;
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
|
||||||
--echo # Should increment lookup counter.
|
--echo # Should increment lookup counter.
|
||||||
--let $base_count = query_get_value($show_count_statement, Value, 1)
|
let $base_count = query_get_value($show_count_statement, Value, 1);
|
||||||
--let $base_opt = query_get_value($show_opt_statement, Value, 1)
|
let $base_opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
select id, bigfield from prefixinno where bigfield = repeat('z', 128);
|
select id, bigfield from prefixinno where bigfield = repeat('z', 128);
|
||||||
--let $count = query_get_value($show_count_statement, Value, 1)
|
|
||||||
|
let $count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
--disable_query_log
|
||||||
eval select $count - $base_count into @cluster_lookups;
|
eval select $count - $base_count into @cluster_lookups;
|
||||||
select @cluster_lookups = 1 as cluster_lookups_matched;
|
eval select $opt - $base_opt into @cluster_lookups_avoided;
|
||||||
--let $opt = query_get_value($show_opt_statement, Value, 1)
|
--enable_query_log
|
||||||
eval select $opt - $base_opt into @cluster_lookups;
|
|
||||||
select @cluster_lookups = 0 as cluster_lookups_avoided_matched;
|
select @cluster_lookups;
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
|
||||||
--echo # Disable optimization, confirm we still increment counter.
|
--echo # Disable optimization, confirm we still increment counter.
|
||||||
--let $base_count = query_get_value($show_count_statement, Value, 1)
|
let $base_count = query_get_value($show_count_statement, Value, 1);
|
||||||
--let $base_opt = query_get_value($show_opt_statement, Value, 1)
|
let $base_opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
set global innodb_prefix_index_cluster_optimization = OFF;
|
set global innodb_prefix_index_cluster_optimization = OFF;
|
||||||
select id, bigfield from prefixinno where fake_id = 1033;
|
select id, bigfield from prefixinno where fake_id = 1033;
|
||||||
--let $count = query_get_value($show_count_statement, Value, 1)
|
|
||||||
|
let $count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
--disable_query_log
|
||||||
eval select $count - $base_count into @cluster_lookups;
|
eval select $count - $base_count into @cluster_lookups;
|
||||||
select @cluster_lookups = 1 as cluster_lookups_matched;
|
eval select $opt - $base_opt into @cluster_lookups_avoided;
|
||||||
--let $opt = query_get_value($show_opt_statement, Value, 1)
|
--enable_query_log
|
||||||
eval select $opt - $base_opt into @cluster_lookups;
|
|
||||||
select @cluster_lookups = 0 as cluster_lookups_avoided_matched;
|
|
||||||
|
|
||||||
|
select @cluster_lookups;
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
|
||||||
--echo # make test suite happy by cleaning up our mess
|
|
||||||
drop table prefixinno;
|
drop table prefixinno;
|
||||||
|
|
||||||
|
--echo # Multi-byte handling case
|
||||||
|
|
||||||
|
set global innodb_prefix_index_cluster_optimization = ON;
|
||||||
|
SET NAMES utf8mb4;
|
||||||
|
CREATE TABLE t1(
|
||||||
|
f1 varchar(10) CHARACTER SET UTF8MB4 COLLATE UTF8MB4_BIN,
|
||||||
|
INDEX (f1(3)))ENGINE=INNODB;
|
||||||
|
|
||||||
|
INSERT INTO t1 VALUES('a'), ('cccc'), ('až'), ('cčc'), ('ggᵷg'), ('¢¢');
|
||||||
|
INSERT INTO t1 VALUES('தமிழ்'), ('🐱🌑'), ('🌒'), ('🌑');
|
||||||
|
INSERT INTO t1 VALUES('😊me'), ('eu€'), ('ls¢');
|
||||||
|
|
||||||
|
--echo # Eligible - record length is shorter than prefix
|
||||||
|
let $base_count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $base_opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
SELECT f1 FROM t1 FORCE INDEX (`f1`) WHERE f1 = 'a';
|
||||||
|
|
||||||
|
let $count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
--disable_query_log
|
||||||
|
eval set @cluster_lookups = $count - $base_count;
|
||||||
|
eval set @cluster_lookups_avoided = $opt - $base_opt;
|
||||||
|
--enable_query_log
|
||||||
|
|
||||||
|
select @cluster_lookups;
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
|
||||||
|
--echo # Not eligible - record length longer than prefix length
|
||||||
|
let $base_count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $base_opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
SELECT f1 FROM t1 FORCE INDEX (`f1`) WHERE f1 like 'c%';
|
||||||
|
|
||||||
|
let $count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
--disable_query_log
|
||||||
|
eval set @cluster_lookups = $count - $base_count;
|
||||||
|
eval set @cluster_lookups_avoided = $opt - $base_opt;
|
||||||
|
--enable_query_log
|
||||||
|
|
||||||
|
select @cluster_lookups;
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
|
||||||
|
--echo # Eligible - record length shorter than prefix length
|
||||||
|
let $base_count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $base_opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
SELECT f1 FROM t1 FORCE INDEX (`f1`) WHERE f1 = 'až';
|
||||||
|
|
||||||
|
let $count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
--disable_query_log
|
||||||
|
eval set @cluster_lookups = $count - $base_count;
|
||||||
|
eval set @cluster_lookups_avoided = $opt - $base_opt;
|
||||||
|
--enable_query_log
|
||||||
|
|
||||||
|
select @cluster_lookups;
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
|
||||||
|
--echo # Not eligible - record length longer than prefix length
|
||||||
|
|
||||||
|
let $base_count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $base_opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
SELECT f1 FROM t1 FORCE INDEX (`f1`) WHERE f1 = 'தமிழ்';
|
||||||
|
|
||||||
|
let $count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
--disable_query_log
|
||||||
|
eval set @cluster_lookups = $count - $base_count;
|
||||||
|
eval set @cluster_lookups_avoided = $opt - $base_opt;
|
||||||
|
--enable_query_log
|
||||||
|
|
||||||
|
select @cluster_lookups;
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
|
||||||
|
--echo # Not eligible - record length longer than prefix length
|
||||||
|
|
||||||
|
let $base_count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $base_opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
SELECT f1 FROM t1 FORCE INDEX (`f1`) WHERE f1 like 'ggᵷ%';
|
||||||
|
|
||||||
|
let $count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
--disable_query_log
|
||||||
|
eval set @cluster_lookups = $count - $base_count;
|
||||||
|
eval set @cluster_lookups_avoided = $opt - $base_opt;
|
||||||
|
--enable_query_log
|
||||||
|
|
||||||
|
select @cluster_lookups;
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
|
||||||
|
--echo # Not eligible - record length longer than prefix length
|
||||||
|
|
||||||
|
let $base_count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $base_opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
SELECT f1 FROM t1 FORCE INDEX (`f1`) WHERE f1 like '😊%';
|
||||||
|
|
||||||
|
let $count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
--disable_query_log
|
||||||
|
eval set @cluster_lookups = $count - $base_count;
|
||||||
|
eval set @cluster_lookups_avoided = $opt - $base_opt;
|
||||||
|
--enable_query_log
|
||||||
|
|
||||||
|
select @cluster_lookups;
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
|
||||||
|
--echo # Not eligible - record length longer than prefix length
|
||||||
|
|
||||||
|
let $base_count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $base_opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
SELECT f1 FROM t1 FORCE INDEX (`f1`) WHERE f1 = 'ls¢';
|
||||||
|
|
||||||
|
let $count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
--disable_query_log
|
||||||
|
eval set @cluster_lookups = $count - $base_count;
|
||||||
|
eval set @cluster_lookups_avoided = $opt - $base_opt;
|
||||||
|
--enable_query_log
|
||||||
|
|
||||||
|
select @cluster_lookups;
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
|
||||||
|
--echo # Eligible - record length shorter than prefix length
|
||||||
|
|
||||||
|
let $base_count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $base_opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
SELECT f1 FROM t1 FORCE INDEX (`f1`) WHERE f1 like '¢¢%';
|
||||||
|
|
||||||
|
let $count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
--disable_query_log
|
||||||
|
eval set @cluster_lookups = $count - $base_count;
|
||||||
|
eval set @cluster_lookups_avoided = $opt - $base_opt;
|
||||||
|
--enable_query_log
|
||||||
|
|
||||||
|
select @cluster_lookups;
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
|
||||||
|
--echo # Eligible - record length shorter than prefix length
|
||||||
|
|
||||||
|
let $base_count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $base_opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
SELECT f1 FROM t1 FORCE INDEX (`f1`) WHERE f1 like '🐱🌑%';
|
||||||
|
|
||||||
|
let $count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
--disable_query_log
|
||||||
|
eval set @cluster_lookups = $count - $base_count;
|
||||||
|
eval set @cluster_lookups_avoided = $opt - $base_opt;
|
||||||
|
--enable_query_log
|
||||||
|
|
||||||
|
select @cluster_lookups;
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
|
||||||
|
--echo # Not eligible - record length longer than prefix length
|
||||||
|
|
||||||
|
let $base_count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $base_opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
SELECT f1 FROM t1 FORCE INDEX (`f1`) WHERE f1 like '🌑%';
|
||||||
|
|
||||||
|
let $count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
--disable_query_log
|
||||||
|
eval set @cluster_lookups = $count - $base_count;
|
||||||
|
eval set @cluster_lookups_avoided = $opt - $base_opt;
|
||||||
|
--enable_query_log
|
||||||
|
|
||||||
|
select @cluster_lookups;
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
|
||||||
|
--echo # Not eligible - record length longer than prefix length
|
||||||
|
|
||||||
|
let $base_count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $base_opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
SELECT f1 FROM t1 FORCE INDEX (`f1`) WHERE f1 like '🌒%';
|
||||||
|
|
||||||
|
let $count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
--disable_query_log
|
||||||
|
eval set @cluster_lookups = $count - $base_count;
|
||||||
|
eval set @cluster_lookups_avoided = $opt - $base_opt;
|
||||||
|
--enable_query_log
|
||||||
|
|
||||||
|
select @cluster_lookups;
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo # Multi-byte with minimum character length > 1 bytes
|
||||||
|
|
||||||
|
CREATE TABLE t1(
|
||||||
|
f1 varchar(10) CHARACTER SET UTF16 COLLATE UTF16_BIN,
|
||||||
|
INDEX (f1(3)))ENGINE=INNODB;
|
||||||
|
|
||||||
|
INSERT INTO t1 VALUES('a'), ('cccc'), ('až'), ('cčc'), ('ggᵷg'), ('¢¢');
|
||||||
|
INSERT INTO t1 VALUES('தமிழ்'), ('🐱🌑'), ('🌒'), ('🌑');
|
||||||
|
INSERT INTO t1 VALUES('😊me'), ('eu€'), ('ls¢');
|
||||||
|
|
||||||
|
--echo # Eligible - record length is shorter than prefix
|
||||||
|
let $base_count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $base_opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
SELECT f1 FROM t1 FORCE INDEX (`f1`) WHERE f1 = 'a';
|
||||||
|
|
||||||
|
let $count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
--disable_query_log
|
||||||
|
eval set @cluster_lookups = $count - $base_count;
|
||||||
|
eval set @cluster_lookups_avoided = $opt - $base_opt;
|
||||||
|
--enable_query_log
|
||||||
|
|
||||||
|
select @cluster_lookups;
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
|
||||||
|
--echo # Not eligible - record length longer than prefix length
|
||||||
|
let $base_count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $base_opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
SELECT f1 FROM t1 FORCE INDEX (`f1`) WHERE f1 like 'c%';
|
||||||
|
|
||||||
|
let $count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
--disable_query_log
|
||||||
|
eval set @cluster_lookups = $count - $base_count;
|
||||||
|
eval set @cluster_lookups_avoided = $opt - $base_opt;
|
||||||
|
--enable_query_log
|
||||||
|
|
||||||
|
select @cluster_lookups;
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
|
||||||
|
--echo # Eligible - record length shorter than prefix length
|
||||||
|
|
||||||
|
let $base_count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $base_opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
SELECT f1 FROM t1 FORCE INDEX (`f1`) WHERE f1 = 'až';
|
||||||
|
|
||||||
|
let $count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
--disable_query_log
|
||||||
|
eval set @cluster_lookups = $count - $base_count;
|
||||||
|
eval set @cluster_lookups_avoided = $opt - $base_opt;
|
||||||
|
--enable_query_log
|
||||||
|
|
||||||
|
select @cluster_lookups;
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
|
||||||
|
--echo # Not eligible - record length longer than prefix length
|
||||||
|
|
||||||
|
let $base_count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $base_opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
SELECT f1 FROM t1 FORCE INDEX (`f1`) WHERE f1 = 'தமிழ்';
|
||||||
|
|
||||||
|
let $count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
--disable_query_log
|
||||||
|
eval set @cluster_lookups = $count - $base_count;
|
||||||
|
eval set @cluster_lookups_avoided = $opt - $base_opt;
|
||||||
|
--enable_query_log
|
||||||
|
|
||||||
|
select @cluster_lookups;
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
|
||||||
|
--echo # Not eligible - record length longer than prefix length
|
||||||
|
|
||||||
|
let $base_count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $base_opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
SELECT f1 FROM t1 FORCE INDEX (`f1`) WHERE f1 like 'ggᵷ%';
|
||||||
|
|
||||||
|
let $count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
--disable_query_log
|
||||||
|
eval set @cluster_lookups = $count - $base_count;
|
||||||
|
eval set @cluster_lookups_avoided = $opt - $base_opt;
|
||||||
|
--enable_query_log
|
||||||
|
|
||||||
|
select @cluster_lookups;
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
|
||||||
|
--echo # Not eligible - record length longer than prefix length
|
||||||
|
|
||||||
|
let $base_count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $base_opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
SELECT f1 FROM t1 FORCE INDEX (`f1`) WHERE f1 like '😊%';
|
||||||
|
|
||||||
|
let $count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
--disable_query_log
|
||||||
|
eval set @cluster_lookups = $count - $base_count;
|
||||||
|
eval set @cluster_lookups_avoided = $opt - $base_opt;
|
||||||
|
--enable_query_log
|
||||||
|
|
||||||
|
select @cluster_lookups;
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
|
||||||
|
--echo # Not eligible - record length longer than prefix length
|
||||||
|
|
||||||
|
let $base_count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $base_opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
SELECT f1 FROM t1 FORCE INDEX (`f1`) WHERE f1 = 'ls¢';
|
||||||
|
|
||||||
|
let $count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
--disable_query_log
|
||||||
|
eval set @cluster_lookups = $count - $base_count;
|
||||||
|
eval set @cluster_lookups_avoided = $opt - $base_opt;
|
||||||
|
--enable_query_log
|
||||||
|
|
||||||
|
select @cluster_lookups;
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
|
||||||
|
--echo # Eligible - record length shorter than prefix length
|
||||||
|
|
||||||
|
let $base_count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $base_opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
SELECT f1 FROM t1 FORCE INDEX(`f1`) WHERE f1 like '¢¢%';
|
||||||
|
|
||||||
|
let $count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
--disable_query_log
|
||||||
|
eval set @cluster_lookups = $count - $base_count;
|
||||||
|
eval set @cluster_lookups_avoided = $opt - $base_opt;
|
||||||
|
--enable_query_log
|
||||||
|
|
||||||
|
select @cluster_lookups;
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
|
||||||
|
--echo # Eligible - record length shorter than prefix length
|
||||||
|
|
||||||
|
let $base_count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $base_opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
SELECT f1 FROM t1 FORCE INDEX (`f1`) WHERE f1 like '🐱🌑%';
|
||||||
|
|
||||||
|
let $count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
--disable_query_log
|
||||||
|
eval set @cluster_lookups = $count - $base_count;
|
||||||
|
eval set @cluster_lookups_avoided = $opt - $base_opt;
|
||||||
|
--enable_query_log
|
||||||
|
|
||||||
|
select @cluster_lookups;
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
|
||||||
|
--echo # Eligible - record length is shorter than prefix length
|
||||||
|
|
||||||
|
let $base_count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $base_opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
SELECT f1 FROM t1 FORCE INDEX (`f1`) WHERE f1 like '🌑%';
|
||||||
|
|
||||||
|
let $count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
--disable_query_log
|
||||||
|
eval set @cluster_lookups = $count - $base_count;
|
||||||
|
eval set @cluster_lookups_avoided = $opt - $base_opt;
|
||||||
|
--enable_query_log
|
||||||
|
|
||||||
|
select @cluster_lookups;
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
|
||||||
|
--echo # Eligible - record length is shorter than prefix length
|
||||||
|
|
||||||
|
let $base_count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $base_opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
SELECT f1 FROM t1 FORCE INDEX (`f1`) WHERE f1 like '🌒%';
|
||||||
|
|
||||||
|
let $count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
--disable_query_log
|
||||||
|
eval set @cluster_lookups = $count - $base_count;
|
||||||
|
eval set @cluster_lookups_avoided = $opt - $base_opt;
|
||||||
|
--enable_query_log
|
||||||
|
|
||||||
|
select @cluster_lookups;
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
CREATE TABLE t1(
|
||||||
|
col1 INT,
|
||||||
|
col2 BLOB DEFAULT NULL,
|
||||||
|
INDEX `idx1`(col2(4), col1))ENGINE=INNODB;
|
||||||
|
INSERT INTO t1 VALUES (2, 'test'), (3, repeat('test1', 2000));
|
||||||
|
INSERT INTO t1(col1) VALUES(1);
|
||||||
|
|
||||||
|
--echo # Eligible - record length is shorter than prefix length
|
||||||
|
|
||||||
|
let $base_count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $base_opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
SELECT col1 FROM t1 FORCE INDEX (`idx1`) WHERE col2 is NULL;
|
||||||
|
|
||||||
|
let $count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
--disable_query_log
|
||||||
|
eval set @cluster_lookups = $count - $base_count;
|
||||||
|
eval set @cluster_lookups_avoided = $opt - $base_opt;
|
||||||
|
--enable_query_log
|
||||||
|
|
||||||
|
select @cluster_lookups;
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
|
||||||
|
--echo # Not eligible - record length longer than prefix index
|
||||||
|
|
||||||
|
let $base_count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $base_opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
SELECT col1 FROM t1 FORCE INDEX (`idx1`) WHERE col2 like 'test1%';
|
||||||
|
|
||||||
|
let $count = query_get_value($show_count_statement, Value, 1);
|
||||||
|
let $opt = query_get_value($show_opt_statement, Value, 1);
|
||||||
|
|
||||||
|
--disable_query_log
|
||||||
|
eval set @cluster_lookups = $count - $base_count;
|
||||||
|
eval set @cluster_lookups_avoided = $opt - $base_opt;
|
||||||
|
--enable_query_log
|
||||||
|
|
||||||
|
select @cluster_lookups;
|
||||||
|
select @cluster_lookups_avoided;
|
||||||
|
|
||||||
|
DROP TABLE t1;
|
||||||
set global innodb_prefix_index_cluster_optimization = OFF;
|
set global innodb_prefix_index_cluster_optimization = OFF;
|
||||||
|
@ -723,6 +723,29 @@ INSERT INTO t1 VALUES ('10:10:10'),('10:20:30');
|
|||||||
SELECT MAX(a), MAX(COALESCE(a)) FROM t1;
|
SELECT MAX(a), MAX(COALESCE(a)) FROM t1;
|
||||||
DROP TABLE t1;
|
DROP TABLE t1;
|
||||||
|
|
||||||
|
--echo #
|
||||||
|
--echo # MDEV-15321: different results when using value of optimizer_use_condition_selectivity=4 and =1
|
||||||
|
--echo #
|
||||||
|
|
||||||
|
SET @save_old_mode=@@old_mode;
|
||||||
|
SET @@old_mode=zero_date_time_cast;
|
||||||
|
CREATE TABLE t1 (a TIME);
|
||||||
|
INSERT INTO t1 VALUES ('0000-00-00 10:20:30'),('0000-00-00 10:20:31');
|
||||||
|
INSERT INTO t1 VALUES ('0000-00-01 10:20:30'),('0000-00-01 10:20:31');
|
||||||
|
INSERT INTO t1 VALUES ('31 10:20:30'),('32 10:20:30'),('33 10:20:30'),('34 10:20:30');
|
||||||
|
|
||||||
|
SET @save_optimizer_use_condition_selectivity= @@optimizer_use_condition_selectivity;
|
||||||
|
SET @@optimizer_use_condition_selectivity=1;
|
||||||
|
SELECT * FROM t1 WHERE a='0000-00-01 10:20:30' AND LENGTH(a)=8;
|
||||||
|
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='0000-00-01 10:20:30' AND LENGTH(a)=8;
|
||||||
|
|
||||||
|
SET @@optimizer_use_condition_selectivity=4;
|
||||||
|
SELECT * FROM t1 WHERE a='0000-00-01 10:20:30' AND LENGTH(a)=8;
|
||||||
|
EXPLAIN EXTENDED SELECT * FROM t1 WHERE a='0000-00-01 10:20:30' AND LENGTH(a)=8;
|
||||||
|
drop table t1;
|
||||||
|
SET @@optimizer_use_condition_selectivity= @save_optimizer_use_condition_selectivity;
|
||||||
|
set @@old_mode= @save_old_mode;
|
||||||
|
|
||||||
--echo #
|
--echo #
|
||||||
--echo # End of 10.1 tests
|
--echo # End of 10.1 tests
|
||||||
--echo #
|
--echo #
|
||||||
|
14
sql/item.cc
14
sql/item.cc
@ -179,19 +179,21 @@ bool Item::get_time_with_conversion(THD *thd, MYSQL_TIME *ltime,
|
|||||||
- truncate the YYYYMMDD part
|
- truncate the YYYYMMDD part
|
||||||
- add (MM*33+DD)*24 to hours
|
- add (MM*33+DD)*24 to hours
|
||||||
- add (MM*31+DD)*24 to hours
|
- add (MM*31+DD)*24 to hours
|
||||||
Let's return NULL here, to disallow equal field propagation.
|
Let's return TRUE here, to disallow equal field propagation.
|
||||||
Note, If we start to use this method in more pieces of the code other
|
Note, If we start to use this method in more pieces of the code other
|
||||||
than eqial field propagation, we should probably return
|
than equal field propagation, we should probably return
|
||||||
NULL only if some flag in fuzzydate is set.
|
TRUE only if some flag in fuzzydate is set.
|
||||||
*/
|
*/
|
||||||
return (null_value= true);
|
return true;
|
||||||
}
|
}
|
||||||
if (datetime_to_time_with_warn(thd, ltime, <ime2, TIME_SECOND_PART_DIGITS))
|
if (datetime_to_time_with_warn(thd, ltime, <ime2, TIME_SECOND_PART_DIGITS))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
Time difference between CURRENT_DATE and ltime
|
If the time difference between CURRENT_DATE and ltime
|
||||||
did not fit into the supported TIME range
|
did not fit into the supported TIME range, then we set the
|
||||||
|
difference to the maximum possible value in the supported TIME range
|
||||||
*/
|
*/
|
||||||
|
DBUG_ASSERT(0);
|
||||||
return (null_value= true);
|
return (null_value= true);
|
||||||
}
|
}
|
||||||
*ltime= ltime2;
|
*ltime= ltime2;
|
||||||
|
@ -1383,6 +1383,13 @@ public:
|
|||||||
{
|
{
|
||||||
value_res= item->val_str(&value);
|
value_res= item->val_str(&value);
|
||||||
m_null_value= item->null_value;
|
m_null_value= item->null_value;
|
||||||
|
// Make sure to cache the result String inside "value"
|
||||||
|
if (value_res && value_res != &value)
|
||||||
|
{
|
||||||
|
if (value.copy(*value_res))
|
||||||
|
value.set("", 0, item->collation.collation);
|
||||||
|
value_res= &value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
int cmp(Item *arg)
|
int cmp(Item *arg)
|
||||||
{
|
{
|
||||||
|
@ -5726,11 +5726,15 @@ public:
|
|||||||
sent by the user (ie: stored procedure).
|
sent by the user (ie: stored procedure).
|
||||||
*/
|
*/
|
||||||
#define CF_SKIP_QUESTIONS (1U << 1)
|
#define CF_SKIP_QUESTIONS (1U << 1)
|
||||||
|
#ifdef WITH_WSREP
|
||||||
/**
|
/**
|
||||||
Do not check that wsrep snapshot is ready before allowing this command
|
Do not check that wsrep snapshot is ready before allowing this command
|
||||||
*/
|
*/
|
||||||
#define CF_SKIP_WSREP_CHECK (1U << 2)
|
#define CF_SKIP_WSREP_CHECK (1U << 2)
|
||||||
|
#else
|
||||||
|
#define CF_SKIP_WSREP_CHECK 0
|
||||||
|
#endif /* WITH_WSREP */
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Do not allow it for COM_MULTI batch
|
Do not allow it for COM_MULTI batch
|
||||||
*/
|
*/
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* Copyright (c) 2000, 2017, Oracle and/or its affiliates.
|
/* Copyright (c) 2000, 2017, Oracle and/or its affiliates.
|
||||||
Copyright (c) 2008, 2017, MariaDB
|
Copyright (c) 2008, 2018, MariaDB
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -506,6 +506,7 @@ void init_update_queries(void)
|
|||||||
server_command_flags[COM_SHUTDOWN]= CF_SKIP_WSREP_CHECK;
|
server_command_flags[COM_SHUTDOWN]= CF_SKIP_WSREP_CHECK;
|
||||||
server_command_flags[COM_SLEEP]= CF_SKIP_WSREP_CHECK;
|
server_command_flags[COM_SLEEP]= CF_SKIP_WSREP_CHECK;
|
||||||
server_command_flags[COM_TIME]= CF_SKIP_WSREP_CHECK;
|
server_command_flags[COM_TIME]= CF_SKIP_WSREP_CHECK;
|
||||||
|
server_command_flags[COM_INIT_DB]= CF_SKIP_WSREP_CHECK;
|
||||||
server_command_flags[COM_END]= CF_SKIP_WSREP_CHECK;
|
server_command_flags[COM_END]= CF_SKIP_WSREP_CHECK;
|
||||||
for (uint i= COM_MDB_GAP_BEG; i <= COM_MDB_GAP_END; i++)
|
for (uint i= COM_MDB_GAP_BEG; i <= COM_MDB_GAP_END; i++)
|
||||||
{
|
{
|
||||||
@ -519,6 +520,8 @@ void init_update_queries(void)
|
|||||||
server_command_flags[COM_QUERY]= CF_SKIP_WSREP_CHECK;
|
server_command_flags[COM_QUERY]= CF_SKIP_WSREP_CHECK;
|
||||||
server_command_flags[COM_SET_OPTION]= CF_SKIP_WSREP_CHECK;
|
server_command_flags[COM_SET_OPTION]= CF_SKIP_WSREP_CHECK;
|
||||||
server_command_flags[COM_STMT_PREPARE]= CF_SKIP_QUESTIONS | CF_SKIP_WSREP_CHECK;
|
server_command_flags[COM_STMT_PREPARE]= CF_SKIP_QUESTIONS | CF_SKIP_WSREP_CHECK;
|
||||||
|
server_command_flags[COM_STMT_EXECUTE]= CF_SKIP_WSREP_CHECK;
|
||||||
|
server_command_flags[COM_STMT_FETCH]= CF_SKIP_WSREP_CHECK;
|
||||||
server_command_flags[COM_STMT_CLOSE]= CF_SKIP_QUESTIONS | CF_SKIP_WSREP_CHECK;
|
server_command_flags[COM_STMT_CLOSE]= CF_SKIP_QUESTIONS | CF_SKIP_WSREP_CHECK;
|
||||||
server_command_flags[COM_STMT_RESET]= CF_SKIP_QUESTIONS | CF_SKIP_WSREP_CHECK;
|
server_command_flags[COM_STMT_RESET]= CF_SKIP_QUESTIONS | CF_SKIP_WSREP_CHECK;
|
||||||
server_command_flags[COM_STMT_EXECUTE]= CF_SKIP_WSREP_CHECK;
|
server_command_flags[COM_STMT_EXECUTE]= CF_SKIP_WSREP_CHECK;
|
||||||
@ -1146,21 +1149,28 @@ static enum enum_server_command fetch_command(THD *thd, char *packet)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#ifndef EMBEDDED_LIBRARY
|
|
||||||
|
|
||||||
#ifdef WITH_WSREP
|
#ifdef WITH_WSREP
|
||||||
static bool wsrep_node_is_ready(THD *thd)
|
static bool wsrep_tables_accessible_when_detached(const TABLE_LIST *tables)
|
||||||
{
|
{
|
||||||
if (thd->variables.wsrep_on && !thd->wsrep_applier && !wsrep_ready)
|
bool has_tables = false;
|
||||||
|
for (const TABLE_LIST *table= tables; table; table= table->next_global)
|
||||||
|
{
|
||||||
|
TABLE_CATEGORY c;
|
||||||
|
LEX_STRING db, tn;
|
||||||
|
lex_string_set(&db, table->db);
|
||||||
|
lex_string_set(&tn, table->table_name);
|
||||||
|
c= get_table_category(&db, &tn);
|
||||||
|
if (c != TABLE_CATEGORY_INFORMATION &&
|
||||||
|
c != TABLE_CATEGORY_PERFORMANCE)
|
||||||
{
|
{
|
||||||
my_message(ER_UNKNOWN_COM_ERROR,
|
|
||||||
"WSREP has not yet prepared node for application use",
|
|
||||||
MYF(0));
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
has_tables = true;
|
||||||
}
|
}
|
||||||
#endif
|
return has_tables;
|
||||||
|
}
|
||||||
|
#endif /* WITH_WSREP */
|
||||||
|
#ifndef EMBEDDED_LIBRARY
|
||||||
|
|
||||||
/**
|
/**
|
||||||
Read one command from connection and execute it (query or simple command).
|
Read one command from connection and execute it (query or simple command).
|
||||||
@ -1336,8 +1346,9 @@ bool do_command(THD *thd)
|
|||||||
/*
|
/*
|
||||||
Bail out if DB snapshot has not been installed.
|
Bail out if DB snapshot has not been installed.
|
||||||
*/
|
*/
|
||||||
if (!(server_command_flags[command] & CF_SKIP_WSREP_CHECK) &&
|
if (thd->variables.wsrep_on && !thd->wsrep_applier &&
|
||||||
!wsrep_node_is_ready(thd))
|
(!wsrep_ready || wsrep_reject_queries != WSREP_REJECT_NONE) &&
|
||||||
|
(server_command_flags[command] & CF_SKIP_WSREP_CHECK) == 0)
|
||||||
{
|
{
|
||||||
thd->protocol->end_statement();
|
thd->protocol->end_statement();
|
||||||
|
|
||||||
@ -3143,21 +3154,24 @@ mysql_execute_command(THD *thd)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Bail out if DB snapshot has not been installed. SET and SHOW commands,
|
* Bail out if DB snapshot has not been installed. We however,
|
||||||
however, are always allowed.
|
* allow SET and SHOW queries and reads from information schema
|
||||||
Select query is also allowed if it does not access any table.
|
* and dirty reads (if configured)
|
||||||
We additionally allow all other commands that do not change data in
|
|
||||||
case wsrep_dirty_reads is enabled.
|
|
||||||
*/
|
*/
|
||||||
if (lex->sql_command != SQLCOM_SET_OPTION &&
|
if (thd->variables.wsrep_on &&
|
||||||
!wsrep_is_show_query(lex->sql_command) &&
|
!thd->wsrep_applier &&
|
||||||
|
!(wsrep_ready && wsrep_reject_queries == WSREP_REJECT_NONE) &&
|
||||||
!(thd->variables.wsrep_dirty_reads &&
|
!(thd->variables.wsrep_dirty_reads &&
|
||||||
!is_update_query(lex->sql_command)) &&
|
(sql_command_flags[lex->sql_command] & CF_CHANGES_DATA) == 0) &&
|
||||||
!(lex->sql_command == SQLCOM_SELECT &&
|
!wsrep_tables_accessible_when_detached(all_tables) &&
|
||||||
!all_tables) &&
|
lex->sql_command != SQLCOM_SET_OPTION &&
|
||||||
!wsrep_node_is_ready(thd))
|
!wsrep_is_show_query(lex->sql_command))
|
||||||
|
{
|
||||||
|
my_message(ER_UNKNOWN_COM_ERROR,
|
||||||
|
"WSREP has not yet prepared node for application use", MYF(0));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
#endif /* WITH_WSREP */
|
#endif /* WITH_WSREP */
|
||||||
status_var_increment(thd->status_var.com_stat[lex->sql_command]);
|
status_var_increment(thd->status_var.com_stat[lex->sql_command]);
|
||||||
thd->progress.report_to_client= MY_TEST(sql_command_flags[lex->sql_command] &
|
thd->progress.report_to_client= MY_TEST(sql_command_flags[lex->sql_command] &
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/* Copyright (c) 2002, 2015, Oracle and/or its affiliates.
|
/* Copyright (c) 2002, 2015, Oracle and/or its affiliates.
|
||||||
Copyright (c) 2012, 2017, MariaDB Corporation.
|
Copyright (c) 2012, 2018, MariaDB Corporation.
|
||||||
|
|
||||||
This program is free software; you can redistribute it and/or modify
|
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
|
it under the terms of the GNU General Public License as published by
|
||||||
@ -5077,6 +5077,14 @@ static Sys_var_mybool Sys_wsrep_desync (
|
|||||||
ON_CHECK(wsrep_desync_check),
|
ON_CHECK(wsrep_desync_check),
|
||||||
ON_UPDATE(wsrep_desync_update));
|
ON_UPDATE(wsrep_desync_update));
|
||||||
|
|
||||||
|
static const char *wsrep_reject_queries_names[]= { "NONE", "ALL", "ALL_KILL", NullS };
|
||||||
|
static Sys_var_enum Sys_wsrep_reject_queries(
|
||||||
|
"wsrep_reject_queries", "Variable to set to reject queries",
|
||||||
|
GLOBAL_VAR(wsrep_reject_queries), CMD_LINE(OPT_ARG),
|
||||||
|
wsrep_reject_queries_names, DEFAULT(WSREP_REJECT_NONE),
|
||||||
|
NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(0),
|
||||||
|
ON_UPDATE(wsrep_reject_queries_update));
|
||||||
|
|
||||||
static const char *wsrep_binlog_format_names[]=
|
static const char *wsrep_binlog_format_names[]=
|
||||||
{"MIXED", "STATEMENT", "ROW", "NONE", NullS};
|
{"MIXED", "STATEMENT", "ROW", "NONE", NullS};
|
||||||
static Sys_var_enum Sys_wsrep_forced_binlog_format(
|
static Sys_var_enum Sys_wsrep_forced_binlog_format(
|
||||||
|
@ -80,6 +80,7 @@ extern const char* wsrep_notify_cmd;
|
|||||||
extern long wsrep_max_protocol_version;
|
extern long wsrep_max_protocol_version;
|
||||||
extern ulong wsrep_forced_binlog_format;
|
extern ulong wsrep_forced_binlog_format;
|
||||||
extern my_bool wsrep_desync;
|
extern my_bool wsrep_desync;
|
||||||
|
extern ulong wsrep_reject_queries;
|
||||||
extern my_bool wsrep_replicate_myisam;
|
extern my_bool wsrep_replicate_myisam;
|
||||||
extern ulong wsrep_mysql_replication_bundle;
|
extern ulong wsrep_mysql_replication_bundle;
|
||||||
extern my_bool wsrep_restart_slave;
|
extern my_bool wsrep_restart_slave;
|
||||||
@ -91,6 +92,12 @@ extern bool wsrep_new_cluster;
|
|||||||
extern bool wsrep_gtid_mode;
|
extern bool wsrep_gtid_mode;
|
||||||
extern uint32 wsrep_gtid_domain_id;
|
extern uint32 wsrep_gtid_domain_id;
|
||||||
|
|
||||||
|
enum enum_wsrep_reject_types {
|
||||||
|
WSREP_REJECT_NONE, /* nothing rejected */
|
||||||
|
WSREP_REJECT_ALL, /* reject all queries, with UNKNOWN_COMMAND error */
|
||||||
|
WSREP_REJECT_ALL_KILL /* kill existing connections and reject all queries*/
|
||||||
|
};
|
||||||
|
|
||||||
enum enum_wsrep_OSU_method {
|
enum enum_wsrep_OSU_method {
|
||||||
WSREP_OSU_TOI,
|
WSREP_OSU_TOI,
|
||||||
WSREP_OSU_RSU,
|
WSREP_OSU_RSU,
|
||||||
|
@ -26,6 +26,7 @@
|
|||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
|
ulong wsrep_reject_queries;
|
||||||
|
|
||||||
static long wsrep_prev_slave_threads = wsrep_slave_threads;
|
static long wsrep_prev_slave_threads = wsrep_slave_threads;
|
||||||
|
|
||||||
@ -413,6 +414,27 @@ void wsrep_provider_options_init(const char* value)
|
|||||||
wsrep_provider_options = (value) ? my_strdup(value, MYF(0)) : NULL;
|
wsrep_provider_options = (value) ? my_strdup(value, MYF(0)) : NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool wsrep_reject_queries_update(sys_var *self, THD* thd, enum_var_type type)
|
||||||
|
{
|
||||||
|
switch (wsrep_reject_queries) {
|
||||||
|
case WSREP_REJECT_NONE:
|
||||||
|
WSREP_INFO("Allowing client queries due to manual setting");
|
||||||
|
break;
|
||||||
|
case WSREP_REJECT_ALL:
|
||||||
|
WSREP_INFO("Rejecting client queries due to manual setting");
|
||||||
|
break;
|
||||||
|
case WSREP_REJECT_ALL_KILL:
|
||||||
|
wsrep_close_client_connections(FALSE);
|
||||||
|
WSREP_INFO("Rejecting client queries and killing connections due to manual setting");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
WSREP_INFO("Unknown value for wsrep_reject_queries: %lu",
|
||||||
|
wsrep_reject_queries);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
static int wsrep_cluster_address_verify (const char* cluster_address_str)
|
static int wsrep_cluster_address_verify (const char* cluster_address_str)
|
||||||
{
|
{
|
||||||
/* There is no predefined address format, it depends on provider. */
|
/* There is no predefined address format, it depends on provider. */
|
||||||
|
@ -92,6 +92,7 @@ extern bool wsrep_desync_update UPDATE_ARGS;
|
|||||||
|
|
||||||
extern bool wsrep_max_ws_size_check CHECK_ARGS;
|
extern bool wsrep_max_ws_size_check CHECK_ARGS;
|
||||||
extern bool wsrep_max_ws_size_update UPDATE_ARGS;
|
extern bool wsrep_max_ws_size_update UPDATE_ARGS;
|
||||||
|
extern bool wsrep_reject_queries_update UPDATE_ARGS;
|
||||||
|
|
||||||
#else /* WITH_WSREP */
|
#else /* WITH_WSREP */
|
||||||
|
|
||||||
|
@ -275,7 +275,20 @@ buf_dump(
|
|||||||
buf_dump_status(STATUS_INFO, "Dumping buffer pool(s) to %s",
|
buf_dump_status(STATUS_INFO, "Dumping buffer pool(s) to %s",
|
||||||
full_filename);
|
full_filename);
|
||||||
|
|
||||||
f = fopen(tmp_filename, "w");
|
#if defined(__GLIBC__) || defined(__WIN__) || O_CLOEXEC == 0
|
||||||
|
f = fopen(tmp_filename, "w" STR_O_CLOEXEC);
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
fd = open(tmp_filename, O_CREAT | O_TRUNC | O_CLOEXEC | O_WRONLY, 0640);
|
||||||
|
if (fd >= 0) {
|
||||||
|
f = fdopen(fd, "w");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
f = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (f == NULL) {
|
if (f == NULL) {
|
||||||
buf_dump_status(STATUS_ERR,
|
buf_dump_status(STATUS_ERR,
|
||||||
"Cannot open '%s' for writing: %s",
|
"Cannot open '%s' for writing: %s",
|
||||||
|
@ -2255,7 +2255,7 @@ AIO::is_linux_native_aio_supported()
|
|||||||
|
|
||||||
strcpy(name + dirnamelen, "ib_logfile0");
|
strcpy(name + dirnamelen, "ib_logfile0");
|
||||||
|
|
||||||
fd = open(name, O_RDONLY);
|
fd = open(name, O_RDONLY | O_CLOEXEC);
|
||||||
|
|
||||||
if (fd == -1) {
|
if (fd == -1) {
|
||||||
|
|
||||||
|
@ -2915,7 +2915,9 @@ row_sel_field_store_in_mysql_format_func(
|
|||||||
|| !(templ->mysql_col_len % templ->mbmaxlen));
|
|| !(templ->mysql_col_len % templ->mbmaxlen));
|
||||||
ut_ad(len * templ->mbmaxlen >= templ->mysql_col_len
|
ut_ad(len * templ->mbmaxlen >= templ->mysql_col_len
|
||||||
|| (field_no == templ->icp_rec_field_no
|
|| (field_no == templ->icp_rec_field_no
|
||||||
&& field->prefix_len > 0));
|
&& field->prefix_len > 0)
|
||||||
|
|| templ->rec_field_is_prefix);
|
||||||
|
|
||||||
ut_ad(templ->is_virtual
|
ut_ad(templ->is_virtual
|
||||||
|| !(field->prefix_len % templ->mbmaxlen));
|
|| !(field->prefix_len % templ->mbmaxlen));
|
||||||
|
|
||||||
@ -4061,6 +4063,118 @@ row_sel_fill_vrow(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Return the record field length in characters.
|
||||||
|
@param[in] col table column of the field
|
||||||
|
@param[in] field_no field number
|
||||||
|
@param[in] rec physical record
|
||||||
|
@param[in] offsets field offsets in the physical record
|
||||||
|
@return field length in characters. */
|
||||||
|
static
|
||||||
|
size_t
|
||||||
|
rec_field_len_in_chars(
|
||||||
|
const dict_col_t* col,
|
||||||
|
const ulint field_no,
|
||||||
|
const rec_t* rec,
|
||||||
|
const ulint* offsets)
|
||||||
|
{
|
||||||
|
const ulint cset = dtype_get_charset_coll(col->prtype);
|
||||||
|
const CHARSET_INFO* cs = all_charsets[cset];
|
||||||
|
ulint rec_field_len;
|
||||||
|
const char* rec_field = reinterpret_cast<const char *>(
|
||||||
|
rec_get_nth_field(
|
||||||
|
rec, offsets, field_no, &rec_field_len));
|
||||||
|
|
||||||
|
if (UNIV_UNLIKELY(!cs)) {
|
||||||
|
ib::warn() << "Missing collation " << cset;
|
||||||
|
return SIZE_T_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(cs->cset->numchars(cs, rec_field, rec_field + rec_field_len));
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Avoid the clustered index lookup if all the following conditions
|
||||||
|
are true:
|
||||||
|
1) all columns are in secondary index
|
||||||
|
2) all values for columns that are prefix-only indexes are shorter
|
||||||
|
than the prefix size. This optimization can avoid many IOs for certain schemas.
|
||||||
|
@return true, to avoid clustered index lookup. */
|
||||||
|
static
|
||||||
|
bool row_search_with_covering_prefix(
|
||||||
|
row_prebuilt_t* prebuilt,
|
||||||
|
const rec_t* rec,
|
||||||
|
const ulint* offsets)
|
||||||
|
{
|
||||||
|
const dict_index_t* index = prebuilt->index;
|
||||||
|
ut_ad(!dict_index_is_clust(index));
|
||||||
|
|
||||||
|
if (!srv_prefix_index_cluster_optimization) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Optimization only applicable if there the number of secondary index
|
||||||
|
fields are greater than or equal to number of clustered index fields. */
|
||||||
|
if (prebuilt->n_template > index->n_fields) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ulint i = 0; i < prebuilt->n_template; i++) {
|
||||||
|
mysql_row_templ_t* templ = prebuilt->mysql_template + i;
|
||||||
|
ulint j = templ->rec_prefix_field_no;
|
||||||
|
|
||||||
|
/** Condition (1) : is the field in the index. */
|
||||||
|
if (j == ULINT_UNDEFINED) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Condition (2): If this is a prefix index then
|
||||||
|
row's value size shorter than prefix length. */
|
||||||
|
|
||||||
|
if (!templ->rec_field_is_prefix) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ulint rec_size = rec_offs_nth_size(offsets, j);
|
||||||
|
const dict_field_t* field = dict_index_get_nth_field(index, j);
|
||||||
|
ulint max_chars = field->prefix_len / templ->mbmaxlen;
|
||||||
|
|
||||||
|
ut_a(field->prefix_len > 0);
|
||||||
|
|
||||||
|
if (rec_size < max_chars) {
|
||||||
|
/* Record in bytes shorter than the index
|
||||||
|
prefix length in char. */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rec_size * templ->mbminlen >= field->prefix_len) {
|
||||||
|
/* Shortest representation string by the
|
||||||
|
byte length of the record is longer than the
|
||||||
|
maximum possible index prefix. */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t num_chars = rec_field_len_in_chars(
|
||||||
|
field->col, j, rec, offsets);
|
||||||
|
|
||||||
|
if (num_chars >= max_chars) {
|
||||||
|
/* No of chars to store the record exceeds
|
||||||
|
the index prefix character length. */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If prefix index optimization condition satisfied then
|
||||||
|
for all columns above, use rec_prefix_field_no instead of
|
||||||
|
rec_field_no, and skip the clustered lookup below. */
|
||||||
|
for (ulint i = 0; i < prebuilt->n_template; i++) {
|
||||||
|
mysql_row_templ_t* templ = prebuilt->mysql_template + i;
|
||||||
|
templ->rec_field_no = templ->rec_prefix_field_no;
|
||||||
|
ut_a(templ->rec_field_no != ULINT_UNDEFINED);
|
||||||
|
}
|
||||||
|
|
||||||
|
srv_stats.n_sec_rec_cluster_reads_avoided.inc();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/** Searches for rows in the database using cursor.
|
/** Searches for rows in the database using cursor.
|
||||||
Function is mainly used for tables that are shared across connections and
|
Function is mainly used for tables that are shared across connections and
|
||||||
so it employs technique that can help re-construct the rows that
|
so it employs technique that can help re-construct the rows that
|
||||||
@ -4120,7 +4234,6 @@ row_search_mvcc(
|
|||||||
ulint* offsets = offsets_;
|
ulint* offsets = offsets_;
|
||||||
ibool table_lock_waited = FALSE;
|
ibool table_lock_waited = FALSE;
|
||||||
byte* next_buf = 0;
|
byte* next_buf = 0;
|
||||||
ibool use_clustered_index = FALSE;
|
|
||||||
bool spatial_search = false;
|
bool spatial_search = false;
|
||||||
|
|
||||||
rec_offs_init(offsets_);
|
rec_offs_init(offsets_);
|
||||||
@ -5179,69 +5292,10 @@ locks_ok_del_marked:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the clustered index record if needed, if we did not do the
|
if (index != clust_index && prebuilt->need_to_access_clustered) {
|
||||||
search using the clustered index... */
|
if (row_search_with_covering_prefix(prebuilt, rec, offsets)) {
|
||||||
|
goto use_covering_index;
|
||||||
use_clustered_index =
|
|
||||||
(index != clust_index && prebuilt->need_to_access_clustered);
|
|
||||||
|
|
||||||
if (use_clustered_index && srv_prefix_index_cluster_optimization
|
|
||||||
&& prebuilt->n_template <= index->n_fields) {
|
|
||||||
/* ...but, perhaps avoid the clustered index lookup if
|
|
||||||
all of the following are true:
|
|
||||||
1) all columns are in the secondary index
|
|
||||||
2) all values for columns that are prefix-only
|
|
||||||
indexes are shorter than the prefix size
|
|
||||||
This optimization can avoid many IOs for certain schemas.
|
|
||||||
*/
|
|
||||||
ibool row_contains_all_values = TRUE;
|
|
||||||
uint i;
|
|
||||||
for (i = 0; i < prebuilt->n_template; i++) {
|
|
||||||
/* Condition (1) from above: is the field in the
|
|
||||||
index (prefix or not)? */
|
|
||||||
mysql_row_templ_t* templ =
|
|
||||||
prebuilt->mysql_template + i;
|
|
||||||
ulint secondary_index_field_no =
|
|
||||||
templ->rec_prefix_field_no;
|
|
||||||
if (secondary_index_field_no == ULINT_UNDEFINED) {
|
|
||||||
row_contains_all_values = FALSE;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
/* Condition (2) from above: if this is a
|
|
||||||
prefix, is this row's value size shorter
|
|
||||||
than the prefix? */
|
|
||||||
if (templ->rec_field_is_prefix) {
|
|
||||||
ulint record_size = rec_offs_nth_size(
|
|
||||||
offsets,
|
|
||||||
secondary_index_field_no);
|
|
||||||
const dict_field_t *field =
|
|
||||||
dict_index_get_nth_field(
|
|
||||||
index,
|
|
||||||
secondary_index_field_no);
|
|
||||||
ut_a(field->prefix_len > 0);
|
|
||||||
if (record_size >= field->prefix_len) {
|
|
||||||
row_contains_all_values = FALSE;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* If (1) and (2) were true for all columns above, use
|
|
||||||
rec_prefix_field_no instead of rec_field_no, and skip
|
|
||||||
the clustered lookup below. */
|
|
||||||
if (row_contains_all_values) {
|
|
||||||
for (i = 0; i < prebuilt->n_template; i++) {
|
|
||||||
mysql_row_templ_t* templ =
|
|
||||||
prebuilt->mysql_template + i;
|
|
||||||
templ->rec_field_no =
|
|
||||||
templ->rec_prefix_field_no;
|
|
||||||
ut_a(templ->rec_field_no != ULINT_UNDEFINED);
|
|
||||||
}
|
|
||||||
use_clustered_index = FALSE;
|
|
||||||
srv_stats.n_sec_rec_cluster_reads_avoided.inc();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (use_clustered_index) {
|
|
||||||
requires_clust_rec:
|
requires_clust_rec:
|
||||||
ut_ad(index != clust_index);
|
ut_ad(index != clust_index);
|
||||||
/* We use a 'goto' to the preceding label if a consistent
|
/* We use a 'goto' to the preceding label if a consistent
|
||||||
@ -5339,6 +5393,7 @@ requires_clust_rec:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
use_covering_index:
|
||||||
result_rec = rec;
|
result_rec = rec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,6 +29,10 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_ORACLE_OCI
|
#ifdef HAVE_ORACLE_OCI
|
||||||
|
#if (defined(WIN32) || defined(_WIN32) || defined(WINDOWS) || defined(_WINDOWS))
|
||||||
|
#include <Shlwapi.h>
|
||||||
|
#define strcasestr StrStr
|
||||||
|
#endif
|
||||||
#include <oci.h>
|
#include <oci.h>
|
||||||
#include "spd_err.h"
|
#include "spd_err.h"
|
||||||
#include "spd_param.h"
|
#include "spd_param.h"
|
||||||
@ -3817,7 +3821,7 @@ int spider_db_oracle_util::open_item_func(
|
|||||||
{
|
{
|
||||||
Item_func_conv_charset *item_func_conv_charset =
|
Item_func_conv_charset *item_func_conv_charset =
|
||||||
(Item_func_conv_charset *)item_func;
|
(Item_func_conv_charset *)item_func;
|
||||||
CHARSET_INFO *conv_charset = item_func_conv_charset->conv_charset;
|
CHARSET_INFO *conv_charset = item_func_conv_charset->collation.collation;
|
||||||
uint cset_length = strlen(conv_charset->csname);
|
uint cset_length = strlen(conv_charset->csname);
|
||||||
if (str->reserve(SPIDER_SQL_USING_LEN + cset_length))
|
if (str->reserve(SPIDER_SQL_USING_LEN + cset_length))
|
||||||
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
|
DBUG_RETURN(HA_ERR_OUT_OF_MEM);
|
||||||
|
@ -371,6 +371,14 @@ SPIDER_CONN *spider_udf_direct_sql_create_conn(
|
|||||||
if (direct_sql->access_mode == 0)
|
if (direct_sql->access_mode == 0)
|
||||||
{
|
{
|
||||||
#endif
|
#endif
|
||||||
|
if (direct_sql->dbton_id == SPIDER_DBTON_SIZE)
|
||||||
|
{
|
||||||
|
/* Invalid target wrapper */
|
||||||
|
*error_num = ER_SPIDER_INVALID_CONNECT_INFO_NUM;
|
||||||
|
my_printf_error(*error_num, ER_SPIDER_INVALID_CONNECT_INFO_STR,
|
||||||
|
MYF(0), direct_sql->tgt_wrapper);
|
||||||
|
goto error_alloc_conn;
|
||||||
|
}
|
||||||
if (!(conn = (SPIDER_CONN *)
|
if (!(conn = (SPIDER_CONN *)
|
||||||
spider_bulk_malloc(spider_current_trx, 32, MYF(MY_WME | MY_ZEROFILL),
|
spider_bulk_malloc(spider_current_trx, 32, MYF(MY_WME | MY_ZEROFILL),
|
||||||
&conn, sizeof(*conn),
|
&conn, sizeof(*conn),
|
||||||
@ -398,6 +406,14 @@ SPIDER_CONN *spider_udf_direct_sql_create_conn(
|
|||||||
conn->default_database.init_calc_mem(138);
|
conn->default_database.init_calc_mem(138);
|
||||||
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
|
#if defined(HS_HAS_SQLCOM) && defined(HAVE_HANDLERSOCKET)
|
||||||
} else {
|
} else {
|
||||||
|
if (direct_sql->dbton_id == SPIDER_DBTON_SIZE)
|
||||||
|
{
|
||||||
|
/* Invalid target wrapper */
|
||||||
|
*error_num = ER_SPIDER_NOSQL_WRAPPER_IS_INVALID_NUM;
|
||||||
|
my_printf_error(*error_num, ER_SPIDER_NOSQL_WRAPPER_IS_INVALID_STR,
|
||||||
|
MYF(0), direct_sql->tgt_wrapper);
|
||||||
|
goto error_alloc_conn;
|
||||||
|
}
|
||||||
if (!(conn = (SPIDER_CONN *)
|
if (!(conn = (SPIDER_CONN *)
|
||||||
spider_bulk_malloc(spider_current_trx, 33, MYF(MY_WME | MY_ZEROFILL),
|
spider_bulk_malloc(spider_current_trx, 33, MYF(MY_WME | MY_ZEROFILL),
|
||||||
&conn, sizeof(*conn),
|
&conn, sizeof(*conn),
|
||||||
|
@ -10,7 +10,7 @@ col3 smallint(5) NOT NULL DEFAULT '1',
|
|||||||
filler varchar(255) DEFAULT NULL,
|
filler varchar(255) DEFAULT NULL,
|
||||||
KEY pk_ersatz(col1,col2,col3),
|
KEY pk_ersatz(col1,col2,col3),
|
||||||
KEY key1 (col1,col2) USING BTREE
|
KEY key1 (col1,col2) USING BTREE
|
||||||
) ENGINE=TokuDB DEFAULT CHARSET=latin1 PACK_KEYS=1 COMPRESSION=TOKUDB_LZMA;
|
) ENGINE=TokuDB DEFAULT CHARSET=latin1 PACK_KEYS=1;
|
||||||
insert into t3 select 1300000000+a, 12345, 7890, 'data' from t2;
|
insert into t3 select 1300000000+a, 12345, 7890, 'data' from t2;
|
||||||
insert into t3 select 1400000000+a, 12345, 7890, 'data' from t2;
|
insert into t3 select 1400000000+a, 12345, 7890, 'data' from t2;
|
||||||
insert into t3 select 1410799999+a, 12345, 7890, 'data' from t2;
|
insert into t3 select 1410799999+a, 12345, 7890, 'data' from t2;
|
||||||
@ -34,7 +34,7 @@ from t3
|
|||||||
where col1 <= 1410799999
|
where col1 <= 1410799999
|
||||||
order by col1 desc,col2 desc,col3 desc limit 1;
|
order by col1 desc,col2 desc,col3 desc limit 1;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t3 range pk_ersatz,key1 pk_ersatz 4 NULL 2001 Using where; Using index
|
1 SIMPLE t3 range pk_ersatz,key1 pk_ersatz 4 NULL # Using where; Using index
|
||||||
# The same query but the constant is bigger.
|
# The same query but the constant is bigger.
|
||||||
# The query should use range(PRIMARY), not full index scan:
|
# The query should use range(PRIMARY), not full index scan:
|
||||||
explain
|
explain
|
||||||
@ -43,5 +43,5 @@ from t3
|
|||||||
where col1 <= 1412199999
|
where col1 <= 1412199999
|
||||||
order by col1 desc, col2 desc, col3 desc limit 1;
|
order by col1 desc, col2 desc, col3 desc limit 1;
|
||||||
id select_type table type possible_keys key key_len ref rows Extra
|
id select_type table type possible_keys key key_len ref rows Extra
|
||||||
1 SIMPLE t3 range pk_ersatz,key1 pk_ersatz 4 NULL 15001 Using where; Using index
|
1 SIMPLE t3 range pk_ersatz,key1 pk_ersatz 4 NULL # Using where; Using index
|
||||||
drop table t1,t2,t3;
|
drop table t1,t2,t3;
|
||||||
|
@ -15,7 +15,7 @@ CREATE TABLE t3 (
|
|||||||
filler varchar(255) DEFAULT NULL,
|
filler varchar(255) DEFAULT NULL,
|
||||||
KEY pk_ersatz(col1,col2,col3),
|
KEY pk_ersatz(col1,col2,col3),
|
||||||
KEY key1 (col1,col2) USING BTREE
|
KEY key1 (col1,col2) USING BTREE
|
||||||
) ENGINE=TokuDB DEFAULT CHARSET=latin1 PACK_KEYS=1 COMPRESSION=TOKUDB_LZMA;
|
) ENGINE=TokuDB DEFAULT CHARSET=latin1 PACK_KEYS=1;
|
||||||
|
|
||||||
insert into t3 select 1300000000+a, 12345, 7890, 'data' from t2;
|
insert into t3 select 1300000000+a, 12345, 7890, 'data' from t2;
|
||||||
insert into t3 select 1400000000+a, 12345, 7890, 'data' from t2;
|
insert into t3 select 1400000000+a, 12345, 7890, 'data' from t2;
|
||||||
@ -35,6 +35,7 @@ insert into t3 select 1412099999+a, 12345, 7890, 'data' from t2;
|
|||||||
insert into t3 select 1412199999+a, 12345, 7890, 'data' from t2;
|
insert into t3 select 1412199999+a, 12345, 7890, 'data' from t2;
|
||||||
|
|
||||||
--echo # The following must use range(PRIMARY):
|
--echo # The following must use range(PRIMARY):
|
||||||
|
--replace_column 9 #
|
||||||
explain
|
explain
|
||||||
select col1,col2,col3
|
select col1,col2,col3
|
||||||
from t3
|
from t3
|
||||||
@ -43,6 +44,7 @@ order by col1 desc,col2 desc,col3 desc limit 1;
|
|||||||
|
|
||||||
--echo # The same query but the constant is bigger.
|
--echo # The same query but the constant is bigger.
|
||||||
--echo # The query should use range(PRIMARY), not full index scan:
|
--echo # The query should use range(PRIMARY), not full index scan:
|
||||||
|
--replace_column 9 #
|
||||||
explain
|
explain
|
||||||
select col1,col2,col3
|
select col1,col2,col3
|
||||||
from t3
|
from t3
|
||||||
|
@ -216,7 +216,20 @@ buf_dump(
|
|||||||
buf_dump_status(STATUS_NOTICE, "Dumping buffer pool(s) to %s",
|
buf_dump_status(STATUS_NOTICE, "Dumping buffer pool(s) to %s",
|
||||||
full_filename);
|
full_filename);
|
||||||
|
|
||||||
f = fopen(tmp_filename, "w");
|
#if defined(__GLIBC__) || defined(__WIN__) || O_CLOEXEC == 0
|
||||||
|
f = fopen(tmp_filename, "w" STR_O_CLOEXEC);
|
||||||
|
#else
|
||||||
|
{
|
||||||
|
int fd;
|
||||||
|
fd = open(tmp_filename, O_CREAT | O_TRUNC | O_CLOEXEC | O_WRONLY, 0640);
|
||||||
|
if (fd >= 0) {
|
||||||
|
f = fdopen(fd, "w");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
f = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
if (f == NULL) {
|
if (f == NULL) {
|
||||||
buf_dump_status(STATUS_ERR,
|
buf_dump_status(STATUS_ERR,
|
||||||
"Cannot open '%s' for writing: %s",
|
"Cannot open '%s' for writing: %s",
|
||||||
|
@ -3685,6 +3685,117 @@ row_search_idx_cond_check(
|
|||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Return the record field length in characters.
|
||||||
|
@param[in] col table column of the field
|
||||||
|
@param[in] field_no field number
|
||||||
|
@param[in] rec physical record
|
||||||
|
@param[in] offsets field offsets in the physical record
|
||||||
|
@return field length in characters. */
|
||||||
|
static
|
||||||
|
size_t
|
||||||
|
rec_field_len_in_chars(
|
||||||
|
const dict_col_t* col,
|
||||||
|
const ulint field_no,
|
||||||
|
const rec_t* rec,
|
||||||
|
const ulint* offsets)
|
||||||
|
{
|
||||||
|
const ulint cset = dtype_get_charset_coll(col->prtype);
|
||||||
|
const CHARSET_INFO* cs = all_charsets[cset];
|
||||||
|
ulint rec_field_len;
|
||||||
|
const char* rec_field = reinterpret_cast<const char *>(
|
||||||
|
rec_get_nth_field(
|
||||||
|
rec, offsets, field_no, &rec_field_len));
|
||||||
|
|
||||||
|
if (UNIV_UNLIKELY(!cs)) {
|
||||||
|
ib_logf(IB_LOG_LEVEL_WARN, "Missing collation " ULINTPF, cset);
|
||||||
|
return SIZE_T_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(cs->cset->numchars(cs, rec_field, rec_field + rec_field_len));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/** Avoid the clustered index lookup if all the following conditions
|
||||||
|
are true:
|
||||||
|
1) all columns are in secondary index
|
||||||
|
2) all values for columns that are prefix-only indexes are shorter
|
||||||
|
than the prefix size. This optimization can avoid many IOs for certain schemas.
|
||||||
|
@return true, to avoid clustered index lookup. */
|
||||||
|
static
|
||||||
|
bool row_search_with_covering_prefix(
|
||||||
|
row_prebuilt_t* prebuilt,
|
||||||
|
const rec_t* rec,
|
||||||
|
const ulint* offsets)
|
||||||
|
{
|
||||||
|
const dict_index_t* index = prebuilt->index;
|
||||||
|
ut_ad(!dict_index_is_clust(index));
|
||||||
|
|
||||||
|
if (!srv_prefix_index_cluster_optimization) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Optimization only applicable if the number of secondary index
|
||||||
|
fields are greater than or equal to number of clustered index fields. */
|
||||||
|
if (prebuilt->n_template > index->n_fields) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ulint i = 0; i < prebuilt->n_template; i++) {
|
||||||
|
mysql_row_templ_t* templ = prebuilt->mysql_template + i;
|
||||||
|
ulint j = templ->rec_prefix_field_no;
|
||||||
|
|
||||||
|
/** Condition (1) : is the field in the index. */
|
||||||
|
if (j == ULINT_UNDEFINED) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Condition (2): If this is a prefix index then
|
||||||
|
row's value size shorter than prefix length. */
|
||||||
|
|
||||||
|
if (!templ->rec_field_is_prefix) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
ulint rec_size = rec_offs_nth_size(offsets, j);
|
||||||
|
const dict_field_t* field = dict_index_get_nth_field(index, j);
|
||||||
|
ulint max_chars = field->prefix_len / templ->mbmaxlen;
|
||||||
|
|
||||||
|
ut_a(field->prefix_len > 0);
|
||||||
|
|
||||||
|
if (rec_size < max_chars) {
|
||||||
|
/* Record in bytes shorter than the index
|
||||||
|
prefix length in char. */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (rec_size * templ->mbminlen >= field->prefix_len) {
|
||||||
|
/* Shortest representation string by the
|
||||||
|
byte length of the record is longer than the
|
||||||
|
maximum possible index prefix. */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
size_t num_chars = rec_field_len_in_chars(
|
||||||
|
field->col, j, rec, offsets);
|
||||||
|
|
||||||
|
if (num_chars >= max_chars) {
|
||||||
|
/* No of chars to store the record exceeds
|
||||||
|
the index prefix character length. */
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (ulint i = 0; i < prebuilt->n_template; i++) {
|
||||||
|
mysql_row_templ_t* templ = prebuilt->mysql_template + i;
|
||||||
|
templ->rec_field_no = templ->rec_prefix_field_no;
|
||||||
|
ut_a(templ->rec_field_no != ULINT_UNDEFINED);
|
||||||
|
}
|
||||||
|
|
||||||
|
srv_stats.n_sec_rec_cluster_reads_avoided.inc();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
/********************************************************************//**
|
/********************************************************************//**
|
||||||
Searches for rows in the database. This is used in the interface to
|
Searches for rows in the database. This is used in the interface to
|
||||||
MySQL. This function opens a cursor, and also implements fetch next
|
MySQL. This function opens a cursor, and also implements fetch next
|
||||||
@ -3748,7 +3859,6 @@ row_search_for_mysql(
|
|||||||
ulint* offsets = offsets_;
|
ulint* offsets = offsets_;
|
||||||
ibool table_lock_waited = FALSE;
|
ibool table_lock_waited = FALSE;
|
||||||
byte* next_buf = 0;
|
byte* next_buf = 0;
|
||||||
bool use_clustered_index = false;
|
|
||||||
|
|
||||||
rec_offs_init(offsets_);
|
rec_offs_init(offsets_);
|
||||||
|
|
||||||
@ -4810,71 +4920,10 @@ locks_ok:
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get the clustered index record if needed, if we did not do the
|
if (index != clust_index && prebuilt->need_to_access_clustered) {
|
||||||
search using the clustered index... */
|
if (row_search_with_covering_prefix(prebuilt, rec, offsets)) {
|
||||||
|
goto use_covering_index;
|
||||||
use_clustered_index =
|
|
||||||
(index != clust_index && prebuilt->need_to_access_clustered);
|
|
||||||
|
|
||||||
if (use_clustered_index && srv_prefix_index_cluster_optimization
|
|
||||||
&& prebuilt->n_template <= index->n_fields) {
|
|
||||||
/* ...but, perhaps avoid the clustered index lookup if
|
|
||||||
all of the following are true:
|
|
||||||
1) all columns are in the secondary index
|
|
||||||
2) all values for columns that are prefix-only
|
|
||||||
indexes are shorter than the prefix size
|
|
||||||
This optimization can avoid many IOs for certain schemas.
|
|
||||||
*/
|
|
||||||
bool row_contains_all_values = true;
|
|
||||||
unsigned int i;
|
|
||||||
for (i = 0; i < prebuilt->n_template; i++) {
|
|
||||||
/* Condition (1) from above: is the field in the
|
|
||||||
index (prefix or not)? */
|
|
||||||
const mysql_row_templ_t* templ =
|
|
||||||
prebuilt->mysql_template + i;
|
|
||||||
ulint secondary_index_field_no =
|
|
||||||
templ->rec_prefix_field_no;
|
|
||||||
if (secondary_index_field_no == ULINT_UNDEFINED) {
|
|
||||||
row_contains_all_values = false;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
/* Condition (2) from above: if this is a
|
|
||||||
prefix, is this row's value size shorter
|
|
||||||
than the prefix? */
|
|
||||||
if (templ->rec_field_is_prefix) {
|
|
||||||
ulint record_size = rec_offs_nth_size(
|
|
||||||
offsets,
|
|
||||||
secondary_index_field_no);
|
|
||||||
const dict_field_t *field =
|
|
||||||
dict_index_get_nth_field(
|
|
||||||
index,
|
|
||||||
secondary_index_field_no);
|
|
||||||
ut_a(field->prefix_len > 0);
|
|
||||||
if (record_size >= field->prefix_len
|
|
||||||
/ templ->mbmaxlen) {
|
|
||||||
row_contains_all_values = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
/* If (1) and (2) were true for all columns above, use
|
|
||||||
rec_prefix_field_no instead of rec_field_no, and skip
|
|
||||||
the clustered lookup below. */
|
|
||||||
if (row_contains_all_values) {
|
|
||||||
for (i = 0; i < prebuilt->n_template; i++) {
|
|
||||||
mysql_row_templ_t* templ =
|
|
||||||
prebuilt->mysql_template + i;
|
|
||||||
templ->rec_field_no =
|
|
||||||
templ->rec_prefix_field_no;
|
|
||||||
ut_a(templ->rec_field_no != ULINT_UNDEFINED);
|
|
||||||
}
|
|
||||||
use_clustered_index = false;
|
|
||||||
srv_stats.n_sec_rec_cluster_reads_avoided.inc();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (use_clustered_index) {
|
|
||||||
|
|
||||||
requires_clust_rec:
|
requires_clust_rec:
|
||||||
ut_ad(index != clust_index);
|
ut_ad(index != clust_index);
|
||||||
/* We use a 'goto' to the preceding label if a consistent
|
/* We use a 'goto' to the preceding label if a consistent
|
||||||
@ -4960,6 +5009,7 @@ requires_clust_rec:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
use_covering_index:
|
||||||
result_rec = rec;
|
result_rec = rec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user